diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..8fa7d62d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,93 @@ +## Version 4.13.0 + +### Добавлено + +#### grid +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1311 | Вычисляемые поля `cpu_allocation_ratio_vm`, `cpu_allocation_ratio`, `custom_backup_path`, `interface_generation_scheme`, `mac_address_prefix`, `node_self_stop_timer_uptime_monitor` и `node_self_stop_uptime_monitor` в datasource `decort_cb_grid_get_settings` в cloudbroker/grid | +| BATF-1311 | Вычисляемое поле `zero_access_enabled` в datasource `decort_cb_grid` в cloudbroker/grid | +| BATF-1311 | Вычисляемое поле `policies` в datasource `decort_cb_grid_get_consumption` в cloudbroker/grid | + +#### extnet +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1302 | Вычисляемое поле `free_ips` в datasource `decort_extnet_list` в cloudapi/extnet | + +#### node +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1306 | Вычисляемое поле `pci_devices` в datasource `decort_cb_node_list` в cloudbroker/node | +| BATF-1294 | Вычисляемые поля `one_g_free`, `one_g_reserved`, `one_g_available`, `one_g_used`, `one_g_dpdk_reserved`, `two_m_free`, `two_m_reserved`, `two_m_available` и `two_m_used` в блоке `memory` в datasources `decort_cb_node` и `decort_cb_node_list` в cloudbroker/node | +| BATF-1305 | Datasources `decort_cb_node_network_info` и `decort_cb_node_pci_devices` в cloudbroker/node | + +#### kvmvm +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1303 | Опциональное поле `clock` в resource `decort_cb_kvmvm` в cloudbroker/kvmvm | +| BATF-1303 | Опциональное поле `clock` в resource `decort_kvmvm` в cloudapi/kvmvm | +| BATF-1303 | Вычисляемое поле `clock` в datasources `decort_cb_kvmvm`, `decort_cb_kvmvm_list` и `decort_cb_kvmvm_list_deleted` в cloudbroker/kvmvm | +| BATF-1303 | Вычисляемое поле `clock` в datasources `decort_kvmvm`, `decort_kvmvm_list` и `decort_kvmvm_list_deleted` в cloudapi/kvmvm | +| BATF-1297 | Datasource `decort_cb_kvmvm_cpu_alignment_profile` в cloudbroker/kvmvm | +| BATF-1297 | Datasource `decort_kvmvm_cpu_alignment_profile` в cloudapi/kvmvm | +| BATF-1297 | Опциональное поле `cpu_alignment_profile` в resource `decort_cb_kvmvm` в cloudbroker/kvmvm и | +| BATF-1297 | Опциональное поле `cpu_alignment_profile` в resource `decort_kvmvm` в cloudapi/kvmvm | +| BATF-1297 | Вычисляемое поле `cpu_alignment_profiles` в datasources `decort_cb_kvmvm`, `decort_cb_kvmvm_list` и `decort_cb_kvmvm_list_deleted` в cloudbroker/kvmvm | +| BATF-1297 | Вычисляемое поле `cpu_alignment_profiles` в datasources `decort_kvmvm`, `decort_kvmvm_list` и `decort_kvmvm_list_deleted` в cloudapi/kvmvm | + +#### zone +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1295 | Опциональное поле `hypervisor_similarity_in_percentage` и вычисляемое поле `cpu_alignment_profiles` в resource `decort_cb_zone` в cloudbroker/zone | +| BATF-1295 | Datasources `decort_cb_zone_cpu_alignment_profile`, `decort_cb_zone_cpu_alignment_profile_list` и `decort_cb_zone_cpu_alignment_profile_test` в cloudbroker/zone | + +### Изменено + +#### image +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1304 | Тип опционального поля `type_image` с `string` на `[]string` в datasource `decort_image_list` в cloudapi/image | +| BATF-1304 | Тип опционального поля `type_image` с `string` на `[]string` в datasource `decort_cb_image_list` в cloudbroker/image | + +#### kvmvm +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1300 | Тип вычисляемого поля `blk_discard` с `bool` на `string` и переименование в `discard` в блоке `disks` в resource `decort_cb_kvmvm` в cloudbroker/kvmvm | +| BATF-1300 | Тип опционального поля `blk_discard` с `bool` на `string` и переименование в `discard` в блоке `disks` в resource `decort_cb_kvmvm` в cloudbroker/kvmvm | +| BATF-1300 | Тип опционального поля `boot_disk_blk_discard` с `bool` на `string` и переименование в `boot_disk_discard` в resource `decort_cb_kvmvm` в cloudbroker/kvmvm | +| BATF-1300 | Тип вычисляемого поля `blk_discard` с `bool` на `string` и переименование в `discard` в блоке `disks` в datasource `decort_cb_kvmvm` в cloudbroker/kvmvm | +| BATF-1300 | Тип вычисляемого поля `blk_discard` с `bool` на `string` и переименование в `discard` в блоке `disks` в resource `decort_kvmvm` и datasource `decort_kvmvm` в cloudapi/kvmvm | + +#### disks +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1300 | Тип опционального поля `blk_discard` с `bool` на `string` и переименование в `discard` в resource `decort_cb_disk` в cloudbroker/disks | +| BATF-1300 | Тип вычисляемого поля `blk_discard` с `bool` на `string` и переименование в `discard` в datasources `decort_cb_disk`, `decort_cb_disk_list`, `decort_cb_disk_list_unattached` и `decort_cb_disk_list_deleted` в cloudbroker/disks | +| BATF-1300 | Тип вычисляемого поля `blk_discard` с `bool` на `string` и переименование в `discard` в resource `decort_disk` и datasources `decort_disk`, `decort_disk_list`, `decort_disk_list_unattached` и `decort_disk_list_deleted` в cloudapi/disks | + +#### user +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1293 | Тип поля `password` с опционального на обязательный в resource `decort_cb_user` в cloudbroker/user | + +#### image +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1299 | Тип поля `account_id` c опционального на обязательное в resource `decort_image_virtual` в cloudapi/image | + + +### Исправлено + + +### Удалено + +#### grid +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1311 | Вычисляемые поля `ckey` и `meta` в datasource `decort_cb_grid` в cloudbroker/grid | + +#### user +| Идентификатор
задачи | Описание | +| --- | --- | +| BATF-1293 | Вычисляемое поле `password` в datasources `decort_cb_user` и `decort_cb_user_list` в cloudbroker/user | + diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..36cfecbd --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022 Basis LTD + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..d5e4de5e --- /dev/null +++ b/Makefile @@ -0,0 +1,85 @@ +TEST?=$$(go list ./... | grep -v 'vendor') +HOSTNAME=basis +NAMESPACE=decort +NAME=terraform-provider-decort +BINDIR = ./bin +ZIPDIR = ./zip +BINARY=${NAME} +WORKPATH= ./examples/terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH} +MAINPATH = ./cmd/decort/ +VERSION=4.13.0 +OS_ARCH=$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH) + +FILES = ${BINARY}_${VERSION}_darwin_amd64\ + ${BINARY}_${VERSION}_darwin_arm64\ + ${BINARY}_${VERSION}_freebsd_386\ + ${BINARY}_${VERSION}_freebsd_amd64\ + ${BINARY}_${VERSION}_freebsd_arm\ + ${BINARY}_${VERSION}_linux_386\ + ${BINARY}_${VERSION}_linux_amd64\ + ${BINARY}_${VERSION}_linux_arm\ + ${BINARY}_${VERSION}_linux_arm64\ + ${BINARY}_${VERSION}_openbsd_386\ + ${BINARY}_${VERSION}_openbsd_amd64\ + ${BINARY}_${VERSION}_solaris_amd64\ + ${BINARY}_${VERSION}_windows_386.exe\ + ${BINARY}_${VERSION}_windows_amd64.exe\ + +BINS = $(addprefix bin/, $(FILES)) + +default: install + +image: + GOOS=linux GOARCH=amd64 go build -o terraform-provider-decort ./cmd/decort/ + docker build . -t rudecs/tf:3.2.2 + rm terraform-provider-decort + +lint: + golangci-lint run --timeout 600s + +st: + go build -o ${BINARY} ${MAINPATH} + cp ${BINARY} ${WORKPATH} + rm ${BINARY} + +build: + go build -o ${BINARY} ${MAINPATH} + +release: $(FILES) + +$(FILES) : $(BINDIR) $(ZIPDIR) $(BINS) + zip -r $(ZIPDIR)/$@.zip $(BINDIR)/$@ + zip -rj $(ZIPDIR)/$@.zip scripts/install.bat scripts/install.sh + +$(BINDIR): + mkdir $@ + +$(ZIPDIR): + mkdir $@ + +$(BINS): + GOOS=darwin GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_darwin_amd64 $(MAINPATH) + GOOS=darwin GOARCH=arm64 go build -o ./bin/${BINARY}_${VERSION}_darwin_arm64 $(MAINPATH) + GOOS=freebsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_freebsd_386 $(MAINPATH) + GOOS=freebsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_freebsd_amd64 $(MAINPATH) + GOOS=freebsd GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_freebsd_arm $(MAINPATH) + GOOS=linux GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_linux_386 $(MAINPATH) + GOOS=linux GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_linux_amd64 $(MAINPATH) + GOOS=linux GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_linux_arm $(MAINPATH) + GOOS=linux GOARCH=arm64 go build -o ./bin/${BINARY}_${VERSION}_linux_arm64 ${MAINPATH} + GOOS=openbsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_openbsd_386 $(MAINPATH) + GOOS=openbsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_openbsd_amd64 $(MAINPATH) + GOOS=solaris GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_solaris_amd64 $(MAINPATH) + GOOS=windows GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_windows_386.exe $(MAINPATH) + GOOS=windows GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_windows_amd64.exe $(MAINPATH) + +install: build + mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH} + mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH} + +test: + go test -i $(TEST) || exit 1 + echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 + +testacc: + TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m diff --git a/README.md b/README.md new file mode 100644 index 00000000..f379f63d --- /dev/null +++ b/README.md @@ -0,0 +1,244 @@ +# terraform-provider-decort + +Terraform provider для платформы Digital Energy Cloud Orchestration Technology (DECORT) + +## Соответсвие версий платформы версиям провайдера + +| Версия DECORT API | Версия провайдера Terraform | +| ------ | ------ | +| 4.6.0 | 4.12.x | +| 4.5.0 | 4.11.x | +| 4.4.0 | 4.10.x | +| 4.3.0 | 4.9.x | +| 4.2.0 | 4.8.x | +| 4.1.0 | 4.7.x | +| 4.0.0 | 4.6.x | +| 3.8.9 | 4.5.x | +| 3.8.8 | 4.4.x | +| 3.8.7 | 4.3.x | +| 3.8.6 | 4.0.x, 4.1.x, 4.2.x | +| 3.8.5 | 3.4.x | +| 3.8.0 - 3.8.4 | 3.3.1 | +| 3.7.x | rc-1.25 | +| 3.6.x | rc-1.10 | +| до 3.6.0 | [terraform-provider-decs](https://github.com/rudecs/terraform-provider-decs) | + +## Режимы работы + +Провайдер позволяет работать в трех режимах: + +- Режим пользователя, +- Режим администратора.
+ Используйте ресурсы `decort_cb_` для администрирования.
+- Режим SDN.
+ Используйте ресурсы `decort_sdn_` для работы с группой sdn.
+ Вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki + +## Возможности провайдера + +- Режим пользователя: + - Работа с accounts, + - Работа с audit, + - Работа с bservice, + - Работа с disks, + - Работа с dpdk, + - Работа с extnets, + - Работа с flipgroups, + - Работа с image, + - Работа с k8s, + - Работа с Compute instances, + - Работа с load balancer, + - Работа с locations, + - Работа с pfw, + - Работа с resource groups, + - Работа с security groups, + - Работа с snapshots, + - Работа с trunk, + - Работа с VINS, + - Работа с SEPs, + - Работа с Zone. + +- Режим администратора: + - Работа с accounts, + - Работа с audit, + - Работа с disks, + - Работа с dpdk, + - Работа с extnets, + - Работа с flipgroups, + - Работа с grids, + - Работа с images, + - Работа с k8ci, + - Работа с k8s, + - Работа с Compute instances, + - Работа с load balancer, + - Работа с pci device, + - Работа с resource groups, + - Работа с seps, + - Работа с user, + - Работа с security groups, + - Работа с trunk, + - Работа с VINS, + - Работа с Zone. + +- Режим SDN: + - Работа с access groups, + - Работа с default security policies, + - Работа с hypervisors, + - Работа с segments, + - Работа с network object groups + +Со списком и описанием функционала всех групп можно ознамоиться на Вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki + +## Установка +Начиная с версии провайдера `4.3.0` в релизном архиве находятся скрипты-инсталляторы. +Чтобы выполнить установку, необходимо: +1. Перейти по адресу: https://repository.basistech.ru/BASIS/terraform-provider-decort/releases +2. Выбрать необходимую версию провайдера подходящую под операционную систему. +3. Скачать архив. +4. Распаковать архив. +5. Выполнить скрипт установщика, `install.sh` или `install.bat` для Windows.
+*Для запуска `install.sh` не забудьте изменить права доступа к файлу* +```bash +chmod u+x install.sh +``` +6. Дождаться сообщения об успешной установке. Установщик выведет актуальный блок конфигурации провайдера, скопируйте его +```bash +DECORT provider version 4.12.0 has been successfully installed + +Copy this provider configuration to main.tf file: +terraform { + required_providers { + decort = { + version = "4.12.0" + source = "basis/decort/decort" + } + } +} +``` +7. После этого, создайте файл `main.tf` в рабочей директории, которая может находится в любом удобном для пользователя месте. +В данном примере, рабочая директория с файлом main.tf находится по пути: +```bash +~/work/tfdir/main.tf +``` +8. Вставьте в `main.tf` блок конфигурации провайдера, который был выведен на экран установщиком: +```terraform +terraform { + required_providers { + decort = { + version = "4.10.0" + source = "basis/decort/decort" + } + } +} +``` +9. Добавьте в файл блок с инициализацией провайдера. +```terraform +provider "decort" { + authenticator = "decs3o" + controller_url = "https://mr4.digitalenergy.online" + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} +``` + +10. В консоли выполните команду +```bash +terraform init +``` + +11. В случае успешной установки, Terraform инициализирует провайдер и будет готов к дальнейшей работе. + +## Установка из релизов +Terraform провайдер DECORT имеет скомпилированные релизные версии, которые расположены по адресу: [Релизы](https://repository.basistech.ru/BASIS/terraform-provider-decort/releases). +Чтобы выполнить установку из релиза, необходимо: +1. Перейти по адресу: https://repository.basistech.ru/BASIS/terraform-provider-decort/releases +2. Выбрать необходимую версию провайдера подходящую под операционную систему. +3. Скачать архив. +4. Распаковать архив. +5. Полученный файл (в директории `bin/`) необходимо поместить: +Linux: +```bash +~/.terraform.d/plugins/${host_name}/${namespace}/${type}/${version}/${target} +``` +Windows: +```powershell +%APPDATA%\terraform.d\plugins\${host_name}\${namespace}\${type}\${version}\${target} +``` +Где: +- host_name - имя хоста, держателя провайдера, например, basis +- namespace - пространство имен хоста, например decort +- type - тип провайдера, может совпадать с пространством имен, например, decort +- version - версия провайдера, например 4.12.0 +- target - архитектура операционной системы, например windows_amd64 + +В примере ниже используется путь до провайдера на машине с ОС Linux: + +```bash +~/.terraform.d/plugins/basis/decort/decort/4.12.0/linux_amd64/tf-provider + ^ ^ ^ ^ ^ ^ + host_name | | | | | | + | | | | | + namespace | | | | | + | | | | + type | | | | + | | | + version | | | + | | + target | | + | + исполняемый файл | +``` + +6. После этого, создайте файл `main.tf` в рабочей директории, которая может находится в любом удобном для пользователя месте. +В данном примере, рабочая директория с файлом main.tf находится по пути: +```bash +~/work/tfdir/main.tf +``` +7. Добавьте в `main.tf` следующий блок +```terraform +terraform { + required_providers { + decort = { + version = "4.12.0" + source = "basis/decort/decort" + } + } +} +``` +В поле `version` указывается версия провайдера. +
+**ВНИМАНИЕ: Версии в блоке и в пути к исполняемому файлу провайдера должны совпадать!** + +В поле `source` помещается путь до репозитория с версией вида: + +```bash +${host_name}/${namespace}/${type} +``` + +**ВНИМАНИЕ: Версии в блоке и в пути к исполняемому файлу провайдера должны совпадать!** + +8. Добавьте в файл блок с инициализацией провайдера. +```terraform +provider "decort" { + authenticator = "decs3o" + controller_url = "https://mr4.digitalenergy.online" + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} +``` + +9. В консоли выполните команду +```bash +terraform init +``` + +10. В случае успешной установки, Terraform инициализирует провайдер и будет готов к дальнейшей работе. + +## Примеры работы + +Примеры работы можно найти: + +- На вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +- В папке `samples` + +Хорошей работы! diff --git a/cmd/decort/main.go b/cmd/decort/main.go new file mode 100644 index 00000000..61730323 --- /dev/null +++ b/cmd/decort/main.go @@ -0,0 +1,56 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package main + +import ( + log "github.com/sirupsen/logrus" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/provider" +) + +//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs + +func main() { + log.SetLevel(log.DebugLevel) + log.Debug("Debug logging enabled") + + plugin.Serve(&plugin.ServeOpts{ + ProviderFunc: func() *schema.Provider { + return provider.Provider() + }, + }) +} diff --git a/debug.txt b/debug.txt deleted file mode 100644 index b2b5d0d0..00000000 --- a/debug.txt +++ /dev/null @@ -1 +0,0 @@ -debug \ No newline at end of file diff --git a/docs/data-sources/account.md b/docs/data-sources/account.md new file mode 100644 index 00000000..30f6939f --- /dev/null +++ b/docs/data-sources/account.md @@ -0,0 +1,130 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `company` (String) +- `companyurl` (String) +- `compute_features` (List of String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `dc_location` (String) +- `deactivation_time` (Number) +- `default_zone_id` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `displayname` (String) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `machines` (List of Object) (see [below for nested schema](#nestedatt--machines)) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedatt--resource_limits)) +- `send_access_emails` (Boolean) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `updated_by` (String) +- `updated_time` (Number) +- `version` (Number) +- `vins` (List of Number) +- `vinses` (Number) +- `zone_ids` (List of Object) (see [below for nested schema](#nestedatt--zone_ids)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `can_be_deleted` (Boolean) +- `emails` (List of String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `started` (Number) +- `stopped` (Number) + + + +### Nested Schema for `machines` + +Read-Only: + +- `halted` (Number) +- `running` (Number) + + + +### Nested Schema for `resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (List of Object) (see [below for nested schema](#nestedobjatt--resource_limits--storage_policy)) + + +### Nested Schema for `resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) + + + + +### Nested Schema for `zone_ids` + +Read-Only: + +- `id` (Number) +- `name` (String) diff --git a/docs/data-sources/account_audits_list.md b/docs/data-sources/account_audits_list.md new file mode 100644 index 00000000..a897a5aa --- /dev/null +++ b/docs/data-sources/account_audits_list.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_audits_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_audits_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `call` (String) +- `responsetime` (Number) +- `statuscode` (Number) +- `timestamp` (Number) +- `user` (String) diff --git a/docs/data-sources/account_computes_list.md b/docs/data-sources/account_computes_list.md new file mode 100644 index 00000000..063535c2 --- /dev/null +++ b/docs/data-sources/account_computes_list.md @@ -0,0 +1,76 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_computes_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_computes_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `compute_id` (Number) Filter by compute ID +- `extnet_id` (Number) Filter by extnet ID +- `extnet_name` (String) Filter by extnet name +- `ip_address` (String) Filter by IP address +- `name` (String) Filter by compute name +- `page` (Number) Page number +- `rg_id` (Number) Filter by RG ID +- `rg_name` (String) Filter by RG name +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `tech_status` (String) Filter by tech. status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `compute_id` (Number) +- `compute_name` (String) +- `cpus` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `ram` (Number) +- `registered` (Boolean) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `tech_status` (String) +- `total_disks_size` (Number) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_connected` (Number) diff --git a/docs/data-sources/account_consumed_units.md b/docs/data-sources/account_consumed_units.md new file mode 100644 index 00000000..9f1a35e3 --- /dev/null +++ b/docs/data-sources/account_consumed_units.md @@ -0,0 +1,42 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_consumed_units Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_consumed_units (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/account_consumed_units_by_type.md b/docs/data-sources/account_consumed_units_by_type.md new file mode 100644 index 00000000..94818412 --- /dev/null +++ b/docs/data-sources/account_consumed_units_by_type.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_consumed_units_by_type Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_consumed_units_by_type (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account +- `cu_type` (String) cloud unit resource type + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `cu_result` (Number) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/account_deleted_list.md b/docs/data-sources/account_deleted_list.md new file mode 100644 index 00000000..0adab393 --- /dev/null +++ b/docs/data-sources/account_deleted_list.md @@ -0,0 +1,72 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_deleted_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_deleted_list (Data Source) + + + + + + +## Schema + +### Optional + +- `acl` (String) Filter by ACL +- `by_id` (Number) Filter by ID +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `compute_features` (List of String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `zone_ids` (List of Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) diff --git a/docs/data-sources/account_disks_list.md b/docs/data-sources/account_disks_list.md new file mode 100644 index 00000000..3e88c5f9 --- /dev/null +++ b/docs/data-sources/account_disks_list.md @@ -0,0 +1,59 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_disks_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_disks_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `disk_id` (Number) Filter by disk ID +- `disk_max_size` (Number) Filter by disk max size +- `name` (String) Filter by disk name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `type` (String) Filter by disk type + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `disk_id` (Number) +- `disk_name` (String) +- `pool` (String) +- `sep_id` (Number) +- `shareable` (Boolean) +- `size_max` (Number) +- `type` (String) diff --git a/docs/data-sources/account_flipgroups_list.md b/docs/data-sources/account_flipgroups_list.md new file mode 100644 index 00000000..ebf3b14b --- /dev/null +++ b/docs/data-sources/account_flipgroups_list.md @@ -0,0 +1,75 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_flipgroups_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_flipgroups_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `by_ip` (String) Filter by IP +- `extnet_id` (Number) Filter by extnet ID +- `flipgroup_id` (Number) Filter by flipgroup ID +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) Filter by ViNS ID +- `vins_name` (String) Filter by ViNS name + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `client_type` (String) +- `conn_type` (String) +- `created_by` (String) +- `created_time` (Number) +- `default_gw` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `fg_id` (Number) +- `fg_name` (String) +- `gid` (Number) +- `guid` (Number) +- `ip` (String) +- `milestones` (Number) +- `net_id` (Number) +- `net_type` (String) +- `netmask` (Number) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) diff --git a/docs/data-sources/account_list.md b/docs/data-sources/account_list.md new file mode 100644 index 00000000..509348ae --- /dev/null +++ b/docs/data-sources/account_list.md @@ -0,0 +1,73 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_list (Data Source) + + + + + + +## Schema + +### Optional + +- `acl` (String) Filter by ACL +- `by_id` (Number) Filter by ID +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `compute_features` (List of String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `zone_ids` (List of Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) diff --git a/docs/data-sources/account_reserved_units.md b/docs/data-sources/account_reserved_units.md new file mode 100644 index 00000000..6e78cc85 --- /dev/null +++ b/docs/data-sources/account_reserved_units.md @@ -0,0 +1,42 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_reserved_units Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_reserved_units (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/account_resource_consumption_get.md b/docs/data-sources/account_resource_consumption_get.md new file mode 100644 index 00000000..05e74f75 --- /dev/null +++ b/docs/data-sources/account_resource_consumption_get.md @@ -0,0 +1,157 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_resource_consumption_get Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_resource_consumption_get (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `consumed` (List of Object) (see [below for nested schema](#nestedatt--consumed)) +- `id` (String) The ID of this resource. +- `reserved` (List of Object) (see [below for nested schema](#nestedatt--reserved)) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedatt--resource_limits)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `consumed` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `ext_ips` (Number) +- `gpu` (Number) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--consumed--policies)) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--consumed--seps)) + + +### Nested Schema for `consumed.policies` + +Read-Only: + +- `disk_size` (Number) +- `disk_size_max` (Number) +- `id` (String) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--consumed--policies--seps)) + + +### Nested Schema for `consumed.policies.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `reserved` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `ext_ips` (Number) +- `gpu` (Number) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--reserved--policies)) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--reserved--seps)) + + +### Nested Schema for `reserved.policies` + +Read-Only: + +- `disk_size` (Number) +- `disk_size_max` (Number) +- `id` (String) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--reserved--policies--seps)) + + +### Nested Schema for `reserved.policies.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (List of Object) (see [below for nested schema](#nestedobjatt--resource_limits--storage_policy)) + + +### Nested Schema for `resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) diff --git a/docs/data-sources/account_resource_consumption_list.md b/docs/data-sources/account_resource_consumption_list.md new file mode 100644 index 00000000..c23520ad --- /dev/null +++ b/docs/data-sources/account_resource_consumption_list.md @@ -0,0 +1,138 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_resource_consumption_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_resource_consumption_list (Data Source) + + + + + + +## Schema + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `consumed` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed)) +- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved)) + + +### Nested Schema for `items.consumed` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `ext_ips` (Number) +- `gpu` (Number) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed--policies)) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed--seps)) + + +### Nested Schema for `items.consumed.policies` + +Read-Only: + +- `disk_size` (Number) +- `disk_size_max` (Number) +- `id` (String) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed--policies--seps)) + + +### Nested Schema for `items.consumed.policies.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.reserved` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `ext_ips` (Number) +- `gpu` (Number) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved--policies)) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved--seps)) + + +### Nested Schema for `items.reserved.policies` + +Read-Only: + +- `disk_size` (Number) +- `disk_size_max` (Number) +- `id` (String) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved--policies--seps)) + + +### Nested Schema for `items.reserved.policies.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) diff --git a/docs/data-sources/account_rg_list.md b/docs/data-sources/account_rg_list.md new file mode 100644 index 00000000..f2b23e08 --- /dev/null +++ b/docs/data-sources/account_rg_list.md @@ -0,0 +1,120 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_rg_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_rg_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `name` (String) Filter by name +- `page` (Number) Page number +- `rg_id` (Number) Filter by RG ID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) Filter by ViNS ID +- `vm_id` (Number) Filter by VM ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `computes` (List of Object) (see [below for nested schema](#nestedobjatt--items--computes)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `milestones` (Number) +- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources)) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vinses` (Number) + + +### Nested Schema for `items.computes` + +Read-Only: + +- `started` (Number) +- `stopped` (Number) + + + +### Nested Schema for `items.resources` + +Read-Only: + +- `consumed` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--consumed)) +- `limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--limits)) +- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--reserved)) + + +### Nested Schema for `items.resources.consumed` + +Read-Only: + +- `cpu` (Number) +- `disksize` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) + + + +### Nested Schema for `items.resources.limits` + +Read-Only: + +- `cpu` (Number) +- `disksize` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) + + + +### Nested Schema for `items.resources.reserved` + +Read-Only: + +- `cpu` (Number) +- `disksize` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) diff --git a/docs/data-sources/account_templates_list.md b/docs/data-sources/account_templates_list.md new file mode 100644 index 00000000..d359d441 --- /dev/null +++ b/docs/data-sources/account_templates_list.md @@ -0,0 +1,62 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_templates_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_templates_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `image_id` (Number) Find by image id +- `include_deleted` (Boolean) +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `type` (String) Filter by type + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `desc` (String) +- `public` (Boolean) +- `size` (Number) +- `status` (String) +- `template_id` (Number) +- `template_name` (String) +- `type` (String) +- `unc_path` (String) +- `username` (String) diff --git a/docs/data-sources/account_vins_list.md b/docs/data-sources/account_vins_list.md new file mode 100644 index 00000000..e2e9e957 --- /dev/null +++ b/docs/data-sources/account_vins_list.md @@ -0,0 +1,71 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account_vins_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account_vins_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `ext_ip` (String) Filter by external IP +- `name` (String) Filter by name +- `page` (Number) Page number +- `rg_id` (Number) Filter by RG ID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) Filter by ViNS ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `computes` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `external_ip` (String) +- `extnet_id` (Number) +- `free_ips` (Number) +- `network` (String) +- `pri_vnf_dev_id` (Number) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vin_id` (Number) +- `vin_name` (String) diff --git a/docs/data-sources/audit.md b/docs/data-sources/audit.md new file mode 100644 index 00000000..94b9bdea --- /dev/null +++ b/docs/data-sources/audit.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_audit Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_audit (Data Source) + + + + + + +## Schema + +### Required + +- `audit_guid` (String) audit guid + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `args` (String) +- `call` (String) +- `correlation_id` (String) +- `guid` (String) +- `id` (String) The ID of this resource. +- `kwargs` (String) +- `remote_addr` (String) +- `responsetime` (Number) +- `result` (String) +- `status_code` (Number) +- `tags` (String) +- `timestamp` (Number) +- `timestamp_end` (Number) +- `user` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/audit_list.md b/docs/data-sources/audit_list.md new file mode 100644 index 00000000..2044c20b --- /dev/null +++ b/docs/data-sources/audit_list.md @@ -0,0 +1,77 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_audit_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_audit_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) +- `call` (String) find by api endpoint (Mongo RegExp supported) +- `compute_id` (Number) +- `exclude_audit_lines` (Boolean) +- `flipgroup_id` (Number) +- `k8s_id` (Number) +- `lb_id` (Number) +- `max_status_code` (Number) find by HTTP max status code +- `min_status_code` (Number) find by HTTP min status code +- `page` (Number) page number +- `request_id` (String) request id +- `resgroup_id` (Number) +- `sep_id` (Number) +- `service_id` (Number) +- `size` (Number) page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `timestamp_at` (Number) find all audits after point in time (unixtime) +- `timestamp_to` (Number) find all audits before point in time (unixtime) +- `user` (String) find by user (Mongo RegExp supported) +- `vins_id` (Number) + +### Read-Only + +- `entry_count` (Number) entry count +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `args` (String) +- `call` (String) +- `compute_id` (Number) +- `correlation_id` (String) +- `guid` (String) +- `kwargs` (String) +- `remote_addr` (String) +- `resgroup_id` (Number) +- `responsetime` (Number) +- `result` (String) +- `status_code` (Number) +- `timestamp` (Number) +- `timestamp_end` (Number) +- `ttl` (String) +- `user` (String) diff --git a/docs/data-sources/bservice.md b/docs/data-sources/bservice.md new file mode 100644 index 00000000..9d192895 --- /dev/null +++ b/docs/data-sources/bservice.md @@ -0,0 +1,107 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_bservice Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_bservice (Data Source) + + + + + + +## Schema + +### Required + +- `service_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `base_domain` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `cpu_total` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `disk_total` (Number) +- `gid` (Number) +- `groups` (List of Object) (see [below for nested schema](#nestedatt--groups)) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `milestones` (Number) +- `parent_srv_id` (Number) +- `parent_srv_type` (String) +- `ram_total` (Number) +- `rg_id` (Number) +- `rg_name` (String) +- `service_name` (String) +- `snapshots` (List of Object) (see [below for nested schema](#nestedatt--snapshots)) +- `ssh_key` (String) +- `ssh_user` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `account_id` (Number) +- `architecture` (String) +- `compgroup_id` (Number) +- `compgroup_name` (String) +- `compgroup_role` (String) +- `id` (Number) +- `name` (String) +- `node_id` (Number) +- `rg_id` (Number) +- `status` (String) +- `tech_status` (String) + + + +### Nested Schema for `groups` + +Read-Only: + +- `computes` (Number) +- `consistency` (Boolean) +- `id` (Number) +- `name` (String) +- `status` (String) +- `tech_status` (String) + + + +### Nested Schema for `snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `timestamp` (Number) +- `valid` (Boolean) diff --git a/docs/data-sources/bservice_deleted_list.md b/docs/data-sources/bservice_deleted_list.md new file mode 100644 index 00000000..45d16113 --- /dev/null +++ b/docs/data-sources/bservice_deleted_list.md @@ -0,0 +1,70 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_bservice_deleted_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_bservice_deleted_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) ID of the account to query for BasicService instances +- `page` (Number) Page number +- `rg_id` (Number) ID of the resource group to query for BasicService instances +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `base_domain` (String) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `gid` (Number) +- `groups` (List of Number) +- `guid` (Number) +- `parent_srv_id` (Number) +- `parent_srv_type` (String) +- `rg_id` (Number) +- `rg_name` (String) +- `service_id` (Number) +- `service_name` (String) +- `ssh_user` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `zone_id` (Number) diff --git a/docs/data-sources/bservice_group.md b/docs/data-sources/bservice_group.md new file mode 100644 index 00000000..d7af6b53 --- /dev/null +++ b/docs/data-sources/bservice_group.md @@ -0,0 +1,87 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_bservice_group Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_bservice_group (Data Source) + + + + + + +## Schema + +### Required + +- `compgroup_id` (Number) +- `service_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `compgroup_name` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `consistency` (Boolean) +- `cpu` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `disk` (Number) +- `driver` (String) +- `extnets` (List of Number) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `milestones` (Number) +- `parents` (List of Number) +- `ram` (Number) +- `rg_id` (Number) +- `rg_name` (String) +- `role` (String) +- `sep_id` (Number) +- `seq_no` (Number) +- `status` (String) +- `tech_status` (String) +- `timeout_start` (Number) +- `updated_by` (String) +- `updated_time` (Number) +- `vinses` (List of Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `chipset` (String) +- `id` (Number) +- `ip_addresses` (List of String) +- `name` (String) +- `os_users` (List of Object) (see [below for nested schema](#nestedobjatt--computes--os_users)) + + +### Nested Schema for `computes.os_users` + +Read-Only: + +- `login` (String) +- `password` (String) diff --git a/docs/data-sources/bservice_list.md b/docs/data-sources/bservice_list.md new file mode 100644 index 00000000..aae578db --- /dev/null +++ b/docs/data-sources/bservice_list.md @@ -0,0 +1,76 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_bservice_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_bservice_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) ID of the account to query for BasicService instances +- `account_name` (String) Filter by account name +- `by_id` (Number) Filter by ID +- `name` (String) Filter by bservice name +- `page` (Number) Page number +- `rg_id` (Number) ID of the resource group to query for BasicService instances +- `rg_name` (String) Filter by resource group name +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `tech_status` (String) Filter by tech status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `base_domain` (String) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `gid` (Number) +- `groups` (List of Number) +- `guid` (Number) +- `parent_srv_id` (Number) +- `parent_srv_type` (String) +- `rg_id` (Number) +- `rg_name` (String) +- `service_id` (Number) +- `service_name` (String) +- `ssh_user` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `zone_id` (Number) diff --git a/docs/data-sources/bservice_snapshot_list.md b/docs/data-sources/bservice_snapshot_list.md new file mode 100644 index 00000000..c2a590e3 --- /dev/null +++ b/docs/data-sources/bservice_snapshot_list.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_bservice_snapshot_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_bservice_snapshot_list (Data Source) + + + + + + +## Schema + +### Required + +- `service_id` (Number) ID of the BasicService instance + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `timestamp` (Number) +- `valid` (Boolean) diff --git a/docs/data-sources/cb_account.md b/docs/data-sources/cb_account.md new file mode 100644 index 00000000..c3a9dff7 --- /dev/null +++ b/docs/data-sources/cb_account.md @@ -0,0 +1,110 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `company` (String) +- `companyurl` (String) +- `compute_features` (List of String) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `dc_location` (String) +- `deactivation_time` (Number) +- `default_zone_id` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `displayname` (String) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `resource_limits` (List of Object) (see [below for nested schema](#nestedatt--resource_limits)) +- `resource_types` (List of String) +- `send_access_emails` (Boolean) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `uniq_pools` (List of String) +- `updated_by` (String) +- `updated_time` (Number) +- `version` (Number) +- `vins` (List of Number) +- `zone_ids` (Set of Object) (see [below for nested schema](#nestedatt--zone_ids)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `emails` (List of String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (List of Object) (see [below for nested schema](#nestedobjatt--resource_limits--storage_policy)) + + +### Nested Schema for `resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) + + + + +### Nested Schema for `zone_ids` + +Read-Only: + +- `id` (Number) +- `name` (String) diff --git a/docs/data-sources/cb_account_audits_list.md b/docs/data-sources/cb_account_audits_list.md new file mode 100644 index 00000000..dc89e9af --- /dev/null +++ b/docs/data-sources/cb_account_audits_list.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_audits_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_audits_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `call` (String) +- `responsetime` (Number) +- `statuscode` (Number) +- `timestamp` (Number) +- `user` (String) diff --git a/docs/data-sources/cb_account_available_templates_list.md b/docs/data-sources/cb_account_available_templates_list.md new file mode 100644 index 00000000..553e4870 --- /dev/null +++ b/docs/data-sources/cb_account_available_templates_list.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_available_templates_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_available_templates_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_account_computes_list.md b/docs/data-sources/cb_account_computes_list.md new file mode 100644 index 00000000..bcfb9687 --- /dev/null +++ b/docs/data-sources/cb_account_computes_list.md @@ -0,0 +1,76 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_computes_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_computes_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `compute_id` (Number) Filter by compute ID +- `extnet_id` (Number) Filter by extnet ID +- `extnet_name` (String) Filter by extnet name +- `ip_address` (String) Filter by IP address +- `name` (String) Filter by compute name +- `page` (Number) Page number +- `rg_id` (Number) Filter by RG ID +- `rg_name` (String) Filter by RG name +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `tech_status` (String) Filter by tech. status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `compute_id` (Number) +- `compute_name` (String) +- `cpus` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `ram` (Number) +- `registered` (Boolean) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `tech_status` (String) +- `total_disks_size` (Number) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_connected` (Number) diff --git a/docs/data-sources/cb_account_disks_list.md b/docs/data-sources/cb_account_disks_list.md new file mode 100644 index 00000000..0ad3d74a --- /dev/null +++ b/docs/data-sources/cb_account_disks_list.md @@ -0,0 +1,59 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_disks_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_disks_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `disk_id` (Number) Filter by disk ID +- `disk_max_size` (Number) Filter by disk max size +- `name` (String) Filter by disk name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `type` (String) Filter by disk type + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `disk_id` (Number) +- `disk_name` (String) +- `pool_name` (String) +- `sep_id` (Number) +- `shareable` (Boolean) +- `size_max` (Number) +- `type` (String) diff --git a/docs/data-sources/cb_account_flipgroups_list.md b/docs/data-sources/cb_account_flipgroups_list.md new file mode 100644 index 00000000..3e5227af --- /dev/null +++ b/docs/data-sources/cb_account_flipgroups_list.md @@ -0,0 +1,75 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_flipgroups_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_flipgroups_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `by_ip` (String) Filter by IP +- `extnet_id` (Number) Filter by extnet ID +- `flipgroup_id` (Number) Filter by flipgroup ID +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) Filter by ViNS ID +- `vins_name` (String) Filter by ViNS name + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `client_type` (String) +- `conn_type` (String) +- `created_by` (String) +- `created_time` (Number) +- `default_gw` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `fg_id` (Number) +- `fg_name` (String) +- `gid` (Number) +- `guid` (Number) +- `ip` (String) +- `milestones` (Number) +- `net_id` (Number) +- `net_type` (String) +- `netmask` (Number) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) diff --git a/docs/data-sources/cb_account_list.md b/docs/data-sources/cb_account_list.md new file mode 100644 index 00000000..1d5725c2 --- /dev/null +++ b/docs/data-sources/cb_account_list.md @@ -0,0 +1,112 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_list (Data Source) + + + + + + +## Schema + +### Optional + +- `acl` (String) Filter by ACL +- `by_id` (Number) Filter by ID +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `company` (String) +- `companyurl` (String) +- `compute_features` (List of String) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `dc_location` (String) +- `deactivation_time` (Number) +- `default_zone_id` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `displayname` (String) +- `guid` (Number) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits)) +- `resource_types` (List of String) +- `send_access_emails` (Boolean) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `uniq_pools` (List of String) +- `updated_by` (String) +- `updated_time` (Number) +- `version` (Number) +- `vins` (List of Number) +- `zone_ids` (List of Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits--storage_policy)) + + +### Nested Schema for `items.resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) diff --git a/docs/data-sources/cb_account_list_deleted.md b/docs/data-sources/cb_account_list_deleted.md new file mode 100644 index 00000000..76dc470e --- /dev/null +++ b/docs/data-sources/cb_account_list_deleted.md @@ -0,0 +1,110 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `acl` (String) Filter by ACL +- `by_id` (Number) Filter by ID +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `company` (String) +- `companyurl` (String) +- `compute_features` (List of String) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `dc_location` (String) +- `deactivation_time` (Number) +- `default_zone_id` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `displayname` (String) +- `guid` (Number) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits)) +- `resource_types` (List of String) +- `send_access_emails` (Boolean) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `uniq_pools` (List of String) +- `updated_by` (String) +- `updated_time` (Number) +- `version` (Number) +- `vins` (List of Number) +- `zone_ids` (List of Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits--storage_policy)) + + +### Nested Schema for `items.resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) diff --git a/docs/data-sources/cb_account_resource_consumption_get.md b/docs/data-sources/cb_account_resource_consumption_get.md new file mode 100644 index 00000000..646de1d4 --- /dev/null +++ b/docs/data-sources/cb_account_resource_consumption_get.md @@ -0,0 +1,148 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_resource_consumption_get Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_resource_consumption_get (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `consumed` (List of Object) (see [below for nested schema](#nestedatt--consumed)) +- `id` (String) The ID of this resource. +- `reserved` (List of Object) (see [below for nested schema](#nestedatt--reserved)) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedatt--resource_limits)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `consumed` + +Read-Only: + +- `cpu` (Number) +- `disksize` (Number) +- `disksizemax` (Number) +- `extips` (Number) +- `gpu` (Number) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--consumed--policies)) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--consumed--seps)) + + +### Nested Schema for `consumed.policies` + +Read-Only: + +- `disk_size` (Number) +- `disk_size_max` (Number) +- `id` (String) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--consumed--policies--seps)) + + +### Nested Schema for `consumed.policies.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `reserved` + +Read-Only: + +- `cpu` (Number) +- `disksize` (Number) +- `disksizemax` (Number) +- `extips` (Number) +- `gpu` (Number) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--reserved--policies)) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--reserved--seps)) + + +### Nested Schema for `reserved.policies` + +Read-Only: + +- `disk_size` (Number) +- `disk_size_max` (Number) +- `id` (String) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--reserved--policies--seps)) + + +### Nested Schema for `reserved.policies.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) diff --git a/docs/data-sources/cb_account_resource_consumption_list.md b/docs/data-sources/cb_account_resource_consumption_list.md new file mode 100644 index 00000000..9484727c --- /dev/null +++ b/docs/data-sources/cb_account_resource_consumption_list.md @@ -0,0 +1,138 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_resource_consumption_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_resource_consumption_list (Data Source) + + + + + + +## Schema + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `consumed` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed)) +- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved)) + + +### Nested Schema for `items.consumed` + +Read-Only: + +- `cpu` (Number) +- `disksize` (Number) +- `disksizemax` (Number) +- `extips` (Number) +- `gpu` (Number) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed--policies)) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed--seps)) + + +### Nested Schema for `items.consumed.policies` + +Read-Only: + +- `disk_size` (Number) +- `disk_size_max` (Number) +- `id` (String) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed--policies--seps)) + + +### Nested Schema for `items.consumed.policies.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.reserved` + +Read-Only: + +- `cpu` (Number) +- `disksize` (Number) +- `disksizemax` (Number) +- `extips` (Number) +- `gpu` (Number) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved--policies)) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved--seps)) + + +### Nested Schema for `items.reserved.policies` + +Read-Only: + +- `disk_size` (Number) +- `disk_size_max` (Number) +- `id` (String) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved--policies--seps)) + + +### Nested Schema for `items.reserved.policies.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) diff --git a/docs/data-sources/cb_account_rg_list.md b/docs/data-sources/cb_account_rg_list.md new file mode 100644 index 00000000..150e4a1a --- /dev/null +++ b/docs/data-sources/cb_account_rg_list.md @@ -0,0 +1,147 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_rg_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_rg_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `entry_count` (Number) +- `name` (String) Filter by name +- `page` (Number) Page number +- `rg_id` (Number) Filter by RG ID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) Filter by ViNS ID +- `vm_id` (Number) Filter by VM ID + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `computes` (List of Object) (see [below for nested schema](#nestedobjatt--items--computes)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `milestones` (Number) +- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources)) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vinses` (Number) + + +### Nested Schema for `items.computes` + +Read-Only: + +- `started` (Number) +- `stopped` (Number) + + + +### Nested Schema for `items.resources` + +Read-Only: + +- `consumed` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--consumed)) +- `limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--limits)) +- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--reserved)) + + +### Nested Schema for `items.resources.consumed` + +Read-Only: + +- `cpu` (Number) +- `disksize` (Number) +- `disksizemax` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--consumed--seps)) + + +### Nested Schema for `items.resources.consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.resources.limits` + +Read-Only: + +- `cpu` (Number) +- `disksize` (Number) +- `disksizemax` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (Number) + + + +### Nested Schema for `items.resources.reserved` + +Read-Only: + +- `cpu` (Number) +- `disksize` (Number) +- `disksizemax` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--reserved--seps)) + + +### Nested Schema for `items.resources.reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) diff --git a/docs/data-sources/cb_account_vins_list.md b/docs/data-sources/cb_account_vins_list.md new file mode 100644 index 00000000..2b9798fa --- /dev/null +++ b/docs/data-sources/cb_account_vins_list.md @@ -0,0 +1,71 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account_vins_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account_vins_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) ID of the account + +### Optional + +- `ext_ip` (String) Filter by external IP +- `name` (String) Filter by name +- `page` (Number) Page number +- `rg_id` (Number) Filter by RG ID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) Filter by ViNS ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `computes` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `external_ip` (String) +- `extnet_id` (Number) +- `free_ips` (Number) +- `network` (String) +- `pri_vnf_dev_id` (Number) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vin_id` (Number) +- `vin_name` (String) diff --git a/docs/data-sources/cb_audit.md b/docs/data-sources/cb_audit.md new file mode 100644 index 00000000..ab7c61ca --- /dev/null +++ b/docs/data-sources/cb_audit.md @@ -0,0 +1,52 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_audit Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_audit (Data Source) + + + + + + +## Schema + +### Required + +- `audit_guid` (String) audit guid + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `args` (String) +- `call` (String) +- `compute_id` (Number) +- `correlation_id` (String) +- `guid` (String) +- `id` (String) The ID of this resource. +- `kwargs` (String) +- `remote_addr` (String) +- `resgroup_id` (Number) +- `responsetime` (Number) +- `result` (String) +- `status_code` (Number) +- `timestamp` (Number) +- `timestamp_end` (Number) +- `ttl` (String) +- `user` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_audit_linked_jobs.md b/docs/data-sources/cb_audit_linked_jobs.md new file mode 100644 index 00000000..c2c4f401 --- /dev/null +++ b/docs/data-sources/cb_audit_linked_jobs.md @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_audit_linked_jobs Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_audit_linked_jobs (Data Source) + + + + + + +## Schema + +### Required + +- `audit_guid` (String) audit guid + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `cmd` (String) +- `guid` (String) +- `nid` (Number) +- `physical_node` (Boolean) +- `state` (String) +- `time_create` (Number) +- `time_start` (Number) +- `time_stop` (Number) +- `timeout` (Number) diff --git a/docs/data-sources/cb_audit_list.md b/docs/data-sources/cb_audit_list.md new file mode 100644 index 00000000..80caa82c --- /dev/null +++ b/docs/data-sources/cb_audit_list.md @@ -0,0 +1,75 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_audit_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_audit_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) +- `call` (String) find by api endpoint (Mongo RegExp supported) +- `compute_id` (Number) +- `exclude_audit_lines` (Boolean) +- `flipgroup_id` (Number) +- `k8s_id` (Number) +- `lb_id` (Number) +- `max_status_code` (Number) find by HTTP max status code +- `min_status_code` (Number) find by HTTP min status code +- `node_id` (Number) +- `page` (Number) page number +- `request_id` (String) request id +- `resgroup_id` (Number) +- `sep_id` (Number) +- `service_id` (Number) +- `size` (Number) page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `timestamp_at` (Number) find all audits after point in time (unixtime) +- `timestamp_to` (Number) find all audits before point in time (unixtime) +- `user` (String) find by user (Mongo RegExp supported) +- `vins_id` (Number) + +### Read-Only + +- `entry_count` (Number) entry count +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `args` (String) +- `call` (String) +- `correlation_id` (String) +- `guid` (String) +- `kwargs` (String) +- `remote_addr` (String) +- `responsetime` (Number) +- `result` (String) +- `status_code` (Number) +- `timestamp` (Number) +- `timestamp_end` (Number) +- `ttl` (String) +- `user` (String) diff --git a/docs/data-sources/cb_audits_export_to_file.md b/docs/data-sources/cb_audits_export_to_file.md new file mode 100644 index 00000000..4ed2c274 --- /dev/null +++ b/docs/data-sources/cb_audits_export_to_file.md @@ -0,0 +1,33 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_audits_export_to_file Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_audits_export_to_file (Data Source) + + + + + + +## Schema + +### Optional + +- `file_path` (String) file path +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_disk.md b/docs/data-sources/cb_disk.md new file mode 100644 index 00000000..28751371 --- /dev/null +++ b/docs/data-sources/cb_disk.md @@ -0,0 +1,150 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_disk Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_disk (Data Source) + + + + + + +## Schema + +### Required + +- `disk_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `acl` (String) +- `blk_discard` (Boolean) +- `block_size` (String) +- `boot_partition` (Number) +- `cache` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `destruction_time` (Number) +- `devicename` (String) +- `disk_name` (String) +- `disk_path` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `images` (List of Number) +- `independent` (Boolean) +- `iotune` (List of Object) (see [below for nested schema](#nestedatt--iotune)) +- `iqn` (String) +- `login` (String) +- `machine_id` (Number) +- `machine_name` (String) +- `milestones` (Number) +- `order` (Number) +- `params` (String) +- `parent_id` (Number) +- `passwd` (String) +- `pci_slot` (Number) +- `pool` (String) +- `present_to` (Map of Number) +- `provision` (String) +- `purge_attempts` (Number) +- `purge_time` (Number) +- `reality_device_number` (Number) +- `reference_id` (String) +- `replication` (List of Object) Replication status (see [below for nested schema](#nestedatt--replication)) +- `res_id` (String) +- `res_name` (String) +- `role` (String) +- `sep_id` (Number) +- `sep_type` (String) +- `shareable` (Boolean) +- `size_available` (Number) +- `size_max` (Number) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedatt--snapshots)) +- `status` (String) +- `storage_policy_id` (Number) Storage policy ID +- `tech_status` (String) +- `to_clean` (Boolean) +- `updated_by` (String) +- `updated_time` (Number) +- `vmid` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `compute_id` (String) +- `compute_name` (String) + + + +### Nested Schema for `iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `reference_id` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/cb_disk_list.md b/docs/data-sources/cb_disk_list.md new file mode 100644 index 00000000..505986f6 --- /dev/null +++ b/docs/data-sources/cb_disk_list.md @@ -0,0 +1,170 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_disk_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_disk_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) ID of the account the disks belong to +- `account_name` (String) Find by account name +- `by_id` (Number) Find by ID +- `compute_id` (Number) Find by compute id +- `disk_max_size` (Number) Find by max disk size +- `name` (String) Find by name +- `page` (Number) Page number +- `pool` (String) Find by pool name +- `rg_id` (Number) Find by rg id +- `sep_id` (Number) Find by sep id +- `shared` (Boolean) Find by shared field +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `storage_policy_id` (Number) storage policy ID +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (String) +- `blk_discard` (Boolean) +- `block_size` (String) +- `boot_partition` (Number) +- `cache` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedobjatt--items--computes)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `destruction_time` (Number) +- `devicename` (String) +- `disk_id` (Number) +- `disk_name` (String) +- `disk_path` (String) +- `gid` (Number) +- `guid` (Number) +- `image_id` (Number) +- `images` (List of Number) +- `independent` (Boolean) +- `iotune` (List of Object) (see [below for nested schema](#nestedobjatt--items--iotune)) +- `iqn` (String) +- `login` (String) +- `machine_id` (Number) +- `machine_name` (String) +- `milestones` (Number) +- `order` (Number) +- `params` (String) +- `parent_id` (Number) +- `passwd` (String) +- `pci_slot` (Number) +- `pool` (String) +- `present_to` (Map of Number) +- `provision` (String) +- `purge_attempts` (Number) +- `purge_time` (Number) +- `reality_device_number` (Number) +- `reference_id` (String) +- `replication` (List of Object) (see [below for nested schema](#nestedobjatt--items--replication)) +- `res_id` (String) +- `res_name` (String) +- `role` (String) +- `sep_id` (Number) +- `sep_type` (String) +- `shareable` (Boolean) +- `size_available` (Number) +- `size_max` (Number) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedobjatt--items--snapshots)) +- `status` (String) +- `storage_policy_id` (Number) +- `tech_status` (String) +- `to_clean` (Boolean) +- `updated_by` (String) +- `updated_time` (Number) +- `vmid` (Number) + + +### Nested Schema for `items.computes` + +Read-Only: + +- `compute_id` (String) +- `compute_name` (String) + + + +### Nested Schema for `items.iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `items.replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `items.snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `reference_id` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/cb_disk_list_deleted.md b/docs/data-sources/cb_disk_list_deleted.md new file mode 100644 index 00000000..86318a6c --- /dev/null +++ b/docs/data-sources/cb_disk_list_deleted.md @@ -0,0 +1,164 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_disk_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_disk_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) ID of the account the disks belong to +- `account_name` (String) Find by account name +- `by_id` (Number) Find by ID +- `disk_max_size` (Number) Find by max disk size +- `name` (String) Find by name +- `page` (Number) Page number +- `shared` (Boolean) Find by shared field +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (String) +- `blk_discard` (Boolean) +- `block_size` (String) +- `boot_partition` (Number) +- `cache` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedobjatt--items--computes)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `destruction_time` (Number) +- `devicename` (String) +- `disk_id` (Number) +- `disk_name` (String) +- `disk_path` (String) +- `gid` (Number) +- `guid` (Number) +- `image_id` (Number) +- `images` (List of Number) +- `independent` (Boolean) +- `iotune` (List of Object) (see [below for nested schema](#nestedobjatt--items--iotune)) +- `iqn` (String) +- `login` (String) +- `machine_id` (Number) +- `machine_name` (String) +- `milestones` (Number) +- `order` (Number) +- `params` (String) +- `parent_id` (Number) +- `passwd` (String) +- `pci_slot` (Number) +- `pool` (String) +- `present_to` (Map of Number) +- `provision` (String) +- `purge_attempts` (Number) +- `purge_time` (Number) +- `reality_device_number` (Number) +- `reference_id` (String) +- `replication` (List of Object) (see [below for nested schema](#nestedobjatt--items--replication)) +- `res_id` (String) +- `res_name` (String) +- `role` (String) +- `sep_id` (Number) +- `sep_type` (String) +- `shareable` (Boolean) +- `size_available` (Number) +- `size_max` (Number) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedobjatt--items--snapshots)) +- `status` (String) +- `storage_policy_id` (Number) +- `tech_status` (String) +- `to_clean` (Boolean) +- `updated_by` (String) +- `updated_time` (Number) +- `vmid` (Number) + + +### Nested Schema for `items.computes` + +Read-Only: + +- `compute_id` (String) +- `compute_name` (String) + + + +### Nested Schema for `items.iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `items.replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `items.snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `reference_id` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/cb_disk_list_unattached.md b/docs/data-sources/cb_disk_list_unattached.md new file mode 100644 index 00000000..01bde6cb --- /dev/null +++ b/docs/data-sources/cb_disk_list_unattached.md @@ -0,0 +1,132 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_disk_list_unattached Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_disk_list_unattached (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) ID of the account the disks belong to +- `account_name` (String) Find by account name +- `by_id` (Number) Find by ID +- `disk_max_size` (Number) Find by max disk size +- `page` (Number) Page number +- `pool` (String) +- `sep_id` (Number) ID of SEP +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `storage_policy_id` (Number) storage policy ID +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `_meta` (List of String) +- `account_id` (Number) +- `account_name` (String) +- `acl` (String) +- `blk_discard` (Boolean) +- `block_size` (String) +- `boot_partition` (Number) +- `cache` (String) +- `created_time` (Number) +- `deleted_time` (Number) +- `desc` (String) +- `destruction_time` (Number) +- `disk_id` (Number) +- `disk_name` (String) +- `disk_path` (String) +- `gid` (Number) +- `guid` (Number) +- `image_id` (Number) +- `images` (List of Number) +- `iotune` (List of Object) (see [below for nested schema](#nestedobjatt--items--iotune)) +- `iqn` (String) +- `login` (String) +- `milestones` (Number) +- `order` (Number) +- `params` (String) +- `parent_id` (Number) +- `passwd` (String) +- `pci_slot` (Number) +- `pool` (String) +- `present_to` (Map of Number) +- `provision` (String) +- `purge_attempts` (Number) +- `purge_time` (Number) +- `reality_device_number` (Number) +- `reference_id` (String) +- `res_id` (String) +- `res_name` (String) +- `role` (String) +- `sep_id` (Number) +- `shareable` (Boolean) +- `size_max` (Number) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedobjatt--items--snapshots)) +- `status` (String) +- `tech_status` (String) +- `to_clean` (Boolean) +- `vmid` (Number) + + +### Nested Schema for `items.iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `items.snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `reference_id` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/cb_disk_replication.md b/docs/data-sources/cb_disk_replication.md new file mode 100644 index 00000000..15cff809 --- /dev/null +++ b/docs/data-sources/cb_disk_replication.md @@ -0,0 +1,140 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_disk_replication Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_disk_replication (Data Source) + + + + + + +## Schema + +### Required + +- `disk_id` (Number) Id of primary disk +- `replica_disk_id` (Number) Id of secondary disk + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `acl` (String) +- `boot_partition` (Number) +- `cache` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `created_time` (Number) +- `deleted_time` (Number) +- `desc` (String) +- `destruction_time` (Number) +- `devicename` (String) +- `disk_name` (String) +- `disk_path` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `images` (List of Number) +- `iotune` (List of Object) (see [below for nested schema](#nestedatt--iotune)) +- `iqn` (String) +- `login` (String) +- `milestones` (Number) +- `order` (Number) +- `params` (String) +- `parent_id` (Number) +- `passwd` (String) +- `pci_slot` (Number) +- `pool` (String) +- `present_to` (Map of Number) +- `purge_attempts` (Number) +- `purge_time` (Number) +- `reality_device_number` (Number) +- `reference_id` (String) +- `replication` (List of Object) Replication status (see [below for nested schema](#nestedatt--replication)) +- `res_id` (String) +- `res_name` (String) +- `role` (String) +- `sep_id` (Number) +- `sep_type` (String) +- `shareable` (Boolean) +- `size_max` (Number) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedatt--snapshots)) +- `status` (String) +- `status_replication` (String) Status of replication +- `tech_status` (String) +- `type` (String) +- `vmid` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `compute_id` (String) +- `compute_name` (String) + + + +### Nested Schema for `iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `reference_id` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/cb_disk_snapshot.md b/docs/data-sources/cb_disk_snapshot.md new file mode 100644 index 00000000..d64d8fce --- /dev/null +++ b/docs/data-sources/cb_disk_snapshot.md @@ -0,0 +1,43 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_disk_snapshot Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_disk_snapshot (Data Source) + + + + + + +## Schema + +### Required + +- `disk_id` (Number) The unique ID of the subscriber-owner of the disk +- `label` (String) Name of the snapshot + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `guid` (String) ID of the snapshot +- `id` (String) The ID of this resource. +- `reference_id` (String) +- `res_id` (String) Reference to the snapshot +- `snap_set_guid` (String) The set snapshot ID +- `snap_set_time` (Number) The set time of the snapshot +- `timestamp` (Number) Snapshot time + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_disk_snapshot_list.md b/docs/data-sources/cb_disk_snapshot_list.md new file mode 100644 index 00000000..196bae0b --- /dev/null +++ b/docs/data-sources/cb_disk_snapshot_list.md @@ -0,0 +1,51 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_disk_snapshot_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_disk_snapshot_list (Data Source) + + + + + + +## Schema + +### Required + +- `disk_id` (Number) The unique ID of the subscriber-owner of the disk + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `reference_id` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/cb_dpdknet.md b/docs/data-sources/cb_dpdknet.md new file mode 100644 index 00000000..90665e76 --- /dev/null +++ b/docs/data-sources/cb_dpdknet.md @@ -0,0 +1,48 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_dpdknet Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_dpdknet (Data Source) + + + + + + +## Schema + +### Required + +- `dpdk_id` (Number) The unique ID of the subscriber-owner of the DPDK network + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_access` (List of Number) List of accounts with access +- `compute_ids` (List of Number) Compute IDs which uses this DPDK network +- `created_time` (Number) Created time +- `desc` (String) Description of DPDK network +- `gid` (Number) ID of the grid (platform) +- `guid` (Number) DPDK network ID on the storage side +- `id` (String) The ID of this resource. +- `name` (String) Name of network +- `ovs_bridge` (String) OVS bridge in which interfaces for computers created +- `rg_access` (List of Number) List of resource groups with access +- `status` (String) DPDK network status +- `updated_time` (Number) Updated time +- `vlan_id` (Number) vlan ID + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_dpdknet_list.md b/docs/data-sources/cb_dpdknet_list.md new file mode 100644 index 00000000..c1e00ce2 --- /dev/null +++ b/docs/data-sources/cb_dpdknet_list.md @@ -0,0 +1,64 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_dpdknet_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_dpdknet_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) Find by ID +- `compute_ids` (List of Number) Find by compute IDs +- `desc` (String) Find by description +- `gid` (Number) Find by GID +- `name` (String) Find by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_access` (List of Number) +- `compute_ids` (List of Number) +- `created_time` (Number) +- `desc` (String) +- `dpdk_id` (Number) +- `enable_secgroups` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `name` (String) +- `ovs_bridge` (String) +- `rg_access` (List of Number) +- `status` (String) +- `updated_time` (Number) +- `vlan_id` (Number) diff --git a/docs/data-sources/cb_extnet.md b/docs/data-sources/cb_extnet.md new file mode 100644 index 00000000..ac985f5c --- /dev/null +++ b/docs/data-sources/cb_extnet.md @@ -0,0 +1,143 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_extnet Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_extnet (Data Source) + + + + + + +## Schema + +### Required + +- `extnet_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `check_ips` (List of String) +- `ckey` (String) +- `default` (Boolean) +- `default_qos` (List of Object) (see [below for nested schema](#nestedatt--default_qos)) +- `desc` (String) +- `dns` (List of String) +- `excluded` (List of Object) (see [below for nested schema](#nestedatt--excluded)) +- `free_ips` (Number) +- `gateway` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `ipcidr` (String) +- `meta` (List of String) meta +- `milestones` (Number) +- `mtu` (Number) +- `name` (String) +- `network` (String) +- `network_ids` (List of Object) (see [below for nested schema](#nestedatt--network_ids)) +- `ntp` (List of String) +- `ovs_bridge` (String) +- `pre_reservations` (List of Object) (see [below for nested schema](#nestedatt--pre_reservations)) +- `pre_reservations_num` (Number) +- `prefix` (Number) +- `pri_vnfdev_id` (Number) +- `redundant` (Boolean) +- `reservations` (List of Object) (see [below for nested schema](#nestedatt--reservations)) +- `sec_vnfdev_id` (Number) +- `shared_with` (List of Number) +- `status` (String) +- `vlan_id` (Number) +- `vnfs` (List of Object) (see [below for nested schema](#nestedatt--vnfs)) +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `default_qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_burst` (Number) +- `in_rate` (Number) + + + +### Nested Schema for `excluded` + +Read-Only: + +- `client_type` (String) +- `desc` (String) +- `domain_name` (String) +- `hostname` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + +### Nested Schema for `network_ids` + +Read-Only: + +- `primary` (Number) +- `secondary` (Number) + + + +### Nested Schema for `pre_reservations` + +Read-Only: + +- `account_id` (Number) +- `client_type` (String) +- `desc` (String) +- `domain_name` (String) +- `hostname` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + +### Nested Schema for `reservations` + +Read-Only: + +- `account_id` (Number) +- `client_type` (String) +- `desc` (String) +- `domain_name` (String) +- `hostname` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + +### Nested Schema for `vnfs` + +Read-Only: + +- `dhcp` (Number) diff --git a/docs/data-sources/cb_extnet_default.md b/docs/data-sources/cb_extnet_default.md new file mode 100644 index 00000000..5fab2972 --- /dev/null +++ b/docs/data-sources/cb_extnet_default.md @@ -0,0 +1,33 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_extnet_default Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_extnet_default (Data Source) + + + + + + +## Schema + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `extnet_id` (Number) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_extnet_list.md b/docs/data-sources/cb_extnet_list.md new file mode 100644 index 00000000..44f7c27b --- /dev/null +++ b/docs/data-sources/cb_extnet_list.md @@ -0,0 +1,105 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_extnet_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_extnet_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Find by account ID +- `by_id` (Number) Find by ID +- `name` (String) Find by name +- `network` (String) +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vlan_id` (Number) Find by VLAN ID +- `vnfdev_id` (Number) Find by VnfDEV ID +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `check_ips` (List of String) +- `ckey` (String) +- `default` (Boolean) +- `default_qos` (List of Object) (see [below for nested schema](#nestedobjatt--items--default_qos)) +- `desc` (String) +- `enable_secgroups` (Boolean) +- `extnet_id` (Number) +- `free_ips` (Number) +- `gid` (Number) +- `guid` (Number) +- `ipcidr` (String) +- `meta` (List of String) +- `milestones` (Number) +- `mtu` (Number) +- `name` (String) +- `network_ids` (List of Object) (see [below for nested schema](#nestedobjatt--items--network_ids)) +- `ovs_bridge` (String) +- `pre_reservations_num` (Number) +- `pri_vnfdev_id` (Number) +- `redundant` (Boolean) +- `sec_vnfdev_id` (Number) +- `shared_with` (List of Number) +- `status` (String) +- `vlan_id` (Number) +- `vnfs` (List of Object) (see [below for nested schema](#nestedobjatt--items--vnfs)) +- `zone_id` (Number) + + +### Nested Schema for `items.default_qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_burst` (Number) +- `in_rate` (Number) + + + +### Nested Schema for `items.network_ids` + +Read-Only: + +- `primary` (Number) +- `secondary` (Number) + + + +### Nested Schema for `items.vnfs` + +Read-Only: + +- `dhcp` (Number) diff --git a/docs/data-sources/cb_extnet_reserved_ip_list.md b/docs/data-sources/cb_extnet_reserved_ip_list.md new file mode 100644 index 00000000..ea3e22ab --- /dev/null +++ b/docs/data-sources/cb_extnet_reserved_ip_list.md @@ -0,0 +1,61 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_extnet_reserved_ip_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_extnet_reserved_ip_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) + +### Optional + +- `extnet_id` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `extnet_id` (Number) +- `reservations` (List of Object) (see [below for nested schema](#nestedobjatt--items--reservations)) + + +### Nested Schema for `items.reservations` + +Read-Only: + +- `account_id` (Number) +- `client_type` (String) +- `domain_name` (String) +- `hostname` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) diff --git a/docs/data-sources/cb_extnet_static_route.md b/docs/data-sources/cb_extnet_static_route.md new file mode 100644 index 00000000..4b3385d3 --- /dev/null +++ b/docs/data-sources/cb_extnet_static_route.md @@ -0,0 +1,42 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_extnet_static_route Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_extnet_static_route (Data Source) + + + + + + +## Schema + +### Required + +- `extnet_id` (Number) Unique ID of the ExtNet +- `route_id` (Number) Unique ID of the static route + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `id` (String) The ID of this resource. +- `netmask` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_extnet_static_route_list.md b/docs/data-sources/cb_extnet_static_route_list.md new file mode 100644 index 00000000..afe3958a --- /dev/null +++ b/docs/data-sources/cb_extnet_static_route_list.md @@ -0,0 +1,51 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_extnet_static_route_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_extnet_static_route_list (Data Source) + + + + + + +## Schema + +### Required + +- `extnet_id` (Number) ID of ExtNet + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) diff --git a/docs/data-sources/cb_flipgroup.md b/docs/data-sources/cb_flipgroup.md new file mode 100644 index 00000000..e4fc7c24 --- /dev/null +++ b/docs/data-sources/cb_flipgroup.md @@ -0,0 +1,60 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_flipgroup Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_flipgroup (Data Source) + + + + + + +## Schema + +### Required + +- `flipgroup_id` (Number) flipgroup_id + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) account_id +- `account_name` (String) account_name +- `client_ids` (List of Number) client_ids +- `client_names` (List of String) client_names +- `client_type` (String) client_type +- `conn_id` (Number) conn_id +- `conn_type` (String) conn_type +- `created_by` (String) created_by +- `created_time` (Number) created_time +- `default_gw` (String) default_gw +- `deleted_by` (String) deleted_by +- `deleted_time` (Number) deleted_time +- `description` (String) description +- `gid` (Number) gid +- `guid` (Number) guid +- `id` (String) The ID of this resource. +- `ip` (String) ip +- `milestones` (Number) milestones +- `name` (String) name +- `net_id` (Number) net_id +- `net_type` (String) net_type +- `network` (String) network +- `status` (String) status +- `updated_by` (String) updated_by +- `updated_time` (Number) updated_time + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_flipgroup_list.md b/docs/data-sources/cb_flipgroup_list.md new file mode 100644 index 00000000..bcde1626 --- /dev/null +++ b/docs/data-sources/cb_flipgroup_list.md @@ -0,0 +1,73 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_flipgroup_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_flipgroup_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Account id +- `by_id` (Number) by_id +- `by_ip` (String) by_ip +- `client_ids` (List of Number) client_ids +- `conn_id` (Number) Conn id +- `extnet_id` (Number) extnet_id +- `name` (String) name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) vins_id +- `vins_name` (String) vins_name + +### Read-Only + +- `entry_count` (Number) entry_count +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `ckey` (String) +- `client_ids` (List of Number) +- `client_type` (String) +- `conn_id` (Number) +- `conn_type` (String) +- `default_gw` (String) +- `description` (String) +- `flipgroup_id` (Number) +- `gid` (Number) +- `guid` (Number) +- `ip` (String) +- `meta` (List of String) +- `milestones` (Number) +- `name` (String) +- `net_id` (Number) +- `net_mask` (Number) +- `net_type` (String) +- `status` (String) diff --git a/docs/data-sources/cb_grid.md b/docs/data-sources/cb_grid.md new file mode 100644 index 00000000..caaf7925 --- /dev/null +++ b/docs/data-sources/cb_grid.md @@ -0,0 +1,46 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_grid Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_grid (Data Source) + + + + + + +## Schema + +### Required + +- `grid_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `auth_broker` (List of String) +- `ckey` (String) +- `flag` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) The ID of this resource. +- `location_code` (String) +- `meta` (List of String) meta +- `name` (String) +- `network_modes` (List of String) +- `sdn_support` (Boolean) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_grid_get_consumption.md b/docs/data-sources/cb_grid_get_consumption.md new file mode 100644 index 00000000..77c0622d --- /dev/null +++ b/docs/data-sources/cb_grid_get_consumption.md @@ -0,0 +1,87 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_grid_get_consumption Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_grid_get_consumption (Data Source) + + + + + + +## Schema + +### Required + +- `grid_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `consumed` (List of Object) (see [below for nested schema](#nestedatt--consumed)) +- `id` (String) The ID of this resource. +- `reserved` (List of Object) (see [below for nested schema](#nestedatt--reserved)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `consumed` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `ext_ips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--consumed--seps)) + + +### Nested Schema for `consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `reserved` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `ext_ips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--reserved--seps)) + + +### Nested Schema for `reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) diff --git a/docs/data-sources/cb_grid_get_diagnosis.md b/docs/data-sources/cb_grid_get_diagnosis.md new file mode 100644 index 00000000..22cad6b3 --- /dev/null +++ b/docs/data-sources/cb_grid_get_diagnosis.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_grid_get_diagnosis Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_grid_get_diagnosis (Data Source) + + + + + + +## Schema + +### Required + +- `file_path` (String) +- `gid` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_grid_get_settings.md b/docs/data-sources/cb_grid_get_settings.md new file mode 100644 index 00000000..824faafe --- /dev/null +++ b/docs/data-sources/cb_grid_get_settings.md @@ -0,0 +1,114 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_grid_get_settings Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_grid_get_settings (Data Source) + + + + + + +## Schema + +### Required + +- `grid_id` (Number) grid (platform) ID + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `allowed_ports` (List of Number) +- `cleanup_retention_period` (Number) +- `docker_registry` (List of Object) (see [below for nested schema](#nestedatt--docker_registry)) +- `enable_uptime_monitor` (Boolean) +- `extnet_max_pre_reservations_num` (Number) +- `healthcheck_notifications` (List of Object) (see [below for nested schema](#nestedatt--healthcheck_notifications)) +- `id` (String) The ID of this resource. +- `k8s_cleanup_enabled` (Boolean) +- `limits` (String) +- `location_url` (String) +- `net_qos` (List of Object) (see [below for nested schema](#nestedatt--net_qos)) +- `networks` (String) +- `prometheus` (List of Object) (see [below for nested schema](#nestedatt--prometheus)) +- `vins_max_pre_reservations_num` (Number) +- `vnfdev_mgmt_net_range` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `docker_registry` + +Read-Only: + +- `password` (String) +- `server` (String) +- `username` (String) + + + +### Nested Schema for `healthcheck_notifications` + +Read-Only: + +- `emails` (List of Object) (see [below for nested schema](#nestedobjatt--healthcheck_notifications--emails)) + + +### Nested Schema for `healthcheck_notifications.emails` + +Read-Only: + +- `address` (String) +- `enabled` (Boolean) + + + + +### Nested Schema for `net_qos` + +Read-Only: + +- `extnet` (List of Object) (see [below for nested schema](#nestedobjatt--net_qos--extnet)) +- `vins` (List of Object) (see [below for nested schema](#nestedobjatt--net_qos--vins)) + + +### Nested Schema for `net_qos.extnet` + +Read-Only: + +- `e_rate` (Number) +- `in_burst` (Number) +- `in_rate` (Number) + + + +### Nested Schema for `net_qos.vins` + +Read-Only: + +- `e_rate` (Number) +- `in_burst` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `prometheus` + +Read-Only: + +- `scrape_interval` (Number) diff --git a/docs/data-sources/cb_grid_get_status.md b/docs/data-sources/cb_grid_get_status.md new file mode 100644 index 00000000..a42f5a22 --- /dev/null +++ b/docs/data-sources/cb_grid_get_status.md @@ -0,0 +1,33 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_grid_get_status Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_grid_get_status (Data Source) + + + + + + +## Schema + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `status` (Boolean) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_grid_list.md b/docs/data-sources/cb_grid_list.md new file mode 100644 index 00000000..3287f132 --- /dev/null +++ b/docs/data-sources/cb_grid_list.md @@ -0,0 +1,113 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_grid_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_grid_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) by id +- `name` (String) name +- `page` (Number) page number +- `size` (Number) page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) entry count +- `id` (String) The ID of this resource. +- `items` (List of Object) grid list (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `auth_broker` (List of String) +- `flag` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `location_code` (String) +- `name` (String) +- `network_modes` (List of String) +- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources)) +- `sdn_support` (Boolean) +- `zero_access_enabled` (Boolean) + + +### Nested Schema for `items.resources` + +Read-Only: + +- `current` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--current)) +- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--reserved)) + + +### Nested Schema for `items.resources.current` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `ext_ips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--current--seps)) + + +### Nested Schema for `items.resources.current.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.resources.reserved` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `ext_ips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--reserved--seps)) + + +### Nested Schema for `items.resources.reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) diff --git a/docs/data-sources/cb_grid_list_consumption.md b/docs/data-sources/cb_grid_list_consumption.md new file mode 100644 index 00000000..d495c2bf --- /dev/null +++ b/docs/data-sources/cb_grid_list_consumption.md @@ -0,0 +1,92 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_grid_list_consumption Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_grid_list_consumption (Data Source) + + + + + + +## Schema + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) entry count +- `id` (String) The ID of this resource. +- `items` (List of Object) grid list consumption (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `consumed` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed)) +- `id` (Number) +- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved)) + + +### Nested Schema for `items.consumed` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `ext_ips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed--seps)) + + +### Nested Schema for `items.consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.reserved` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `ext_ips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved--seps)) + + +### Nested Schema for `items.reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) diff --git a/docs/data-sources/cb_grid_list_emails.md b/docs/data-sources/cb_grid_list_emails.md new file mode 100644 index 00000000..a82a3ac4 --- /dev/null +++ b/docs/data-sources/cb_grid_list_emails.md @@ -0,0 +1,36 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_grid_list_emails Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_grid_list_emails (Data Source) + + + + + + +## Schema + +### Optional + +- `page` (Number) page number +- `size` (Number) page size +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) entry count +- `id` (String) The ID of this resource. +- `items` (List of String) grid list emails + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_grid_post_status.md b/docs/data-sources/cb_grid_post_status.md new file mode 100644 index 00000000..44099940 --- /dev/null +++ b/docs/data-sources/cb_grid_post_status.md @@ -0,0 +1,33 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_grid_post_status Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_grid_post_status (Data Source) + + + + + + +## Schema + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `status` (Boolean) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_image.md b/docs/data-sources/cb_image.md new file mode 100644 index 00000000..e2cee173 --- /dev/null +++ b/docs/data-sources/cb_image.md @@ -0,0 +1,103 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_image Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_image (Data Source) + + + + + + +## Schema + +### Required + +- `image_id` (Number) image id + +### Optional + +- `shared_with` (List of Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) AccountId to make the image exclusive +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `architecture` (String) binary architecture of this image, one of X86_64 +- `boot_type` (String) Boot type of image bios or uefi +- `bootable` (Boolean) Does this image boot OS +- `cd_presented_to` (String) +- `computeci_id` (Number) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) List of types of compute suitable for image. Example: [ "KVM_X86" ] +- `enabled` (Boolean) +- `gid` (Number) grid (platform) ID where this template should be create in +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `hot_resize` (Boolean) Does this machine supports hot resize +- `id` (String) The ID of this resource. +- `image_type` (String) Image type linux, windows or other +- `independent` (Boolean) +- `last_modified` (Number) +- `link_to` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `name` (String) Name of the rescue disk +- `network_interface_naming` (String) +- `password` (String) Optional password for the image +- `pool_name` (String) pool for image create +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `reference_id` (String) +- `res_id` (String) +- `res_name` (String) +- `rescuecd` (Boolean) +- `sep_id` (Number) storage endpoint provider ID +- `size` (Number) image size +- `snapshot_id` (String) snapshot id +- `status` (String) status +- `storage_policy_id` (Number) +- `tech_status` (String) tech status +- `to_clean` (Boolean) +- `unc_path` (String) unc path +- `url` (String) URL where to download media from +- `username` (String) Optional username for the image +- `version` (String) version + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/cb_image_list.md b/docs/data-sources/cb_image_list.md new file mode 100644 index 00000000..e5266720 --- /dev/null +++ b/docs/data-sources/cb_image_list.md @@ -0,0 +1,126 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_image_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_image_list (Data Source) + + + + + + +## Schema + +### Optional + +- `architecture` (String) find by architecture +- `bootable` (Boolean) find by bootable True or False +- `by_id` (Number) find by ID +- `enabled` (Boolean) find by enabled True or False +- `hot_resize` (Boolean) find by hot resize True or False +- `image_size` (Number) find by image size +- `name` (String) find by name +- `page` (Number) page number +- `pool` (String) find by pool +- `public` (Boolean) find by public True or False +- `sep_id` (Number) find by storage endpoint provider ID +- `sep_name` (String) find by SEP name +- `size` (Number) page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) find by status +- `storage_policy_id` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `type_image` (String) find by type + +### Read-Only + +- `entry_count` (Number) entry count +- `id` (String) The ID of this resource. +- `items` (List of Object) image list (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `architecture` (String) +- `boot_type` (String) +- `bootable` (Boolean) +- `cd_presented_to` (String) +- `computeci_id` (Number) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `enabled` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedobjatt--items--history)) +- `hot_resize` (Boolean) +- `image_id` (Number) +- `image_type` (String) +- `independent` (Boolean) +- `last_modified` (Number) +- `link_to` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `name` (String) +- `network_interface_naming` (String) +- `password` (String) +- `pool_name` (String) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `reference_id` (String) +- `res_id` (String) +- `res_name` (String) +- `rescuecd` (Boolean) +- `sep_id` (Number) +- `shared_with` (List of Number) +- `size` (Number) +- `snapshot_id` (String) +- `status` (String) +- `storage_policy_id` (Number) +- `tech_status` (String) +- `to_clean` (Boolean) +- `unc_path` (String) +- `url` (String) +- `username` (String) +- `version` (String) +- `virtual` (Boolean) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/cb_k8ci.md b/docs/data-sources/cb_k8ci.md new file mode 100644 index 00000000..55711315 --- /dev/null +++ b/docs/data-sources/cb_k8ci.md @@ -0,0 +1,51 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8ci Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8ci (Data Source) + + + + + + +## Schema + +### Required + +- `k8ci_id` (Number) K8CI ID + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `desc` (String) +- `gid` (Number) gid +- `guid` (Number) guid +- `id` (String) The ID of this resource. +- `lb_image_id` (Number) LB Image ID +- `master_image_id` (Number) +- `max_master_count` (Number) +- `max_worker_count` (Number) +- `milestones` (Number) +- `name` (String) K8CI name +- `network_plugins` (List of String) +- `shared_with` (List of Number) +- `status` (String) K8CI Status +- `version` (String) +- `worker_driver` (String) +- `worker_image_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_k8ci_list.md b/docs/data-sources/cb_k8ci_list.md new file mode 100644 index 00000000..ea244e37 --- /dev/null +++ b/docs/data-sources/cb_k8ci_list.md @@ -0,0 +1,63 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8ci_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8ci_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) Filter by ID +- `include_disabled` (Boolean) Include deleted k8cis in result +- `name` (String) Filter by name +- `network_plugin` (String) Filter by network plugin +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `created_time` (Number) +- `desc` (String) +- `gid` (Number) +- `guid` (Number) +- `k8ci_id` (Number) +- `lb_image_id` (Number) +- `master_image_id` (Number) +- `max_master_count` (Number) +- `max_worker_count` (Number) +- `name` (String) +- `shared_with` (List of Number) +- `status` (String) +- `version` (String) +- `worker_image_id` (Number) diff --git a/docs/data-sources/cb_k8ci_list_deleted.md b/docs/data-sources/cb_k8ci_list_deleted.md new file mode 100644 index 00000000..a13cf68b --- /dev/null +++ b/docs/data-sources/cb_k8ci_list_deleted.md @@ -0,0 +1,61 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8ci_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8ci_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) Filter by ID +- `name` (String) Filter by name +- `network_plugin` (String) Filter by network plugin +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `created_time` (Number) +- `desc` (String) +- `gid` (Number) +- `guid` (Number) +- `k8ci_id` (Number) +- `lb_image_id` (Number) +- `master_image_id` (Number) +- `max_master_count` (Number) +- `max_worker_count` (Number) +- `name` (String) +- `shared_with` (List of Number) +- `status` (String) +- `version` (String) +- `worker_image_id` (Number) diff --git a/docs/data-sources/cb_k8s.md b/docs/data-sources/cb_k8s.md new file mode 100644 index 00000000..6a66b649 --- /dev/null +++ b/docs/data-sources/cb_k8s.md @@ -0,0 +1,211 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8s Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8s (Data Source) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `bservice_id` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `extnet_id` (Number) ID of the external network to connect workers to. If omitted network will be chosen by the platfom. +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `k8s_ci_name` (String) +- `k8s_groups` (List of Object) (see [below for nested schema](#nestedatt--k8s_groups)) +- `k8sci_id` (Number) +- `kubeconfig` (String) Kubeconfig for cluster access. +- `lb_id` (Number) +- `lb_ip` (String) IP address of default load balancer. +- `milestones` (Number) +- `name` (String) +- `network_plugin` (String) +- `rg_id` (Number) +- `rg_name` (String) +- `service_account` (List of Object) (see [below for nested schema](#nestedatt--service_account)) +- `ssh_key` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins_id` (Number) +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `account_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--account_acl)) +- `k8s_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--k8s_acl)) +- `rg_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--rg_acl)) + + +### Nested Schema for `acl.account_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.k8s_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.rg_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + + +### Nested Schema for `k8s_groups` + +Read-Only: + +- `masters` (List of Object) (see [below for nested schema](#nestedobjatt--k8s_groups--masters)) +- `workers` (List of Object) (see [below for nested schema](#nestedobjatt--k8s_groups--workers)) + + +### Nested Schema for `k8s_groups.masters` + +Read-Only: + +- `cpu` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedobjatt--k8s_groups--masters--detailed_info)) +- `disk` (Number) +- `master_id` (Number) +- `name` (String) +- `num` (Number) +- `ram` (Number) + + +### Nested Schema for `k8s_groups.masters.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `external_ip` (String) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--k8s_groups--masters--detailed_info--interfaces)) +- `name` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `k8s_groups.masters.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) + + + + + +### Nested Schema for `k8s_groups.workers` + +Read-Only: + +- `annotations` (List of String) +- `cpu` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedobjatt--k8s_groups--workers--detailed_info)) +- `disk` (Number) +- `guid` (String) +- `id` (Number) +- `labels` (List of String) +- `name` (String) +- `num` (Number) +- `ram` (Number) +- `taints` (List of String) + + +### Nested Schema for `k8s_groups.workers.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `external_ip` (String) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--k8s_groups--workers--detailed_info--interfaces)) +- `name` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `k8s_groups.workers.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) + + + + + + +### Nested Schema for `service_account` + +Read-Only: + +- `guid` (String) +- `password` (String) +- `username` (String) diff --git a/docs/data-sources/cb_k8s_computes.md b/docs/data-sources/cb_k8s_computes.md new file mode 100644 index 00000000..16db778c --- /dev/null +++ b/docs/data-sources/cb_k8s_computes.md @@ -0,0 +1,62 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8s_computes Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8s_computes (Data Source) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `masters` (List of Object) (see [below for nested schema](#nestedatt--masters)) +- `workers` (List of Object) (see [below for nested schema](#nestedatt--workers)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `masters` + +Read-Only: + +- `group_name` (String) +- `id` (Number) +- `name` (String) +- `status` (String) +- `tech_status` (String) + + + +### Nested Schema for `workers` + +Read-Only: + +- `group_name` (String) +- `id` (Number) +- `name` (String) +- `status` (String) +- `tech_status` (String) diff --git a/docs/data-sources/cb_k8s_list.md b/docs/data-sources/cb_k8s_list.md new file mode 100644 index 00000000..befc4cb1 --- /dev/null +++ b/docs/data-sources/cb_k8s_list.md @@ -0,0 +1,105 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8s_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8s_list (Data Source) + + + + + + +## Schema + +### Optional + +- `basic_service_id` (Number) Filter by BasicServiceID +- `by_id` (Number) Filter by ID +- `include_deleted` (Boolean) Include deleted k8s in result +- `ip_address` (String) Filter by ipAddress +- `lb_id` (Number) Filter by LBID +- `name` (String) Filter by name +- `page` (Number) Page number +- `rg_id` (Number) Filter by RGID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `tech_status` (String) Filter by Tech Status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of String) +- `bservice_id` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `extnet_id` (Number) +- `gid` (Number) +- `guid` (Number) +- `k8s_id` (Number) +- `k8s_name` (String) +- `k8sci_id` (Number) +- `kubeconfig` (String) +- `lb_id` (Number) +- `milestones` (Number) +- `network_plugin` (String) +- `rg_id` (Number) +- `rg_name` (String) +- `service_account` (List of Object) (see [below for nested schema](#nestedobjatt--items--service_account)) +- `ssh_key` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins_id` (Number) +- `workers_groups` (List of Object) (see [below for nested schema](#nestedobjatt--items--workers_groups)) +- `zone_id` (Number) + + +### Nested Schema for `items.service_account` + +Read-Only: + +- `guid` (String) +- `password` (String) +- `username` (String) + + + +### Nested Schema for `items.workers_groups` + +Read-Only: + +- `annotations` (List of String) +- `guid` (String) +- `id` (Number) +- `labels` (List of String) +- `taints` (List of String) diff --git a/docs/data-sources/cb_k8s_list_deleted.md b/docs/data-sources/cb_k8s_list_deleted.md new file mode 100644 index 00000000..476d36ff --- /dev/null +++ b/docs/data-sources/cb_k8s_list_deleted.md @@ -0,0 +1,128 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8s_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8s_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `basic_service_id` (Number) Filter by BasicServiceID +- `by_id` (Number) Filter by ID +- `ip_address` (String) Filter by ipAddress +- `lb_id` (Number) Filter by LBID +- `name` (String) Filter by name +- `page` (Number) Page number +- `rg_id` (Number) Filter by RGID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `tech_status` (String) Filter by Tech Status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of String) +- `bservice_id` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `extnet_id` (Number) +- `gid` (Number) +- `guid` (Number) +- `k8s_id` (Number) +- `k8s_name` (String) +- `k8sci_id` (Number) +- `kubeconfig` (String) +- `lb_id` (Number) +- `milestones` (Number) +- `network_plugin` (String) +- `rg_id` (Number) +- `rg_name` (String) +- `service_account` (List of Object) (see [below for nested schema](#nestedobjatt--items--service_account)) +- `ssh_key` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins_id` (Number) +- `workers_groups` (List of Object) (see [below for nested schema](#nestedobjatt--items--workers_groups)) +- `zone_id` (Number) + + +### Nested Schema for `items.service_account` + +Read-Only: + +- `guid` (String) +- `password` (String) +- `username` (String) + + + +### Nested Schema for `items.workers_groups` + +Read-Only: + +- `annotations` (List of String) +- `cpu` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--workers_groups--detailed_info)) +- `disk` (Number) +- `guid` (String) +- `id` (Number) +- `labels` (List of String) +- `name` (String) +- `num` (Number) +- `ram` (Number) +- `taints` (List of String) + + +### Nested Schema for `items.workers_groups.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `external_ip` (String) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--items--workers_groups--detailed_info--interfaces)) +- `name` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `items.workers_groups.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/data-sources/cb_k8s_wg.md b/docs/data-sources/cb_k8s_wg.md new file mode 100644 index 00000000..55ea8ed9 --- /dev/null +++ b/docs/data-sources/cb_k8s_wg.md @@ -0,0 +1,68 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8s_wg Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8s_wg (Data Source) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) ID of k8s instance. +- `wg_id` (Number) ID of k8s worker Group. + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `annotations` (List of String) +- `cpu` (Number) Worker node CPU count. +- `detailed_info` (List of Object) (see [below for nested schema](#nestedatt--detailed_info)) +- `disk` (Number) Worker node boot disk size. If unspecified or 0, size is defined by OS image size. +- `guid` (String) +- `id` (String) The ID of this resource. +- `labels` (List of String) +- `name` (String) Name of the worker group. +- `num` (Number) Number of worker nodes to create. +- `ram` (Number) Worker node RAM in MB. +- `taints` (List of String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `external_ip` (String) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--detailed_info--interfaces)) +- `name` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/data-sources/cb_k8s_wg_cloud_init.md b/docs/data-sources/cb_k8s_wg_cloud_init.md new file mode 100644 index 00000000..d41d2e77 --- /dev/null +++ b/docs/data-sources/cb_k8s_wg_cloud_init.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8s_wg_cloud_init Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8s_wg_cloud_init (Data Source) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) Kubernetes cluster ID +- `wg_id` (Number) ID of the workers compute group + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `cloud_init` (String) Worker group Cloud init +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_k8s_wg_list.md b/docs/data-sources/cb_k8s_wg_list.md new file mode 100644 index 00000000..0bca899d --- /dev/null +++ b/docs/data-sources/cb_k8s_wg_list.md @@ -0,0 +1,75 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8s_wg_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8s_wg_list (Data Source) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `annotations` (List of String) +- `cpu` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--detailed_info)) +- `disk` (Number) +- `guid` (String) +- `labels` (List of String) +- `name` (String) +- `num` (Number) +- `ram` (Number) +- `taints` (List of String) +- `wg_id` (Number) + + +### Nested Schema for `items.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `external_ip` (String) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--items--detailed_info--interfaces)) +- `name` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `items.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/data-sources/cb_kvmvm.md b/docs/data-sources/cb_kvmvm.md new file mode 100644 index 00000000..3dfc8f3e --- /dev/null +++ b/docs/data-sources/cb_kvmvm.md @@ -0,0 +1,406 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) Get compute by id + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) ID of the account this compute instance belongs to. +- `account_name` (String) Name of the account this compute instance belongs to. +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `affinity_label` (String) +- `affinity_rules` (List of Object) (see [below for nested schema](#nestedatt--affinity_rules)) +- `affinity_weight` (Number) +- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedatt--anti_affinity_rules)) +- `arch` (String) +- `auto_start_w_node` (Boolean) +- `boot_disk_id` (Number) +- `boot_disk_size` (Number) +- `boot_image_id` (Number) +- `boot_order` (List of String) +- `boot_type` (String) +- `cd_image_id` (Number) +- `chipset` (String) +- `clone_reference` (Number) +- `clones` (List of Number) +- `computeci_id` (Number) +- `cpu_pin` (Boolean) +- `cpus` (Number) +- `created_by` (String) +- `created_time` (Number) +- `custom_fields` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `devices` (String) +- `disks` (List of Object) (see [below for nested schema](#nestedatt--disks)) +- `driver` (String) +- `gid` (Number) +- `guid` (Number) +- `hot_resize` (Boolean) +- `hp_backed` (Boolean) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `image_name` (String) +- `independent` (Boolean) +- `interfaces` (List of Object) (see [below for nested schema](#nestedatt--interfaces)) +- `live_migration_job_id` (Number) +- `loader_meta_iso` (List of Object) (see [below for nested schema](#nestedatt--loader_meta_iso)) +- `loader_type` (String) +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `migrationjob` (Number) +- `milestones` (Number) +- `name` (String) +- `natable_vins_id` (Number) +- `natable_vins_ip` (String) +- `natable_vins_name` (String) +- `natable_vins_network` (String) +- `natable_vins_network_name` (String) +- `need_reboot` (Boolean) +- `network_interface_naming` (String) +- `node_id` (Number) +- `node_name` (String) +- `numa_affinity` (String) +- `numa_node_id` (Number) +- `os_users` (List of Object) (see [below for nested schema](#nestedatt--os_users)) +- `os_version` (String) +- `pci_devices` (List of Number) +- `pinned` (Number) +- `pool` (String) +- `preferred_cpu` (List of Number) +- `qemu_guest` (List of Object) (see [below for nested schema](#nestedatt--qemu_guest)) +- `ram` (Number) +- `read_only` (Boolean) Shows if compute is locked to read-only operations. +- `reference_id` (String) +- `registered` (Boolean) +- `res_name` (String) +- `reserved_node_cpus` (List of Number) +- `rg_id` (Number) +- `rg_name` (String) +- `sep_id` (Number) +- `snap_sets` (List of Object) (see [below for nested schema](#nestedatt--snap_sets)) +- `stateless_sep_id` (Number) +- `stateless_sep_type` (String) +- `status` (String) +- `tags` (List of Object) (see [below for nested schema](#nestedatt--tags)) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_data` (String) +- `user_managed` (Boolean) +- `vgpus` (List of Object) List of virtual GPUs (see [below for nested schema](#nestedatt--vgpus)) +- `vnc_password` (String) +- `weight` (Number) +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `anti_affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `disks` + +Read-Only: + +- `account_id` (Number) +- `blk_discard` (Boolean) +- `block_size` (String) +- `boot_partition` (Number) +- `bus_number` (Number) +- `cache` (String) +- `ckey` (String) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `destruction_time` (Number) +- `devicename` (String) +- `disk_id` (Number) +- `disk_path` (String) +- `gid` (Number) +- `guid` (Number) +- `image_id` (Number) +- `images` (List of Number) +- `independent` (Boolean) +- `iotune` (List of Object) (see [below for nested schema](#nestedobjatt--disks--iotune)) +- `iqn` (String) +- `login` (String) +- `meta` (List of String) +- `milestones` (Number) +- `name` (String) +- `params` (String) +- `parent_id` (Number) +- `passwd` (String) +- `pci_slot` (Number) +- `pool` (String) +- `present_to` (Map of Number) +- `provision` (String) +- `purge_attempts` (Number) +- `purge_time` (Number) +- `reality_device_number` (Number) +- `reference_id` (String) +- `replication` (List of Object) (see [below for nested schema](#nestedobjatt--disks--replication)) +- `res_id` (String) +- `res_name` (String) +- `role` (String) +- `sep_id` (Number) +- `shareable` (Boolean) +- `size_available` (Number) +- `size_max` (Number) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedobjatt--disks--snapshots)) +- `status` (String) +- `storage_policy_id` (Number) +- `tech_status` (String) +- `to_clean` (Boolean) +- `type` (String) +- `updated_time` (Number) + + +### Nested Schema for `disks.iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `disks.replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `disks.snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) + + + + +### Nested Schema for `interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flip_group_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_type` (String) +- `netmask` (Number) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `trunk_tags` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `loader_meta_iso` + +Read-Only: + +- `device_name` (String) +- `path` (String) + + + +### Nested Schema for `os_users` + +Read-Only: + +- `guid` (String) +- `login` (String) +- `password` (String) +- `public_key` (String) + + + +### Nested Schema for `qemu_guest` + +Read-Only: + +- `enabled` (Boolean) +- `enabled_agent_features` (List of String) +- `guid` (String) +- `last_update` (Number) +- `user` (String) + + + +### Nested Schema for `snap_sets` + +Read-Only: + +- `disks` (List of Number) +- `guid` (String) +- `label` (String) +- `timestamp` (Number) + + + +### Nested Schema for `tags` + +Read-Only: + +- `key` (String) +- `val` (String) + + + +### Nested Schema for `vgpus` + +Read-Only: + +- `account_id` (Number) +- `bus_number` (Number) +- `created_time` (Number) +- `deleted_time` (Number) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `last_claimed_by` (Number) +- `last_update_time` (Number) +- `mode` (String) +- `pci_slot` (Number) +- `pgpuid` (Number) +- `profile_id` (Number) +- `ram` (Number) +- `reference_id` (String) +- `rg_id` (Number) +- `status` (String) +- `type` (String) +- `vmid` (Number) diff --git a/docs/data-sources/cb_kvmvm_affinity_relations.md b/docs/data-sources/cb_kvmvm_affinity_relations.md new file mode 100644 index 00000000..e0bd7d0f --- /dev/null +++ b/docs/data-sources/cb_kvmvm_affinity_relations.md @@ -0,0 +1,42 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_affinity_relations Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_affinity_relations (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `other_node` (List of String) +- `other_node_indirect` (List of String) +- `other_node_indirect_soft` (List of String) +- `other_node_soft` (List of String) +- `same_node` (List of String) +- `same_node_soft` (List of String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_kvmvm_audits.md b/docs/data-sources/cb_kvmvm_audits.md new file mode 100644 index 00000000..215b63ef --- /dev/null +++ b/docs/data-sources/cb_kvmvm_audits.md @@ -0,0 +1,59 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_audits Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_audits (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `call` (String) +- `max_status_code` (Number) +- `min_status_code` (Number) +- `page` (Number) +- `size` (Number) +- `sort_by` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `timestamp_at` (Number) +- `timestamp_to` (Number) +- `user` (String) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `call` (String) +- `responsetime` (Number) +- `statuscode` (Number) +- `timestamp` (Number) +- `user` (String) diff --git a/docs/data-sources/cb_kvmvm_boot_order_get.md b/docs/data-sources/cb_kvmvm_boot_order_get.md new file mode 100644 index 00000000..26f6a6d9 --- /dev/null +++ b/docs/data-sources/cb_kvmvm_boot_order_get.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_boot_order_get Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_boot_order_get (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `boot_order` (List of String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_kvmvm_get_audits.md b/docs/data-sources/cb_kvmvm_get_audits.md new file mode 100644 index 00000000..6e6cfa92 --- /dev/null +++ b/docs/data-sources/cb_kvmvm_get_audits.md @@ -0,0 +1,46 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_get_audits Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_get_audits (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `epoch` (Number) +- `message` (String) diff --git a/docs/data-sources/cb_kvmvm_get_console_url.md b/docs/data-sources/cb_kvmvm_get_console_url.md new file mode 100644 index 00000000..c764a672 --- /dev/null +++ b/docs/data-sources/cb_kvmvm_get_console_url.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_get_console_url Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_get_console_url (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `console_url` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_kvmvm_get_log.md b/docs/data-sources/cb_kvmvm_get_log.md new file mode 100644 index 00000000..b46b39df --- /dev/null +++ b/docs/data-sources/cb_kvmvm_get_log.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_get_log Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_get_log (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) +- `path` (String) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `log` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_kvmvm_list.md b/docs/data-sources/cb_kvmvm_list.md new file mode 100644 index 00000000..429d0375 --- /dev/null +++ b/docs/data-sources/cb_kvmvm_list.md @@ -0,0 +1,288 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Find by AccountID +- `by_id` (Number) Find by ID +- `cd_image_id` (Number) Find by CD image ID +- `extnet_id` (Number) Find by Extnet ID +- `extnet_name` (String) Find by Extnet name +- `ignore_k8s` (Boolean) If set to true, ignores any VMs associated with any k8s cluster +- `includedeleted` (Boolean) +- `ip_address` (String) Find by IP address +- `name` (String) Find by name +- `node_id` (Number) Find by node ID +- `node_name` (String) Find by node name. +- `page` (Number) +- `rg_id` (Number) Find by RGID +- `rg_name` (String) Find by resgroup name +- `size` (Number) +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `tech_status` (String) Find by tech status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `affinity_label` (String) +- `affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--affinity_rules)) +- `affinity_weight` (Number) +- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--anti_affinity_rules)) +- `arch` (String) +- `auto_start_w_node` (Boolean) +- `boot_image_id` (Number) +- `boot_order` (List of String) +- `boot_type` (String) +- `bootdisk_size` (Number) +- `cd_image_id` (Number) +- `chipset` (String) +- `clone_reference` (Number) +- `clones` (List of Number) +- `compute_id` (Number) +- `computeci_id` (Number) +- `cpu_pin` (Boolean) +- `cpus` (Number) +- `created_by` (String) +- `created_time` (Number) +- `custom_fields` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `devices` (String) +- `disks` (List of Object) (see [below for nested schema](#nestedobjatt--items--disks)) +- `driver` (String) +- `gid` (Number) +- `guid` (Number) +- `hot_resize` (Boolean) +- `hp_backed` (Boolean) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces)) +- `live_migration_job_id` (Number) +- `loader_type` (String) +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `migrationjob` (Number) +- `milestones` (Number) +- `name` (String) +- `need_reboot` (Boolean) +- `network_interface_naming` (String) +- `nid` (Number) +- `node_id` (Number) +- `node_name` (String) +- `numa_affinity` (String) +- `numa_node_id` (Number) +- `os_users` (List of Object) (see [below for nested schema](#nestedobjatt--items--os_users)) +- `os_version` (String) +- `pinned` (Number) +- `preferred_cpu` (List of Number) +- `qemu_guest` (List of Object) (see [below for nested schema](#nestedobjatt--items--qemu_guest)) +- `ram` (Number) +- `read_only` (Boolean) +- `reference_id` (String) +- `registered` (Boolean) +- `res_name` (String) +- `reserved_node_cpus` (List of Number) +- `rg_id` (Number) +- `rg_name` (String) +- `snap_sets` (List of Object) (see [below for nested schema](#nestedobjatt--items--snap_sets)) +- `stateless_sep_id` (Number) +- `stateless_sep_type` (String) +- `status` (String) +- `tags` (List of Object) (see [below for nested schema](#nestedobjatt--items--tags)) +- `tech_status` (String) +- `total_disk_size` (Number) +- `updated_by` (String) +- `updated_time` (Number) +- `user_data` (String) +- `user_managed` (Boolean) +- `vgpus` (List of Number) +- `vins_connected` (Number) +- `weight` (Number) +- `zone_id` (Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `items.anti_affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `items.disks` + +Read-Only: + +- `bus_number` (Number) +- `disk_id` (Number) +- `pci_slot` (Number) +- `sep_id` (Number) + + + +### Nested Schema for `items.interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flip_group_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_type` (String) +- `netmask` (Number) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `trunk_tags` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `items.interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `items.interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `items.os_users` + +Read-Only: + +- `guid` (String) +- `login` (String) +- `password` (String) +- `public_key` (String) + + + +### Nested Schema for `items.qemu_guest` + +Read-Only: + +- `enabled` (Boolean) +- `enabled_agent_features` (List of String) +- `guid` (String) +- `last_update` (Number) +- `user` (String) + + + +### Nested Schema for `items.snap_sets` + +Read-Only: + +- `disks` (List of Number) +- `guid` (String) +- `label` (String) +- `timestamp` (Number) + + + +### Nested Schema for `items.tags` + +Read-Only: + +- `key` (String) +- `val` (String) diff --git a/docs/data-sources/cb_kvmvm_list_deleted.md b/docs/data-sources/cb_kvmvm_list_deleted.md new file mode 100644 index 00000000..5138f95b --- /dev/null +++ b/docs/data-sources/cb_kvmvm_list_deleted.md @@ -0,0 +1,265 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Find by AccountID +- `by_id` (Number) Find by ID +- `extnet_id` (Number) Find by Extnet ID +- `extnet_name` (String) Find by Extnet name +- `ignore_k8s` (Boolean) If set to true, ignores any VMs associated with any k8s cluster +- `ip_address` (String) Find by IP address +- `name` (String) Find by name +- `page` (Number) +- `rg_id` (Number) Find by RGID +- `rg_name` (String) Find by resgroup name +- `size` (Number) +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `tech_status` (String) Find by tech status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `affinity_label` (String) +- `affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--affinity_rules)) +- `affinity_weight` (Number) +- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--anti_affinity_rules)) +- `arch` (String) +- `auto_start_w_node` (Boolean) +- `boot_image_id` (Number) +- `boot_order` (List of String) +- `boot_type` (String) +- `bootdisk_size` (Number) +- `cd_image_id` (Number) +- `chipset` (String) +- `clone_reference` (Number) +- `clones` (List of Number) +- `compute_id` (Number) +- `computeci_id` (Number) +- `cpu_pin` (Boolean) +- `cpus` (Number) +- `created_by` (String) +- `created_time` (Number) +- `custom_fields` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `devices` (String) +- `disks` (List of Object) (see [below for nested schema](#nestedobjatt--items--disks)) +- `driver` (String) +- `gid` (Number) +- `guid` (Number) +- `hot_resize` (Boolean) +- `hp_backed` (Boolean) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces)) +- `loader_type` (String) +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `migrationjob` (Number) +- `milestones` (Number) +- `name` (String) +- `need_reboot` (Boolean) +- `network_interface_naming` (String) +- `node_id` (Number) +- `node_name` (String) +- `numa_affinity` (String) +- `numa_node_id` (Number) +- `os_users` (List of Object) (see [below for nested schema](#nestedobjatt--items--os_users)) +- `os_version` (String) +- `pinned` (Number) +- `preferred_cpu` (List of Number) +- `ram` (Number) +- `reference_id` (String) +- `registered` (Boolean) +- `res_name` (String) +- `reserved_node_cpus` (List of Number) +- `rg_id` (Number) +- `rg_name` (String) +- `snap_sets` (List of Object) (see [below for nested schema](#nestedobjatt--items--snap_sets)) +- `stateless_sep_id` (Number) +- `stateless_sep_type` (String) +- `status` (String) +- `tags` (List of Object) (see [below for nested schema](#nestedobjatt--items--tags)) +- `tech_status` (String) +- `total_disk_size` (Number) +- `updated_by` (String) +- `updated_time` (Number) +- `user_data` (String) +- `user_managed` (Boolean) +- `vgpus` (List of Number) +- `vins_connected` (Number) +- `weight` (Number) +- `zone_id` (Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `items.anti_affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `items.disks` + +Read-Only: + +- `disk_id` (Number) +- `pci_slot` (Number) +- `sep_id` (Number) + + + +### Nested Schema for `items.interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flip_group_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_type` (String) +- `netmask` (Number) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `trunk_tags` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `items.interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `items.interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `items.os_users` + +Read-Only: + +- `guid` (String) +- `login` (String) +- `password` (String) +- `public_key` (String) + + + +### Nested Schema for `items.snap_sets` + +Read-Only: + +- `disks` (List of Number) +- `guid` (String) +- `label` (String) +- `timestamp` (Number) + + + +### Nested Schema for `items.tags` + +Read-Only: + +- `key` (String) +- `val` (String) diff --git a/docs/data-sources/cb_kvmvm_migrate_storage_info.md b/docs/data-sources/cb_kvmvm_migrate_storage_info.md new file mode 100644 index 00000000..c149bec8 --- /dev/null +++ b/docs/data-sources/cb_kvmvm_migrate_storage_info.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_migrate_storage_info Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_migrate_storage_info (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `migrate_storage_info` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_kvmvm_pci_device_list.md b/docs/data-sources/cb_kvmvm_pci_device_list.md new file mode 100644 index 00000000..a1156af2 --- /dev/null +++ b/docs/data-sources/cb_kvmvm_pci_device_list.md @@ -0,0 +1,64 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_pci_device_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_pci_device_list (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `device_id` (Number) Find by device id +- `name` (String) Find by name +- `page` (Number) Page number +- `rg_id` (Number) Find by RG id +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `ckey` (String) +- `compute_id` (Number) +- `description` (String) +- `device_id` (Number) +- `guid` (Number) +- `hwpath` (String) +- `meta` (List of String) +- `name` (String) +- `node_id` (Number) +- `rg_id` (Number) +- `status` (String) +- `system_name` (String) diff --git a/docs/data-sources/cb_kvmvm_pfw_list.md b/docs/data-sources/cb_kvmvm_pfw_list.md new file mode 100644 index 00000000..e73d39c8 --- /dev/null +++ b/docs/data-sources/cb_kvmvm_pfw_list.md @@ -0,0 +1,52 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_pfw_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_pfw_list (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `local_ip` (String) +- `local_port` (Number) +- `pfw_id` (Number) +- `protocol` (String) +- `public_port_end` (Number) +- `public_port_start` (Number) +- `vm_id` (Number) diff --git a/docs/data-sources/cb_kvmvm_snapshot_list.md b/docs/data-sources/cb_kvmvm_snapshot_list.md new file mode 100644 index 00000000..27780435 --- /dev/null +++ b/docs/data-sources/cb_kvmvm_snapshot_list.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_snapshot_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_snapshot_list (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `disks` (List of Number) +- `guid` (String) +- `label` (String) +- `timestamp` (Number) diff --git a/docs/data-sources/cb_kvmvm_snapshot_usage.md b/docs/data-sources/cb_kvmvm_snapshot_usage.md new file mode 100644 index 00000000..5d89b37f --- /dev/null +++ b/docs/data-sources/cb_kvmvm_snapshot_usage.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_snapshot_usage Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_snapshot_usage (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `label` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `count` (Number) +- `label` (String) +- `stored` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/cb_kvmvm_user_list.md b/docs/data-sources/cb_kvmvm_user_list.md new file mode 100644 index 00000000..019465bc --- /dev/null +++ b/docs/data-sources/cb_kvmvm_user_list.md @@ -0,0 +1,78 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_user_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_user_list (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_acl` (List of Object) (see [below for nested schema](#nestedatt--account_acl)) +- `compute_acl` (List of Object) (see [below for nested schema](#nestedatt--compute_acl)) +- `id` (String) The ID of this resource. +- `rg_acl` (List of Object) (see [below for nested schema](#nestedatt--rg_acl)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `account_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `compute_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `rg_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) diff --git a/docs/data-sources/cb_kvmvm_vgpu_list.md b/docs/data-sources/cb_kvmvm_vgpu_list.md new file mode 100644 index 00000000..0d55b233 --- /dev/null +++ b/docs/data-sources/cb_kvmvm_vgpu_list.md @@ -0,0 +1,70 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm_vgpu_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm_vgpu_list (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `gpu_id` (Number) Find by GPU id +- `includedeleted` (Boolean) Include deleted computes. If using field 'status', then includedeleted will be ignored +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `type` (String) Find by type + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `created_time` (Number) +- `deleted_time` (Number) +- `gid` (Number) +- `guid` (Number) +- `last_claimed_by` (Number) +- `last_update_time` (Number) +- `mode` (String) +- `pci_slot` (Number) +- `pgpuid` (Number) +- `profile_id` (Number) +- `ram` (Number) +- `reference_id` (String) +- `rg_id` (Number) +- `status` (String) +- `type` (String) +- `vgpu_id` (Number) +- `vm_id` (Number) diff --git a/docs/data-sources/cb_lb.md b/docs/data-sources/cb_lb.md new file mode 100644 index 00000000..a37845ce --- /dev/null +++ b/docs/data-sources/cb_lb.md @@ -0,0 +1,170 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_lb Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_lb (Data Source) + + + + + + +## Schema + +### Required + +- `lb_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) + +### Read-Only + +- `account_id` (Number) +- `acl` (String) +- `backend_haip` (String) +- `backends` (List of Object) (see [below for nested schema](#nestedatt--backends)) +- `ckey` (String) +- `desc` (String) +- `dp_api_password` (String) +- `dp_api_user` (String) +- `extnet_id` (Number) +- `frontend_haip` (String) +- `frontends` (List of Object) (see [below for nested schema](#nestedatt--frontends)) +- `gid` (Number) +- `guid` (Number) +- `ha_mode` (Boolean) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `manager_id` (Number) +- `manager_type` (String) +- `meta` (List of String) +- `milestones` (Number) +- `name` (String) +- `part_k8s` (Boolean) +- `primary_node` (List of Object) (see [below for nested schema](#nestedatt--primary_node)) +- `rg_id` (Number) +- `secondary_node` (List of Object) (see [below for nested schema](#nestedatt--secondary_node)) +- `status` (String) +- `tech_status` (String) +- `user_managed` (Boolean) +- `vins_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `backends` + +Read-Only: + +- `algorithm` (String) +- `guid` (String) +- `name` (String) +- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--backends--server_default_settings)) +- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--backends--servers)) + + +### Nested Schema for `backends.server_default_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + +### Nested Schema for `backends.servers` + +Read-Only: + +- `address` (String) +- `check` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--backends--servers--server_settings)) + + +### Nested Schema for `backends.servers.server_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + + + +### Nested Schema for `frontends` + +Read-Only: + +- `backend` (String) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--frontends--bindings)) +- `guid` (String) +- `name` (String) + + +### Nested Schema for `frontends.bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) + + + + +### Nested Schema for `primary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) + + + +### Nested Schema for `secondary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) diff --git a/docs/data-sources/cb_lb_list.md b/docs/data-sources/cb_lb_list.md new file mode 100644 index 00000000..0771be13 --- /dev/null +++ b/docs/data-sources/cb_lb_list.md @@ -0,0 +1,191 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_lb_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_lb_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Filter by Account ID +- `back_ip` (String) Filter by BackIP +- `by_id` (Number) Filter by ID +- `front_ip` (String) Filter by FrontIP +- `includedeleted` (Boolean) +- `name` (String) Filter by name +- `page` (Number) +- `rg_id` (Number) Filter by RG ID +- `size` (Number) +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by Status +- `tech_status` (String) Filter by TechStatus +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `acl` (String) +- `backend_haip` (String) +- `backends` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dp_api_password` (String) +- `dp_api_user` (String) +- `extnet_id` (Number) +- `frontend_haip` (String) +- `frontends` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends)) +- `gid` (Number) +- `guid` (Number) +- `ha_mode` (Boolean) +- `lb_id` (Number) +- `manager_id` (Number) +- `manager_type` (String) +- `milestones` (Number) +- `name` (String) +- `part_k8s` (Boolean) +- `primary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--primary_node)) +- `rg_id` (Number) +- `rg_name` (String) +- `secondary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--secondary_node)) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_id` (Number) +- `zone_id` (Number) + + +### Nested Schema for `items.backends` + +Read-Only: + +- `algorithm` (String) +- `guid` (String) +- `name` (String) +- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--server_default_settings)) +- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers)) + + +### Nested Schema for `items.backends.server_default_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + +### Nested Schema for `items.backends.servers` + +Read-Only: + +- `address` (String) +- `check` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers--server_settings)) + + +### Nested Schema for `items.backends.servers.server_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + + + +### Nested Schema for `items.frontends` + +Read-Only: + +- `backend` (String) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends--bindings)) +- `guid` (String) +- `name` (String) + + +### Nested Schema for `items.frontends.bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) + + + + +### Nested Schema for `items.primary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) + + + +### Nested Schema for `items.secondary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) diff --git a/docs/data-sources/cb_lb_list_deleted.md b/docs/data-sources/cb_lb_list_deleted.md new file mode 100644 index 00000000..80afc2bc --- /dev/null +++ b/docs/data-sources/cb_lb_list_deleted.md @@ -0,0 +1,189 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_lb_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_lb_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Filter by Account ID +- `back_ip` (String) Filter by BackIP +- `by_id` (Number) Filter by ID +- `front_ip` (String) Filter by FrontIP +- `name` (String) Filter by name +- `page` (Number) +- `rg_id` (Number) Filter by RG ID +- `size` (Number) +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `tech_status` (String) Filter by TechStatus +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `acl` (String) +- `backend_haip` (String) +- `backends` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dp_api_password` (String) +- `dp_api_user` (String) +- `extnet_id` (Number) +- `frontend_haip` (String) +- `frontends` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends)) +- `gid` (Number) +- `guid` (Number) +- `ha_mode` (Boolean) +- `lb_id` (Number) +- `manager_id` (Number) +- `manager_type` (String) +- `milestones` (Number) +- `name` (String) +- `part_k8s` (Boolean) +- `primary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--primary_node)) +- `rg_id` (Number) +- `rg_name` (String) +- `secondary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--secondary_node)) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_id` (Number) +- `zone_id` (Number) + + +### Nested Schema for `items.backends` + +Read-Only: + +- `algorithm` (String) +- `guid` (String) +- `name` (String) +- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--server_default_settings)) +- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers)) +- `zone_id` (Number) + + +### Nested Schema for `items.backends.server_default_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + +### Nested Schema for `items.backends.servers` + +Read-Only: + +- `address` (String) +- `check` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers--server_settings)) + + +### Nested Schema for `items.backends.servers.server_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + + + +### Nested Schema for `items.frontends` + +Read-Only: + +- `backend` (String) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends--bindings)) +- `guid` (String) +- `name` (String) + + +### Nested Schema for `items.frontends.bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) + + + + +### Nested Schema for `items.primary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) + + + +### Nested Schema for `items.secondary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) diff --git a/docs/data-sources/cb_node.md b/docs/data-sources/cb_node.md new file mode 100644 index 00000000..73d30862 --- /dev/null +++ b/docs/data-sources/cb_node.md @@ -0,0 +1,254 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_node Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_node (Data Source) + + + + + + +## Schema + +### Required + +- `node_id` (Number) node id + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `auto_start` (Boolean) +- `auto_start_count` (Number) +- `consumption` (List of Object) (see [below for nested schema](#nestedatt--consumption)) +- `cpu_allocation_ratio` (Number) +- `cpu_info` (List of Object) (see [below for nested schema](#nestedatt--cpu_info)) +- `description` (String) +- `dpdk` (List of Object) (see [below for nested schema](#nestedatt--dpdk)) +- `gid` (Number) +- `id` (String) The ID of this resource. +- `ipaddr` (List of String) +- `isolated_cpus` (List of String) +- `mem_allocation_ratio` (Number) +- `name` (String) +- `need_reboot` (Boolean) +- `net_addr` (List of Object) (see [below for nested schema](#nestedatt--net_addr)) +- `network_mode` (String) +- `nic_info` (List of Object) (see [below for nested schema](#nestedatt--nic_info)) +- `numa_topology` (List of Object) (see [below for nested schema](#nestedatt--numa_topology)) +- `openvswitch_bridges` (List of String) +- `reserved_cpus` (List of String) +- `roles` (List of String) +- `sdn_hypervisor_name` (String) +- `sriov_enabled` (Boolean) +- `status` (String) +- `to_active` (List of Object) (see [below for nested schema](#nestedatt--to_active)) +- `to_installing` (List of Object) (see [below for nested schema](#nestedatt--to_installing)) +- `to_maintenance` (List of Object) (see [below for nested schema](#nestedatt--to_maintenance)) +- `to_restricted` (List of Object) (see [below for nested schema](#nestedatt--to_restricted)) +- `usable_cpus` (List of String) +- `version` (String) +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `consumption` + +Read-Only: + +- `consumed` (List of Object) (see [below for nested schema](#nestedobjatt--consumption--consumed)) +- `free` (List of Object) (see [below for nested schema](#nestedobjatt--consumption--free)) +- `hostname` (String) +- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--consumption--reserved)) +- `total` (List of Object) (see [below for nested schema](#nestedobjatt--consumption--total)) + + +### Nested Schema for `consumption.consumed` + +Read-Only: + +- `computes` (Number) +- `ram` (Number) +- `routers` (Number) +- `vcpu` (Number) + + + +### Nested Schema for `consumption.free` + +Read-Only: + +- `ram` (Number) +- `vcpu` (Number) + + + +### Nested Schema for `consumption.reserved` + +Read-Only: + +- `ram` (Number) + + + +### Nested Schema for `consumption.total` + +Read-Only: + +- `ram` (Number) + + + + +### Nested Schema for `cpu_info` + +Read-Only: + +- `clock_speed` (Number) +- `core_count` (Number) +- `flags` (List of String) +- `model_name` (String) +- `phys_count` (Number) +- `thread_count` (Number) + + + +### Nested Schema for `dpdk` + +Read-Only: + +- `bridges` (List of Object) (see [below for nested schema](#nestedobjatt--dpdk--bridges)) +- `hp_memory` (Map of Number) +- `pmd_cpu` (List of Number) + + +### Nested Schema for `dpdk.bridges` + +Read-Only: + +- `backplane1` (List of Object) (see [below for nested schema](#nestedobjatt--dpdk--bridges--backplane1)) + + +### Nested Schema for `dpdk.bridges.backplane1` + +Read-Only: + +- `interfaces` (List of String) +- `numa_node` (Number) + + + + + +### Nested Schema for `net_addr` + +Read-Only: + +- `ip` (List of String) +- `name` (String) + + + +### Nested Schema for `nic_info` + +Read-Only: + +- `driver` (String) +- `max_vfs` (Number) +- `num_vfs` (Number) +- `numa_node` (Number) +- `os_name` (String) +- `pci_slot` (String) +- `vf_list` (List of Object) (see [below for nested schema](#nestedobjatt--nic_info--vf_list)) + + +### Nested Schema for `nic_info.vf_list` + +Read-Only: + +- `fn_id` (Number) +- `pci_slot` (String) + + + + +### Nested Schema for `numa_topology` + +Read-Only: + +- `node_num` (Number) +- `nodes` (List of Object) (see [below for nested schema](#nestedobjatt--numa_topology--nodes)) + + +### Nested Schema for `numa_topology.nodes` + +Read-Only: + +- `cpu_list` (List of Number) +- `memory` (List of Object) (see [below for nested schema](#nestedobjatt--numa_topology--nodes--memory)) + + +### Nested Schema for `numa_topology.nodes.memory` + +Read-Only: + +- `one_g` (Number) +- `total` (Number) +- `two_m` (Number) + + + + + +### Nested Schema for `to_active` + +Read-Only: + +- `actor` (String) +- `reason` (String) +- `time` (Number) + + + +### Nested Schema for `to_installing` + +Read-Only: + +- `actor` (String) +- `reason` (String) +- `time` (Number) + + + +### Nested Schema for `to_maintenance` + +Read-Only: + +- `actor` (String) +- `reason` (String) +- `time` (Number) + + + +### Nested Schema for `to_restricted` + +Read-Only: + +- `actor` (String) +- `reason` (String) +- `time` (Number) diff --git a/docs/data-sources/cb_node_list.md b/docs/data-sources/cb_node_list.md new file mode 100644 index 00000000..ba7b78bf --- /dev/null +++ b/docs/data-sources/cb_node_list.md @@ -0,0 +1,215 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_node_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_node_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) find node by id +- `name` (String) find node by name +- `page` (Number) page number +- `release` (String) find node by release +- `role` (String) find node by role +- `sep_id` (Number) find node by sepId +- `size` (Number) page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) find node by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `version` (String) find node by version +- `zone_id` (Number) find node by zone id + +### Read-Only + +- `entry_count` (Number) entry count +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `additional_pkgs` (List of String) +- `api_url` (String) +- `auto_start` (Boolean) +- `auto_start_count` (Number) +- `cpu_allocation_ratio` (Number) +- `cpu_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--cpu_info)) +- `description` (String) +- `dpdk` (List of Object) (see [below for nested schema](#nestedobjatt--items--dpdk)) +- `drivers` (List of String) +- `gid` (Number) +- `guid` (String) +- `hostkey` (String) +- `ipaddr` (List of String) +- `isolated_cpus` (List of String) +- `lastcheck` (Number) +- `machine_guid` (String) +- `mainboard_sn` (String) +- `mem_allocation_ratio` (Number) +- `memory` (Number) +- `milestones` (Number) +- `model` (String) +- `name` (String) +- `need_reboot` (Boolean) +- `net_addr` (List of Object) (see [below for nested schema](#nestedobjatt--items--net_addr)) +- `network_mode` (String) +- `nic_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--nic_info)) +- `node_id` (Number) +- `node_uuid` (String) +- `numa_topology` (List of Object) (see [below for nested schema](#nestedobjatt--items--numa_topology)) +- `old_compat_lvm_id` (Number) +- `openvswitch_bridges` (List of String) +- `packages` (List of Object) (see [below for nested schema](#nestedobjatt--items--packages)) +- `peer_backup` (Number) +- `peer_log` (Number) +- `peer_stats` (Number) +- `pgpus` (List of Number) +- `public_keys` (List of String) +- `release` (String) +- `reserved_cpus` (List of String) +- `roles` (List of String) +- `sdn_hypervisor_name` (String) +- `seps` (List of Number) +- `serial_num` (String) +- `sriov_enabled` (Boolean) +- `status` (String) +- `tags` (List of String) +- `type` (String) +- `uefi_firmware_file` (String) +- `usable_cpus` (List of String) +- `version` (String) +- `zone_id` (Number) + + +### Nested Schema for `items.cpu_info` + +Read-Only: + +- `clock_speed` (Number) +- `core_count` (Number) +- `flags` (List of String) +- `model_name` (String) +- `phys_count` (Number) +- `thread_count` (Number) + + + +### Nested Schema for `items.dpdk` + +Read-Only: + +- `bridges` (List of Object) (see [below for nested schema](#nestedobjatt--items--dpdk--bridges)) +- `hp_memory` (Map of Number) +- `pmd_cpu` (List of Number) + + +### Nested Schema for `items.dpdk.bridges` + +Read-Only: + +- `backplane1` (List of Object) (see [below for nested schema](#nestedobjatt--items--dpdk--bridges--backplane1)) + + +### Nested Schema for `items.dpdk.bridges.backplane1` + +Read-Only: + +- `interfaces` (List of String) +- `numa_node` (Number) + + + + + +### Nested Schema for `items.net_addr` + +Read-Only: + +- `cidr` (List of String) +- `index` (Number) +- `ip` (List of String) +- `mac` (String) +- `mtu` (Number) +- `name` (String) + + + +### Nested Schema for `items.nic_info` + +Read-Only: + +- `driver` (String) +- `max_vfs` (Number) +- `num_vfs` (Number) +- `numa_node` (Number) +- `os_name` (String) +- `pci_slot` (String) +- `vf_list` (List of Object) (see [below for nested schema](#nestedobjatt--items--nic_info--vf_list)) + + +### Nested Schema for `items.nic_info.vf_list` + +Read-Only: + +- `fn_id` (Number) +- `pci_slot` (String) + + + + +### Nested Schema for `items.numa_topology` + +Read-Only: + +- `node_num` (Number) +- `nodes` (List of Object) (see [below for nested schema](#nestedobjatt--items--numa_topology--nodes)) + + +### Nested Schema for `items.numa_topology.nodes` + +Read-Only: + +- `cpu_list` (List of Number) +- `memory` (List of Object) (see [below for nested schema](#nestedobjatt--items--numa_topology--nodes--memory)) + + +### Nested Schema for `items.numa_topology.nodes.memory` + +Read-Only: + +- `one_g` (Number) +- `total` (Number) +- `two_m` (Number) + + + + + +### Nested Schema for `items.packages` + +Read-Only: + +- `size` (String) +- `ver` (String) diff --git a/docs/data-sources/cb_pcidevice.md b/docs/data-sources/cb_pcidevice.md new file mode 100644 index 00000000..f83bd306 --- /dev/null +++ b/docs/data-sources/cb_pcidevice.md @@ -0,0 +1,45 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_pcidevice Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_pcidevice (Data Source) + + + + + + +## Schema + +### Required + +- `device_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `compute_id` (Number) +- `description` (String) +- `guid` (Number) +- `hw_path` (String) +- `id` (String) The ID of this resource. +- `name` (String) +- `node_id` (Number) +- `rg_id` (Number) +- `status` (String) +- `system_name` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_pcidevice_list.md b/docs/data-sources/cb_pcidevice_list.md new file mode 100644 index 00000000..4731a8cf --- /dev/null +++ b/docs/data-sources/cb_pcidevice_list.md @@ -0,0 +1,58 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_pcidevice_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_pcidevice_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) by_id +- `compute_id` (Number) compute_id +- `name` (String) name +- `page` (Number) page number +- `rg_id` (Number) rg_id +- `size` (Number) page size +- `status` (String) status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) entry count +- `id` (String) The ID of this resource. +- `items` (List of Object) pcidevice list (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `compute_id` (Number) +- `description` (String) +- `device_id` (Number) +- `guid` (Number) +- `hw_path` (String) +- `name` (String) +- `node_id` (Number) +- `rg_id` (Number) +- `status` (String) +- `system_name` (String) diff --git a/docs/data-sources/cb_rg.md b/docs/data-sources/cb_rg.md new file mode 100644 index 00000000..7df682b7 --- /dev/null +++ b/docs/data-sources/cb_rg.md @@ -0,0 +1,102 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `compute_features` (List of String) +- `computes` (List of Number) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `def_net_id` (Number) +- `def_net_type` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dirty` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `lock_status` (String) +- `milestones` (Number) +- `name` (String) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedatt--resource_limits)) +- `resource_types` (List of String) +- `sdn_access_group_id` (String) +- `secret` (String) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `uniq_pools` (List of String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins` (List of Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `email` (String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (Set of Object) (see [below for nested schema](#nestedobjatt--resource_limits--storage_policy)) + + +### Nested Schema for `resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) diff --git a/docs/data-sources/cb_rg_affinity_group_computes.md b/docs/data-sources/cb_rg_affinity_group_computes.md new file mode 100644 index 00000000..570df398 --- /dev/null +++ b/docs/data-sources/cb_rg_affinity_group_computes.md @@ -0,0 +1,52 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_affinity_group_computes Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_affinity_group_computes (Data Source) + + + + + + +## Schema + +### Required + +- `affinity_group` (String) Affinity group label +- `rg_id` (Number) ID of the RG + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `compute_id` (Number) +- `other_node` (List of Number) +- `other_node_indirect` (List of Number) +- `other_node_indirect_soft` (List of Number) +- `other_node_soft` (List of Number) +- `same_node` (List of Number) +- `same_node_soft` (List of Number) diff --git a/docs/data-sources/cb_rg_affinity_groups_get.md b/docs/data-sources/cb_rg_affinity_groups_get.md new file mode 100644 index 00000000..2850f7fc --- /dev/null +++ b/docs/data-sources/cb_rg_affinity_groups_get.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_affinity_groups_get Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_affinity_groups_get (Data Source) + + + + + + +## Schema + +### Required + +- `affinity_group` (String) Affinity group label +- `rg_id` (Number) ID of the RG + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `ids` (List of Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_rg_affinity_groups_list.md b/docs/data-sources/cb_rg_affinity_groups_list.md new file mode 100644 index 00000000..0c1160b3 --- /dev/null +++ b/docs/data-sources/cb_rg_affinity_groups_list.md @@ -0,0 +1,50 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_affinity_groups_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_affinity_groups_list (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the RG + +### Optional + +- `page` (Number) Page number +- `size` (Number) Page size +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `affinity_groups` (List of Object) (see [below for nested schema](#nestedatt--affinity_groups)) +- `entry_count` (Number) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `affinity_groups` + +Read-Only: + +- `id` (Number) +- `label` (String) +- `node_id` (Number) diff --git a/docs/data-sources/cb_rg_audits.md b/docs/data-sources/cb_rg_audits.md new file mode 100644 index 00000000..ce4b372e --- /dev/null +++ b/docs/data-sources/cb_rg_audits.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_audits Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_audits (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `call` (String) +- `responsetime` (Number) +- `statuscode` (Number) +- `timestamp` (Number) +- `user` (String) diff --git a/docs/data-sources/cb_rg_list.md b/docs/data-sources/cb_rg_list.md new file mode 100644 index 00000000..b0b1cb4f --- /dev/null +++ b/docs/data-sources/cb_rg_list.md @@ -0,0 +1,118 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Filter by account ID +- `account_name` (String) Filter by account name +- `by_id` (Number) Filter by ID +- `created_after` (Number) Filter RGs created after certain point in time (unix timestamp) +- `created_before` (Number) Filter RGs created before certain point in time (unix timestamp) +- `includedeleted` (Boolean) Include deleted +- `lock_status` (String) Filter by lock status +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `compute_features` (List of String) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `def_net_id` (Number) +- `def_net_type` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dirty` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `name` (String) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits)) +- `resource_types` (List of String) +- `rg_id` (Number) +- `sdn_access_group_id` (String) +- `secret` (String) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `uniq_pools` (List of String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins` (List of Number) +- `vms` (List of Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (Set of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits--storage_policy)) + + +### Nested Schema for `items.resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) diff --git a/docs/data-sources/cb_rg_list_computes.md b/docs/data-sources/cb_rg_list_computes.md new file mode 100644 index 00000000..100f05a6 --- /dev/null +++ b/docs/data-sources/cb_rg_list_computes.md @@ -0,0 +1,105 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_list_computes Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_list_computes (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the RG + +### Optional + +- `account_id` (Number) Filter by account ID +- `compute_id` (Number) Filter by compute ID +- `extnet_id` (Number) Filter by extnet ID +- `extnet_name` (String) Filter by extnet name +- `ip_address` (String) FIlter by IP address +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `tech_status` (String) Filter by tech. status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `affinity_label` (String) +- `affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--affinity_rules)) +- `affinity_weight` (Number) +- `antiaffinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--antiaffinity_rules)) +- `cpus` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `id` (Number) +- `name` (String) +- `ram` (Number) +- `registered` (Boolean) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `tech_status` (String) +- `total_disks_size` (Number) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_connected` (Number) + + +### Nested Schema for `items.affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `items.antiaffinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) diff --git a/docs/data-sources/cb_rg_list_deleted.md b/docs/data-sources/cb_rg_list_deleted.md new file mode 100644 index 00000000..1d2e05e2 --- /dev/null +++ b/docs/data-sources/cb_rg_list_deleted.md @@ -0,0 +1,116 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Filter by account ID +- `account_name` (String) Filter by account name +- `by_id` (Number) Filter by ID +- `created_after` (Number) Filter RGs created after certain point in time (unix timestamp) +- `created_before` (Number) Filter RGs created before certain point in time (unix timestamp) +- `lock_status` (String) Filter by lock status +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `compute_features` (List of String) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `def_net_id` (Number) +- `def_net_type` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dirty` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `name` (String) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits)) +- `resource_types` (List of String) +- `rg_id` (Number) +- `sdn_access_group_id` (String) +- `secret` (String) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `uniq_pools` (List of String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins` (List of Number) +- `vms` (List of Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (Set of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits--storage_policy)) + + +### Nested Schema for `items.resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) diff --git a/docs/data-sources/cb_rg_list_lb.md b/docs/data-sources/cb_rg_list_lb.md new file mode 100644 index 00000000..734bf619 --- /dev/null +++ b/docs/data-sources/cb_rg_list_lb.md @@ -0,0 +1,196 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_list_lb Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_list_lb (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the RG + +### Optional + +- `back_ip` (String) Filter by backend IP +- `by_id` (Number) Filter by ID +- `front_ip` (String) Filter by frontend IP +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `tech_status` (String) Filter by tech. status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `backends` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dp_api_user` (String) +- `extnet_id` (Number) +- `frontends` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends)) +- `gid` (Number) +- `guid` (Number) +- `ha_mode` (Boolean) +- `id` (Number) +- `image_id` (Number) +- `milestones` (Number) +- `name` (String) +- `primary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--primary_node)) +- `rg_name` (String) +- `secondary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--secondary_node)) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins_id` (Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.backends` + +Read-Only: + +- `algorithm` (String) +- `guid` (String) +- `name` (String) +- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--server_default_settings)) +- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers)) + + +### Nested Schema for `items.backends.server_default_settings` + +Read-Only: + +- `down_inter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `max_conn` (Number) +- `max_queue` (Number) +- `rise` (Number) +- `slow_start` (Number) +- `weight` (Number) + + + +### Nested Schema for `items.backends.servers` + +Read-Only: + +- `address` (String) +- `check` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers--server_settings)) + + +### Nested Schema for `items.backends.servers.server_settings` + +Read-Only: + +- `down_inter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `max_conn` (Number) +- `max_queue` (Number) +- `rise` (Number) +- `slow_start` (Number) +- `weight` (Number) + + + + + +### Nested Schema for `items.frontends` + +Read-Only: + +- `backend` (String) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends--bindings)) +- `guid` (String) +- `name` (String) + + +### Nested Schema for `items.frontends.bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) + + + + +### Nested Schema for `items.primary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) + + + +### Nested Schema for `items.secondary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) diff --git a/docs/data-sources/cb_rg_list_pfw.md b/docs/data-sources/cb_rg_list_pfw.md new file mode 100644 index 00000000..5cb2b5a7 --- /dev/null +++ b/docs/data-sources/cb_rg_list_pfw.md @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_list_pfw Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_list_pfw (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the RG + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `public_port_end` (Number) +- `public_port_start` (Number) +- `vins_id` (Number) +- `vins_name` (String) +- `vm_id` (Number) +- `vm_ip` (String) +- `vm_name` (String) +- `vm_port` (Number) diff --git a/docs/data-sources/cb_rg_list_vins.md b/docs/data-sources/cb_rg_list_vins.md new file mode 100644 index 00000000..1bacd221 --- /dev/null +++ b/docs/data-sources/cb_rg_list_vins.md @@ -0,0 +1,71 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_list_vins Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_list_vins (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the RG + +### Optional + +- `account_id` (Number) Filter by account ID +- `ext_ip` (String) Filter by external IP +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) Filter by ViNS ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `computes` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `external_ip` (String) +- `extnet_id` (Number) +- `free_ips` (Number) +- `id` (Number) +- `name` (String) +- `network` (String) +- `pri_vnf_dev_id` (Number) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) diff --git a/docs/data-sources/cb_rg_resource_consumption_get.md b/docs/data-sources/cb_rg_resource_consumption_get.md new file mode 100644 index 00000000..9ea6ed40 --- /dev/null +++ b/docs/data-sources/cb_rg_resource_consumption_get.md @@ -0,0 +1,102 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_resource_consumption_get Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_resource_consumption_get (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `consumed` (List of Object) (see [below for nested schema](#nestedatt--consumed)) +- `id` (String) The ID of this resource. +- `reserved` (List of Object) (see [below for nested schema](#nestedatt--reserved)) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedatt--resource_limits)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `consumed` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--consumed--seps)) + + +### Nested Schema for `consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `reserved` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--reserved--seps)) + + +### Nested Schema for `reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) diff --git a/docs/data-sources/cb_rg_resource_consumption_list.md b/docs/data-sources/cb_rg_resource_consumption_list.md new file mode 100644 index 00000000..698d0c77 --- /dev/null +++ b/docs/data-sources/cb_rg_resource_consumption_list.md @@ -0,0 +1,107 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_resource_consumption_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_resource_consumption_list (Data Source) + + + + + + +## Schema + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `consumed` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed)) +- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved)) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits)) +- `rg_id` (Number) + + +### Nested Schema for `items.consumed` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed--seps)) + + +### Nested Schema for `items.consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.reserved` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved--seps)) + + +### Nested Schema for `items.reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) diff --git a/docs/data-sources/cb_rg_usage.md b/docs/data-sources/cb_rg_usage.md new file mode 100644 index 00000000..c0756945 --- /dev/null +++ b/docs/data-sources/cb_rg_usage.md @@ -0,0 +1,54 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg_usage Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg_usage (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `extips` (Number) +- `gpu` (Number) +- `id` (String) The ID of this resource. +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedatt--seps)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) diff --git a/docs/data-sources/cb_security_group.md b/docs/data-sources/cb_security_group.md new file mode 100644 index 00000000..992605b1 --- /dev/null +++ b/docs/data-sources/cb_security_group.md @@ -0,0 +1,58 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_security_group Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_security_group (Data Source) + + + + + + +## Schema + +### Required + +- `security_group_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `created_at` (Number) +- `created_by` (String) +- `description` (String) +- `id` (String) The ID of this resource. +- `name` (String) +- `rules` (List of Object) (see [below for nested schema](#nestedatt--rules)) +- `updated_at` (Number) +- `updated_by` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `rules` + +Read-Only: + +- `direction` (String) +- `ethertype` (String) +- `id` (Number) +- `port_range_max` (Number) +- `port_range_min` (Number) +- `protocol` (String) +- `remote_ip_prefix` (String) diff --git a/docs/data-sources/cb_security_group_list.md b/docs/data-sources/cb_security_group_list.md new file mode 100644 index 00000000..f0e90bcc --- /dev/null +++ b/docs/data-sources/cb_security_group_list.md @@ -0,0 +1,74 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_security_group_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_security_group_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) +- `by_id` (Number) +- `created_max` (Number) +- `created_min` (Number) +- `desc` (String) +- `name` (String) +- `page` (Number) +- `size` (Number) +- `sort_by` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `updated_max` (Number) +- `updated_min` (Number) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `created_at` (Number) +- `created_by` (String) +- `description` (String) +- `name` (String) +- `rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--rules)) +- `security_group_id` (Number) +- `updated_at` (Number) +- `updated_by` (String) + + +### Nested Schema for `items.rules` + +Read-Only: + +- `direction` (String) +- `ethertype` (String) +- `id` (Number) +- `port_range_max` (Number) +- `port_range_min` (Number) +- `protocol` (String) +- `remote_ip_prefix` (String) diff --git a/docs/data-sources/cb_sep.md b/docs/data-sources/cb_sep.md new file mode 100644 index 00000000..d4fb73e5 --- /dev/null +++ b/docs/data-sources/cb_sep.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_sep Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_sep (Data Source) + + + + + + +## Schema + +### Required + +- `sep_id` (Number) sep type des id + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `config` (String) config +- `consumed_by` (Set of Number) consumed by +- `desc` (String) description +- `gid` (Number) gid +- `guid` (Number) guid +- `id` (String) The ID of this resource. +- `milestones` (Number) milestones +- `multipath_num` (Number) multipath_num +- `name` (String) name +- `obj_status` (String) object status +- `provided_by` (List of Number) provided by +- `shared_with` (List of Number) shared with +- `tech_status` (String) tech status +- `type` (String) type + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_sep_and_pools_available_list.md b/docs/data-sources/cb_sep_and_pools_available_list.md new file mode 100644 index 00000000..b6c4f0b6 --- /dev/null +++ b/docs/data-sources/cb_sep_and_pools_available_list.md @@ -0,0 +1,59 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_sep_and_pools_available_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_sep_and_pools_available_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) Account ID + +### Optional + +- `rg_id` (Number) Resource group ID +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) Number of available SEP entries +- `id` (String) The ID of this resource. +- `items` (List of Object) List of available SEPs (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `pools` (List of Object) (see [below for nested schema](#nestedobjatt--items--pools)) +- `sep_id` (Number) +- `sep_name` (String) +- `sep_type` (String) + + +### Nested Schema for `items.pools` + +Read-Only: + +- `name` (String) +- `system` (Boolean) +- `types` (List of String) diff --git a/docs/data-sources/cb_sep_config.md b/docs/data-sources/cb_sep_config.md new file mode 100644 index 00000000..8ffb9a35 --- /dev/null +++ b/docs/data-sources/cb_sep_config.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_sep_config Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_sep_config (Data Source) + + + + + + +## Schema + +### Required + +- `sep_id` (Number) storage endpoint provider ID + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `config` (String) sep config json string +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_sep_consumption.md b/docs/data-sources/cb_sep_consumption.md new file mode 100644 index 00000000..2341a8e3 --- /dev/null +++ b/docs/data-sources/cb_sep_consumption.md @@ -0,0 +1,67 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_sep_consumption Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_sep_consumption (Data Source) + + + + + + +## Schema + +### Required + +- `sep_id` (Number) sep id + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `by_pool` (List of Object) consumption divided by pool (see [below for nested schema](#nestedatt--by_pool)) +- `id` (String) The ID of this resource. +- `total` (List of Object) total consumption (see [below for nested schema](#nestedatt--total)) +- `type` (String) sep type + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `by_pool` + +Read-Only: + +- `disk_count` (Number) +- `disk_usage` (Number) +- `name` (String) +- `snapshot_count` (Number) +- `snapshot_usage` (Number) +- `usage` (Number) +- `usage_limit` (Number) + + + +### Nested Schema for `total` + +Read-Only: + +- `capacity_limit` (Number) +- `disk_count` (Number) +- `disk_usage` (Number) +- `snapshot_count` (Number) +- `snapshot_usage` (Number) +- `usage` (Number) +- `usage_limit` (Number) diff --git a/docs/data-sources/cb_sep_disk_list.md b/docs/data-sources/cb_sep_disk_list.md new file mode 100644 index 00000000..00427b18 --- /dev/null +++ b/docs/data-sources/cb_sep_disk_list.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_sep_disk_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_sep_disk_list (Data Source) + + + + + + +## Schema + +### Required + +- `sep_id` (Number) storage endpoint provider ID + +### Optional + +- `pool_name` (String) pool name +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Number) sep disk list + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_sep_list.md b/docs/data-sources/cb_sep_list.md new file mode 100644 index 00000000..0a31bc1b --- /dev/null +++ b/docs/data-sources/cb_sep_list.md @@ -0,0 +1,66 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_sep_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_sep_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) find by id +- `consumed_by` (Number) find by consumed physical node id +- `gid` (Number) find by gid +- `name` (String) find by name +- `page` (Number) page number +- `provided_by` (Number) find by provided physical node id +- `sep_ids` (List of Number) sort by list of SEP identifiers +- `size` (Number) page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `tech_status` (String) find by techStatus +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `type` (String) find by sep type + +### Read-Only + +- `entry_count` (Number) entryCount +- `id` (String) The ID of this resource. +- `items` (List of Object) sep list (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `config` (String) +- `consumed_by` (Set of Number) +- `desc` (String) +- `gid` (Number) +- `guid` (Number) +- `milestones` (Number) +- `multipath_num` (Number) +- `name` (String) +- `obj_status` (String) +- `provided_by` (List of Number) +- `sep_id` (Number) +- `shared_with` (List of Number) +- `tech_status` (String) +- `type` (String) diff --git a/docs/data-sources/cb_sep_pool.md b/docs/data-sources/cb_sep_pool.md new file mode 100644 index 00000000..bb3cfece --- /dev/null +++ b/docs/data-sources/cb_sep_pool.md @@ -0,0 +1,61 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_sep_pool Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_sep_pool (Data Source) + + + + + + +## Schema + +### Required + +- `pool_name` (String) pool name +- `sep_id` (Number) storage endpoint provider ID + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `pool` (List of Object) pool (see [below for nested schema](#nestedatt--pool)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `pool` + +Read-Only: + +- `access_account_ids` (List of Number) +- `access_res_group_ids` (List of Number) +- `name` (String) +- `pagecache_ratio` (Number) +- `reference_id` (String) +- `types` (List of String) +- `uris` (Set of Object) (see [below for nested schema](#nestedobjatt--pool--uris)) +- `usage_limit` (Number) + + +### Nested Schema for `pool.uris` + +Read-Only: + +- `ip` (String) +- `port` (Number) diff --git a/docs/data-sources/cb_sep_template.md b/docs/data-sources/cb_sep_template.md new file mode 100644 index 00000000..3870ed3b --- /dev/null +++ b/docs/data-sources/cb_sep_template.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_sep_template Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_sep_template (Data Source) + + + + + + +## Schema + +### Required + +- `lang` (String) language +- `sep_type` (String) type of sep + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `sep_template` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_storage_policy.md b/docs/data-sources/cb_storage_policy.md new file mode 100644 index 00000000..aa82291c --- /dev/null +++ b/docs/data-sources/cb_storage_policy.md @@ -0,0 +1,63 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_storage_policy Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_storage_policy (Data Source) + + + + + + +## Schema + +### Required + +- `storage_policy_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `access_seps_pools` (List of Object) (see [below for nested schema](#nestedatt--access_seps_pools)) +- `description` (String) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `limit_iops` (Number) +- `name` (String) +- `status` (String) +- `usage` (List of Object) (see [below for nested schema](#nestedatt--usage)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `access_seps_pools` + +Read-Only: + +- `pool_names` (List of String) +- `sep_id` (Number) +- `sep_name` (String) +- `sep_tech_status` (String) + + + +### Nested Schema for `usage` + +Read-Only: + +- `accounts` (List of Number) +- `resgroups` (List of Number) diff --git a/docs/data-sources/cb_storage_policy_list.md b/docs/data-sources/cb_storage_policy_list.md new file mode 100644 index 00000000..0129b2ca --- /dev/null +++ b/docs/data-sources/cb_storage_policy_list.md @@ -0,0 +1,81 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_storage_policy_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_storage_policy_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) +- `by_id` (Number) +- `desc` (String) +- `limit_iops` (Number) +- `name` (String) +- `page` (Number) +- `pool_name` (String) +- `resgroup_id` (Number) +- `sep_id` (Number) +- `sep_tech_status` (String) +- `size` (Number) +- `sort_by` (String) +- `status` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `access_seps_pools` (List of Object) (see [below for nested schema](#nestedobjatt--items--access_seps_pools)) +- `description` (String) +- `guid` (Number) +- `limit_iops` (Number) +- `name` (String) +- `status` (String) +- `storage_policy_id` (Number) +- `usage` (List of Object) (see [below for nested schema](#nestedobjatt--items--usage)) + + +### Nested Schema for `items.access_seps_pools` + +Read-Only: + +- `pool_names` (List of String) +- `sep_id` (Number) +- `sep_name` (String) +- `sep_tech_status` (String) + + + +### Nested Schema for `items.usage` + +Read-Only: + +- `accounts` (List of Number) +- `resgroups` (List of Number) diff --git a/docs/data-sources/cb_trunk.md b/docs/data-sources/cb_trunk.md new file mode 100644 index 00000000..a99c9e54 --- /dev/null +++ b/docs/data-sources/cb_trunk.md @@ -0,0 +1,52 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_trunk Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_trunk (Data Source) + + + + + + +## Schema + +### Required + +- `trunk_id` (Number) trunk id + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_ids` (Set of Number) List of account IDs with access to this trunk +- `created_at` (Number) when the trunk was created +- `created_by` (String) who created the trunk +- `deleted_at` (Number) when the trunk was updated +- `deleted_by` (String) who updated the trunk +- `description` (String) Description of the trunk +- `guid` (Number) GUID +- `id` (String) The ID of this resource. +- `mac` (String) MAC address +- `mtu` (Number) Maximum Transmission Unit +- `name` (String) Name of the trunk +- `native_vlan_id` (Number) Native VLAN ID +- `ovs_bridge` (String) OVS bridge name +- `status` (String) if the trunk is enabled +- `trunk_tags` (String) List of trunk tags (values between 1-4095) +- `updated_at` (Number) when the trunk was updated +- `updated_by` (String) who updated the trunk + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_trunk_list.md b/docs/data-sources/cb_trunk_list.md new file mode 100644 index 00000000..db9fb404 --- /dev/null +++ b/docs/data-sources/cb_trunk_list.md @@ -0,0 +1,65 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_trunk_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_trunk_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_ids` (List of Number) Account access ID(s) to filter by +- `page` (Number) Page number. +- `size` (Number) Page size. +- `sort_by` (String) Sort by one of supported fields, format ± +- `status` (String) find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `trunk_ids` (List of Number) ID of the trunk(s) to filter by +- `trunk_tags` (String) Trunk tags to filter by (value between 1-4095) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_ids` (Set of Number) +- `created_at` (Number) +- `created_by` (String) +- `deleted_at` (Number) +- `deleted_by` (String) +- `description` (String) +- `guid` (Number) +- `id` (Number) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `native_vlan_id` (Number) +- `ovs_bridge` (String) +- `status` (String) +- `trunk_tags` (String) +- `updated_at` (Number) +- `updated_by` (String) diff --git a/docs/data-sources/cb_user.md b/docs/data-sources/cb_user.md new file mode 100644 index 00000000..161328cd --- /dev/null +++ b/docs/data-sources/cb_user.md @@ -0,0 +1,57 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_user Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_user (Data Source) + + + + + + +## Schema + +### Required + +- `user_id` (String) user_id + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `active` (Boolean) active +- `api_access` (Map of String) api_access +- `authkey` (String) authkey +- `authkeys` (List of String) authkeys +- `blocked` (Boolean) is the user blocked +- `ckey` (String) ckey +- `data` (String) data +- `description` (String) description +- `domain` (String) domain +- `emails` (List of String) emails +- `gid` (Number) gid +- `groups` (List of String) groups +- `guid` (String) guid +- `id` (String) The ID of this resource. +- `last_check` (Number) last_check +- `meta` (List of String) meta +- `mobile` (List of String) mobile +- `password` (String) password +- `protected` (Boolean) protected +- `roles` (List of String) roles +- `service_account` (Boolean) service_account +- `xmpp` (List of String) xmpp + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_user_get_audit.md b/docs/data-sources/cb_user_get_audit.md new file mode 100644 index 00000000..1a5b1478 --- /dev/null +++ b/docs/data-sources/cb_user_get_audit.md @@ -0,0 +1,54 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_user_get_audit Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_user_get_audit (Data Source) + + + + + + +## Schema + +### Optional + +- `call` (String) find by api call +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format ± +- `status_code` (Number) find by status code +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `timestamp_at` (Number) find all audits after point in time (unixtime) +- `timestamp_to` (Number) find all audits before point in time (unixtime) +- `username` (String) name of user (get audits for current user if set to empty) + +### Read-Only + +- `entry_count` (Number) entry_count +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `call` (String) +- `guid` (String) +- `response_time` (Number) +- `status_code` (Number) +- `time` (Number) diff --git a/docs/data-sources/cb_user_list.md b/docs/data-sources/cb_user_list.md new file mode 100644 index 00000000..b0e84aa8 --- /dev/null +++ b/docs/data-sources/cb_user_list.md @@ -0,0 +1,70 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_user_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_user_list (Data Source) + + + + + + +## Schema + +### Optional + +- `active` (Boolean) find by active. True or False +- `by_id` (String) find by id +- `email` (String) find by email +- `page` (Number) Page number +- `service_account` (Boolean) find by service account. True or False +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) entry_count +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `active` (Boolean) +- `apiaccess` (Map of String) +- `authkey` (String) +- `authkeys` (List of String) +- `blocked` (Boolean) +- `ckey` (String) +- `data` (String) +- `description` (String) +- `domain` (String) +- `emails` (List of String) +- `gid` (Number) +- `groups` (List of String) +- `guid` (String) +- `last_check` (Number) +- `meta` (List of String) +- `mobile` (List of String) +- `password` (String) +- `protected` (Boolean) +- `roles` (List of String) +- `service_account` (Boolean) +- `user_id` (String) +- `xmpp` (List of String) diff --git a/docs/data-sources/cb_vfpool.md b/docs/data-sources/cb_vfpool.md new file mode 100644 index 00000000..1cef8a10 --- /dev/null +++ b/docs/data-sources/cb_vfpool.md @@ -0,0 +1,72 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vfpool Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vfpool (Data Source) + + + + + + +## Schema + +### Required + +- `vfpool_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_access` (List of Number) +- `created_time` (Number) +- `description` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `name` (String) +- `rg_access` (List of Number) +- `status` (String) +- `updated_time` (Number) +- `vfs` (List of Object) (see [below for nested schema](#nestedatt--vfs)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `vfs` + +Read-Only: + +- `node_id` (Number) +- `vf_list` (List of Object) (see [below for nested schema](#nestedobjatt--vfs--vf_list)) + + +### Nested Schema for `vfs.vf_list` + +Read-Only: + +- `nic_name` (String) +- `vfs_info` (List of Object) (see [below for nested schema](#nestedobjatt--vfs--vf_list--vfs_info)) + + +### Nested Schema for `vfs.vf_list.vfs_info` + +Read-Only: + +- `claimed` (Boolean) +- `id` (Number) +- `vm_id` (Number) diff --git a/docs/data-sources/cb_vfpool_list.md b/docs/data-sources/cb_vfpool_list.md new file mode 100644 index 00000000..29bf9a1f --- /dev/null +++ b/docs/data-sources/cb_vfpool_list.md @@ -0,0 +1,87 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vfpool_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vfpool_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_access` (Number) Find by accountAccess +- `by_id` (Number) Find by ID +- `description` (String) Find by description +- `gid` (Number) Find by Grid ID +- `name` (String) Find by name +- `page` (Number) Page number +- `rg_access` (Number) Find by rgAccess +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_access` (List of Number) +- `created_time` (Number) +- `description` (String) +- `gid` (Number) +- `guid` (Number) +- `name` (String) +- `rg_access` (List of Number) +- `status` (String) +- `updated_time` (Number) +- `vfpool_id` (Number) +- `vfs` (List of Object) (see [below for nested schema](#nestedobjatt--items--vfs)) + + +### Nested Schema for `items.vfs` + +Read-Only: + +- `node_id` (Number) +- `vf_list` (List of Object) (see [below for nested schema](#nestedobjatt--items--vfs--vf_list)) + + +### Nested Schema for `items.vfs.vf_list` + +Read-Only: + +- `nic_name` (String) +- `vfs_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--vfs--vf_list--vfs_info)) + + +### Nested Schema for `items.vfs.vf_list.vfs_info` + +Read-Only: + +- `claimed` (Boolean) +- `id` (Number) +- `vm_id` (Number) diff --git a/docs/data-sources/cb_vins.md b/docs/data-sources/cb_vins.md new file mode 100644 index 00000000..7b47ec6d --- /dev/null +++ b/docs/data-sources/cb_vins.md @@ -0,0 +1,449 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) vins id + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) account id +- `account_name` (String) account name +- `created_by` (String) created by +- `created_time` (Number) created time +- `default_gw` (String) default gw +- `default_qos` (List of Object) default qoa (see [below for nested schema](#nestedatt--default_qos)) +- `deleted_by` (String) deleted by +- `deleted_time` (Number) deleted time +- `description` (String) description +- `gid` (Number) gid +- `guid` (Number) guid +- `id` (String) The ID of this resource. +- `lock_status` (String) lock status +- `manager_id` (Number) manager id +- `manager_type` (String) manager type +- `milestones` (Number) milestones +- `name` (String) name +- `netmask` (Number) net mask +- `network` (String) network +- `pre_reservations_num` (Number) pre reservations num +- `redundant` (Boolean) redundant +- `rg_id` (Number) resource group id +- `rg_name` (String) resource group name +- `sec_vnf_dev_id` (Number) +- `status` (String) status +- `updated_by` (String) updated by +- `updated_time` (Number) updated time +- `user_managed` (Boolean) user managed +- `vnf_dev` (List of Object) vnf dev (see [below for nested schema](#nestedatt--vnf_dev)) +- `vnfs` (List of Object) vnfs (see [below for nested schema](#nestedatt--vnfs)) +- `vxlan_id` (Number) vxlan id +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `default_qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_burst` (Number) +- `in_rate` (Number) + + + +### Nested Schema for `vnf_dev` + +Read-Only: + +- `account_id` (Number) +- `capabilities` (List of String) +- `ckey` (String) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config)) +- `config_saved` (Boolean) +- `custom_precfg` (Boolean) +- `description` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces)) +- `live_migration_job_id` (Number) +- `lock_status` (String) +- `meta` (List of String) +- `milestones` (Number) +- `name` (String) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `vins` (List of Number) +- `vnc_password` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnf_dev.config` + +Read-Only: + +- `mgmt` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config--mgmt)) +- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config--resources)) + + +### Nested Schema for `vnf_dev.config.mgmt` + +Read-Only: + +- `ip_addr` (String) +- `password` (String) +- `ssh_key` (String) +- `user` (String) + + + +### Nested Schema for `vnf_dev.config.resources` + +Read-Only: + +- `cpu` (Number) +- `node_id` (Number) +- `ram` (Number) +- `uuid` (String) + + + + +### Nested Schema for `vnf_dev.interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flipgroup_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_mask` (Number) +- `net_type` (String) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `vnf_dev.interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `vnf_dev.interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_burst` (Number) +- `in_rate` (Number) + + + + + +### Nested Schema for `vnfs` + +Read-Only: + +- `dhcp` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp)) +- `gw` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw)) +- `nat` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat)) + + +### Nested Schema for `vnfs.dhcp` + +Read-Only: + +- `account_id` (Number) +- `ckey` (String) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--devices)) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `lock_status` (String) +- `meta` (List of String) +- `milestones` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.dhcp.config` + +Read-Only: + +- `default_gw` (String) +- `dns` (List of String) +- `ip_end` (String) +- `ip_start` (String) +- `lease` (Number) +- `net_mask` (Number) +- `network` (String) +- `reservations` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--config--reservations)) + + +### Nested Schema for `vnfs.dhcp.config.reservations` + +Read-Only: + +- `account_id` (Number) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + + +### Nested Schema for `vnfs.dhcp.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--devices--primary)) + + +### Nested Schema for `vnfs.dhcp.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.dhcp.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) + + + + +### Nested Schema for `vnfs.gw` + +Read-Only: + +- `account_id` (Number) +- `ckey` (String) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--devices)) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `lock_status` (String) +- `meta` (List of String) +- `milestones` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.gw.config` + +Read-Only: + +- `default_gw` (String) +- `ext_net_id` (Number) +- `ext_net_ip` (String) +- `ext_netmask` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--config--qos)) + + +### Nested Schema for `vnfs.gw.config.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_burst` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `vnfs.gw.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--devices--primary)) + + +### Nested Schema for `vnfs.gw.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.gw.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) + + + + +### Nested Schema for `vnfs.nat` + +Read-Only: + +- `account_id` (Number) +- `ckey` (String) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--devices)) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `lock_status` (String) +- `meta` (List of String) +- `milestones` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.nat.config` + +Read-Only: + +- `net_mask` (Number) +- `network` (String) +- `rules` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--config--rules)) + + +### Nested Schema for `vnfs.nat.config.rules` + +Read-Only: + +- `local_ip` (String) +- `local_port` (Number) +- `protocol` (String) +- `public_port_end` (Number) +- `public_port_start` (Number) +- `rule_id` (Number) +- `vm_id` (Number) +- `vm_name` (String) + + + + +### Nested Schema for `vnfs.nat.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--devices--primary)) + + +### Nested Schema for `vnfs.nat.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.nat.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) diff --git a/docs/data-sources/cb_vins_audits.md b/docs/data-sources/cb_vins_audits.md new file mode 100644 index 00000000..5221568f --- /dev/null +++ b/docs/data-sources/cb_vins_audits.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins_audits Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins_audits (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored. + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `call` (String) +- `response_time` (Number) +- `status_code` (Number) +- `time_stamp` (Number) +- `user` (String) diff --git a/docs/data-sources/cb_vins_ext_net_list.md b/docs/data-sources/cb_vins_ext_net_list.md new file mode 100644 index 00000000..5b7cb1ef --- /dev/null +++ b/docs/data-sources/cb_vins_ext_net_list.md @@ -0,0 +1,51 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins_ext_net_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins_ext_net_list (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored. + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `default_gw` (String) +- `ext_net_id` (Number) +- `ip` (String) +- `prefix_len` (Number) +- `status` (String) +- `tech_status` (String) diff --git a/docs/data-sources/cb_vins_ip_list.md b/docs/data-sources/cb_vins_ip_list.md new file mode 100644 index 00000000..5717585a --- /dev/null +++ b/docs/data-sources/cb_vins_ip_list.md @@ -0,0 +1,52 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins_ip_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins_ip_list (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) Unique ID of the ViNS + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `client_type` (String) +- `domain_name` (String) +- `host_name` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) diff --git a/docs/data-sources/cb_vins_list.md b/docs/data-sources/cb_vins_list.md new file mode 100644 index 00000000..c9b1b50a --- /dev/null +++ b/docs/data-sources/cb_vins_list.md @@ -0,0 +1,112 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Find by account id +- `by_id` (Number) Find by id +- `ext_ip` (String) Find by ext ip +- `include_deleted` (Boolean) include deleted computes +- `name` (String) Name +- `page` (Number) Page number +- `rg_id` (Number) Find by rg id +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) sort by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vnfdev_id` (Number) find by VNF Device id +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) entry count +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `created_by` (String) +- `created_time` (Number) +- `default_gw` (String) +- `default_qos` (List of Object) (see [below for nested schema](#nestedobjatt--items--default_qos)) +- `deleted_by` (String) +- `deleted_time` (Number) +- `description` (String) +- `enable_secgroups` (Boolean) +- `external_ip` (String) +- `extnet_id` (Number) +- `free_ips` (Number) +- `gid` (Number) +- `guid` (Number) +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `milestones` (Number) +- `name` (String) +- `netmask` (Number) +- `network` (String) +- `pre_reservations_num` (Number) +- `pri_vnf_dev_id` (Number) +- `redundant` (Boolean) +- `rg_id` (Number) +- `rg_name` (String) +- `sec_vnf_dev_id` (Number) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_id` (Number) +- `vnfs` (List of Object) (see [below for nested schema](#nestedobjatt--items--vnfs)) +- `vxlan_id` (Number) +- `zone_id` (Number) + + +### Nested Schema for `items.default_qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_burst` (Number) +- `in_rate` (Number) + + + +### Nested Schema for `items.vnfs` + +Read-Only: + +- `dhcp` (Number) +- `dns` (Number) +- `fw` (Number) +- `gw` (Number) +- `nat` (Number) +- `vpn` (Number) diff --git a/docs/data-sources/cb_vins_list_deleted.md b/docs/data-sources/cb_vins_list_deleted.md new file mode 100644 index 00000000..8a915845 --- /dev/null +++ b/docs/data-sources/cb_vins_list_deleted.md @@ -0,0 +1,106 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Filter by account ID +- `by_id` (Number) Filter by ID +- `ext_ip` (String) Filter by external IP +- `name` (String) Filter by name +- `page` (Number) Page number +- `rg_id` (Number) Filter by resgroup ID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vnf_dev_id` (Number) Filter by VNF Device id + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `created_by` (String) +- `created_time` (Number) +- `default_gw` (String) +- `default_qos` (List of Object) (see [below for nested schema](#nestedobjatt--items--default_qos)) +- `deleted_by` (String) +- `deleted_time` (Number) +- `description` (String) +- `external_ip` (String) +- `gid` (Number) +- `guid` (Number) +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `milestones` (Number) +- `name` (String) +- `netmask` (Number) +- `network` (String) +- `pre_reservations_num` (Number) +- `pri_vnf_dev_id` (Number) +- `redundant` (Boolean) +- `rg_id` (Number) +- `rg_name` (String) +- `sec_vnf_dev_id` (Number) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_id` (Number) +- `vnfs` (List of Object) (see [below for nested schema](#nestedobjatt--items--vnfs)) +- `vxlan_id` (Number) +- `zone_id` (Number) + + +### Nested Schema for `items.default_qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_burst` (Number) +- `in_rate` (Number) + + + +### Nested Schema for `items.vnfs` + +Read-Only: + +- `dhcp` (Number) +- `dns` (Number) +- `fw` (Number) +- `gw` (Number) +- `nat` (Number) +- `vpn` (Number) diff --git a/docs/data-sources/cb_vins_nat_rule_list.md b/docs/data-sources/cb_vins_nat_rule_list.md new file mode 100644 index 00000000..c803517d --- /dev/null +++ b/docs/data-sources/cb_vins_nat_rule_list.md @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins_nat_rule_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins_nat_rule_list (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored. + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `id` (Number) +- `local_ip` (String) +- `local_port` (Number) +- `protocol` (String) +- `public_port_end` (Number) +- `public_port_start` (Number) +- `vm_id` (Number) +- `vm_name` (String) diff --git a/docs/data-sources/cb_vins_static_route.md b/docs/data-sources/cb_vins_static_route.md new file mode 100644 index 00000000..39eed779 --- /dev/null +++ b/docs/data-sources/cb_vins_static_route.md @@ -0,0 +1,42 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins_static_route Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins_static_route (Data Source) + + + + + + +## Schema + +### Required + +- `route_id` (Number) Unique ID of the static route +- `vins_id` (Number) Unique ID of the ViNS + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `id` (String) The ID of this resource. +- `netmask` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_vins_static_route_list.md b/docs/data-sources/cb_vins_static_route_list.md new file mode 100644 index 00000000..6af2d6d2 --- /dev/null +++ b/docs/data-sources/cb_vins_static_route_list.md @@ -0,0 +1,51 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins_static_route_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins_static_route_list (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) ID of VINS + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) diff --git a/docs/data-sources/cb_zone.md b/docs/data-sources/cb_zone.md new file mode 100644 index 00000000..cc0d3989 --- /dev/null +++ b/docs/data-sources/cb_zone.md @@ -0,0 +1,64 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_zone Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_zone (Data Source) + + + + + + +## Schema + +### Required + +- `zone_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_ids` (List of Number) +- `app_id` (String) +- `auto_start` (Boolean) +- `broadcast_addr` (String) +- `bservice_ids` (List of Number) +- `compute_ids` (List of Number) +- `created_time` (Number) +- `decort_url` (String) +- `deletable` (Boolean) +- `description` (String) +- `domain` (String) +- `drs` (Boolean) +- `drs_name` (String) +- `drs_uid` (String) +- `extnet_ids` (List of Number) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `k8s_ids` (List of Number) +- `lb_ids` (List of Number) +- `name` (String) +- `node_ids` (List of Number) +- `ping_addr` (String) +- `ssl_skip_verify` (Boolean) +- `sso_type` (String) +- `sso_url` (String) +- `status` (String) +- `updated_time` (Number) +- `vins_ids` (List of Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/cb_zone_list.md b/docs/data-sources/cb_zone_list.md new file mode 100644 index 00000000..7fab8233 --- /dev/null +++ b/docs/data-sources/cb_zone_list.md @@ -0,0 +1,73 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_zone_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_zone_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) Find by ID +- `deletable` (Boolean) Find by deletable +- `description` (String) Find by description +- `gid` (Number) Find by Grid ID +- `name` (String) Find by name +- `node_id` (Number) Find by nodeId +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `app_id` (String) +- `auto_start` (Boolean) +- `broadcast_addr` (String) +- `created_time` (Number) +- `decort_url` (String) +- `deletable` (Boolean) +- `description` (String) +- `domain` (String) +- `drs` (Boolean) +- `drs_name` (String) +- `drs_uid` (String) +- `gid` (Number) +- `guid` (Number) +- `name` (String) +- `node_ids` (List of Number) +- `ping_addr` (String) +- `ssl_skip_verify` (Boolean) +- `sso_type` (String) +- `sso_url` (String) +- `status` (String) +- `updated_time` (Number) +- `zone_id` (Number) diff --git a/docs/data-sources/disk.md b/docs/data-sources/disk.md new file mode 100644 index 00000000..f280ec60 --- /dev/null +++ b/docs/data-sources/disk.md @@ -0,0 +1,140 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_disk Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_disk (Data Source) + + + + + + +## Schema + +### Required + +- `disk_id` (Number) The unique ID of the subscriber-owner of the disk + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) The unique ID of the subscriber-owner of the disk +- `account_name` (String) The name of the subscriber '(account') to whom this disk belongs +- `acl` (String) +- `blk_discard` (Boolean) +- `block_size` (String) +- `cache` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `created_by` (String) +- `created_time` (Number) Created time +- `deleted_by` (String) +- `deleted_time` (Number) Deleted time +- `desc` (String) Description of disk +- `destruction_time` (Number) Time of final deletion +- `devicename` (String) Name of the device +- `disk_name` (String) Name of disk +- `gid` (Number) ID of the grid (platform) +- `id` (String) The ID of this resource. +- `image_id` (Number) Image ID +- `images` (List of Number) IDs of images using the disk +- `independent` (Boolean) +- `iotune` (List of Object) (see [below for nested schema](#nestedatt--iotune)) +- `machine_id` (Number) +- `machine_name` (String) +- `milestones` (Number) Milestones +- `order` (Number) Disk order +- `params` (String) Disk params +- `parent_id` (Number) ID of the parent disk +- `pci_slot` (Number) ID of the pci slot to which the disk is connected +- `pool` (String) Pool for disk location +- `present_to` (Map of Number) +- `provision` (String) +- `purge_time` (Number) Time of the last deletion attempt +- `replication` (List of Object) Replication status (see [below for nested schema](#nestedatt--replication)) +- `res_id` (String) Resource ID +- `res_name` (String) Name of the resource +- `role` (String) Disk role +- `sep_id` (Number) Storage endpoint provider ID to create disk +- `sep_type` (String) Type SEP. Defines the type of storage system and contains one of the values set in the cloud platform +- `shareable` (Boolean) +- `size_available` (Number) +- `size_max` (Number) Size in GB +- `size_used` (Number) Number of used space, in GB +- `snapshots` (List of Object) (see [below for nested schema](#nestedatt--snapshots)) +- `status` (String) Disk status +- `storage_policy_id` (Number) Storage policy ID +- `tech_status` (String) Technical status of the disk +- `to_clean` (Boolean) +- `updated_by` (String) +- `updated_time` (Number) +- `vmid` (Number) Virtual Machine ID (Deprecated) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `compute_id` (String) +- `compute_name` (String) + + + +### Nested Schema for `iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/disk_list.md b/docs/data-sources/disk_list.md new file mode 100644 index 00000000..aa1acbf0 --- /dev/null +++ b/docs/data-sources/disk_list.md @@ -0,0 +1,160 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_disk_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_disk_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) ID of the account the disks belong to +- `account_name` (String) Find by account name +- `by_id` (Number) Find by ID +- `compute_id` (Number) Find by compute ID +- `disk_max_size` (Number) Find by max disk size +- `name` (String) Find by name +- `page` (Number) Page number +- `pool_name` (String) find by pool name +- `rg_id` (Number) Find by rg ID +- `sep_id` (Number) find by sep ID +- `shared` (Boolean) Find by shared field +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `storage_policy_id` (Number) storage policy ID +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (String) +- `blk_discard` (Boolean) +- `block_size` (String) +- `cache` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedobjatt--items--computes)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `destruction_time` (Number) +- `devicename` (String) +- `disk_id` (Number) +- `disk_name` (String) +- `gid` (Number) +- `image_id` (Number) +- `images` (List of Number) +- `independent` (Boolean) +- `iotune` (List of Object) (see [below for nested schema](#nestedobjatt--items--iotune)) +- `machine_id` (Number) +- `machine_name` (String) +- `milestones` (Number) +- `order` (Number) +- `params` (String) +- `parent_id` (Number) +- `pci_slot` (Number) +- `pool` (String) +- `present_to` (Map of Number) +- `provision` (String) +- `purge_time` (Number) +- `replication` (List of Object) (see [below for nested schema](#nestedobjatt--items--replication)) +- `res_id` (String) +- `res_name` (String) +- `role` (String) +- `sep_id` (Number) +- `sep_type` (String) +- `shareable` (Boolean) +- `size_available` (Number) +- `size_max` (Number) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedobjatt--items--snapshots)) +- `status` (String) +- `storage_policy_id` (Number) +- `tech_status` (String) +- `to_clean` (Boolean) +- `updated_by` (String) +- `updated_time` (Number) +- `vmid` (Number) + + +### Nested Schema for `items.computes` + +Read-Only: + +- `compute_id` (String) +- `compute_name` (String) + + + +### Nested Schema for `items.iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `items.replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `items.snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/disk_list_deleted.md b/docs/data-sources/disk_list_deleted.md new file mode 100644 index 00000000..afdaec8c --- /dev/null +++ b/docs/data-sources/disk_list_deleted.md @@ -0,0 +1,154 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_disk_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_disk_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) ID of the account the disks belong to +- `account_name` (String) Filter by account name +- `by_id` (Number) Filter by disk ID +- `disk_max_size` (Number) Filter by max disk size +- `name` (String) Filter by disk name +- `page` (Number) Page number +- `shared` (Boolean) Find shared disks +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (String) +- `blk_discard` (Boolean) +- `block_size` (String) +- `cache` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedobjatt--items--computes)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `destruction_time` (Number) +- `devicename` (String) +- `disk_id` (Number) +- `disk_name` (String) +- `gid` (Number) +- `image_id` (Number) +- `images` (List of Number) +- `independent` (Boolean) +- `iotune` (List of Object) (see [below for nested schema](#nestedobjatt--items--iotune)) +- `machine_id` (Number) +- `machine_name` (String) +- `milestones` (Number) +- `order` (Number) +- `params` (String) +- `parent_id` (Number) +- `pci_slot` (Number) +- `pool` (String) +- `present_to` (Map of Number) +- `provision` (String) +- `purge_time` (Number) +- `replication` (List of Object) (see [below for nested schema](#nestedobjatt--items--replication)) +- `res_id` (String) +- `res_name` (String) +- `role` (String) +- `sep_id` (Number) +- `sep_type` (String) +- `shareable` (Boolean) +- `size_available` (Number) +- `size_max` (Number) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedobjatt--items--snapshots)) +- `status` (String) +- `storage_policy_id` (Number) +- `tech_status` (String) +- `to_clean` (Boolean) +- `updated_by` (String) +- `updated_time` (Number) +- `vmid` (Number) + + +### Nested Schema for `items.computes` + +Read-Only: + +- `compute_id` (String) +- `compute_name` (String) + + + +### Nested Schema for `items.iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `items.replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `items.snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/disk_list_unattached.md b/docs/data-sources/disk_list_unattached.md new file mode 100644 index 00000000..c21236b1 --- /dev/null +++ b/docs/data-sources/disk_list_unattached.md @@ -0,0 +1,131 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_disk_list_unattached Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_disk_list_unattached (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) ID of the account the disks belong to +- `account_name` (String) Find by account name +- `by_id` (Number) Find by ID +- `disk_max_size` (Number) Find by max disk size +- `page` (Number) Page number +- `pool_name` (String) find by pool name +- `sep_id` (Number) find by sep ID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `storage_policy_id` (Number) storage policy ID +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `_meta` (List of String) +- `account_id` (Number) +- `account_name` (String) +- `acl` (String) +- `blk_discard` (Boolean) +- `block_size` (String) +- `boot_partition` (Number) +- `cache` (String) +- `created_time` (Number) +- `deleted_time` (Number) +- `desc` (String) +- `destruction_time` (Number) +- `disk_id` (Number) +- `disk_name` (String) +- `disk_path` (String) +- `gid` (Number) +- `guid` (Number) +- `image_id` (Number) +- `images` (List of Number) +- `iotune` (List of Object) (see [below for nested schema](#nestedobjatt--items--iotune)) +- `iqn` (String) +- `login` (String) +- `milestones` (Number) +- `order` (Number) +- `params` (String) +- `parent_id` (Number) +- `passwd` (String) +- `pci_slot` (Number) +- `pool` (String) +- `present_to` (Map of Number) +- `provision` (String) +- `purge_attempts` (Number) +- `purge_time` (Number) +- `reality_device_number` (Number) +- `reference_id` (String) +- `res_id` (String) +- `res_name` (String) +- `role` (String) +- `sep_id` (Number) +- `shareable` (Boolean) +- `size_max` (Number) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedobjatt--items--snapshots)) +- `status` (String) +- `tech_status` (String) +- `to_clean` (Boolean) +- `vmid` (Number) + + +### Nested Schema for `items.iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `items.snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/disk_replication.md b/docs/data-sources/disk_replication.md new file mode 100644 index 00000000..2d83f8eb --- /dev/null +++ b/docs/data-sources/disk_replication.md @@ -0,0 +1,127 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_disk_replication Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_disk_replication (Data Source) + + + + + + +## Schema + +### Required + +- `disk_id` (Number) Id of primary disk +- `replica_disk_id` (Number) Id of secondary disk + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) The unique ID of the subscriber-owner of the disk +- `account_name` (String) The name of the subscriber '(account') to whom this disk belongs +- `acl` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `created_time` (Number) Created time +- `deleted_time` (Number) Deleted time +- `desc` (String) Description of disk +- `destruction_time` (Number) Time of final deletion +- `devicename` (String) Name of the device +- `disk_name` (String) Name of disk +- `gid` (Number) ID of the grid (platform) +- `id` (String) The ID of this resource. +- `image_id` (Number) Image ID +- `images` (List of Number) IDs of images using the disk +- `iotune` (List of Object) (see [below for nested schema](#nestedatt--iotune)) +- `order` (Number) Disk order +- `params` (String) Disk params +- `parent_id` (Number) ID of the parent disk +- `pci_slot` (Number) ID of the pci slot to which the disk is connected +- `pool` (String) Pool for disk location +- `present_to` (Map of Number) +- `purge_time` (Number) Time of the last deletion attempt +- `replication` (List of Object) Replication status (see [below for nested schema](#nestedatt--replication)) +- `res_id` (String) Resource ID +- `res_name` (String) Name of the resource +- `role` (String) Disk role +- `sep_id` (Number) Storage endpoint provider ID to create disk +- `sep_type` (String) Type SEP. Defines the type of storage system and contains one of the values set in the cloud platform +- `shareable` (Boolean) +- `size_max` (Number) Size in GB +- `size_used` (Number) Number of used space, in GB +- `snapshots` (List of Object) (see [below for nested schema](#nestedatt--snapshots)) +- `status` (String) Disk status +- `status_replication` (String) Status of replication +- `tech_status` (String) Technical status of the disk +- `vmid` (Number) Virtual Machine ID (Deprecated) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `compute_id` (String) +- `compute_name` (String) + + + +### Nested Schema for `iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/disk_snapshot.md b/docs/data-sources/disk_snapshot.md new file mode 100644 index 00000000..92467bfd --- /dev/null +++ b/docs/data-sources/disk_snapshot.md @@ -0,0 +1,42 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_disk_snapshot Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_disk_snapshot (Data Source) + + + + + + +## Schema + +### Required + +- `disk_id` (Number) The unique ID of the subscriber-owner of the disk +- `label` (String) Name of the snapshot + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `guid` (String) ID of the snapshot +- `id` (String) The ID of this resource. +- `res_id` (String) Reference to the snapshot +- `snap_set_guid` (String) The set snapshot ID +- `snap_set_time` (Number) The set time of the snapshot +- `timestamp` (Number) Snapshot time + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/disk_snapshot_list.md b/docs/data-sources/disk_snapshot_list.md new file mode 100644 index 00000000..1f1e43ec --- /dev/null +++ b/docs/data-sources/disk_snapshot_list.md @@ -0,0 +1,50 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_disk_snapshot_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_disk_snapshot_list (Data Source) + + + + + + +## Schema + +### Required + +- `disk_id` (Number) The unique ID of the subscriber-owner of the disk + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/dpdknet.md b/docs/data-sources/dpdknet.md new file mode 100644 index 00000000..6e7655f5 --- /dev/null +++ b/docs/data-sources/dpdknet.md @@ -0,0 +1,48 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_dpdknet Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_dpdknet (Data Source) + + + + + + +## Schema + +### Required + +- `dpdk_id` (Number) The unique ID of the subscriber-owner of the DPDK network + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_access` (List of Number) List of accounts with access +- `compute_ids` (List of Number) Compute IDs which uses this DPDK network +- `created_time` (Number) Created time +- `desc` (String) Description of DPDK network +- `gid` (Number) ID of the grid (platform) +- `guid` (Number) DPDK network ID on the storage side +- `id` (String) The ID of this resource. +- `name` (String) Name of network +- `ovs_bridge` (String) OVS bridge in which interfaces for computers created +- `rg_access` (List of Number) List of resource groups with access +- `status` (String) DPDK network status +- `updated_time` (Number) Updated time +- `vlan_id` (Number) vlan ID + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/dpdknet_list.md b/docs/data-sources/dpdknet_list.md new file mode 100644 index 00000000..c71c1b64 --- /dev/null +++ b/docs/data-sources/dpdknet_list.md @@ -0,0 +1,63 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_dpdknet_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_dpdknet_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) Find by ID +- `compute_ids` (List of Number) Find by compute IDs +- `desc` (String) Find by description +- `gid` (Number) Find by GID +- `name` (String) Find by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_access` (List of Number) +- `compute_ids` (List of Number) +- `created_time` (Number) +- `desc` (String) +- `dpdk_id` (Number) +- `gid` (Number) +- `guid` (Number) +- `name` (String) +- `ovs_bridge` (String) +- `rg_access` (List of Number) +- `status` (String) +- `updated_time` (Number) +- `vlan_id` (Number) diff --git a/docs/data-sources/extnet.md b/docs/data-sources/extnet.md new file mode 100644 index 00000000..11d0d7bf --- /dev/null +++ b/docs/data-sources/extnet.md @@ -0,0 +1,140 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_extnet Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_extnet (Data Source) + + + + + + +## Schema + +### Required + +- `net_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `check_ips` (List of String) +- `ckey` (String) +- `default` (Boolean) +- `default_qos` (List of Object) (see [below for nested schema](#nestedatt--default_qos)) +- `desc` (String) +- `dns` (List of String) +- `excluded` (List of Object) (see [below for nested schema](#nestedatt--excluded)) +- `free_ips` (Number) +- `gateway` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `ipcidr` (String) +- `meta` (List of String) meta +- `milestones` (Number) +- `mtu` (Number) +- `net_name` (String) +- `network` (String) +- `network_ids` (List of Object) (see [below for nested schema](#nestedatt--network_ids)) +- `ntp` (List of String) +- `pre_reservations` (List of Object) (see [below for nested schema](#nestedatt--pre_reservations)) +- `pre_reservations_num` (Number) +- `prefix` (Number) +- `pri_vnf_dev_id` (Number) +- `redundant` (Boolean) +- `reservations` (List of Object) (see [below for nested schema](#nestedatt--reservations)) +- `sec_vnfdev_id` (Number) +- `shared_with` (List of Number) +- `status` (String) +- `vlan_id` (Number) +- `vnfs` (List of Object) (see [below for nested schema](#nestedatt--vnfs)) +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `default_qos` + +Read-Only: + +- `e_burst` (Number) +- `e_rate` (Number) +- `guid` (String) +- `in_burst` (Number) +- `in_rate` (Number) + + + +### Nested Schema for `excluded` + +Read-Only: + +- `client_type` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + +### Nested Schema for `network_ids` + +Read-Only: + +- `primary` (Number) +- `secondary` (Number) + + + +### Nested Schema for `pre_reservations` + +Read-Only: + +- `account_id` (Number) +- `client_type` (String) +- `desc` (String) +- `domain_name` (String) +- `hostname` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + +### Nested Schema for `reservations` + +Read-Only: + +- `account_id` (Number) +- `client_type` (String) +- `desc` (String) +- `domainname` (String) +- `hostname` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + +### Nested Schema for `vnfs` + +Read-Only: + +- `dhcp` (Number) diff --git a/docs/data-sources/extnet_computes_list.md b/docs/data-sources/extnet_computes_list.md new file mode 100644 index 00000000..624ed5c6 --- /dev/null +++ b/docs/data-sources/extnet_computes_list.md @@ -0,0 +1,67 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_extnet_computes_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_extnet_computes_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) filter by account ID + +### Optional + +- `compute_id` (Number) Filter by compute ID +- `page` (Number) Page number +- `rg_id` (Number) Filter by RG ID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `extnets` (List of Object) (see [below for nested schema](#nestedobjatt--items--extnets)) +- `id` (Number) +- `name` (String) +- `rg_id` (Number) +- `rg_name` (String) + + +### Nested Schema for `items.extnets` + +Read-Only: + +- `ipaddr` (String) +- `ipcidr` (String) +- `name` (String) +- `net_id` (Number) diff --git a/docs/data-sources/extnet_default.md b/docs/data-sources/extnet_default.md new file mode 100644 index 00000000..22eae05b --- /dev/null +++ b/docs/data-sources/extnet_default.md @@ -0,0 +1,33 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_extnet_default Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_extnet_default (Data Source) + + + + + + +## Schema + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `net_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/extnet_list.md b/docs/data-sources/extnet_list.md new file mode 100644 index 00000000..bcdf894e --- /dev/null +++ b/docs/data-sources/extnet_list.md @@ -0,0 +1,57 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_extnet_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_extnet_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Find by account ID +- `by_id` (Number) Find by ID +- `name` (String) Find by name +- `network` (String) +- `ovs_bridge` (String) Name of the openVswitch bridge +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vlan_id` (Number) Find by VLAN ID +- `vnfdev_id` (Number) Find by VnfDEV ID +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `ipcidr` (String) +- `name` (String) +- `net_id` (Number) +- `status` (String) diff --git a/docs/data-sources/extnet_reserved_ip_list.md b/docs/data-sources/extnet_reserved_ip_list.md new file mode 100644 index 00000000..4a798179 --- /dev/null +++ b/docs/data-sources/extnet_reserved_ip_list.md @@ -0,0 +1,61 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_extnet_reserved_ip_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_extnet_reserved_ip_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) + +### Optional + +- `extnet_id` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `extnet_id` (Number) +- `reservations` (List of Object) (see [below for nested schema](#nestedobjatt--items--reservations)) + + +### Nested Schema for `items.reservations` + +Read-Only: + +- `account_id` (Number) +- `client_type` (String) +- `domain_name` (String) +- `hostname` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) diff --git a/docs/data-sources/flipgroup.md b/docs/data-sources/flipgroup.md new file mode 100644 index 00000000..f007c9b8 --- /dev/null +++ b/docs/data-sources/flipgroup.md @@ -0,0 +1,59 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_flipgroup Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_flipgroup (Data Source) + + + + + + +## Schema + +### Required + +- `flipgroup_id` (Number) Flipgroupd ID + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `client_ids` (List of Number) +- `client_type` (String) +- `conn_id` (Number) +- `conn_type` (String) +- `created_by` (String) +- `created_time` (Number) +- `default_gw` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `ip` (String) +- `milestones` (Number) +- `name` (String) +- `net_id` (Number) +- `net_type` (String) +- `network` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/flipgroup_list.md b/docs/data-sources/flipgroup_list.md new file mode 100644 index 00000000..36599a54 --- /dev/null +++ b/docs/data-sources/flipgroup_list.md @@ -0,0 +1,73 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_flipgroup_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_flipgroup_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Account id +- `by_id` (Number) Filter by ID +- `by_ip` (String) Filter by IP-address +- `client_ids` (List of Number) client_ids +- `conn_id` (Number) Conn id +- `extnet_id` (Number) Filter by ExtNetID +- `name` (String) Filter by Name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) Filter by ViNS ID +- `vins_name` (String) Filter by ViNS name + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `ckey` (String) +- `client_ids` (List of Number) +- `client_type` (String) +- `conn_id` (Number) +- `conn_type` (String) +- `default_gw` (String) +- `desc` (String) +- `flipgroup_id` (Number) +- `gid` (Number) +- `guid` (Number) +- `ip` (String) +- `meta` (List of String) +- `milestones` (Number) +- `name` (String) +- `net_id` (Number) +- `net_mask` (Number) +- `net_type` (String) +- `status` (String) diff --git a/docs/data-sources/image.md b/docs/data-sources/image.md new file mode 100644 index 00000000..cfa72fea --- /dev/null +++ b/docs/data-sources/image.md @@ -0,0 +1,88 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_image Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_image (Data Source) + + + + + + +## Schema + +### Required + +- `image_id` (Number) + +### Optional + +- `show_all` (Boolean) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `acl` (String) +- `architecture` (String) +- `boot_type` (String) +- `bootable` (Boolean) +- `cd_presented_to` (String) +- `compute_ci_id` (Number) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `enabled` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `hot_resize` (Boolean) +- `id` (String) The ID of this resource. +- `image_name` (String) +- `independent` (Boolean) +- `last_modified` (Number) +- `link_to` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `network_interface_naming` (String) +- `password` (String) +- `pool_name` (String) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `res_id` (String) +- `rescuecd` (Boolean) +- `sep_id` (Number) +- `shared_with` (List of Number) +- `size` (Number) +- `snapshot_id` (String) +- `status` (String) +- `storage_policy_id` (Number) +- `tech_status` (String) +- `to_clean` (Boolean) +- `type` (String) +- `unc_path` (String) +- `username` (String) +- `version` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/image_list.md b/docs/data-sources/image_list.md new file mode 100644 index 00000000..1b41ae20 --- /dev/null +++ b/docs/data-sources/image_list.md @@ -0,0 +1,79 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_image_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_image_list (Data Source) + + + + + + +## Schema + +### Optional + +- `architecture` (String) Filter by architecture +- `bootable` (Boolean) Find bootable images +- `by_id` (Number) Filter by ID +- `enabled` (Boolean) find by enabled True or False +- `hot_resize` (Boolean) Find hot resizable images +- `image_size` (Number) Filter by image size +- `name` (String) Filter by name +- `page` (Number) page number +- `pool` (String) Filter by pool +- `public` (Boolean) Find public/private images +- `sep_id` (Number) Filter by Storage Endpoint ID +- `sep_name` (String) Filter by SEP name +- `size` (Number) page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `storage_policy_id` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `type_image` (String) Filter by image type + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) image list (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `architecture` (String) +- `boot_type` (String) +- `bootable` (Boolean) +- `cdrom` (Boolean) +- `desc` (String) +- `drivers` (List of String) +- `hot_resize` (Boolean) +- `image_id` (Number) +- `image_name` (String) +- `link_to` (Number) +- `links_to` (List of Number) +- `network_interface_naming` (String) +- `pool_name` (String) +- `sep_id` (Number) +- `size` (Number) +- `status` (String) +- `storage_policy_id` (Number) +- `type` (String) +- `username` (String) +- `virtual` (Boolean) diff --git a/docs/data-sources/k8ci_list.md b/docs/data-sources/k8ci_list.md new file mode 100644 index 00000000..fd6fd8d1 --- /dev/null +++ b/docs/data-sources/k8ci_list.md @@ -0,0 +1,59 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8ci_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8ci_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) Filter by ID +- `include_disabled` (Boolean) Include deleted k8cis in result +- `master_driver` (String) Filter by master driver +- `name` (String) Filter by name +- `network_plugin` (String) Filter by network plugin +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `worker_driver` (String) Filter by worker driver + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `created_time` (Number) +- `desc` (String) +- `k8ci_id` (Number) +- `lb_image_id` (Number) +- `name` (String) +- `network_plugins` (List of String) +- `status` (String) +- `version` (String) diff --git a/docs/data-sources/k8s.md b/docs/data-sources/k8s.md new file mode 100644 index 00000000..b4531170 --- /dev/null +++ b/docs/data-sources/k8s.md @@ -0,0 +1,188 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8s Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8s (Data Source) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `bservice_id` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `extnet_id` (Number) ID of the external network to connect workers to. If omitted network will be chosen by the platfom. +- `id` (String) The ID of this resource. +- `k8s_ci_name` (String) +- `k8sci_id` (Number) +- `kubeconfig` (String) Kubeconfig for cluster access. +- `lb_id` (Number) +- `lb_ip` (String) IP address of default load balancer. +- `masters` (List of Object) (see [below for nested schema](#nestedatt--masters)) +- `name` (String) +- `network_plugin` (String) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins_id` (Number) +- `workers` (List of Object) (see [below for nested schema](#nestedatt--workers)) +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `account_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--account_acl)) +- `k8s_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--k8s_acl)) +- `rg_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--rg_acl)) + + +### Nested Schema for `acl.account_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.k8s_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.rg_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + + +### Nested Schema for `masters` + +Read-Only: + +- `cpu` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedobjatt--masters--detailed_info)) +- `disk` (Number) +- `master_id` (Number) +- `name` (String) +- `num` (Number) +- `ram` (Number) + + +### Nested Schema for `masters.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--masters--detailed_info--interfaces)) +- `name` (String) +- `natable_vins_ip` (String) +- `natable_vins_network` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `masters.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) + + + + + +### Nested Schema for `workers` + +Read-Only: + +- `annotations` (List of String) +- `cpu` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedobjatt--workers--detailed_info)) +- `disk` (Number) +- `guid` (String) +- `id` (Number) +- `labels` (List of String) +- `name` (String) +- `num` (Number) +- `ram` (Number) +- `taints` (List of String) + + +### Nested Schema for `workers.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--workers--detailed_info--interfaces)) +- `name` (String) +- `natable_vins_ip` (String) +- `natable_vins_network` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `workers.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/data-sources/k8s_computes.md b/docs/data-sources/k8s_computes.md new file mode 100644 index 00000000..7ef0849e --- /dev/null +++ b/docs/data-sources/k8s_computes.md @@ -0,0 +1,62 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8s_computes Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8s_computes (Data Source) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `masters` (List of Object) (see [below for nested schema](#nestedatt--masters)) +- `workers` (List of Object) (see [below for nested schema](#nestedatt--workers)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `masters` + +Read-Only: + +- `group_name` (String) +- `id` (Number) +- `name` (String) +- `status` (String) +- `tech_status` (String) + + + +### Nested Schema for `workers` + +Read-Only: + +- `group_name` (String) +- `id` (Number) +- `name` (String) +- `status` (String) +- `tech_status` (String) diff --git a/docs/data-sources/k8s_list.md b/docs/data-sources/k8s_list.md new file mode 100644 index 00000000..73ad1290 --- /dev/null +++ b/docs/data-sources/k8s_list.md @@ -0,0 +1,131 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8s_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8s_list (Data Source) + + + + + + +## Schema + +### Optional + +- `bservice_id` (Number) Filter by BService ID +- `by_id` (Number) Filter by ID +- `includedeleted` (Boolean) +- `ip_address` (String) Filter by IP address +- `lb_id` (Number) Filter by LB ID +- `name` (String) Filter by name +- `page` (Number) +- `rg_id` (Number) Filter by RG ID +- `size` (Number) +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `tech_status` (String) Filter by tech. status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of String) +- `bservice_id` (Number) +- `ci_id` (Number) +- `config` (List of String) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `extnet_id` (Number) +- `gid` (Number) +- `guid` (Number) +- `k8s_id` (Number) +- `k8s_name` (String) +- `lb_id` (Number) +- `milestones` (Number) +- `network_plugin` (String) +- `rg_id` (Number) +- `rg_name` (String) +- `service_account` (List of Object) (see [below for nested schema](#nestedobjatt--items--service_account)) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins_id` (Number) +- `workers_groups` (List of Object) (see [below for nested schema](#nestedobjatt--items--workers_groups)) +- `zone_id` (Number) + + +### Nested Schema for `items.service_account` + +Read-Only: + +- `guid` (String) +- `password` (String) +- `username` (String) + + + +### Nested Schema for `items.workers_groups` + +Read-Only: + +- `annotations` (List of String) +- `cpu` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--workers_groups--detailed_info)) +- `detailed_info_id` (Number) +- `disk` (Number) +- `guid` (String) +- `labels` (List of String) +- `name` (String) +- `num` (Number) +- `ram` (Number) +- `taints` (List of String) + + +### Nested Schema for `items.workers_groups.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--items--workers_groups--detailed_info--interfaces)) +- `name` (String) +- `natable_vins_ip` (String) +- `natable_vins_network` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `items.workers_groups.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/data-sources/k8s_list_deleted.md b/docs/data-sources/k8s_list_deleted.md new file mode 100644 index 00000000..d4ac8ab2 --- /dev/null +++ b/docs/data-sources/k8s_list_deleted.md @@ -0,0 +1,129 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8s_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8s_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `bservice_id` (Number) Filter by BService ID +- `by_id` (Number) Filter by ID +- `ip_address` (String) Filter by IP address +- `lb_id` (Number) Filter by LB ID +- `name` (String) Filter by name +- `page` (Number) +- `rg_id` (Number) Filter by RG ID +- `size` (Number) +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `tech_status` (String) Filter by tech. status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of String) +- `bservice_id` (Number) +- `ci_id` (Number) +- `config` (List of String) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `extnet_id` (Number) +- `gid` (Number) +- `guid` (Number) +- `k8s_id` (Number) +- `k8s_name` (String) +- `lb_id` (Number) +- `milestones` (Number) +- `network_plugin` (String) +- `rg_id` (Number) +- `rg_name` (String) +- `service_account` (List of Object) (see [below for nested schema](#nestedobjatt--items--service_account)) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins_id` (Number) +- `workers_groups` (List of Object) (see [below for nested schema](#nestedobjatt--items--workers_groups)) +- `zone_id` (Number) + + +### Nested Schema for `items.service_account` + +Read-Only: + +- `guid` (String) +- `password` (String) +- `username` (String) + + + +### Nested Schema for `items.workers_groups` + +Read-Only: + +- `annotations` (List of String) +- `cpu` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--workers_groups--detailed_info)) +- `detailed_info_id` (Number) +- `disk` (Number) +- `guid` (String) +- `labels` (List of String) +- `name` (String) +- `num` (Number) +- `ram` (Number) +- `taints` (List of String) + + +### Nested Schema for `items.workers_groups.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--items--workers_groups--detailed_info--interfaces)) +- `name` (String) +- `natable_vins_ip` (String) +- `natable_vins_network` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `items.workers_groups.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/data-sources/k8s_wg.md b/docs/data-sources/k8s_wg.md new file mode 100644 index 00000000..1bcf6e45 --- /dev/null +++ b/docs/data-sources/k8s_wg.md @@ -0,0 +1,69 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8s_wg Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8s_wg (Data Source) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) ID of k8s instance. +- `wg_id` (Number) ID of k8s worker Group. + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `annotations` (List of String) +- `cpu` (Number) Worker node CPU count. +- `detailed_info` (List of Object) (see [below for nested schema](#nestedatt--detailed_info)) +- `disk` (Number) Worker node boot disk size. If unspecified or 0, size is defined by OS image size. +- `guid` (String) +- `id` (String) The ID of this resource. +- `labels` (List of String) +- `name` (String) Name of the worker group. +- `num` (Number) Number of worker nodes to create. +- `ram` (Number) Worker node RAM in MB. +- `taints` (List of String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--detailed_info--interfaces)) +- `name` (String) +- `natable_vins_ip` (String) +- `natable_vins_network` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/data-sources/k8s_wg_cloud_init.md b/docs/data-sources/k8s_wg_cloud_init.md new file mode 100644 index 00000000..7062753b --- /dev/null +++ b/docs/data-sources/k8s_wg_cloud_init.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8s_wg_cloud_init Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8s_wg_cloud_init (Data Source) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) Kubernetes cluster ID +- `wg_id` (Number) ID of the workers compute group + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `cloud_init` (String) Worker group Cloud init +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/k8s_wg_list.md b/docs/data-sources/k8s_wg_list.md new file mode 100644 index 00000000..ebe5012f --- /dev/null +++ b/docs/data-sources/k8s_wg_list.md @@ -0,0 +1,76 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8s_wg_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8s_wg_list (Data Source) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `annotations` (List of String) +- `cpu` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--detailed_info)) +- `disk` (Number) +- `guid` (String) +- `labels` (List of String) +- `name` (String) +- `num` (Number) +- `ram` (Number) +- `taints` (List of String) +- `wg_id` (Number) + + +### Nested Schema for `items.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--items--detailed_info--interfaces)) +- `name` (String) +- `natable_vins_ip` (String) +- `natable_vins_network` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `items.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/data-sources/kvmvm.md b/docs/data-sources/kvmvm.md new file mode 100644 index 00000000..9088d505 --- /dev/null +++ b/docs/data-sources/kvmvm.md @@ -0,0 +1,424 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `affinity_label` (String) +- `affinity_rules` (List of Object) (see [below for nested schema](#nestedatt--affinity_rules)) +- `affinity_weight` (Number) +- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedatt--anti_affinity_rules)) +- `arch` (String) +- `auto_start_w_node` (Boolean) +- `boot_image_id` (Number) +- `boot_order` (List of String) +- `boot_type` (String) +- `bootdisk_size` (Number) +- `cd_image_id` (Number) +- `chipset` (String) +- `clone_reference` (Number) +- `clones` (List of Number) +- `computeci_id` (Number) +- `cpu_pin` (Boolean) +- `cpus` (Number) +- `created_by` (String) +- `created_time` (Number) +- `custom_fields` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `devices` (String) +- `disks` (List of Object) (see [below for nested schema](#nestedatt--disks)) +- `driver` (String) +- `gid` (Number) +- `guid` (Number) +- `hot_resize` (Boolean) +- `hp_backed` (Boolean) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedatt--interfaces)) +- `live_migration_job_id` (Number) +- `loader_meta_iso` (List of Object) (see [below for nested schema](#nestedatt--loader_meta_iso)) +- `loader_type` (String) +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `migrationjob` (Number) +- `milestones` (Number) +- `name` (String) +- `natable_vins_id` (Number) +- `natable_vins_ip` (String) +- `natable_vins_name` (String) +- `natable_vins_network` (String) +- `natable_vins_network_name` (String) +- `need_reboot` (Boolean) +- `network_interface_naming` (String) +- `numa_affinity` (String) +- `numa_node_id` (Number) +- `os_users` (List of Object) (see [below for nested schema](#nestedatt--os_users)) +- `os_version` (String) +- `pci_devices` (List of Number) +- `pinned` (Boolean) +- `preferred_cpu` (List of Number) +- `qemu_guest` (List of Object) (see [below for nested schema](#nestedatt--qemu_guest)) +- `ram` (Number) +- `read_only` (Boolean) Shows if compute is in read-only mode. +- `reference_id` (String) +- `registered` (Boolean) +- `res_name` (String) +- `reserved_node_cpus` (List of Number) +- `rg_id` (Number) +- `rg_name` (String) +- `snap_sets` (List of Object) (see [below for nested schema](#nestedatt--snap_sets)) +- `stateless_sep_id` (Number) +- `stateless_sep_type` (String) +- `status` (String) +- `tags` (Map of String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `userdata` (String) +- `vgpus` (List of Object) List of virtual GPUs (see [below for nested schema](#nestedatt--vgpus)) +- `vnc_password` (String) +- `weight` (Number) +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `account_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--account_acl)) +- `compute_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--compute_acl)) +- `rg_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--rg_acl)) + + +### Nested Schema for `acl.account_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.compute_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.rg_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + + +### Nested Schema for `affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `anti_affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `disks` + +Read-Only: + +- `_ckey` (String) +- `account_id` (Number) +- `acl` (String) +- `blk_discard` (Boolean) +- `block_size` (String) +- `boot_partition` (Number) +- `bus_number` (Number) +- `cache` (String) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `description` (String) +- `destruction_time` (Number) +- `devicename` (String) +- `disk_id` (Number) +- `disk_path` (String) +- `gid` (Number) +- `guid` (Number) +- `image_id` (Number) +- `image_name` (String) +- `images` (List of Number) +- `independent` (Boolean) +- `iotune` (List of Object) (see [below for nested schema](#nestedobjatt--disks--iotune)) +- `iqn` (String) +- `login` (String) +- `milestones` (Number) +- `name` (String) +- `params` (String) +- `parent_id` (Number) +- `passwd` (String) +- `pci_slot` (Number) +- `pool` (String) +- `present_to` (Map of Number) +- `provision` (String) +- `purge_time` (Number) +- `reality_device_number` (Number) +- `replication` (List of Object) (see [below for nested schema](#nestedobjatt--disks--replication)) +- `res_id` (String) +- `role` (String) +- `sep_id` (Number) +- `shareable` (Boolean) +- `size_available` (Number) +- `size_max` (Number) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedobjatt--disks--snapshots)) +- `status` (String) +- `storage_policy_id` (Number) +- `tech_status` (String) +- `to_clean` (Boolean) +- `updated_time` (Number) + + +### Nested Schema for `disks.iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `disks.replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `disks.snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `reference_id` (Number) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) + + + + +### Nested Schema for `interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flip_group_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_type` (String) +- `netmask` (Number) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `trunk_tags` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `loader_meta_iso` + +Read-Only: + +- `device_name` (String) +- `path` (String) + + + +### Nested Schema for `os_users` + +Read-Only: + +- `guid` (String) +- `login` (String) +- `password` (String) +- `public_key` (String) + + + +### Nested Schema for `qemu_guest` + +Read-Only: + +- `enabled` (Boolean) +- `enabled_agent_features` (List of String) +- `guid` (String) +- `last_update` (Number) +- `user` (String) + + + +### Nested Schema for `snap_sets` + +Read-Only: + +- `disks` (List of Number) +- `guid` (String) +- `label` (String) +- `timestamp` (Number) + + + +### Nested Schema for `vgpus` + +Read-Only: + +- `account_id` (Number) +- `bus_number` (Number) +- `created_time` (Number) +- `deleted_time` (Number) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `last_claimed_by` (Number) +- `last_update_time` (Number) +- `mode` (String) +- `pci_slot` (Number) +- `pgpuid` (Number) +- `profile_id` (Number) +- `ram` (Number) +- `reference_id` (String) +- `rg_id` (Number) +- `status` (String) +- `type` (String) +- `vmid` (Number) diff --git a/docs/data-sources/kvmvm_audits.md b/docs/data-sources/kvmvm_audits.md new file mode 100644 index 00000000..12f77bf7 --- /dev/null +++ b/docs/data-sources/kvmvm_audits.md @@ -0,0 +1,59 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_audits Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_audits (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `call` (String) +- `max_status_code` (Number) +- `min_status_code` (Number) +- `page` (Number) +- `size` (Number) +- `sort_by` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `timestamp_at` (Number) +- `timestamp_to` (Number) +- `user` (String) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `call` (String) +- `responsetime` (Number) +- `statuscode` (Number) +- `timestamp` (Number) +- `user` (String) diff --git a/docs/data-sources/kvmvm_get_audits.md b/docs/data-sources/kvmvm_get_audits.md new file mode 100644 index 00000000..3957959a --- /dev/null +++ b/docs/data-sources/kvmvm_get_audits.md @@ -0,0 +1,46 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_get_audits Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_get_audits (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `epoch` (Number) +- `message` (String) diff --git a/docs/data-sources/kvmvm_get_console_url.md b/docs/data-sources/kvmvm_get_console_url.md new file mode 100644 index 00000000..696dd7bb --- /dev/null +++ b/docs/data-sources/kvmvm_get_console_url.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_get_console_url Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_get_console_url (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `console_url` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/kvmvm_get_log.md b/docs/data-sources/kvmvm_get_log.md new file mode 100644 index 00000000..0b5f4ff5 --- /dev/null +++ b/docs/data-sources/kvmvm_get_log.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_get_log Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_get_log (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) +- `path` (String) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `log` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/kvmvm_list.md b/docs/data-sources/kvmvm_list.md new file mode 100644 index 00000000..c6c5589d --- /dev/null +++ b/docs/data-sources/kvmvm_list.md @@ -0,0 +1,269 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Find by AccountID +- `by_id` (Number) Find by ID +- `extnet_id` (Number) Find by Extnet ID +- `extnet_name` (String) Find by Extnet name +- `ignore_k8s` (Boolean) If set to true, ignores any VMs associated with any k8s cluster +- `includedeleted` (Boolean) +- `ip_address` (String) Find by IP address +- `name` (String) Find by name +- `page` (Number) +- `rg_id` (Number) Find by RGID +- `rg_name` (String) Find by resgroup name +- `size` (Number) +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `tech_status` (String) Find by tech status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `affinity_label` (String) +- `affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--affinity_rules)) +- `affinity_weight` (Number) +- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--anti_affinity_rules)) +- `arch` (String) +- `auto_start_w_node` (Boolean) +- `boot_image_id` (Number) +- `boot_order` (List of String) +- `boot_type` (String) +- `bootdisk_size` (Number) +- `cd_image_id` (Number) +- `chipset` (String) +- `clone_reference` (Number) +- `clones` (List of Number) +- `compute_id` (Number) +- `computeci_id` (Number) +- `cpu_pin` (Boolean) +- `cpus` (Number) +- `created_by` (String) +- `created_time` (Number) +- `custom_fields` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `devices` (String) +- `disks` (List of Object) (see [below for nested schema](#nestedobjatt--items--disks)) +- `driver` (String) +- `gid` (Number) +- `guid` (Number) +- `hot_resize` (Boolean) +- `hp_backed` (Boolean) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces)) +- `live_migration_job_id` (Number) +- `loader_type` (String) +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `migrationjob` (Number) +- `milestones` (Number) +- `name` (String) +- `need_reboot` (Boolean) +- `network_interface_naming` (String) +- `numa_affinity` (String) +- `numa_node_id` (Number) +- `os_version` (String) +- `pinned` (Boolean) +- `preferred_cpu` (List of Number) +- `qemu_guest` (List of Object) (see [below for nested schema](#nestedobjatt--items--qemu_guest)) +- `ram` (Number) +- `read_only` (Boolean) +- `reference_id` (String) +- `registered` (Boolean) +- `res_name` (String) +- `reserved_node_cpus` (List of Number) +- `rg_id` (Number) +- `rg_name` (String) +- `snap_sets` (List of Object) (see [below for nested schema](#nestedobjatt--items--snap_sets)) +- `stateless_sep_id` (Number) +- `stateless_sep_type` (String) +- `status` (String) +- `tags` (List of Object) (see [below for nested schema](#nestedobjatt--items--tags)) +- `tech_status` (String) +- `total_disk_size` (Number) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vgpus` (List of Number) +- `vins_connected` (Number) +- `weight` (Number) +- `zone_id` (Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `items.anti_affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `items.disks` + +Read-Only: + +- `bus_number` (Number) +- `disk_id` (Number) +- `pci_slot` (Number) +- `sep_id` (Number) + + + +### Nested Schema for `items.interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flip_group_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_type` (String) +- `netmask` (Number) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `trunk_tags` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `items.interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `items.interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `items.qemu_guest` + +Read-Only: + +- `enabled` (Boolean) +- `enabled_agent_features` (List of String) +- `guid` (String) +- `last_update` (Number) +- `user` (String) + + + +### Nested Schema for `items.snap_sets` + +Read-Only: + +- `disks` (List of Number) +- `guid` (String) +- `label` (String) +- `timestamp` (Number) + + + +### Nested Schema for `items.tags` + +Read-Only: + +- `key` (String) +- `val` (String) diff --git a/docs/data-sources/kvmvm_list_deleted.md b/docs/data-sources/kvmvm_list_deleted.md new file mode 100644 index 00000000..dade17cf --- /dev/null +++ b/docs/data-sources/kvmvm_list_deleted.md @@ -0,0 +1,266 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Find by AccountID +- `by_id` (Number) Find by ID +- `extnet_id` (Number) Find by Extnet ID +- `extnet_name` (String) Find by Extnet name +- `ignore_k8s` (Boolean) If set to true, ignores any VMs associated with any k8s cluster +- `ip_address` (String) Find by IP address +- `name` (String) Find by name +- `page` (Number) +- `rg_id` (Number) Find by RGID +- `rg_name` (String) Find by resgroup name +- `size` (Number) +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `tech_status` (String) Find by tech status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `affinity_label` (String) +- `affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--affinity_rules)) +- `affinity_weight` (Number) +- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--anti_affinity_rules)) +- `arch` (String) +- `auto_start_w_node` (Boolean) +- `boot_image_id` (Number) +- `boot_order` (List of String) +- `boot_type` (String) +- `bootdisk_size` (Number) +- `cd_image_id` (Number) +- `chipset` (String) +- `clone_reference` (Number) +- `clones` (List of Number) +- `compute_id` (Number) +- `computeci_id` (Number) +- `cpu_pin` (Boolean) +- `cpus` (Number) +- `created_by` (String) +- `created_time` (Number) +- `custom_fields` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `devices` (String) +- `disks` (List of Object) (see [below for nested schema](#nestedobjatt--items--disks)) +- `driver` (String) +- `gid` (Number) +- `guid` (Number) +- `hot_resize` (Boolean) +- `hp_backed` (Boolean) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces)) +- `live_migration_job_id` (Number) +- `loader_type` (String) +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `migrationjob` (Number) +- `milestones` (Number) +- `name` (String) +- `need_reboot` (Boolean) +- `network_interface_naming` (String) +- `numa_affinity` (String) +- `numa_node_id` (Number) +- `os_version` (String) +- `pinned` (Boolean) +- `preferred_cpu` (List of Number) +- `qemu_guest` (List of Object) (see [below for nested schema](#nestedobjatt--items--qemu_guest)) +- `ram` (Number) +- `read_only` (Boolean) +- `reference_id` (String) +- `registered` (Boolean) +- `res_name` (String) +- `reserved_node_cpus` (List of Number) +- `rg_id` (Number) +- `rg_name` (String) +- `snap_sets` (List of Object) (see [below for nested schema](#nestedobjatt--items--snap_sets)) +- `stateless_sep_id` (Number) +- `stateless_sep_type` (String) +- `status` (String) +- `tags` (List of Object) (see [below for nested schema](#nestedobjatt--items--tags)) +- `tech_status` (String) +- `total_disk_size` (Number) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vgpus` (List of Number) +- `vins_connected` (Number) +- `weight` (Number) +- `zone_id` (Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `items.anti_affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `items.disks` + +Read-Only: + +- `bus_number` (Number) +- `disk_id` (Number) +- `pci_slot` (Number) +- `sep_id` (Number) + + + +### Nested Schema for `items.interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flip_group_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_type` (String) +- `netmask` (Number) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--items--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `trunk_tags` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `items.interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `items.interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `items.qemu_guest` + +Read-Only: + +- `enabled` (Boolean) +- `enabled_agent_features` (List of String) +- `guid` (String) +- `last_update` (Number) +- `user` (String) + + + +### Nested Schema for `items.snap_sets` + +Read-Only: + +- `disks` (List of Number) +- `guid` (String) +- `label` (String) +- `timestamp` (Number) + + + +### Nested Schema for `items.tags` + +Read-Only: + +- `key` (String) +- `val` (String) diff --git a/docs/data-sources/kvmvm_pci_device_list.md b/docs/data-sources/kvmvm_pci_device_list.md new file mode 100644 index 00000000..7e5bd7d4 --- /dev/null +++ b/docs/data-sources/kvmvm_pci_device_list.md @@ -0,0 +1,62 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_pci_device_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_pci_device_list (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `device_id` (Number) Find by device id +- `page` (Number) Page number +- `rg_id` (Number) Find by RG id +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) +- `name` (String) Find by name +- `status` (String) Find by status + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `compute_id` (Number) +- `description` (String) +- `device_id` (Number) +- `guid` (Number) +- `hwpath` (String) +- `name` (String) +- `node_id` (Number) +- `rg_id` (Number) +- `status` (String) +- `system_name` (String) diff --git a/docs/data-sources/kvmvm_pfw_list.md b/docs/data-sources/kvmvm_pfw_list.md new file mode 100644 index 00000000..5bcbd4d7 --- /dev/null +++ b/docs/data-sources/kvmvm_pfw_list.md @@ -0,0 +1,52 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_pfw_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_pfw_list (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `local_ip` (String) +- `local_port` (Number) +- `pfw_id` (Number) +- `protocol` (String) +- `public_port_end` (Number) +- `public_port_start` (Number) +- `vm_id` (Number) diff --git a/docs/data-sources/kvmvm_snapshot_usage.md b/docs/data-sources/kvmvm_snapshot_usage.md new file mode 100644 index 00000000..eb4fc4a5 --- /dev/null +++ b/docs/data-sources/kvmvm_snapshot_usage.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_snapshot_usage Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_snapshot_usage (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `label` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `count` (Number) +- `label` (String) +- `stored` (Number) +- `timestamp` (Number) diff --git a/docs/data-sources/kvmvm_user_list.md b/docs/data-sources/kvmvm_user_list.md new file mode 100644 index 00000000..a1eedb57 --- /dev/null +++ b/docs/data-sources/kvmvm_user_list.md @@ -0,0 +1,78 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_user_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_user_list (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_acl` (List of Object) (see [below for nested schema](#nestedatt--account_acl)) +- `compute_acl` (List of Object) (see [below for nested schema](#nestedatt--compute_acl)) +- `id` (String) The ID of this resource. +- `rg_acl` (List of Object) (see [below for nested schema](#nestedatt--rg_acl)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `account_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `compute_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `rg_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) diff --git a/docs/data-sources/kvmvm_vgpu_list.md b/docs/data-sources/kvmvm_vgpu_list.md new file mode 100644 index 00000000..b74996ca --- /dev/null +++ b/docs/data-sources/kvmvm_vgpu_list.md @@ -0,0 +1,70 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm_vgpu_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm_vgpu_list (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) + +### Optional + +- `gpu_id` (Number) Find by GPU id +- `includedeleted` (Boolean) Include deleted computes. If using field 'status', then includedeleted will be ignored +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) +- `status` (String) Find by status +- `type` (String) Find by type + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `created_time` (Number) +- `deleted_time` (Number) +- `gid` (Number) +- `guid` (Number) +- `last_claimed_by` (Number) +- `last_update_time` (Number) +- `mode` (String) +- `pci_slot` (Number) +- `pgpuid` (Number) +- `profile_id` (Number) +- `ram` (Number) +- `reference_id` (String) +- `rg_id` (Number) +- `status` (String) +- `type` (String) +- `vgpu_id` (Number) +- `vm_id` (Number) diff --git a/docs/data-sources/lb.md b/docs/data-sources/lb.md new file mode 100644 index 00000000..f60c32b6 --- /dev/null +++ b/docs/data-sources/lb.md @@ -0,0 +1,173 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_lb Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_lb (Data Source) + + + + + + +## Schema + +### Required + +- `lb_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) + +### Read-Only + +- `account_id` (Number) +- `backend_haip` (String) +- `backends` (List of Object) (see [below for nested schema](#nestedatt--backends)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dp_api_user` (String) +- `extnet_id` (Number) +- `frontend_haip` (String) +- `frontends` (List of Object) (see [below for nested schema](#nestedatt--frontends)) +- `gid` (Number) +- `guid` (Number) +- `ha_mode` (Boolean) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `manager_id` (Number) +- `manager_type` (String) +- `milestones` (Number) +- `name` (String) +- `part_k8s` (Boolean) +- `primary_node` (List of Object) (see [below for nested schema](#nestedatt--primary_node)) +- `rg_id` (Number) +- `rg_name` (String) +- `secondary_node` (List of Object) (see [below for nested schema](#nestedatt--secondary_node)) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `backends` + +Read-Only: + +- `algorithm` (String) +- `guid` (String) +- `name` (String) +- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--backends--server_default_settings)) +- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--backends--servers)) + + +### Nested Schema for `backends.server_default_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + +### Nested Schema for `backends.servers` + +Read-Only: + +- `address` (String) +- `check` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--backends--servers--server_settings)) + + +### Nested Schema for `backends.servers.server_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + + + +### Nested Schema for `frontends` + +Read-Only: + +- `backend` (String) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--frontends--bindings)) +- `guid` (String) +- `name` (String) + + +### Nested Schema for `frontends.bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) + + + + +### Nested Schema for `primary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) + + + +### Nested Schema for `secondary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) diff --git a/docs/data-sources/lb_list.md b/docs/data-sources/lb_list.md new file mode 100644 index 00000000..8c24a5d7 --- /dev/null +++ b/docs/data-sources/lb_list.md @@ -0,0 +1,192 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_lb_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_lb_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Filter by Account ID +- `back_ip` (String) Filter by BackIP +- `by_id` (Number) Filter by ID +- `front_ip` (String) Filter by FrontIP +- `includedeleted` (Boolean) +- `name` (String) Filter by name +- `page` (Number) +- `rg_id` (Number) Filter by RG ID +- `size` (Number) +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by Status +- `tech_status` (String) Filter by TechStatus +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `backend_haip` (String) +- `backends` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dp_api_password` (String) +- `dp_api_user` (String) +- `extnet_id` (Number) +- `frontend_haip` (String) +- `frontends` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends)) +- `gid` (Number) +- `guid` (Number) +- `ha_mode` (Boolean) +- `image_id` (Number) +- `lb_id` (Number) +- `manager_id` (Number) +- `manager_type` (String) +- `milestones` (Number) +- `name` (String) +- `part_k8s` (Boolean) +- `primary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--primary_node)) +- `rg_id` (Number) +- `rg_name` (String) +- `secondary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--secondary_node)) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_id` (Number) +- `zone_id` (Number) + + +### Nested Schema for `items.backends` + +Read-Only: + +- `algorithm` (String) +- `guid` (String) +- `name` (String) +- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--server_default_settings)) +- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers)) + + +### Nested Schema for `items.backends.server_default_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + +### Nested Schema for `items.backends.servers` + +Read-Only: + +- `address` (String) +- `check` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers--server_settings)) + + +### Nested Schema for `items.backends.servers.server_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + + + +### Nested Schema for `items.frontends` + +Read-Only: + +- `backend` (String) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends--bindings)) +- `guid` (String) +- `name` (String) + + +### Nested Schema for `items.frontends.bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) + + + + +### Nested Schema for `items.primary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) + + + +### Nested Schema for `items.secondary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) diff --git a/docs/data-sources/lb_list_deleted.md b/docs/data-sources/lb_list_deleted.md new file mode 100644 index 00000000..be7badea --- /dev/null +++ b/docs/data-sources/lb_list_deleted.md @@ -0,0 +1,189 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_lb_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_lb_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Filter by Account ID +- `back_ip` (String) Filter by BackIP +- `by_id` (Number) Filter by ID +- `front_ip` (String) Filter by FrontIP +- `name` (String) Filter by name +- `page` (Number) +- `rg_id` (Number) Filter by RG ID +- `size` (Number) +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `tech_status` (String) Filter by TechStatus +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `backend_haip` (String) +- `backends` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dp_api_password` (String) +- `dp_api_user` (String) +- `extnet_id` (Number) +- `frontend_haip` (String) +- `frontends` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends)) +- `gid` (Number) +- `guid` (Number) +- `ha_mode` (Boolean) +- `image_id` (Number) +- `lb_id` (Number) +- `manager_id` (Number) +- `manager_type` (String) +- `milestones` (Number) +- `name` (String) +- `part_k8s` (Boolean) +- `primary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--primary_node)) +- `rg_id` (Number) +- `rg_name` (String) +- `secondary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--secondary_node)) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_id` (Number) +- `zone_id` (Number) + + +### Nested Schema for `items.backends` + +Read-Only: + +- `algorithm` (String) +- `guid` (String) +- `name` (String) +- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--server_default_settings)) +- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers)) + + +### Nested Schema for `items.backends.server_default_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + +### Nested Schema for `items.backends.servers` + +Read-Only: + +- `address` (String) +- `check` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers--server_settings)) + + +### Nested Schema for `items.backends.servers.server_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + + + +### Nested Schema for `items.frontends` + +Read-Only: + +- `backend` (String) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends--bindings)) +- `guid` (String) +- `name` (String) + + +### Nested Schema for `items.frontends.bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) + + + + +### Nested Schema for `items.primary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) + + + +### Nested Schema for `items.secondary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) diff --git a/docs/data-sources/location_url.md b/docs/data-sources/location_url.md new file mode 100644 index 00000000..cb66c393 --- /dev/null +++ b/docs/data-sources/location_url.md @@ -0,0 +1,33 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_location_url Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_location_url (Data Source) + + + + + + +## Schema + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `url` (String) Location url + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/locations_list.md b/docs/data-sources/locations_list.md new file mode 100644 index 00000000..531d26f3 --- /dev/null +++ b/docs/data-sources/locations_list.md @@ -0,0 +1,61 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_locations_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_locations_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) Filter by ID +- `flag` (String) Filter by flag +- `location_code` (String) Filter by location code +- `name` (String) Filter by name +- `page` (Number) page number +- `size` (Number) page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) Locations list (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `auth_broker` (List of String) +- `bro_enabled` (Boolean) +- `ckey` (String) +- `flag` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `location_code` (String) +- `meta` (List of String) +- `name` (String) +- `network_modes` (List of String) +- `sdn_support` (Boolean) +- `zero_access_enabled` (Boolean) diff --git a/docs/data-sources/resgroup.md b/docs/data-sources/resgroup.md new file mode 100644 index 00000000..1380ade5 --- /dev/null +++ b/docs/data-sources/resgroup.md @@ -0,0 +1,102 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_resgroup Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_resgroup (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `compute_features` (List of String) +- `computes` (List of Number) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `def_net_id` (Number) +- `def_net_type` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dirty` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `lock_status` (String) +- `milestones` (Number) +- `name` (String) +- `res_types` (List of String) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedatt--resource_limits)) +- `sdn_access_group_id` (String) +- `secret` (String) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `uniq_pools` (List of String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins` (List of Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `email` (String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (Set of Object) (see [below for nested schema](#nestedobjatt--resource_limits--storage_policy)) + + +### Nested Schema for `resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) diff --git a/docs/data-sources/rg_affinity_group_computes.md b/docs/data-sources/rg_affinity_group_computes.md new file mode 100644 index 00000000..c7bb6fc3 --- /dev/null +++ b/docs/data-sources/rg_affinity_group_computes.md @@ -0,0 +1,52 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_affinity_group_computes Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_affinity_group_computes (Data Source) + + + + + + +## Schema + +### Required + +- `affinity_group` (String) Affinity group label +- `rg_id` (Number) ID of the RG + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `compute_id` (Number) +- `other_node` (List of Number) +- `other_node_indirect` (List of Number) +- `other_node_indirect_soft` (List of Number) +- `other_node_soft` (List of Number) +- `same_node` (List of Number) +- `same_node_soft` (List of Number) diff --git a/docs/data-sources/rg_affinity_groups_get.md b/docs/data-sources/rg_affinity_groups_get.md new file mode 100644 index 00000000..bef8ad57 --- /dev/null +++ b/docs/data-sources/rg_affinity_groups_get.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_affinity_groups_get Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_affinity_groups_get (Data Source) + + + + + + +## Schema + +### Required + +- `affinity_group` (String) Affinity group label +- `rg_id` (Number) ID of the RG + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `ids` (List of Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/rg_affinity_groups_list.md b/docs/data-sources/rg_affinity_groups_list.md new file mode 100644 index 00000000..e5d64e2a --- /dev/null +++ b/docs/data-sources/rg_affinity_groups_list.md @@ -0,0 +1,57 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_affinity_groups_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_affinity_groups_list (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the RG + +### Optional + +- `page` (Number) Page number +- `size` (Number) Page size +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `affinity_groups` (List of Object) (see [below for nested schema](#nestedatt--affinity_groups)) +- `entry_count` (Number) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `affinity_groups` + +Read-Only: + +- `ids` (List of Object) (see [below for nested schema](#nestedobjatt--affinity_groups--ids)) +- `label` (String) + + +### Nested Schema for `affinity_groups.ids` + +Read-Only: + +- `id` (Number) +- `node_id` (Number) diff --git a/docs/data-sources/rg_audits.md b/docs/data-sources/rg_audits.md new file mode 100644 index 00000000..c2513630 --- /dev/null +++ b/docs/data-sources/rg_audits.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_audits Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_audits (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `call` (String) +- `responsetime` (Number) +- `statuscode` (Number) +- `timestamp` (Number) +- `user` (String) diff --git a/docs/data-sources/rg_list.md b/docs/data-sources/rg_list.md new file mode 100644 index 00000000..d99f2e00 --- /dev/null +++ b/docs/data-sources/rg_list.md @@ -0,0 +1,119 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Find by account ID +- `account_name` (String) Find by account name +- `by_id` (Number) Find by ID +- `created_after` (Number) Find RGs created after specific time (unix timestamp) +- `created_before` (Number) Find RGs created before specific time (unix timestamp) +- `includedeleted` (Boolean) included deleted resource groups +- `lock_status` (String) Find by lock status +- `name` (String) Find by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--account_acl)) +- `account_id` (Number) +- `account_name` (String) +- `compute_features` (List of String) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `def_net_id` (Number) +- `def_net_type` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dirty` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `name` (String) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits)) +- `resource_types` (List of String) +- `rg_id` (Number) +- `sdn_access_group_id` (String) +- `secret` (String) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `uniq_pools` (List of String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins` (List of Number) +- `vms` (List of Number) + + +### Nested Schema for `items.account_acl` + +Read-Only: + +- `email` (String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (Set of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits--storage_policy)) + + +### Nested Schema for `items.resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) diff --git a/docs/data-sources/rg_list_computes.md b/docs/data-sources/rg_list_computes.md new file mode 100644 index 00000000..84360f36 --- /dev/null +++ b/docs/data-sources/rg_list_computes.md @@ -0,0 +1,104 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_list_computes Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_list_computes (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the RG + +### Optional + +- `account_id` (Number) Filter by account ID +- `compute_id` (Number) Filter by compute ID +- `extnet_id` (Number) Filter by extnet ID +- `extnet_name` (String) Filter by extnet name +- `ip_address` (String) FIlter by IP address +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `tech_status` (String) Filter by tech. status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `affinity_label` (String) +- `affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--affinity_rules)) +- `affinity_weight` (Number) +- `antiaffinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--antiaffinity_rules)) +- `cpus` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `id` (Number) +- `name` (String) +- `ram` (Number) +- `registered` (Boolean) +- `rg_name` (String) +- `status` (String) +- `tech_status` (String) +- `total_disks_size` (Number) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_connected` (Number) + + +### Nested Schema for `items.affinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) + + + +### Nested Schema for `items.antiaffinity_rules` + +Read-Only: + +- `guid` (String) +- `key` (String) +- `mode` (String) +- `policy` (String) +- `topology` (String) +- `value` (String) diff --git a/docs/data-sources/rg_list_deleted.md b/docs/data-sources/rg_list_deleted.md new file mode 100644 index 00000000..1e95e851 --- /dev/null +++ b/docs/data-sources/rg_list_deleted.md @@ -0,0 +1,117 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Filter by account ID +- `account_name` (String) Filter by account name +- `by_id` (Number) Filter by ID +- `created_after` (Number) Filter RGs created after certain point in time (unix timestamp) +- `created_before` (Number) Filter RGs created before certain point in time (unix timestamp) +- `lock_status` (String) Filter by lock status +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--account_acl)) +- `account_id` (Number) +- `account_name` (String) +- `compute_features` (List of String) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `def_net_id` (Number) +- `def_net_type` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dirty` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `name` (String) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits)) +- `resource_types` (List of String) +- `rg_id` (Number) +- `sdn_access_group_id` (String) +- `secret` (String) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `uniq_pools` (List of String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins` (List of Number) +- `vms` (List of Number) + + +### Nested Schema for `items.account_acl` + +Read-Only: + +- `email` (String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (Set of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits--storage_policy)) + + +### Nested Schema for `items.resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) diff --git a/docs/data-sources/rg_list_lb.md b/docs/data-sources/rg_list_lb.md new file mode 100644 index 00000000..3083c698 --- /dev/null +++ b/docs/data-sources/rg_list_lb.md @@ -0,0 +1,199 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_list_lb Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_list_lb (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the RG + +### Optional + +- `back_ip` (String) Filter by backend IP +- `by_id` (Number) Filter by ID +- `front_ip` (String) Filter by frontend IP +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Filter by status +- `tech_status` (String) Filter by tech. status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl)) +- `backend_haip` (String) +- `backends` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `dp_api_user` (String) +- `extnet_id` (Number) +- `frontend_haip` (String) +- `frontends` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends)) +- `gid` (Number) +- `guid` (Number) +- `ha_mode` (Boolean) +- `id` (Number) +- `image_id` (Number) +- `milestones` (Number) +- `name` (String) +- `primary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--primary_node)) +- `rg_name` (String) +- `secondary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--secondary_node)) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins_id` (Number) + + +### Nested Schema for `items.acl` + +Read-Only: + +- `email` (String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `items.backends` + +Read-Only: + +- `algorithm` (String) +- `guid` (String) +- `name` (String) +- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--server_default_settings)) +- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers)) + + +### Nested Schema for `items.backends.server_default_settings` + +Read-Only: + +- `down_inter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `max_conn` (Number) +- `max_queue` (Number) +- `rise` (Number) +- `slow_start` (Number) +- `weight` (Number) + + + +### Nested Schema for `items.backends.servers` + +Read-Only: + +- `address` (String) +- `check` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers--server_settings)) + + +### Nested Schema for `items.backends.servers.server_settings` + +Read-Only: + +- `down_inter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `max_conn` (Number) +- `max_queue` (Number) +- `rise` (Number) +- `slow_start` (Number) +- `weight` (Number) + + + + + +### Nested Schema for `items.frontends` + +Read-Only: + +- `backend` (String) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends--bindings)) +- `guid` (String) +- `name` (String) + + +### Nested Schema for `items.frontends.bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) + + + + +### Nested Schema for `items.primary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) + + + +### Nested Schema for `items.secondary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) diff --git a/docs/data-sources/rg_list_pfw.md b/docs/data-sources/rg_list_pfw.md new file mode 100644 index 00000000..0917fab1 --- /dev/null +++ b/docs/data-sources/rg_list_pfw.md @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_list_pfw Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_list_pfw (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the RG + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `public_port_end` (Number) +- `public_port_start` (Number) +- `vins_id` (Number) +- `vins_name` (String) +- `vm_id` (Number) +- `vm_ip` (String) +- `vm_name` (String) +- `vm_port` (Number) diff --git a/docs/data-sources/rg_list_vins.md b/docs/data-sources/rg_list_vins.md new file mode 100644 index 00000000..51b808a0 --- /dev/null +++ b/docs/data-sources/rg_list_vins.md @@ -0,0 +1,70 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_list_vins Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_list_vins (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the RG + +### Optional + +- `account_id` (Number) Filter by account ID +- `ext_ip` (String) Filter by external IP +- `name` (String) Filter by name +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) Filter by ViNS ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `computes` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `external_ip` (String) +- `extnet_id` (Number) +- `free_ips` (Number) +- `id` (Number) +- `name` (String) +- `network` (String) +- `pri_vnf_dev_id` (Number) +- `rg_name` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) diff --git a/docs/data-sources/rg_resource_consumption_get.md b/docs/data-sources/rg_resource_consumption_get.md new file mode 100644 index 00000000..c6abdc79 --- /dev/null +++ b/docs/data-sources/rg_resource_consumption_get.md @@ -0,0 +1,102 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_resource_consumption_get Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_resource_consumption_get (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `consumed` (List of Object) (see [below for nested schema](#nestedatt--consumed)) +- `id` (String) The ID of this resource. +- `reserved` (List of Object) (see [below for nested schema](#nestedatt--reserved)) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedatt--resource_limits)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `consumed` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--consumed--seps)) + + +### Nested Schema for `consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `reserved` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--reserved--seps)) + + +### Nested Schema for `reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) diff --git a/docs/data-sources/rg_resource_consumption_list.md b/docs/data-sources/rg_resource_consumption_list.md new file mode 100644 index 00000000..02c645c3 --- /dev/null +++ b/docs/data-sources/rg_resource_consumption_list.md @@ -0,0 +1,107 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_resource_consumption_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_resource_consumption_list (Data Source) + + + + + + +## Schema + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `consumed` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed)) +- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved)) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits)) +- `rg_id` (Number) + + +### Nested Schema for `items.consumed` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--consumed--seps)) + + +### Nested Schema for `items.consumed.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.reserved` + +Read-Only: + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `extips` (Number) +- `gpu` (Number) +- `ram` (Number) +- `seps` (List of Object) (see [below for nested schema](#nestedobjatt--items--reserved--seps)) + + +### Nested Schema for `items.reserved.seps` + +Read-Only: + +- `data_name` (String) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `sep_id` (String) + + + + +### Nested Schema for `items.resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) diff --git a/docs/data-sources/rg_usage.md b/docs/data-sources/rg_usage.md new file mode 100644 index 00000000..c321a8f7 --- /dev/null +++ b/docs/data-sources/rg_usage.md @@ -0,0 +1,52 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_rg_usage Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_rg_usage (Data Source) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `cpu` (Number) +- `disk_size` (Number) +- `disk_size_max` (Number) +- `extips` (Number) +- `gpu` (Number) +- `id` (String) The ID of this resource. +- `ram` (Number) +- `seps` (Set of Object) (see [below for nested schema](#nestedatt--seps)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `seps` + +Read-Only: + +- `map` (Map of String) +- `sep_id` (String) diff --git a/docs/data-sources/sdn_access_group.md b/docs/data-sources/sdn_access_group.md new file mode 100644 index 00000000..56398685 --- /dev/null +++ b/docs/data-sources/sdn_access_group.md @@ -0,0 +1,50 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_access_group Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_access_group (Data Source) + + + + + + +## Schema + +### Required + +- `access_group_id` (String) The unique access group ID + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `comment` (String) Comment description +- `created_at` (String) Creation timestamp +- `display_name` (String) Display name +- `id` (String) The ID of this resource. +- `net_object_access_group` (List of Object) Net object access group configuration (see [below for nested schema](#nestedatt--net_object_access_group)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `net_object_access_group` + +Read-Only: + +- `access_group_id` (String) +- `id` (String) +- `version_id` (Number) diff --git a/docs/data-sources/sdn_access_group_list.md b/docs/data-sources/sdn_access_group_list.md new file mode 100644 index 00000000..55ca1171 --- /dev/null +++ b/docs/data-sources/sdn_access_group_list.md @@ -0,0 +1,79 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_access_group_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_access_group_list (Data Source) + + + + + + +## Schema + +### Optional + +- `created_from` (String) filter by the lower limit of the creation date +- `created_to` (String) filter by the upper limit of the creation date +- `deleted` (Boolean) filter by deleted/not deleted group +- `display_name` (String) filter by display name +- `enabled` (Boolean) filter by enabled/disabled group +- `owner_display_name` (String) +- `page` (Number) Page number +- `per_page` (Number) Items per page +- `sort_by` (String) sort by one of supported fields +- `sort_order` (String) sort order +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) List of access groups (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `comment` (String) +- `created_at` (String) +- `default_security_policy` (List of Object) (see [below for nested schema](#nestedobjatt--items--default_security_policy)) +- `display_name` (String) +- `id` (String) +- `net_object_access_group` (List of Object) (see [below for nested schema](#nestedobjatt--items--net_object_access_group)) + + +### Nested Schema for `items.default_security_policy` + +Read-Only: + +- `access_group_id` (String) +- `default_acl_drop` (String) +- `default_open_session_drop` (Boolean) +- `description` (String) +- `display_name` (String) +- `id` (String) +- `version_id` (Number) + + + +### Nested Schema for `items.net_object_access_group` + +Read-Only: + +- `access_group_id` (String) +- `id` (String) +- `version_id` (Number) diff --git a/docs/data-sources/sdn_access_group_user_list.md b/docs/data-sources/sdn_access_group_user_list.md new file mode 100644 index 00000000..3381f5ad --- /dev/null +++ b/docs/data-sources/sdn_access_group_user_list.md @@ -0,0 +1,63 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_access_group_user_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_access_group_user_list (Data Source) + + + + + + +## Schema + +### Required + +- `access_group_id` (String) filter by access group id + +### Optional + +- `access_group_role` (String) filter by access group role +- `created_by` (String) who created the user +- `created_from` (String) filter by the lower limit of the creation date +- `created_to` (String) filter by the upper limit of the creation date +- `deleted` (Boolean) delete filter +- `deleted_by` (String) who deleted the user +- `disabled_by` (String) who disabled the user +- `display_name` (String) filter by display name +- `enabled` (Boolean) filter by inclusion +- `global_role` (String) filter by global role +- `login` (String) filter by user login +- `page` (Number) result page number +- `per_page` (Number) number of results per page +- `sort_by` (String) sort by one of supported fields +- `sort_order` (String) sorting order +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) List of users (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `display_name` (String) +- `id` (String) +- `login` (String) +- `role_id` (String) diff --git a/docs/data-sources/sdn_default_security_policy_list.md b/docs/data-sources/sdn_default_security_policy_list.md new file mode 100644 index 00000000..35addcc1 --- /dev/null +++ b/docs/data-sources/sdn_default_security_policy_list.md @@ -0,0 +1,149 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_default_security_policy_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_default_security_policy_list (Data Source) + + + + + + +## Schema + +### Optional + +- `access_group_id` (String) id of the access group +- `page` (Number) result page number +- `per_page` (Number) number of results per page +- `sort_by` (String) sort by one of the supported fields +- `sort_order` (String) sorting order +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) List of default security policies (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `access_group_id` (String) +- `created_at` (String) +- `default_acl_drop` (String) +- `default_open_session_drop` (Boolean) +- `description` (String) +- `display_name` (String) +- `id` (String) +- `locked_at` (String) +- `security_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_rules)) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--items--status)) +- `version_id` (Number) + + +### Nested Schema for `items.security_rules` + +Read-Only: + +- `access_group_id` (String) +- `action` (String) +- `description` (String) +- `destination_net_object` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_rules--destination_net_object)) +- `direction` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `filter` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_rules--filter)) +- `id` (String) +- `log_enabled` (Boolean) +- `log_name` (String) +- `log_severity` (String) +- `priority` (Number) +- `security_policy_id` (String) +- `source_net_object` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_rules--source_net_object)) +- `statistics_enabled` (Boolean) +- `version_id` (Number) + + +### Nested Schema for `items.security_rules.destination_net_object` + +Read-Only: + +- `display_name` (String) +- `net_address_pool_id` (String) +- `net_object_group_id` (String) + + + +### Nested Schema for `items.security_rules.filter` + +Read-Only: + +- `filters` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_rules--filter--filters)) +- `name` (String) + + +### Nested Schema for `items.security_rules.filter.filters` + +Read-Only: + +- `all` (Boolean) +- `arp` (Boolean) +- `dhcp` (Boolean) +- `expression` (String) +- `icmp` (Boolean) +- `ip` (Boolean) +- `ip_v4` (Boolean) +- `ip_v6` (Boolean) +- `keep_opened_sessions` (Boolean) +- `nd` (Boolean) +- `tcp` (Boolean) +- `tcp_dst_ports` (List of String) +- `udp` (Boolean) +- `udp_dst_ports` (List of String) + + + + +### Nested Schema for `items.security_rules.source_net_object` + +Read-Only: + +- `display_name` (String) +- `net_address_pool_id` (String) +- `net_object_group_id` (String) + + + + +### Nested Schema for `items.status` + +Read-Only: + +- `common` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--items--status--hypervisors)) + + +### Nested Schema for `items.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `status` (String) +- `synced_at` (String) diff --git a/docs/data-sources/sdn_hypervisor.md b/docs/data-sources/sdn_hypervisor.md new file mode 100644 index 00000000..d139e2b8 --- /dev/null +++ b/docs/data-sources/sdn_hypervisor.md @@ -0,0 +1,72 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_hypervisor Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_hypervisor (Data Source) + + + + + + +## Schema + +### Required + +- `name` (String) + +### Optional + +- `port_info` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `created_at` (String) +- `display_name` (String) +- `hostname` (String) +- `id` (String) The ID of this resource. +- `ip` (String) +- `ports` (List of Object) (see [below for nested schema](#nestedatt--ports)) +- `status` (String) +- `synced_at` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `ports` + +Read-Only: + +- `data` (List of Object) (see [below for nested schema](#nestedobjatt--ports--data)) +- `info` (List of Object) (see [below for nested schema](#nestedobjatt--ports--info)) + + +### Nested Schema for `ports.data` + +Read-Only: + +- `display_name` (String) +- `id` (String) +- `unique_identifier` (String) +- `up` (Boolean) + + + +### Nested Schema for `ports.info` + +Read-Only: + +- `active_ports` (Number) +- `total_ports` (Number) diff --git a/docs/data-sources/sdn_hypervisor_list.md b/docs/data-sources/sdn_hypervisor_list.md new file mode 100644 index 00000000..a40e0b43 --- /dev/null +++ b/docs/data-sources/sdn_hypervisor_list.md @@ -0,0 +1,87 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_hypervisor_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_hypervisor_list (Data Source) + + + + + + +## Schema + +### Optional + +- `created_from` (String) +- `created_to` (String) +- `display_name` (String) +- `hostname` (String) +- `ip` (String) +- `page` (Number) +- `per_page` (Number) +- `port_info` (String) +- `sort_by` (String) +- `sort_order` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `updated_from` (String) +- `updated_to` (String) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) List of hypervisors (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `created_at` (String) +- `display_name` (String) +- `hostname` (String) +- `ip` (String) +- `name` (String) +- `ports` (List of Object) (see [below for nested schema](#nestedobjatt--items--ports)) +- `status` (String) +- `synced_at` (String) + + +### Nested Schema for `items.ports` + +Read-Only: + +- `data` (List of Object) (see [below for nested schema](#nestedobjatt--items--ports--data)) +- `info` (List of Object) (see [below for nested schema](#nestedobjatt--items--ports--info)) + + +### Nested Schema for `items.ports.data` + +Read-Only: + +- `display_name` (String) +- `id` (String) +- `unique_identifier` (String) +- `up` (Boolean) + + + +### Nested Schema for `items.ports.info` + +Read-Only: + +- `active_ports` (Number) +- `total_ports` (Number) diff --git a/docs/data-sources/sdn_logical_port.md b/docs/data-sources/sdn_logical_port.md new file mode 100644 index 00000000..137e5434 --- /dev/null +++ b/docs/data-sources/sdn_logical_port.md @@ -0,0 +1,115 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_logical_port Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_logical_port (Data Source) + + + + + + +## Schema + +### Required + +- `logical_port_id` (String) ID of the logical port to use + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `access_group_id` (String) ID of the access group +- `access_group_name` (String) Name of the access group +- `adapter_mac` (String) MAC address of the adapter +- `address_detection` (Boolean) If the adapter address detection is enabled +- `bindings` (List of Object) (see [below for nested schema](#nestedatt--bindings)) +- `created_at` (String) Creation time of the logical port +- `description` (String) Description of the logical port +- `display_name` (String) Display name of the logical port +- `enabled` (Boolean) If the logical port is enabled +- `external_network_id` (String) +- `hypervisor` (String) ID of the hypervisor +- `hypervisor_display_name` (String) Display name of the hypervisor +- `id` (String) The ID of this resource. +- `labels` (List of Object) Labels (see [below for nested schema](#nestedatt--labels)) +- `live_migration_target_hv` (String) +- `status` (List of Object) (see [below for nested schema](#nestedatt--status)) +- `unique_identifier` (String) Unique identifier of the logical port +- `updated_at` (String) Update time the logical port +- `version_id` (Number) Version ID of the logical port + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `bindings` + +Read-Only: + +- `address_detection` (Boolean) +- `created_at` (String) +- `id` (String) +- `logical_port_addresses` (List of Object) (see [below for nested schema](#nestedobjatt--bindings--logical_port_addresses)) +- `port_security` (Boolean) +- `segment_display_name` (String) +- `segment_id` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `bindings.logical_port_addresses` + +Read-Only: + +- `assigned_at` (String) +- `id` (String) +- `ip` (String) +- `ip_type` (String) +- `is_discovered` (Boolean) +- `is_primary` (Boolean) +- `logical_port_id` (String) +- `mac` (String) + + + + +### Nested Schema for `labels` + +Read-Only: + +- `vm_id` (String) +- `vm_name` (String) + + + +### Nested Schema for `status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) diff --git a/docs/data-sources/sdn_logical_port_get_by_unique_identifier.md b/docs/data-sources/sdn_logical_port_get_by_unique_identifier.md new file mode 100644 index 00000000..9911ecb8 --- /dev/null +++ b/docs/data-sources/sdn_logical_port_get_by_unique_identifier.md @@ -0,0 +1,114 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_logical_port_get_by_unique_identifier Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_logical_port_get_by_unique_identifier (Data Source) + + + + + + +## Schema + +### Required + +- `unique_identifier` (String) Unique ID of the logical port to use + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `access_group_id` (String) ID of the access group +- `access_group_name` (String) Name of the access group +- `adapter_mac` (String) MAC address of the adapter +- `address_detection` (Boolean) If the adapter address detection is enabled +- `bindings` (List of Object) (see [below for nested schema](#nestedatt--bindings)) +- `created_at` (String) Creation time of the logical port +- `description` (String) Description of the logical port +- `display_name` (String) Display name of the logical port +- `enabled` (Boolean) If the logical port is enabled +- `external_network_id` (String) +- `hypervisor` (String) ID of the hypervisor +- `hypervisor_display_name` (String) Display name of the hypervisor +- `id` (String) The ID of this resource. +- `labels` (List of Object) Labels (see [below for nested schema](#nestedatt--labels)) +- `live_migration_target_hv` (String) +- `status` (List of Object) (see [below for nested schema](#nestedatt--status)) +- `updated_at` (String) Update time the logical port +- `version_id` (Number) Version ID of the logical port + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `bindings` + +Read-Only: + +- `address_detection` (Boolean) +- `created_at` (String) +- `id` (String) +- `logical_port_addresses` (List of Object) (see [below for nested schema](#nestedobjatt--bindings--logical_port_addresses)) +- `port_security` (Boolean) +- `segment_display_name` (String) +- `segment_id` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `bindings.logical_port_addresses` + +Read-Only: + +- `assigned_at` (String) +- `id` (String) +- `ip` (String) +- `ip_type` (String) +- `is_discovered` (Boolean) +- `is_primary` (Boolean) +- `logical_port_id` (String) +- `mac` (String) + + + + +### Nested Schema for `labels` + +Read-Only: + +- `vm_id` (String) +- `vm_name` (String) + + + +### Nested Schema for `status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) diff --git a/docs/data-sources/sdn_logical_port_list.md b/docs/data-sources/sdn_logical_port_list.md new file mode 100644 index 00000000..948a9d0a --- /dev/null +++ b/docs/data-sources/sdn_logical_port_list.md @@ -0,0 +1,140 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_logical_port_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_logical_port_list (Data Source) + + + + + + +## Schema + +### Optional + +- `access_group_id` (String) Access Group ID +- `adapter_mac` (String) Adapter mac +- `address_detection` (Boolean) +- `created_from` (String) +- `created_to` (String) +- `display_name` (String) Display name +- `enabled` (Boolean) +- `external_network_id` (String) External Network ID +- `hypervisor` (String) Hypervisor +- `hypervisor_display_name` (String) Hypervisor display name +- `hypervisor_status` (String) Filter by hypervisor status +- `live_migration_target_hv` (String) Live migration target HV +- `operation_status` (String) Filter by operation status +- `page` (Number) +- `per_page` (Number) +- `port_security` (Boolean) +- `segment_display_name` (String) Segment display name +- `segment_id` (String) Segment ID +- `sort_by` (String) +- `sort_order` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `unique_identifier` (String) Unique identifier + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `adapter_mac` (String) +- `address_detection` (Boolean) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--bindings)) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `external_network_id` (String) +- `hypervisor` (String) +- `hypervisor_display_name` (String) +- `id` (String) +- `labels` (List of Object) (see [below for nested schema](#nestedobjatt--items--labels)) +- `live_migration_target_hv` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--items--status)) +- `unique_identifier` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.bindings` + +Read-Only: + +- `address_detection` (Boolean) +- `created_at` (String) +- `id` (String) +- `logical_port_addresses` (List of Object) (see [below for nested schema](#nestedobjatt--items--bindings--logical_port_addresses)) +- `port_security` (Boolean) +- `segment_display_name` (String) +- `segment_id` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.bindings.logical_port_addresses` + +Read-Only: + +- `assigned_at` (String) +- `id` (String) +- `ip` (String) +- `ip_type` (String) +- `is_discovered` (Boolean) +- `is_primary` (Boolean) +- `logical_port_id` (String) +- `mac` (String) + + + + +### Nested Schema for `items.labels` + +Read-Only: + +- `vm_id` (String) +- `vm_name` (String) + + + +### Nested Schema for `items.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--items--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `items.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) diff --git a/docs/data-sources/sdn_network_object_group.md b/docs/data-sources/sdn_network_object_group.md new file mode 100644 index 00000000..6bb5a7b4 --- /dev/null +++ b/docs/data-sources/sdn_network_object_group.md @@ -0,0 +1,705 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_network_object_group Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_network_object_group (Data Source) + + + + + + +## Schema + +### Required + +- `net_object_group_id` (String) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `access_group_id` (String) +- `access_group_name` (String) +- `addresses` (List of Object) (see [below for nested schema](#nestedatt--addresses)) +- `counters` (List of Object) (see [below for nested schema](#nestedatt--counters)) +- `created_at` (String) +- `description` (String) +- `external_network_ports` (List of Object) (see [below for nested schema](#nestedatt--external_network_ports)) +- `id` (String) The ID of this resource. +- `l2_connection_ports` (List of Object) (see [below for nested schema](#nestedatt--l2_connection_ports)) +- `logical_ports` (List of Object) (see [below for nested schema](#nestedatt--logical_ports)) +- `name` (String) +- `purpose` (String) +- `security_policies` (List of Object) (see [below for nested schema](#nestedatt--security_policies)) +- `type` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `addresses` + +Read-Only: + +- `id` (String) +- `ip_addr` (String) +- `ip_addr_range_end` (String) +- `ip_prefix` (String) +- `mac_addr` (String) +- `net_address_type` (String) + + + +### Nested Schema for `counters` + +Read-Only: + +- `addresses_count` (Number) +- `l2_connection_ports_count` (Number) +- `logical_ports_count` (Number) +- `security_policies_count` (Number) +- `security_rules_count` (Number) + + + +### Nested Schema for `external_network_ports` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `bridge_network_name` (String) +- `comment` (String) +- `created_at` (String) +- `default_gateway_ipv4` (String) +- `default_gateway_ipv6` (String) +- `description` (String) +- `enabled` (Boolean) +- `external_network_ports` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports)) +- `hypervisors` (List of String) +- `id` (String) +- `ipv4` (String) +- `mac` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--status)) +- `subnet_v4` (String) +- `subnet_v6` (String) +- `updated_at` (String) +- `version_id` (Number) +- `vlan_tag` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `comment` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `floating_ip` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip)) +- `ipv4` (String) +- `ipv6` (String) +- `ipv6_config` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--ipv6_config)) +- `mac` (String) +- `router_gateaway_port` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--router_gateaway_port)) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `created_at` (String) +- `logical_port` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port)) +- `router` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `adapter_mac` (String) +- `address_detection` (Boolean) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--bindings)) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `exclude_firewall` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--exclude_firewall)) +- `external_network_id` (String) +- `hypervisor` (String) +- `hypervisor_display_name` (String) +- `id` (String) +- `labels` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--labels)) +- `live_migration_target_hv` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--status)) +- `unique_identifier` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.bindings` + +Read-Only: + +- `address_detection` (Boolean) +- `created_at` (String) +- `id` (String) +- `logical_port_addresses` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--bindings--logical_port_addresses)) +- `port_security` (Boolean) +- `segment_display_name` (String) +- `segment_id` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.bindings.logical_port_addresses` + +Read-Only: + +- `assigned_at` (String) +- `id` (String) +- `ip` (String) +- `ip_type` (String) +- `is_discovered` (Boolean) +- `is_primary` (Boolean) +- `logical_port_id` (String) +- `mac` (String) + + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.exclude_firewall` + +Read-Only: + +- `exclusion_reason` (String) +- `logical_port_addresses_excluded` (Boolean) +- `logical_port_excluded` (Boolean) + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.labels` + +Read-Only: + +- `vm_id` (String) +- `vm_name` (String) + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `gateaway_ports` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--gateaway_ports)) +- `id` (String) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--policies)) +- `ports` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--ports)) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--status)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.gateaway_ports` + +Read-Only: + +- `created_at` (String) +- `description` (String) +- `external_l4_port_max` (Number) +- `external_l4_port_min` (Number) +- `id` (String) +- `snat_enabled` (Boolean) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--gateaway_ports--status)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.gateaway_ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--gateaway_ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.gateaway_ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.policies` + +Read-Only: + +- `action` (String) +- `created_at` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `id` (String) +- `match` (String) +- `next_ipv4_address` (List of String) +- `next_ipv6_address` (List of String) +- `priority` (Number) +- `updated_at` (String) +- `version_id` (Number) + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.ports` + +Read-Only: + +- `created_at` (String) +- `description` (String) +- `enabled` (Boolean) +- `id` (String) +- `ipv4_address` (String) +- `ipv6_address` (String) +- `ipv6_config` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--ports--ipv6_config)) +- `mac` (String) +- `segment` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--ports--segment)) +- `segment_id` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--ports--status)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.ports.ipv6_config` + +Read-Only: + +- `address_mode` (String) +- `enable_periodic_ra` (Boolean) +- `interval_ra` (Number) +- `router_preference` (String) + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.ports.segment` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `id` (String) +- `subnet_v4` (String) +- `subnet_v6` (String) +- `updated_at` (String) +- `version_id` (Number) + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + + +### Nested Schema for `external_network_ports.external_network_ports.ipv6_config` + +Read-Only: + +- `address_mode` (String) +- `enable_periodic_ra` (Boolean) +- `interval_ra` (Number) +- `router_preference` (String) + + + +### Nested Schema for `external_network_ports.external_network_ports.router_gateaway_port` + +Read-Only: + +- `created_at` (String) +- `description` (String) +- `id` (String) +- `router_display_name` (String) +- `router_id` (String) +- `snat_enabled` (Boolean) +- `updated_at` (String) + + + + +### Nested Schema for `external_network_ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `external_network_ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `l2_connection_ports` + +Read-Only: + +- `access_group_id` (String) +- `created_at` (String) +- `id` (String) +- `l2_external_network` (List of Object) (see [below for nested schema](#nestedobjatt--l2_connection_ports--l2_external_network)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `l2_connection_ports.l2_external_network` + +Read-Only: + +- `bridge_network_name` (String) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `hypervisors` (List of String) +- `id` (String) +- `updated_at` (String) +- `version_id` (Number) +- `vlan_tag` (Number) + + + + +### Nested Schema for `logical_ports` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `adapter_mac` (String) +- `address_detection` (Boolean) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--bindings)) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `exclude_firewall` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--exclude_firewall)) +- `external_network_id` (String) +- `hypervisor` (String) +- `hypervisor_display_name` (String) +- `id` (String) +- `labels` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--labels)) +- `live_migration_target_hv` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--status)) +- `unique_identifier` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `logical_ports.bindings` + +Read-Only: + +- `address_detection` (Boolean) +- `created_at` (String) +- `id` (String) +- `logical_port_addresses` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--bindings--logical_port_addresses)) +- `port_security` (Boolean) +- `segment_display_name` (String) +- `segment_id` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `logical_ports.bindings.logical_port_addresses` + +Read-Only: + +- `assigned_at` (String) +- `id` (String) +- `ip` (String) +- `ip_type` (String) +- `is_discovered` (Boolean) +- `is_primary` (Boolean) +- `logical_port_id` (String) +- `mac` (String) + + + + +### Nested Schema for `logical_ports.exclude_firewall` + +Read-Only: + +- `exclusion_reason` (String) +- `logical_port_addresses_excluded` (Boolean) +- `logical_port_excluded` (Boolean) + + + +### Nested Schema for `logical_ports.labels` + +Read-Only: + +- `vm_id` (String) +- `vm_name` (String) + + + +### Nested Schema for `logical_ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `logical_ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `security_policies` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `applied_net_object_groups` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--applied_net_object_groups)) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `end_priority` (Number) +- `id` (String) +- `security_rules` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--security_rules)) +- `start_priority` (Number) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--status)) +- `type` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `security_policies.applied_net_object_groups` + +Read-Only: + +- `id` (String) +- `name` (String) +- `version_id` (Number) + + + +### Nested Schema for `security_policies.security_rules` + +Read-Only: + +- `access_group_id` (String) +- `action` (String) +- `description` (String) +- `destination_net_object` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--security_rules--destination_net_object)) +- `direction` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `filter` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--security_rules--filter)) +- `id` (String) +- `log_enabled` (Boolean) +- `log_name` (String) +- `log_severity` (String) +- `priority` (Number) +- `security_policy_id` (String) +- `source_net_object` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--security_rules--source_net_object)) +- `statistics_enabled` (Boolean) +- `type` (String) +- `version_id` (Number) + + +### Nested Schema for `security_policies.security_rules.destination_net_object` + +Read-Only: + +- `display_name` (String) +- `net_address_pool_id` (String) +- `net_object_group_id` (String) + + + +### Nested Schema for `security_policies.security_rules.filter` + +Read-Only: + +- `filters` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--security_rules--filter--filters)) +- `name` (String) + + +### Nested Schema for `security_policies.security_rules.filter.filters` + +Read-Only: + +- `all` (Boolean) +- `arp` (Boolean) +- `dhcp` (Boolean) +- `expression` (String) +- `icmp` (Boolean) +- `ip` (Boolean) +- `ip_v4` (Boolean) +- `ip_v6` (Boolean) +- `keep_opened_sessions` (Boolean) +- `nd` (Boolean) +- `tcp` (Boolean) +- `tcp_dst_ports` (List of String) +- `udp` (Boolean) +- `udp_dst_ports` (List of String) + + + + +### Nested Schema for `security_policies.security_rules.source_net_object` + +Read-Only: + +- `display_name` (String) +- `net_address_pool_id` (String) +- `net_object_group_id` (String) + + + + +### Nested Schema for `security_policies.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `security_policies.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) diff --git a/docs/data-sources/sdn_network_object_group_list.md b/docs/data-sources/sdn_network_object_group_list.md new file mode 100644 index 00000000..a0b0a83d --- /dev/null +++ b/docs/data-sources/sdn_network_object_group_list.md @@ -0,0 +1,720 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_network_object_group_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_network_object_group_list (Data Source) + + + + + + +## Schema + +### Optional + +- `access_group_id` (String) +- `created_from` (String) +- `created_to` (String) +- `name` (String) +- `page` (Number) +- `per_page` (Number) +- `sort_by` (String) +- `sort_order` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `updated_from` (String) +- `updated_to` (String) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `addresses` (List of Object) (see [below for nested schema](#nestedobjatt--items--addresses)) +- `counters` (List of Object) (see [below for nested schema](#nestedobjatt--items--counters)) +- `created_at` (String) +- `description` (String) +- `external_network_ports` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports)) +- `id` (String) +- `l2_connection_ports` (List of Object) (see [below for nested schema](#nestedobjatt--items--l2_connection_ports)) +- `logical_ports` (List of Object) (see [below for nested schema](#nestedobjatt--items--logical_ports)) +- `name` (String) +- `purpose` (String) +- `security_policies` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_policies)) +- `type` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.addresses` + +Read-Only: + +- `id` (String) +- `ip_addr` (String) +- `ip_addr_range_end` (String) +- `ip_prefix` (String) +- `mac_addr` (String) +- `net_address_type` (String) + + + +### Nested Schema for `items.counters` + +Read-Only: + +- `addresses_count` (Number) +- `l2_connection_ports_count` (Number) +- `logical_ports_count` (Number) +- `security_policies_count` (Number) +- `security_rules_count` (Number) + + + +### Nested Schema for `items.external_network_ports` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `bridge_network_name` (String) +- `comment` (String) +- `created_at` (String) +- `default_gateway_ipv4` (String) +- `default_gateway_ipv6` (String) +- `description` (String) +- `enabled` (Boolean) +- `external_network_ports` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports)) +- `hypervisors` (List of String) +- `id` (String) +- `ipv4` (String) +- `mac` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--status)) +- `subnet_v4` (String) +- `subnet_v6` (String) +- `updated_at` (String) +- `version_id` (Number) +- `vlan_tag` (Number) + + +### Nested Schema for `items.external_network_ports.external_network_ports` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `comment` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `floating_ip` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip)) +- `ipv4` (String) +- `ipv6` (String) +- `ipv6_config` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--ipv6_config)) +- `mac` (String) +- `router_gateaway_port` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--router_gateaway_port)) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `created_at` (String) +- `logical_port` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--logical_port)) +- `router` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.logical_port` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `adapter_mac` (String) +- `address_detection` (Boolean) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--logical_port--bindings)) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `exclude_firewall` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--logical_port--exclude_firewall)) +- `external_network_id` (String) +- `hypervisor` (String) +- `hypervisor_display_name` (String) +- `id` (String) +- `labels` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--logical_port--labels)) +- `live_migration_target_hv` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--logical_port--status)) +- `unique_identifier` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.logical_port.bindings` + +Read-Only: + +- `address_detection` (Boolean) +- `created_at` (String) +- `id` (String) +- `logical_port_addresses` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--logical_port--bindings--logical_port_addresses)) +- `port_security` (Boolean) +- `segment_display_name` (String) +- `segment_id` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.logical_port.bindings.logical_port_addresses` + +Read-Only: + +- `assigned_at` (String) +- `id` (String) +- `ip` (String) +- `ip_type` (String) +- `is_discovered` (Boolean) +- `is_primary` (Boolean) +- `logical_port_id` (String) +- `mac` (String) + + + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.logical_port.exclude_firewall` + +Read-Only: + +- `exclusion_reason` (String) +- `logical_port_addresses_excluded` (Boolean) +- `logical_port_excluded` (Boolean) + + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.logical_port.labels` + +Read-Only: + +- `vm_id` (String) +- `vm_name` (String) + + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.logical_port.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--logical_port--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.logical_port.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `gateaway_ports` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--gateaway_ports)) +- `id` (String) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--policies)) +- `ports` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--ports)) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--status)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.gateaway_ports` + +Read-Only: + +- `created_at` (String) +- `description` (String) +- `external_l4_port_max` (Number) +- `external_l4_port_min` (Number) +- `id` (String) +- `snat_enabled` (Boolean) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--gateaway_ports--status)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.gateaway_ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--gateaway_ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.gateaway_ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.policies` + +Read-Only: + +- `action` (String) +- `created_at` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `id` (String) +- `match` (String) +- `next_ipv4_address` (List of String) +- `next_ipv6_address` (List of String) +- `priority` (Number) +- `updated_at` (String) +- `version_id` (Number) + + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.ports` + +Read-Only: + +- `created_at` (String) +- `description` (String) +- `enabled` (Boolean) +- `id` (String) +- `ipv4_address` (String) +- `ipv6_address` (String) +- `ipv6_config` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--ports--ipv6_config)) +- `mac` (String) +- `segment` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--ports--segment)) +- `segment_id` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--ports--status)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.ports.ipv6_config` + +Read-Only: + +- `address_mode` (String) +- `enable_periodic_ra` (Boolean) +- `interval_ra` (Number) +- `router_preference` (String) + + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.ports.segment` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `id` (String) +- `subnet_v4` (String) +- `subnet_v6` (String) +- `updated_at` (String) +- `version_id` (Number) + + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--external_network_ports--floating_ip--router--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `items.external_network_ports.external_network_ports.floating_ip.router.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + + +### Nested Schema for `items.external_network_ports.external_network_ports.ipv6_config` + +Read-Only: + +- `address_mode` (String) +- `enable_periodic_ra` (Boolean) +- `interval_ra` (Number) +- `router_preference` (String) + + + +### Nested Schema for `items.external_network_ports.external_network_ports.router_gateaway_port` + +Read-Only: + +- `created_at` (String) +- `description` (String) +- `id` (String) +- `router_display_name` (String) +- `router_id` (String) +- `snat_enabled` (Boolean) +- `updated_at` (String) + + + + +### Nested Schema for `items.external_network_ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--items--external_network_ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `items.external_network_ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `items.l2_connection_ports` + +Read-Only: + +- `access_group_id` (String) +- `created_at` (String) +- `id` (String) +- `l2_external_network` (List of Object) (see [below for nested schema](#nestedobjatt--items--l2_connection_ports--l2_external_network)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.l2_connection_ports.l2_external_network` + +Read-Only: + +- `bridge_network_name` (String) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `hypervisors` (List of String) +- `id` (String) +- `updated_at` (String) +- `version_id` (Number) +- `vlan_tag` (Number) + + + + +### Nested Schema for `items.logical_ports` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `adapter_mac` (String) +- `address_detection` (Boolean) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--logical_ports--bindings)) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `exclude_firewall` (List of Object) (see [below for nested schema](#nestedobjatt--items--logical_ports--exclude_firewall)) +- `external_network_id` (String) +- `hypervisor` (String) +- `hypervisor_display_name` (String) +- `id` (String) +- `labels` (List of Object) (see [below for nested schema](#nestedobjatt--items--logical_ports--labels)) +- `live_migration_target_hv` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--items--logical_ports--status)) +- `unique_identifier` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.logical_ports.bindings` + +Read-Only: + +- `address_detection` (Boolean) +- `created_at` (String) +- `id` (String) +- `logical_port_addresses` (List of Object) (see [below for nested schema](#nestedobjatt--items--logical_ports--bindings--logical_port_addresses)) +- `port_security` (Boolean) +- `segment_display_name` (String) +- `segment_id` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.logical_ports.bindings.logical_port_addresses` + +Read-Only: + +- `assigned_at` (String) +- `id` (String) +- `ip` (String) +- `ip_type` (String) +- `is_discovered` (Boolean) +- `is_primary` (Boolean) +- `logical_port_id` (String) +- `mac` (String) + + + + +### Nested Schema for `items.logical_ports.exclude_firewall` + +Read-Only: + +- `exclusion_reason` (String) +- `logical_port_addresses_excluded` (Boolean) +- `logical_port_excluded` (Boolean) + + + +### Nested Schema for `items.logical_ports.labels` + +Read-Only: + +- `vm_id` (String) +- `vm_name` (String) + + + +### Nested Schema for `items.logical_ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--items--logical_ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `items.logical_ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `items.security_policies` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `applied_net_object_groups` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_policies--applied_net_object_groups)) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `end_priority` (Number) +- `id` (String) +- `security_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_policies--security_rules)) +- `start_priority` (Number) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_policies--status)) +- `type` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.security_policies.applied_net_object_groups` + +Read-Only: + +- `id` (String) +- `name` (String) +- `version_id` (Number) + + + +### Nested Schema for `items.security_policies.security_rules` + +Read-Only: + +- `access_group_id` (String) +- `action` (String) +- `description` (String) +- `destination_net_object` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_policies--security_rules--destination_net_object)) +- `direction` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `filter` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_policies--security_rules--filter)) +- `id` (String) +- `log_enabled` (Boolean) +- `log_name` (String) +- `log_severity` (String) +- `priority` (Number) +- `security_policy_id` (String) +- `source_net_object` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_policies--security_rules--source_net_object)) +- `statistics_enabled` (Boolean) +- `type` (String) +- `version_id` (Number) + + +### Nested Schema for `items.security_policies.security_rules.destination_net_object` + +Read-Only: + +- `display_name` (String) +- `net_address_pool_id` (String) +- `net_object_group_id` (String) + + + +### Nested Schema for `items.security_policies.security_rules.filter` + +Read-Only: + +- `filters` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_policies--security_rules--filter--filters)) +- `name` (String) + + +### Nested Schema for `items.security_policies.security_rules.filter.filters` + +Read-Only: + +- `all` (Boolean) +- `arp` (Boolean) +- `dhcp` (Boolean) +- `expression` (String) +- `icmp` (Boolean) +- `ip` (Boolean) +- `ip_v4` (Boolean) +- `ip_v6` (Boolean) +- `keep_opened_sessions` (Boolean) +- `nd` (Boolean) +- `tcp` (Boolean) +- `tcp_dst_ports` (List of String) +- `udp` (Boolean) +- `udp_dst_ports` (List of String) + + + + +### Nested Schema for `items.security_policies.security_rules.source_net_object` + +Read-Only: + +- `display_name` (String) +- `net_address_pool_id` (String) +- `net_object_group_id` (String) + + + + +### Nested Schema for `items.security_policies.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--items--security_policies--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `items.security_policies.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) diff --git a/docs/data-sources/sdn_segment.md b/docs/data-sources/sdn_segment.md new file mode 100644 index 00000000..c96de7d2 --- /dev/null +++ b/docs/data-sources/sdn_segment.md @@ -0,0 +1,152 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_segment Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_segment (Data Source) + + + + + + +## Schema + +### Required + +- `segment_id` (String) + +### Optional + +- `access_group_id` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `access_group_name` (String) +- `created_at` (String) +- `description` (String) +- `dhcp_v4` (List of Object) (see [below for nested schema](#nestedatt--dhcp_v4)) +- `dhcp_v6` (List of Object) (see [below for nested schema](#nestedatt--dhcp_v6)) +- `display_name` (String) +- `enabled` (Boolean) +- `id` (String) The ID of this resource. +- `l2_connection_port` (List of Object) (see [below for nested schema](#nestedatt--l2_connection_port)) +- `logical_ports_info` (List of Object) (see [below for nested schema](#nestedatt--logical_ports_info)) +- `routers_info` (List of Object) (see [below for nested schema](#nestedatt--routers_info)) +- `status` (List of Object) (see [below for nested schema](#nestedatt--status)) +- `subnet_v4` (String) +- `subnet_v6` (String) +- `type` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `dhcp_v4` + +Read-Only: + +- `dns` (List of String) +- `enabled` (Boolean) +- `excluded_address_ranges` (List of String) +- `gateway` (String) +- `id` (String) +- `lease_time` (Number) +- `server_ip` (String) +- `server_mac` (String) + + + +### Nested Schema for `dhcp_v6` + +Read-Only: + +- `address_prefix` (String) +- `dns` (List of String) +- `enabled` (Boolean) +- `id` (String) +- `lease_time` (Number) +- `server_mac` (String) + + + +### Nested Schema for `l2_connection_port` + +Read-Only: + +- `access_group_id` (String) +- `created_at` (String) +- `created_by` (String) +- `id` (String) +- `l2_external_network` (List of Object) (see [below for nested schema](#nestedobjatt--l2_connection_port--l2_external_network)) +- `updated_at` (String) +- `updated_by` (String) +- `version_id` (Number) + + +### Nested Schema for `l2_connection_port.l2_external_network` + +Read-Only: + +- `bridge_network_name` (String) +- `created_at` (String) +- `created_by` (String) +- `description` (String) +- `display_name` (String) +- `hypervisors` (List of String) +- `id` (String) +- `updated_at` (String) +- `updated_by` (String) +- `version_id` (Number) +- `vlan_tag` (Number) + + + + +### Nested Schema for `logical_ports_info` + +Read-Only: + +- `display_name` (String) +- `id` (String) + + + +### Nested Schema for `routers_info` + +Read-Only: + +- `display_name` (String) +- `id` (String) + + + +### Nested Schema for `status` + +Read-Only: + +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) diff --git a/docs/data-sources/sdn_segment_list.md b/docs/data-sources/sdn_segment_list.md new file mode 100644 index 00000000..aed9963a --- /dev/null +++ b/docs/data-sources/sdn_segment_list.md @@ -0,0 +1,171 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_segment_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_segment_list (Data Source) + + + + + + +## Schema + +### Optional + +- `access_group_id` (String) find by access group id +- `created_from` (String) find by created date +- `created_to` (String) find by created date +- `display_name` (String) find by display name +- `enabled` (Boolean) find by enabled status +- `is_synced` (Boolean) does core currently believe that its data is synchronized with the data in the OVN? +- `operation_status` (String) filter by operation status +- `page` (Number) Page number +- `per_page` (Number) Items per page +- `sort_by` (String) sort by one of supported fields +- `sort_order` (String) sort order +- `subnet` (String) IPv4 or IPv6 subnet for the current segment +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `updated_from` (String) find by updated date +- `updated_to` (String) find by updated date + +### Read-Only + +- `entry_count` (Number) entry count +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `created_at` (String) +- `description` (String) +- `dhcp_v4` (List of Object) (see [below for nested schema](#nestedobjatt--items--dhcp_v4)) +- `dhcp_v6` (List of Object) (see [below for nested schema](#nestedobjatt--items--dhcp_v6)) +- `display_name` (String) +- `enabled` (Boolean) +- `id` (String) +- `l2_connection_port` (List of Object) (see [below for nested schema](#nestedobjatt--items--l2_connection_port)) +- `logical_ports_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--logical_ports_info)) +- `routers_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--routers_info)) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--items--status)) +- `subnet_v4` (String) +- `subnet_v6` (String) +- `type` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `items.dhcp_v4` + +Read-Only: + +- `dns` (List of String) +- `enabled` (Boolean) +- `excluded_address_ranges` (List of String) +- `gateway` (String) +- `id` (String) +- `lease_time` (Number) +- `server_ip` (String) +- `server_mac` (String) + + + +### Nested Schema for `items.dhcp_v6` + +Read-Only: + +- `address_prefix` (String) +- `dns` (List of String) +- `enabled` (Boolean) +- `id` (String) +- `lease_time` (Number) +- `server_mac` (String) + + + +### Nested Schema for `items.l2_connection_port` + +Read-Only: + +- `access_group_id` (String) +- `created_at` (String) +- `created_by` (String) +- `id` (String) +- `l2_external_network` (List of Object) (see [below for nested schema](#nestedobjatt--items--l2_connection_port--l2_external_network)) +- `updated_at` (String) +- `updated_by` (String) +- `version_id` (Number) + + +### Nested Schema for `items.l2_connection_port.l2_external_network` + +Read-Only: + +- `bridge_network_name` (String) +- `created_at` (String) +- `created_by` (String) +- `description` (String) +- `display_name` (String) +- `hypervisors` (List of String) +- `id` (String) +- `updated_at` (String) +- `updated_by` (String) +- `version_id` (Number) +- `vlan_tag` (Number) + + + + +### Nested Schema for `items.logical_ports_info` + +Read-Only: + +- `display_name` (String) +- `id` (String) + + + +### Nested Schema for `items.routers_info` + +Read-Only: + +- `display_name` (String) +- `id` (String) + + + +### Nested Schema for `items.status` + +Read-Only: + +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--items--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `items.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) diff --git a/docs/data-sources/security_group.md b/docs/data-sources/security_group.md new file mode 100644 index 00000000..c4c9e224 --- /dev/null +++ b/docs/data-sources/security_group.md @@ -0,0 +1,58 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_security_group Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_security_group (Data Source) + + + + + + +## Schema + +### Required + +- `security_group_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) +- `created_at` (Number) +- `created_by` (String) +- `description` (String) +- `id` (String) The ID of this resource. +- `name` (String) +- `rules` (List of Object) (see [below for nested schema](#nestedatt--rules)) +- `updated_at` (Number) +- `updated_by` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `rules` + +Read-Only: + +- `direction` (String) +- `ethertype` (String) +- `id` (Number) +- `port_range_max` (Number) +- `port_range_min` (Number) +- `protocol` (String) +- `remote_ip_prefix` (String) diff --git a/docs/data-sources/security_group_list.md b/docs/data-sources/security_group_list.md new file mode 100644 index 00000000..1f7bd583 --- /dev/null +++ b/docs/data-sources/security_group_list.md @@ -0,0 +1,74 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_security_group_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_security_group_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) +- `by_id` (Number) +- `created_max` (Number) +- `created_min` (Number) +- `desc` (String) +- `name` (String) +- `page` (Number) +- `size` (Number) +- `sort_by` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `updated_max` (Number) +- `updated_min` (Number) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `created_at` (Number) +- `created_by` (String) +- `description` (String) +- `name` (String) +- `rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--rules)) +- `security_group_id` (Number) +- `updated_at` (Number) +- `updated_by` (String) + + +### Nested Schema for `items.rules` + +Read-Only: + +- `direction` (String) +- `ethertype` (String) +- `id` (Number) +- `port_range_max` (Number) +- `port_range_min` (Number) +- `protocol` (String) +- `remote_ip_prefix` (String) diff --git a/docs/data-sources/sep_and_pools_available_list.md b/docs/data-sources/sep_and_pools_available_list.md new file mode 100644 index 00000000..e5e07793 --- /dev/null +++ b/docs/data-sources/sep_and_pools_available_list.md @@ -0,0 +1,59 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sep_and_pools_available_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sep_and_pools_available_list (Data Source) + + + + + + +## Schema + +### Required + +- `account_id` (Number) Account ID + +### Optional + +- `rg_id` (Number) Resource group ID +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) Number of available SEP entries +- `id` (String) The ID of this resource. +- `items` (List of Object) List of available SEPs (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `pools` (List of Object) (see [below for nested schema](#nestedobjatt--items--pools)) +- `sep_id` (Number) +- `sep_name` (String) +- `sep_type` (String) + + +### Nested Schema for `items.pools` + +Read-Only: + +- `name` (String) +- `system` (Boolean) +- `types` (List of String) diff --git a/docs/data-sources/snapshot_list.md b/docs/data-sources/snapshot_list.md new file mode 100644 index 00000000..b1f9e5bd --- /dev/null +++ b/docs/data-sources/snapshot_list.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_snapshot_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_snapshot_list (Data Source) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) ID of the compute instance to create snapshot for. + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) snapshot list (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `disks` (List of Number) +- `guid` (String) +- `label` (String) +- `timestamp` (Number) diff --git a/docs/data-sources/storage_policy.md b/docs/data-sources/storage_policy.md new file mode 100644 index 00000000..d2bd5104 --- /dev/null +++ b/docs/data-sources/storage_policy.md @@ -0,0 +1,63 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_storage_policy Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_storage_policy (Data Source) + + + + + + +## Schema + +### Required + +- `storage_policy_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `access_seps_pools` (List of Object) (see [below for nested schema](#nestedatt--access_seps_pools)) +- `description` (String) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `limit_iops` (Number) +- `name` (String) +- `status` (String) +- `usage` (List of Object) (see [below for nested schema](#nestedatt--usage)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `access_seps_pools` + +Read-Only: + +- `pool_names` (List of String) +- `sep_id` (Number) +- `sep_name` (String) +- `sep_tech_status` (String) + + + +### Nested Schema for `usage` + +Read-Only: + +- `accounts` (List of Number) +- `resgroups` (List of Number) diff --git a/docs/data-sources/storage_policy_list.md b/docs/data-sources/storage_policy_list.md new file mode 100644 index 00000000..3b7cf09e --- /dev/null +++ b/docs/data-sources/storage_policy_list.md @@ -0,0 +1,81 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_storage_policy_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_storage_policy_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) +- `by_id` (Number) +- `desc` (String) +- `limit_iops` (Number) +- `name` (String) +- `page` (Number) +- `pool_name` (String) +- `resgroup_id` (Number) +- `sep_id` (Number) +- `sep_tech_status` (String) +- `size` (Number) +- `sort_by` (String) +- `status` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `access_seps_pools` (List of Object) (see [below for nested schema](#nestedobjatt--items--access_seps_pools)) +- `description` (String) +- `guid` (Number) +- `limit_iops` (Number) +- `name` (String) +- `status` (String) +- `storage_policy_id` (Number) +- `usage` (List of Object) (see [below for nested schema](#nestedobjatt--items--usage)) + + +### Nested Schema for `items.access_seps_pools` + +Read-Only: + +- `pool_names` (List of String) +- `sep_id` (Number) +- `sep_name` (String) +- `sep_tech_status` (String) + + + +### Nested Schema for `items.usage` + +Read-Only: + +- `accounts` (List of Number) +- `resgroups` (List of Number) diff --git a/docs/data-sources/trunk.md b/docs/data-sources/trunk.md new file mode 100644 index 00000000..a4e223e8 --- /dev/null +++ b/docs/data-sources/trunk.md @@ -0,0 +1,52 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_trunk Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_trunk (Data Source) + + + + + + +## Schema + +### Required + +- `trunk_id` (Number) trunk id + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_ids` (Set of Number) List of account IDs with access to this trunk +- `created_at` (Number) when the trunk was created +- `created_by` (String) who created the trunk +- `deleted_at` (Number) when the trunk was updated +- `deleted_by` (String) who updated the trunk +- `description` (String) Description of the trunk +- `guid` (Number) GUID +- `id` (String) The ID of this resource. +- `mac` (String) MAC address +- `mtu` (Number) Maximum Transmission Unit +- `name` (String) Name of the trunk +- `native_vlan_id` (Number) Native VLAN ID +- `ovs_bridge` (String) OVS bridge name +- `status` (String) if the trunk is enabled +- `trunk_tags` (String) List of trunk tags (values between 1-4095) +- `updated_at` (Number) when the trunk was updated +- `updated_by` (String) who updated the trunk + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/trunk_list.md b/docs/data-sources/trunk_list.md new file mode 100644 index 00000000..49fe9f43 --- /dev/null +++ b/docs/data-sources/trunk_list.md @@ -0,0 +1,65 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_trunk_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_trunk_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_ids` (List of Number) Account access ID(s) to filter by +- `page` (Number) Page number. +- `size` (Number) Page size. +- `sort_by` (String) Sort by one of supported fields, format ± +- `status` (String) find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `trunk_ids` (List of Number) ID of the trunk(s) to filter by +- `trunk_tags` (String) Trunk tags to filter by (value between 1-4095) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_ids` (Set of Number) +- `created_at` (Number) +- `created_by` (String) +- `deleted_at` (Number) +- `deleted_by` (String) +- `description` (String) +- `guid` (Number) +- `id` (Number) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `native_vlan_id` (Number) +- `ovs_bridge` (String) +- `status` (String) +- `trunk_tags` (String) +- `updated_at` (Number) +- `updated_by` (String) diff --git a/docs/data-sources/vfpool.md b/docs/data-sources/vfpool.md new file mode 100644 index 00000000..36ee4f80 --- /dev/null +++ b/docs/data-sources/vfpool.md @@ -0,0 +1,72 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vfpool Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vfpool (Data Source) + + + + + + +## Schema + +### Required + +- `vfpool_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_access` (List of Number) +- `created_time` (Number) +- `description` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `name` (String) +- `rg_access` (List of Number) +- `status` (String) +- `updated_time` (Number) +- `vfs` (List of Object) (see [below for nested schema](#nestedatt--vfs)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `vfs` + +Read-Only: + +- `node_id` (Number) +- `vf_list` (List of Object) (see [below for nested schema](#nestedobjatt--vfs--vf_list)) + + +### Nested Schema for `vfs.vf_list` + +Read-Only: + +- `nic_name` (String) +- `vfs_info` (List of Object) (see [below for nested schema](#nestedobjatt--vfs--vf_list--vfs_info)) + + +### Nested Schema for `vfs.vf_list.vfs_info` + +Read-Only: + +- `claimed` (Boolean) +- `id` (Number) +- `vm_id` (Number) diff --git a/docs/data-sources/vfpool_list.md b/docs/data-sources/vfpool_list.md new file mode 100644 index 00000000..bbf2ac4d --- /dev/null +++ b/docs/data-sources/vfpool_list.md @@ -0,0 +1,87 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vfpool_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vfpool_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_access` (Number) Find by accountAccess +- `by_id` (Number) Find by ID +- `description` (String) Find by description +- `gid` (Number) Find by Grid ID +- `name` (String) Find by name +- `page` (Number) Page number +- `rg_access` (Number) Find by rgAccess +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_access` (List of Number) +- `created_time` (Number) +- `description` (String) +- `gid` (Number) +- `guid` (Number) +- `name` (String) +- `rg_access` (List of Number) +- `status` (String) +- `updated_time` (Number) +- `vfpool_id` (Number) +- `vfs` (List of Object) (see [below for nested schema](#nestedobjatt--items--vfs)) + + +### Nested Schema for `items.vfs` + +Read-Only: + +- `node_id` (Number) +- `vf_list` (List of Object) (see [below for nested schema](#nestedobjatt--items--vfs--vf_list)) + + +### Nested Schema for `items.vfs.vf_list` + +Read-Only: + +- `nic_name` (String) +- `vfs_info` (List of Object) (see [below for nested schema](#nestedobjatt--items--vfs--vf_list--vfs_info)) + + +### Nested Schema for `items.vfs.vf_list.vfs_info` + +Read-Only: + +- `claimed` (Boolean) +- `id` (Number) +- `vm_id` (Number) diff --git a/docs/data-sources/vins.md b/docs/data-sources/vins.md new file mode 100644 index 00000000..3c1bd87c --- /dev/null +++ b/docs/data-sources/vins.md @@ -0,0 +1,455 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored. + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_id` (Number) Unique ID of the account, which this ViNS belongs to. +- `account_name` (String) Name of the account, which this ViNS belongs to. +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `created_by` (String) +- `created_time` (Number) +- `default_gw` (String) +- `default_qos` (List of Object) (see [below for nested schema](#nestedatt--default_qos)) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) User-defined text description of this ViNS. +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `milestones` (Number) +- `name` (String) +- `net_mask` (Number) +- `network` (String) +- `pre_reservations_num` (Number) +- `redundant` (Boolean) +- `rg_id` (Number) Unique ID of the resource group, where this ViNS is belongs to (for ViNS created at resource group level, 0 otherwise). +- `rg_name` (String) +- `sec_vnf_dev_id` (Number) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vnf_dev` (List of Object) (see [below for nested schema](#nestedatt--vnf_dev)) +- `vnfs` (List of Object) (see [below for nested schema](#nestedatt--vnfs)) +- `vxlan_id` (Number) +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `compute_id` (Number) +- `compute_name` (String) + + + +### Nested Schema for `default_qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + +### Nested Schema for `vnf_dev` + +Read-Only: + +- `_ckey` (String) +- `account_id` (Number) +- `capabilities` (List of String) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config)) +- `config_saved` (Boolean) +- `custom_pre_cfg` (Boolean) +- `desc` (String) +- `gid` (Number) +- `guid` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces)) +- `live_migration_job_id` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `vins` (List of Number) +- `vnc_password` (String) +- `vnf_id` (Number) +- `vnf_name` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnf_dev.config` + +Read-Only: + +- `mgmt` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config--mgmt)) +- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config--resources)) + + +### Nested Schema for `vnf_dev.config.mgmt` + +Read-Only: + +- `ip_addr` (String) +- `password` (String) +- `ssh_key` (String) +- `user` (String) + + + +### Nested Schema for `vnf_dev.config.resources` + +Read-Only: + +- `cpu` (Number) +- `node_id` (Number) +- `ram` (Number) +- `uuid` (String) + + + + +### Nested Schema for `vnf_dev.interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flipgroup_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_mask` (Number) +- `net_type` (String) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `vnf_dev.interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `vnf_dev.interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + + +### Nested Schema for `vnfs` + +Read-Only: + +- `dhcp` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp)) +- `gw` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw)) +- `nat` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat)) + + +### Nested Schema for `vnfs.dhcp` + +Read-Only: + +- `_ckey` (String) +- `account_id` (Number) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--devices)) +- `dhcp_id` (Number) +- `gid` (Number) +- `guid` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.dhcp.config` + +Read-Only: + +- `default_gw` (String) +- `dns` (List of String) +- `ip_end` (String) +- `ip_start` (String) +- `lease` (Number) +- `netmask` (Number) +- `network` (String) +- `reservations` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--config--reservations)) + + +### Nested Schema for `vnfs.dhcp.config.reservations` + +Read-Only: + +- `account_id` (Number) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + + +### Nested Schema for `vnfs.dhcp.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--devices--primary)) + + +### Nested Schema for `vnfs.dhcp.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.dhcp.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) + + + + +### Nested Schema for `vnfs.gw` + +Read-Only: + +- `_ckey` (String) +- `account_id` (Number) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--devices)) +- `gid` (Number) +- `guid` (Number) +- `gw_id` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.gw.config` + +Read-Only: + +- `default_gw` (String) +- `ext_net_id` (Number) +- `ext_net_ip` (String) +- `ext_netmask` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--config--qos)) + + +### Nested Schema for `vnfs.gw.config.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `vnfs.gw.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--devices--primary)) + + +### Nested Schema for `vnfs.gw.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.gw.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) + + + + +### Nested Schema for `vnfs.nat` + +Read-Only: + +- `_ckey` (String) +- `account_id` (Number) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--devices)) +- `gid` (Number) +- `guid` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `nat_id` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.nat.config` + +Read-Only: + +- `net_mask` (Number) +- `network` (String) +- `rules` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--config--rules)) + + +### Nested Schema for `vnfs.nat.config.rules` + +Read-Only: + +- `local_ip` (String) +- `local_port` (Number) +- `protocol` (String) +- `public_port_end` (Number) +- `public_port_start` (Number) +- `rule_id` (Number) +- `vm_id` (Number) +- `vm_name` (String) + + + + +### Nested Schema for `vnfs.nat.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--devices--primary)) + + +### Nested Schema for `vnfs.nat.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.nat.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) diff --git a/docs/data-sources/vins_audits.md b/docs/data-sources/vins_audits.md new file mode 100644 index 00000000..afcab17e --- /dev/null +++ b/docs/data-sources/vins_audits.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins_audits Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins_audits (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored. + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `call` (String) +- `response_time` (Number) +- `statuscode` (Number) +- `timestamp` (Number) +- `user` (String) diff --git a/docs/data-sources/vins_ext_net_list.md b/docs/data-sources/vins_ext_net_list.md new file mode 100644 index 00000000..2f445bb0 --- /dev/null +++ b/docs/data-sources/vins_ext_net_list.md @@ -0,0 +1,51 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins_ext_net_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins_ext_net_list (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored. + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `default_gw` (String) +- `ext_net_id` (Number) +- `ip` (String) +- `prefix_len` (Number) +- `status` (String) +- `tech_status` (String) diff --git a/docs/data-sources/vins_ip_list.md b/docs/data-sources/vins_ip_list.md new file mode 100644 index 00000000..b99c334f --- /dev/null +++ b/docs/data-sources/vins_ip_list.md @@ -0,0 +1,52 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins_ip_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins_ip_list (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) Unique ID of the ViNS + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `client_type` (String) +- `domainname` (String) +- `hostname` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) diff --git a/docs/data-sources/vins_list.md b/docs/data-sources/vins_list.md new file mode 100644 index 00000000..f1a81a0e --- /dev/null +++ b/docs/data-sources/vins_list.md @@ -0,0 +1,71 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins_list (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Filter by Account ID +- `by_id` (Number) Filter by ID +- `ext_ip` (String) Filter by external IP address +- `include_deleted` (Boolean) Include deleted computes +- `name` (String) Filter by Name +- `page` (Number) Page number +- `rg_id` (Number) Filter by RG ID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) sort by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vnf_dev_id` (Number) Filter by VNF Device id +- `zone_id` (Number) Zone ID + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `external_ip` (String) +- `extnet_id` (Number) +- `free_ips` (Number) +- `network` (String) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins_id` (Number) +- `vins_name` (String) +- `vxlan_id` (Number) diff --git a/docs/data-sources/vins_list_deleted.md b/docs/data-sources/vins_list_deleted.md new file mode 100644 index 00000000..65c194dc --- /dev/null +++ b/docs/data-sources/vins_list_deleted.md @@ -0,0 +1,66 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins_list_deleted Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins_list_deleted (Data Source) + + + + + + +## Schema + +### Optional + +- `account_id` (Number) Filter by account ID +- `by_id` (Number) Filter by ID +- `ext_ip` (String) Filter by external IP +- `name` (String) Filter by name +- `page` (Number) Page number +- `rg_id` (Number) Filter by resgroup ID +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vnfdev_id` (Number) find by VNF Device id + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `account_id` (Number) +- `account_name` (String) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `external_ip` (String) +- `network` (String) +- `rg_id` (Number) +- `rg_name` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `vins_id` (Number) +- `vins_name` (String) +- `vxlan_id` (Number) diff --git a/docs/data-sources/vins_nat_rule_list.md b/docs/data-sources/vins_nat_rule_list.md new file mode 100644 index 00000000..048d8503 --- /dev/null +++ b/docs/data-sources/vins_nat_rule_list.md @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins_nat_rule_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins_nat_rule_list (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored. + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `id` (Number) +- `local_ip` (String) +- `local_port` (Number) +- `protocol` (String) +- `public_port_end` (Number) +- `public_port_start` (Number) +- `vm_id` (Number) +- `vm_name` (String) diff --git a/docs/data-sources/vins_static_route.md b/docs/data-sources/vins_static_route.md new file mode 100644 index 00000000..591a0015 --- /dev/null +++ b/docs/data-sources/vins_static_route.md @@ -0,0 +1,42 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins_static_route Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins_static_route (Data Source) + + + + + + +## Schema + +### Required + +- `route_id` (Number) Unique ID of the static route +- `vins_id` (Number) Unique ID of the ViNS + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `id` (String) The ID of this resource. +- `netmask` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/vins_static_route_list.md b/docs/data-sources/vins_static_route_list.md new file mode 100644 index 00000000..cdbbae15 --- /dev/null +++ b/docs/data-sources/vins_static_route_list.md @@ -0,0 +1,51 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins_static_route_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins_static_route_list (Data Source) + + + + + + +## Schema + +### Required + +- `vins_id` (Number) ID of VINS + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) diff --git a/docs/data-sources/zone.md b/docs/data-sources/zone.md new file mode 100644 index 00000000..9413e542 --- /dev/null +++ b/docs/data-sources/zone.md @@ -0,0 +1,64 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_zone Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_zone (Data Source) + + + + + + +## Schema + +### Required + +- `zone_id` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_ids` (List of Number) +- `app_id` (String) +- `auto_start` (Boolean) +- `broadcast_addr` (String) +- `bservice_ids` (List of Number) +- `compute_ids` (List of Number) +- `created_time` (Number) +- `decort_url` (String) +- `deletable` (Boolean) +- `description` (String) +- `domain` (String) +- `drs` (Boolean) +- `drs_name` (String) +- `drs_uid` (String) +- `extnet_ids` (List of Number) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `k8s_ids` (List of Number) +- `lbs_ids` (List of Number) +- `name` (String) +- `node_ids` (List of Number) +- `ping_addr` (String) +- `ssl_skip_verify` (Boolean) +- `sso_type` (String) +- `sso_url` (String) +- `status` (String) +- `updated_time` (Number) +- `vins_ids` (List of Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) diff --git a/docs/data-sources/zone_list.md b/docs/data-sources/zone_list.md new file mode 100644 index 00000000..99f8d5ec --- /dev/null +++ b/docs/data-sources/zone_list.md @@ -0,0 +1,73 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_zone_list Data Source - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_zone_list (Data Source) + + + + + + +## Schema + +### Optional + +- `by_id` (Number) Find by ID +- `deletable` (Boolean) Find by deletable +- `description` (String) Find by description +- `gid` (Number) Find by Grid ID +- `name` (String) Find by name +- `node_id` (Number) Find by nodeId +- `page` (Number) Page number +- `size` (Number) Page size +- `sort_by` (String) sort by one of supported fields, format +|-(field) +- `status` (String) Find by status +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `entry_count` (Number) +- `id` (String) The ID of this resource. +- `items` (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) +- `read` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `app_id` (String) +- `auto_start` (Boolean) +- `broadcast_addr` (String) +- `created_time` (Number) +- `decort_url` (String) +- `deletable` (Boolean) +- `description` (String) +- `domain` (String) +- `drs` (Boolean) +- `drs_name` (String) +- `drs_uid` (String) +- `gid` (Number) +- `guid` (Number) +- `name` (String) +- `node_ids` (List of Number) +- `ping_addr` (String) +- `ssl_skip_verify` (Boolean) +- `sso_type` (String) +- `sso_url` (String) +- `status` (String) +- `updated_time` (Number) +- `zone_id` (Number) diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..4df9c205 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,36 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort Provider" +description: |- + +--- + +# decort Provider + + + + + + +## Schema + +### Required + +- `authenticator` (String) Authentication mode to use when connecting to DECORT cloud API. Should be one of 'decs3o', 'legacy', 'jwt' or 'bvs'. +- `controller_url` (String) URL of DECORT Cloud controller to use. API calls will be directed to this URL. + +### Optional + +- `allow_unverified_ssl` (Boolean) If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only! +- `app_id` (String) Application ID to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode. +- `app_secret` (String) Application secret to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode. +- `bvs_password` (String) User password for DECORT cloud API operations in 'bvs' authentication mode. +- `bvs_user` (String) User name for DECORT cloud API operations in 'bvs' authentication mode. +- `domain` (String) User password for DECORT cloud API operations in 'bvs' authentication mode. +- `jwt` (String) JWT to access DECORT cloud API in 'jwt' authentication mode. +- `oauth2_url` (String) OAuth2 application URL in 'decs3o' and 'bvs' authentication mode. +- `password` (String) User password for DECORT cloud API operations in 'legacy' authentication mode. +- `path_cfg` (String) The path of the configuration file entry +- `path_token` (String) The path of the token file entry +- `time_to_refresh` (Number) The number of minutes before the expiration of the token, a refresh will be made +- `user` (String) User name for DECORT cloud API operations in 'legacy' authentication mode. diff --git a/docs/resources/account.md b/docs/resources/account.md new file mode 100644 index 00000000..c5da744b --- /dev/null +++ b/docs/resources/account.md @@ -0,0 +1,141 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_account Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_account (Resource) + + + + + + +## Schema + +### Required + +- `account_name` (String) account name + +### Optional + +- `default_zone_id` (Number) email +- `desc` (String) description +- `emailaddress` (String) email +- `enable` (Boolean) enable/disable account +- `permanently` (Boolean) whether to completely delete the account +- `resource_limits` (Block List, Max: 1) (see [below for nested schema](#nestedblock--resource_limits)) +- `restore` (Boolean) restore a deleted account +- `send_access_emails` (Boolean) if true send emails when a user is granted access to resources +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `users` (Block List) (see [below for nested schema](#nestedblock--users)) + +### Read-Only + +- `account_id` (Number) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `company` (String) +- `companyurl` (String) +- `compute_features` (List of String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `dc_location` (String) +- `deactivation_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `displayname` (String) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `machines` (List of Object) (see [below for nested schema](#nestedatt--machines)) +- `status` (String) +- `storage_policy_ids` (List of Number) +- `updated_by` (String) +- `updated_time` (Number) +- `version` (Number) +- `vins` (List of Number) +- `vinses` (Number) +- `zone_ids` (List of Number) + + +### Nested Schema for `resource_limits` + +Optional: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) + +Read-Only: + +- `cu_dm` (Number) +- `storage_policy` (List of Object) (see [below for nested schema](#nestedatt--resource_limits--storage_policy)) + + +### Nested Schema for `resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) + + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `users` + +Required: + +- `access_type` (String) +- `user_id` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `can_be_deleted` (Boolean) +- `emails` (List of String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `started` (Number) +- `stopped` (Number) + + + +### Nested Schema for `machines` + +Read-Only: + +- `halted` (Number) +- `running` (Number) diff --git a/docs/resources/bservice.md b/docs/resources/bservice.md new file mode 100644 index 00000000..cdb85559 --- /dev/null +++ b/docs/resources/bservice.md @@ -0,0 +1,118 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_bservice Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_bservice (Resource) + + + + + + +## Schema + +### Required + +- `rg_id` (Number) ID of the Resource Group where this service will be placed +- `service_name` (String) Name of the service + +### Optional + +- `enable` (Boolean) Enable service. Enabling a service technically means setting model status of all computes and service itself to ENABLED. It does not start computes. +- `permanently` (Boolean) if set to False, Basic service will be deleted to recycle bin. Otherwise destroyed immediately +- `restore` (Boolean) Restores BasicService instance +- `service_id` (Number) +- `snapshots` (Block List) (see [below for nested schema](#nestedblock--snapshots)) +- `ssh_key` (String) SSH key to deploy for the specified user. Same key will be deployed to all computes of the service. +- `ssh_user` (String) name of the user to deploy SSH key for. Pass empty string if no SSH key deployment is required +- `start` (Boolean) Start service. Starting a service technically means starting computes from all service groups according to group relations +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `zone_id` (Number) ID of the zone where this service will be placed + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `base_domain` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `cpu_total` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `disk_total` (Number) +- `gid` (Number) +- `groups` (List of Object) (see [below for nested schema](#nestedatt--groups)) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `milestones` (Number) +- `parent_srv_id` (Number) +- `parent_srv_type` (String) +- `ram_total` (Number) +- `rg_name` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) + + +### Nested Schema for `snapshots` + +Optional: + +- `label` (String) +- `rollback` (Boolean) + +Read-Only: + +- `guid` (String) +- `timestamp` (Number) +- `valid` (Boolean) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `account_id` (Number) +- `architecture` (String) +- `compgroup_id` (Number) +- `compgroup_name` (String) +- `compgroup_role` (String) +- `id` (Number) +- `name` (String) +- `node_id` (Number) +- `rg_id` (Number) +- `status` (String) +- `tech_status` (String) + + + +### Nested Schema for `groups` + +Read-Only: + +- `computes` (Number) +- `consistency` (Boolean) +- `id` (Number) +- `name` (String) +- `status` (String) +- `tech_status` (String) diff --git a/docs/resources/bservice_group.md b/docs/resources/bservice_group.md new file mode 100644 index 00000000..4d002d0e --- /dev/null +++ b/docs/resources/bservice_group.md @@ -0,0 +1,100 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_bservice_group Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_bservice_group (Resource) + + + + + + +## Schema + +### Required + +- `comp_count` (Number) computes number. Defines how many computes must be there in the group +- `compgroup_name` (String) name of the Compute Group to add +- `cpu` (Number) compute CPU number. All computes in the group have the same CPU count +- `disk` (Number) compute boot disk size in GB +- `image_id` (Number) OS image ID to create computes from +- `ram` (Number) compute RAM volume in MB. All computes in the group have the same RAM volume +- `service_id` (Number) ID of the Basic Service to add a group to +- `storage_policy_id` (Number) storage policy id of compute. The rules of the specified storage policy will be used. + +### Optional + +- `chipset` (String) Chipset for virtual machines. +- `cloud_init` (String) Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases. +- `compgroup_id` (Number) +- `extnets` (List of Number) list of external networks to connect computes to +- `force_stop` (Boolean) force stop Compute Group +- `force_update` (Boolean) force resize Compute Group +- `mode` (String) (RELATIVE;ABSOLUTE) either delta or absolute value of computes +- `parents` (List of Number) +- `remove_computes` (List of Number) +- `role` (String) group role tag. Can be empty string, does not have to be unique +- `sep_id` (Number) storage endpoint provider ID +- `sep_pool` (String) pool to use if sepId is set, can be also empty if needed to be chosen by system +- `start` (Boolean) Start the specified Compute Group within BasicService +- `timeout_start` (Number) time of Compute Group readiness +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vinses` (List of Number) list of ViNSes to connect computes to + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `consistency` (Boolean) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `driver` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `milestones` (Number) +- `rg_id` (Number) +- `rg_name` (String) +- `seq_no` (Number) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `chipset` (String) +- `id` (Number) +- `ip_addresses` (List of String) +- `name` (String) +- `os_users` (List of Object) (see [below for nested schema](#nestedobjatt--computes--os_users)) + + +### Nested Schema for `computes.os_users` + +Read-Only: + +- `login` (String) +- `password` (String) diff --git a/docs/resources/cb_account.md b/docs/resources/cb_account.md new file mode 100644 index 00000000..33fecb24 --- /dev/null +++ b/docs/resources/cb_account.md @@ -0,0 +1,132 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_account Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_account (Resource) + + + + + + +## Schema + +### Required + +- `account_name` (String) account name +- `username` (String) username of owner the account + +### Optional + +- `account_id` (Number) +- `available_templates` (Set of Number) Share images with account +- `compute_features` (Set of String) +- `cpu_allocation_parameter` (String) set cpu allocation parameter +- `cpu_allocation_ratio` (Number) set cpu allocation ratio +- `default_zone_id` (Number) email +- `desc` (String) description +- `emailaddress` (String) email +- `enable` (Boolean) enable/disable account +- `permanently` (Boolean) whether to completely delete the account +- `resource_limits` (Block List, Max: 1) (see [below for nested schema](#nestedblock--resource_limits)) +- `restore` (Boolean) restore a deleted account +- `send_access_emails` (Boolean) if true send emails when a user is granted access to resources +- `storage_policy` (Block Set) (see [below for nested schema](#nestedblock--storage_policy)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `uniq_pools` (List of String) +- `users` (Block List) (see [below for nested schema](#nestedblock--users)) +- `zone_ids` (Set of Number) + +### Read-Only + +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `company` (String) +- `companyurl` (String) +- `created_by` (String) +- `created_time` (Number) +- `dc_location` (String) +- `deactivation_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `displayname` (String) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `resource_types` (List of String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `version` (Number) +- `vins` (List of Number) + + +### Nested Schema for `resource_limits` + +Optional: + +- `cu_c` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) + +Read-Only: + +- `cu_d` (Number) +- `storage_policy` (List of Object) (see [below for nested schema](#nestedatt--resource_limits--storage_policy)) + + +### Nested Schema for `resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) + + + + +### Nested Schema for `storage_policy` + +Required: + +- `id` (Number) +- `limit` (Number) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `users` + +Required: + +- `access_type` (String) +- `user_id` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `emails` (List of String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) diff --git a/docs/resources/cb_cdrom_image.md b/docs/resources/cb_cdrom_image.md new file mode 100644 index 00000000..97e34348 --- /dev/null +++ b/docs/resources/cb_cdrom_image.md @@ -0,0 +1,102 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_cdrom_image Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_cdrom_image (Resource) + + + + + + +## Schema + +### Required + +- `name` (String) Name of the rescue disk +- `storage_policy_id` (Number) ID of the storage policy +- `url` (String) URL where to download ISO from + +### Optional + +- `account_id` (Number) AccountId to make the image exclusive +- `architecture` (String) binary architecture of this image, one of X86_64 +- `bootable` (Boolean) Does this image boot OS +- `computeci_id` (Number) +- `enabled` (Boolean) +- `hot_resize` (Boolean) Does this machine supports hot resize +- `password_dl` (String) password for upload binary media +- `pool_name` (String) pool for image create +- `sep_id` (Number) storage endpoint provider ID +- `shared_with` (List of Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `username_dl` (String) username for upload binary media + +### Read-Only + +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `boot_type` (String) Boot type of image bios or uefi +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `id` (String) The ID of this resource. +- `image_id` (Number) image id +- `image_type` (String) Image type linux, windows or other +- `last_modified` (Number) +- `link_to` (Number) +- `milestones` (Number) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `reference_id` (String) +- `res_id` (String) +- `res_name` (String) +- `rescuecd` (Boolean) +- `size` (Number) image size +- `snapshot_id` (String) snapshot id +- `status` (String) status +- `tech_status` (String) tech atatus +- `to_clean` (Boolean) +- `unc_path` (String) unc path +- `version` (String) version + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/resources/cb_disk.md b/docs/resources/cb_disk.md new file mode 100644 index 00000000..d557e3d1 --- /dev/null +++ b/docs/resources/cb_disk.md @@ -0,0 +1,156 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_disk Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_disk (Resource) + + + + + + +## Schema + +### Required + +- `account_id` (Number) +- `disk_name` (String) +- `size_max` (Number) +- `storage_policy_id` (Number) + +### Optional + +- `blk_discard` (Boolean) +- `block_size` (String) +- `cache` (String) Cache mode for the disk +- `desc` (String) +- `detach` (Boolean) detach disk from machine first +- `iotune` (Block List, Max: 1) (see [below for nested schema](#nestedblock--iotune)) +- `node_ids` (Set of Number) +- `permanently` (Boolean) whether to completely delete the disk, works only with non attached disks +- `pool` (String) +- `restore` (Boolean) restore deleting disk +- `sep_id` (Number) +- `shareable` (Boolean) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_name` (String) +- `acl` (String) +- `boot_partition` (Number) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `destruction_time` (Number) +- `devicename` (String) +- `disk_id` (Number) +- `disk_path` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `images` (List of Number) +- `independent` (Boolean) +- `iqn` (String) +- `login` (String) +- `machine_id` (Number) +- `machine_name` (String) +- `milestones` (Number) +- `order` (Number) +- `params` (String) +- `parent_id` (Number) +- `passwd` (String) +- `pci_slot` (Number) +- `present_to` (Map of Number) +- `provision` (String) +- `purge_attempts` (Number) +- `purge_time` (Number) +- `reality_device_number` (Number) +- `reference_id` (String) +- `replication` (List of Object) Replication status (see [below for nested schema](#nestedatt--replication)) +- `res_id` (String) +- `res_name` (String) +- `role` (String) +- `sep_type` (String) +- `size_used` (Number) +- `snapshots` (List of Object) (see [below for nested schema](#nestedatt--snapshots)) +- `status` (String) +- `tech_status` (String) +- `to_clean` (Boolean) +- `updated_by` (String) +- `updated_time` (Number) +- `vmid` (Number) + + +### Nested Schema for `iotune` + +Optional: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `compute_id` (String) +- `compute_name` (String) + + + +### Nested Schema for `replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `reference_id` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/resources/cb_disk_snapshot.md b/docs/resources/cb_disk_snapshot.md new file mode 100644 index 00000000..d90b8679 --- /dev/null +++ b/docs/resources/cb_disk_snapshot.md @@ -0,0 +1,47 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_disk_snapshot Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_disk_snapshot (Resource) + + + + + + +## Schema + +### Required + +- `disk_id` (Number) The unique ID of the subscriber-owner of the disk +- `label` (String) Name of the snapshot + +### Optional + +- `rollback` (Boolean) Needed in order to make a snapshot rollback +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `timestamp` (Number) Snapshot time + +### Read-Only + +- `guid` (String) ID of the snapshot +- `id` (String) The ID of this resource. +- `reference_id` (String) +- `res_id` (String) Reference to the snapshot +- `snap_set_guid` (String) The set snapshot ID +- `snap_set_time` (Number) The set time of the snapshot + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_dpdknet.md b/docs/resources/cb_dpdknet.md new file mode 100644 index 00000000..d6a162d7 --- /dev/null +++ b/docs/resources/cb_dpdknet.md @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_dpdknet Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_dpdknet (Resource) + + + + + + +## Schema + +### Required + +- `gid` (Number) ID of the grid (platform) +- `name` (String) Name of network +- `ovs_bridge` (String) OVS bridge in which interfaces for computers created +- `vlan_id` (Number) vlan ID + +### Optional + +- `account_access` (List of Number) List of accounts with access +- `desc` (String) Description of DPDK network +- `enable_secgroups` (Boolean) enable security groups +- `enabled` (Boolean) Enabled or disabled DPDK network +- `rg_access` (List of Number) List of resource groups with access +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `compute_ids` (List of Number) Compute IDs which uses this DPDK network +- `created_time` (Number) Created time +- `dpdk_id` (Number) The unique ID of the subscriber-owner of the DPDK network +- `guid` (Number) DPDK network ID on the storage side +- `id` (String) The ID of this resource. +- `status` (String) DPDK network status +- `updated_time` (Number) Updated time + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_extnet.md b/docs/resources/cb_extnet.md new file mode 100644 index 00000000..84bdb25d --- /dev/null +++ b/docs/resources/cb_extnet.md @@ -0,0 +1,179 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_extnet Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_extnet (Resource) + + + + + + +## Schema + +### Required + +- `gid` (Number) Grid (platform) ID +- `ipcidr` (String) IP network CIDR +- `name` (String) External network name +- `vlan_id` (Number) VLAN ID + +### Optional + +- `check_ips` (List of String) IPs to check network availability +- `default_qos` (Block List, Max: 1) (see [below for nested schema](#nestedblock--default_qos)) +- `desc` (String) Optional description +- `dns` (List of String) List of DNS addresses +- `enable` (Boolean) Disable/Enable extnet +- `enable_secgroups` (Boolean) enable security groups +- `end_ip` (String) End of IP range to be explicitly included +- `excluded_ips` (Set of String) IPs to exclude in current extnet pool +- `excluded_ips_range` (Block Set) Range of IPs to exclude in current extnet pool (see [below for nested schema](#nestedblock--excluded_ips_range)) +- `gateway` (String) External network gateway IP address +- `highly_available` (Boolean) +- `migrate` (Number) +- `mtu` (Number) +- `ntp` (List of String) List of NTP addresses +- `ovs_bridge` (String) OpenvSwith bridge name for ExtNet connection +- `pre_reservations_num` (Number) Number of pre created reservations +- `reserved_ip` (Block Set) (see [below for nested schema](#nestedblock--reserved_ip)) +- `restart` (Boolean) restart extnet vnf device +- `sec_vnfdev_ip` (String) +- `set_default` (Boolean) Set current extnet as default (can not be undone) +- `shared_with` (Set of Number) +- `start_ip` (String) Start of IP range to be explicitly included +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `virtual` (Boolean) If true - platform DHCP server will not be created +- `vnfdev_ip` (String) IP to create VNFDev with +- `zone_id` (Number) + +### Read-Only + +- `ckey` (String) +- `default` (Boolean) +- `excluded` (List of Object) (see [below for nested schema](#nestedatt--excluded)) +- `extnet_id` (Number) +- `free_ips` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `meta` (List of String) meta +- `milestones` (Number) +- `network` (String) +- `network_ids` (List of Object) (see [below for nested schema](#nestedatt--network_ids)) +- `prefix` (Number) +- `pri_vnfdev_id` (Number) +- `reservations` (List of Object) (see [below for nested schema](#nestedatt--reservations)) +- `routes` (List of Object) (see [below for nested schema](#nestedatt--routes)) +- `status` (String) +- `vnfs` (List of Object) (see [below for nested schema](#nestedatt--vnfs)) + + +### Nested Schema for `default_qos` + +Optional: + +- `e_rate` (Number) +- `in_burst` (Number) +- `in_rate` (Number) + +Read-Only: + +- `guid` (String) + + + +### Nested Schema for `excluded_ips_range` + +Required: + +- `ip_end` (String) +- `ip_start` (String) + + + +### Nested Schema for `reserved_ip` + +Required: + +- `account_id` (Number) + +Optional: + +- `ip_count` (Number) +- `ips` (Set of String) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `excluded` + +Read-Only: + +- `client_type` (String) +- `domain_name` (String) +- `hostname` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + +### Nested Schema for `network_ids` + +Read-Only: + +- `primary` (Number) +- `secondary` (Number) + + + +### Nested Schema for `reservations` + +Read-Only: + +- `account_id` (Number) +- `client_type` (String) +- `desc` (String) +- `domain_name` (String) +- `hostname` (String) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + +### Nested Schema for `routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) + + + +### Nested Schema for `vnfs` + +Read-Only: + +- `dhcp` (Number) diff --git a/docs/resources/cb_extnet_static_route.md b/docs/resources/cb_extnet_static_route.md new file mode 100644 index 00000000..390931b5 --- /dev/null +++ b/docs/resources/cb_extnet_static_route.md @@ -0,0 +1,45 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_extnet_static_route Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_extnet_static_route (Resource) + + + + + + +## Schema + +### Required + +- `destination` (String) +- `extnet_id` (Number) Unique ID of the ExtNet +- `gateway` (String) +- `netmask` (String) + +### Optional + +- `compute_ids` (Set of Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `guid` (String) +- `id` (String) The ID of this resource. +- `route_id` (Number) Unique ID of the static route + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_flipgroup.md b/docs/resources/cb_flipgroup.md new file mode 100644 index 00000000..6754c2ca --- /dev/null +++ b/docs/resources/cb_flipgroup.md @@ -0,0 +1,65 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_flipgroup Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_flipgroup (Resource) + + + + + + +## Schema + +### Required + +- `account_id` (Number) Account ID +- `name` (String) Flipgroup name +- `net_id` (Number) EXTNET or ViNS ID +- `net_type` (String) Network type, EXTNET or VINS + +### Optional + +- `client_ids` (List of Number) List of clients attached to this Flipgroup instance +- `client_type` (String) Type of client, 'compute' ('vins' will be later) +- `desc` (String) Text description of this Flipgroup instance +- `ip` (String) IP address to associate with this group. If empty, the platform will autoselect IP address +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_name` (String) account_name +- `ckey` (String) +- `client_names` (List of String) client_names +- `conn_id` (Number) +- `conn_type` (String) +- `created_by` (String) created_by +- `created_time` (Number) created_time +- `default_gw` (String) +- `deleted_by` (String) deleted_by +- `deleted_time` (Number) deleted_time +- `flipgroup_id` (Number) +- `gid` (Number) gid +- `guid` (Number) guid +- `id` (String) The ID of this resource. +- `milestones` (Number) milestones +- `net_mask` (Number) +- `network` (String) network +- `status` (String) +- `updated_by` (String) updated_by +- `updated_time` (Number) updated_time + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_image.md b/docs/resources/cb_image.md new file mode 100644 index 00000000..db5a07b8 --- /dev/null +++ b/docs/resources/cb_image.md @@ -0,0 +1,109 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_image Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_image (Resource) + + + + + + +## Schema + +### Required + +- `boot_type` (String) Boot type of image bios or uefi +- `image_type` (String) Image type linux, windows or other +- `name` (String) Name of the rescue disk +- `storage_policy_id` (Number) ID of the storage policy +- `url` (String) URL where to download media from + +### Optional + +- `account_id` (Number) AccountId to make the image exclusive +- `bootable` (Boolean) Does this image boot OS +- `computeci_id` (Number) +- `enabled` (Boolean) +- `hot_resize` (Boolean) Does this machine supports hot resize +- `network_interface_naming` (String) select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming +- `password` (String) Optional password for the image +- `password_dl` (String) password for upload binary media +- `pool_name` (String) pool for image create +- `sep_id` (Number) storage endpoint provider ID +- `shared_with` (List of Number) +- `sync_mode` (Boolean) Create image from a media identified by URL (in synchronous mode) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `username` (String) Optional username for the image +- `username_dl` (String) username for upload binary media + +### Read-Only + +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `architecture` (String) binary architecture of this image, one of X86_64 +- `cd_presented_to` (String) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `id` (String) The ID of this resource. +- `image_id` (Number) image id +- `independent` (Boolean) +- `last_modified` (Number) +- `link_to` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `reference_id` (String) +- `res_id` (String) +- `res_name` (String) +- `rescuecd` (Boolean) +- `size` (Number) image size +- `snapshot_id` (String) snapshot id +- `status` (String) status +- `tech_status` (String) tech atatus +- `to_clean` (Boolean) +- `unc_path` (String) unc path +- `version` (String) version + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/resources/cb_image_from_blank_compute.md b/docs/resources/cb_image_from_blank_compute.md new file mode 100644 index 00000000..f28f3dfb --- /dev/null +++ b/docs/resources/cb_image_from_blank_compute.md @@ -0,0 +1,107 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_image_from_blank_compute Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_image_from_blank_compute (Resource) + + + + + + +## Schema + +### Required + +- `boot_type` (String) Boot type of image BIOS or UEFI +- `compute_id` (Number) Compute Id +- `image_type` (String) Image type linux, windows or unknown +- `name` (String) Name of the rescue disk +- `storage_policy_id` (Number) Storage policy ID + +### Optional + +- `account_id` (Number) AccountId to make the image exclusive +- `async_mode` (Boolean) create an image in async/sync mode +- `bootable` (Boolean) Does this image boot OS +- `computeci_id` (Number) +- `enabled` (Boolean) +- `hot_resize` (Boolean) Does this machine supports hot resize +- `network_interface_naming` (String) select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming +- `password` (String) Optional password for the image +- `pool_name` (String) pool for image create +- `shared_with` (List of Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `username` (String) Optional username for the image + +### Read-Only + +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `architecture` (String) +- `cd_presented_to` (String) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `last_modified` (Number) +- `link_to` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `reference_id` (String) +- `res_id` (String) +- `res_name` (String) +- `rescuecd` (Boolean) +- `sep_id` (Number) storage endpoint provider ID +- `size` (Number) +- `snapshot_id` (String) snapshot id +- `status` (String) +- `tech_status` (String) +- `to_clean` (Boolean) +- `unc_path` (String) +- `url` (String) +- `version` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/resources/cb_image_from_platform_disk.md b/docs/resources/cb_image_from_platform_disk.md new file mode 100644 index 00000000..666de83d --- /dev/null +++ b/docs/resources/cb_image_from_platform_disk.md @@ -0,0 +1,106 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_image_from_platform_disk Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_image_from_platform_disk (Resource) + + + + + + +## Schema + +### Required + +- `boot_type` (String) Boot type of image BIOS or UEFI +- `disk_id` (Number) Disk Id +- `image_type` (String) Image type linux, windows or unknown +- `name` (String) Name of the rescue disk + +### Optional + +- `account_id` (Number) AccountId to make the image exclusive +- `async_mode` (Boolean) create an image in async/sync mode +- `bootable` (Boolean) Does this image boot OS +- `computeci_id` (Number) +- `enabled` (Boolean) +- `hot_resize` (Boolean) Does this machine supports hot resize +- `network_interface_naming` (String) select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming +- `password` (String) Optional password for the image +- `pool_name` (String) pool for image create +- `shared_with` (List of Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `username` (String) Optional username for the image + +### Read-Only + +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `architecture` (String) +- `cd_presented_to` (String) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `last_modified` (Number) +- `link_to` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `reference_id` (String) +- `res_id` (String) +- `res_name` (String) +- `rescuecd` (Boolean) +- `sep_id` (Number) storage endpoint provider ID +- `size` (Number) +- `snapshot_id` (String) snapshot id +- `status` (String) +- `tech_status` (String) +- `to_clean` (Boolean) +- `unc_path` (String) +- `url` (String) +- `version` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/resources/cb_k8ci.md b/docs/resources/cb_k8ci.md new file mode 100644 index 00000000..f2013736 --- /dev/null +++ b/docs/resources/cb_k8ci.md @@ -0,0 +1,55 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8ci Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8ci (Resource) + + + + + + +## Schema + +### Required + +- `master_image_id` (Number) +- `max_master_count` (Number) +- `max_worker_count` (Number) +- `name` (String) K8CI name +- `network_plugins` (List of String) +- `version` (String) +- `worker_image_id` (Number) + +### Optional + +- `desc` (String) +- `enabled` (Boolean) +- `permanently` (Boolean) +- `shared_with` (Set of Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `gid` (Number) gid +- `guid` (Number) guid +- `id` (String) The ID of this resource. +- `k8ci_id` (Number) K8CI ID +- `lb_image_id` (Number) LB Image ID +- `milestones` (Number) +- `status` (String) K8CI Status + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_k8s_cp.md b/docs/resources/cb_k8s_cp.md new file mode 100644 index 00000000..abf8faea --- /dev/null +++ b/docs/resources/cb_k8s_cp.md @@ -0,0 +1,164 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8s_cp Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8s_cp (Resource) + + + + + + +## Schema + +### Required + +- `k8sci_id` (Number) ID of the k8s catalog item to base this instance on. +- `name` (String) Name of the cluster. +- `network_plugin` (String) Network plugin to be used +- `rg_id` (Number) Resource group ID that this instance belongs to. +- `storage_policy_id` (Number) ID of the storage policy + +### Optional + +- `additional_sans` (List of String) Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names +- `chipset` (String) Type of the emulated system. Possible values: i440fx, Q35. Default: Q35 +- `cluster_config` (String) is used to define global settings and configurations for the entire cluster. It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. insert a valid JSON string with all levels of nesting. +- `cpu` (Number) Node CPU count. +- `desc` (String) Text description of this instance. +- `disk` (Number) Node boot disk size in GB. +- `enabled` (Boolean) Enable k8s cluster +- `extnet_id` (Number) ID of the external network to connect workers to. If omitted network will be chosen by the platfom. +- `extnet_only` (Boolean) Use only selected ExtNet for infrastructure connections +- `ha_mode` (Boolean) Use Highly Available schema for LB deploy +- `init_config` (String) is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting. +- `join_config` (String) is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting. +- `kube_proxy_config` (String) is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting. +- `kubelet_config` (String) is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. insert a valid JSON string with all levels of nesting. +- `lb_sysctl_params` (List of Map of String) Custom sysctl values for Load Balancer instance. Applied on boot. +- `num` (Number) Number of VMs to create. Can be either 1 or 3 or 5 +- `oidc_cert` (String) insert ssl certificate in x509 pem format +- `permanently` (Boolean) whether to completely delete the account +- `ram` (Number) Node RAM in MB. +- `restore` (Boolean) +- `sep_id` (Number) Storage Endpoint ID +- `sep_pool` (String) Storage Endpoint Pool +- `start` (Boolean) Start k8s cluster. +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) ID of default vins for this instace. +- `with_lb` (Boolean) Create k8s with load balancer if true. +- `zone_id` (Number) + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `bservice_id` (Number) +- `created_by` (String) +- `created_time` (Number) +- `default_wg_id` (Number) ID of default workers group for this instace. +- `deleted_by` (String) +- `deleted_time` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedatt--detailed_info)) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `k8s_ci_name` (String) +- `k8s_id` (Number) +- `kubeconfig` (String) Kubeconfig for cluster access. +- `lb_id` (Number) +- `lb_ip` (String) IP address of default load balancer. +- `master_id` (Number) Master group ID. +- `master_name` (String) Master group name. +- `milestones` (Number) +- `rg_name` (String) +- `ssh_key` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `account_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--account_acl)) +- `k8s_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--k8s_acl)) +- `rg_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--rg_acl)) + + +### Nested Schema for `acl.account_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.k8s_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.rg_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + + +### Nested Schema for `detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--detailed_info--interfaces)) +- `name` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/resources/cb_k8s_wg.md b/docs/resources/cb_k8s_wg.md new file mode 100644 index 00000000..ffa5ff39 --- /dev/null +++ b/docs/resources/cb_k8s_wg.md @@ -0,0 +1,75 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_k8s_wg Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_k8s_wg (Resource) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) ID of k8s instance. +- `name` (String) Name of the worker group. +- `storage_policy_id` (Number) ID of the storage policy + +### Optional + +- `annotations` (List of String) +- `chipset` (String) Type of the emulated system. Possible values: i440fx, Q35. Default: Q35 +- `cloud_init` (String) +- `cpu` (Number) Worker node CPU count. +- `disk` (Number) Worker node boot disk size. If unspecified or 0, size is defined by OS image size. +- `labels` (List of String) +- `num` (Number) Number of worker nodes to create. +- `ram` (Number) Node RAM in MB. +- `taints` (List of String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `worker_sep_id` (Number) +- `worker_sep_pool` (String) + +### Read-Only + +- `detailed_info` (List of Object) (see [below for nested schema](#nestedatt--detailed_info)) +- `guid` (String) +- `id` (String) The ID of this resource. +- `wg_id` (Number) ID of k8s worker Group. + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--detailed_info--interfaces)) +- `name` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/resources/cb_kvmvm.md b/docs/resources/cb_kvmvm.md new file mode 100644 index 00000000..0bcd2fe7 --- /dev/null +++ b/docs/resources/cb_kvmvm.md @@ -0,0 +1,477 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_kvmvm Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_kvmvm (Resource) + + + + + + +## Schema + +### Required + +- `cpu` (Number) Number of CPUs to allocate to this compute instance. +- `name` (String) Name of this compute. Compute names are case sensitive and must be unique in the resource group. +- `ram` (Number) Amount of RAM in MB to allocate to this compute instance. +- `rg_id` (Number) ID of the resource group where this compute should be deployed. +- `storage_policy_id` (Number) Storage policy id of compute. The rules of the specified storage policy will be used. + +### Optional + +- `affinity_label` (String) Set affinity label for compute +- `affinity_rules` (Block List) (see [below for nested schema](#nestedblock--affinity_rules)) +- `alt_boot_id` (Number) ID of CD-ROM live image to boot +- `anti_affinity_rules` (Block List) (see [below for nested schema](#nestedblock--anti_affinity_rules)) +- `auto_start_w_node` (Boolean) +- `boot_disk_blk_discard` (Boolean) +- `boot_disk_cache` (String) Setting the boot disk caching mode +- `boot_disk_size` (Number) This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image. +- `boot_type` (String) Type of image upload. +- `cd` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--cd)) +- `chipset` (String) Type of the emulated system. +- `cloud_init` (String) Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases. +- `cpu_pin` (Boolean) Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node. +- `create_blank` (Boolean) If True, the compute is created via kvmx86/createBlank endpoint (without OS image). The image_id field is not required in this case. +- `custom_fields` (String) +- `description` (String) Optional text description of this compute instance. +- `detach_disks` (Boolean) +- `disks` (Block List) (see [below for nested schema](#nestedblock--disks)) +- `enabled` (Boolean) If true - enable compute, else - disable +- `extra_disks` (Set of Number) Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks. +- `force_pin` (Boolean) +- `force_resize` (Boolean) Flag for resize compute +- `force_stop` (Boolean) Flag for redeploy compute +- `hot_resize` (Boolean) Type of image vm. +- `hp_backed` (Boolean) Use Huge Pages to allocate RAM of the virtual machine. The system must be pre-configured by allocating Huge Pages on the physical node. +- `image_id` (Number) ID of the OS image to base this compute instance on. +- `libvirt_settings` (Block Set) Configure libvirt virtio interface parameters. You can only delete values locally. Data on the platform cannot be deleted. (see [below for nested schema](#nestedblock--libvirt_settings)) +- `loader_type` (String) Type of image vm. +- `network` (Block Set) Optional network connection(s) for this compute. You may specify several network blocks, one for each connection. (see [below for nested schema](#nestedblock--network)) +- `network_interface_naming` (String) Name of netfowrk interface. +- `node_id` (Number) ID of node to start compute +- `numa_affinity` (String) Rule for VM placement with NUMA affinity. +- `os_version` (String) the OS version installed on the VM +- `pause` (Boolean) +- `pci_devices` (Set of Number) ID of the connected pci devices +- `permanently` (Boolean) +- `pin_to_node` (Boolean) +- `pool` (String) Pool to use if sepId is set, can be also empty if needed to be chosen by system. +- `port_forwarding` (Block Set) (see [below for nested schema](#nestedblock--port_forwarding)) +- `preferred_cpu` (List of Number) Recommended isolated CPUs. Field is ignored if compute.cpupin=False or compute.pinned=False +- `read_only` (Boolean) Sets read-only mode for this compute. Only data operations allowed when enabled. +- `reset` (Boolean) +- `restore` (Boolean) +- `rollback` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--rollback)) +- `security_groups` (Block Set) list of security group IDs to apply to this interface (see [below for nested schema](#nestedblock--security_groups)) +- `sep_id` (Number) ID of SEP to create bootDisk on. Uses image's sepId if not set. +- `snapshot` (Block Set) (see [below for nested schema](#nestedblock--snapshot)) +- `started` (Boolean) Is compute started. +- `tags` (Block Set) (see [below for nested schema](#nestedblock--tags)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `user_access` (Block Set) (see [below for nested schema](#nestedblock--user_access)) +- `weight` (Number) Priority weight of the compute. Higher value means higher priority and later migration. +- `without_boot_disk` (Boolean) If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state. +- `zone_id` (Number) + +### Read-Only + +- `account_id` (Number) ID of the account this compute instance belongs to. +- `account_name` (String) Name of the account this compute instance belongs to. +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `affinity_weight` (Number) +- `arch` (String) +- `boot_disk_id` (Number) This compute instance boot disk ID. +- `boot_image_id` (Number) +- `boot_order` (List of String) +- `cd_image_id` (Number) +- `clone_reference` (Number) +- `clones` (List of Number) +- `compute_id` (Number) +- `computeci_id` (Number) +- `created_by` (String) +- `created_time` (Number) +- `delete_async_mode` (Boolean) async mode +- `deleted_by` (String) +- `deleted_time` (Number) +- `devices` (String) +- `driver` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `image_name` (String) +- `interfaces` (List of Object) (see [below for nested schema](#nestedatt--interfaces)) +- `loader_meta_iso` (List of Object) (see [below for nested schema](#nestedatt--loader_meta_iso)) +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `migrationjob` (Number) +- `milestones` (Number) +- `natable_vins_id` (Number) +- `natable_vins_ip` (String) +- `natable_vins_name` (String) +- `natable_vins_network` (String) +- `natable_vins_network_name` (String) +- `need_reboot` (Boolean) +- `node_name` (String) Name of the node, on which VM started +- `numa_node_id` (Number) +- `os_users` (List of Object) Guest OS users provisioned on this compute instance. (see [below for nested schema](#nestedatt--os_users)) +- `pinned` (Number) +- `reference_id` (String) +- `registered` (Boolean) +- `res_name` (String) +- `reserved_node_cpus` (List of Number) +- `rg_name` (String) Name of the resource group where this compute instance is located. +- `snap_sets` (List of Object) (see [below for nested schema](#nestedatt--snap_sets)) +- `stateless_sep_id` (Number) +- `stateless_sep_type` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vgpus` (List of Object) List of virtual GPUs (see [below for nested schema](#nestedatt--vgpus)) +- `virtual_image_name` (String) +- `vnc_password` (String) + + +### Nested Schema for `affinity_rules` + +Required: + +- `key` (String) key that are taken into account when analyzing this rule will be identified +- `mode` (String) EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key' +- `policy` (String) RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule +- `topology` (String) compute or node, for whom rule applies +- `value` (String) value that must match the key to be taken into account when analyzing this rule + + + +### Nested Schema for `anti_affinity_rules` + +Required: + +- `key` (String) key that are taken into account when analyzing this rule will be identified +- `mode` (String) EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key' +- `policy` (String) RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule +- `topology` (String) compute or node, for whom rule applies +- `value` (String) value that must match the key to be taken into account when analyzing this rule + + + +### Nested Schema for `cd` + +Required: + +- `cdrom_id` (Number) + + + +### Nested Schema for `disks` + +Required: + +- `disk_name` (String) Name for disk +- `size` (Number) Disk size in GiB +- `storage_policy_id` (Number) Storage policy id of disk. The rules of the specified storage policy will be used. + +Optional: + +- `blk_discard` (Boolean) +- `block_size` (String) Disk block size +- `cache` (String) Setting the disk caching mode +- `desc` (String) Optional description +- `image_id` (Number) Specify image id for create disk from template +- `iotune` (Block List, Max: 1) (see [below for nested schema](#nestedblock--disks--iotune)) +- `node_ids` (Set of Number) +- `permanently` (Boolean) Disk deletion status +- `pool` (String) Pool name; by default will be chosen automatically +- `sep_id` (Number) Storage endpoint provider ID; by default the same with boot disk + +Read-Only: + +- `bus_number` (Number) Bus number of the disk on virtual bus (6 = boot disk) +- `create_by` (String) +- `create_time` (Number) +- `delete_by` (String) +- `delete_time` (Number) +- `devicename` (String) +- `disk_id` (Number) Disk ID +- `independent` (Boolean) +- `pci_slot` (Number) PCI slot number of the disk +- `present_to` (Map of Number) +- `provision` (String) +- `shareable` (Boolean) +- `size_max` (Number) +- `size_used` (Number) +- `to_clean` (Boolean) +- `update_time` (Number) + + +### Nested Schema for `disks.iotune` + +Optional: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + + +### Nested Schema for `libvirt_settings` + +Required: + +- `net_id` (Number) ID of the network +- `net_type` (String) Type of the network + +Optional: + +- `event_idx` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `network` + +Required: + +- `net_id` (Number) ID of the network for this connection. +- `net_type` (String) Type of the network for this connection + +Optional: + +- `enabled` (Boolean) network enable flag +- `ip_address` (String) Optional IP address to assign to this connection. This IP should belong to the selected network and free for use. +- `mac` (String) MAC address associated with this connection. MAC address is assigned automatically. +- `mtu` (Number) Maximum transmission unit, used only for DPDK type, must be 1500-9216 +- `net_mask` (Number) Subnet mask, used only for DPDK and VFNIC network types +- `sdn_interface_id` (String) unique_identifier of LogicalPort on SDN side +- `weight` (Number) weight the network if you need to sort network list, the smallest attach first. zero or null weight attach last + + + +### Nested Schema for `port_forwarding` + +Required: + +- `proto` (String) +- `public_port_start` (Number) + +Optional: + +- `local_port` (Number) +- `public_port_end` (Number) + +Read-Only: + +- `rule_id` (Number) + + + +### Nested Schema for `rollback` + +Required: + +- `label` (String) + + + +### Nested Schema for `security_groups` + +Required: + +- `net_id` (Number) ID of the network +- `net_type` (String) Type of the network +- `security_groups` (Set of Number) + +Optional: + +- `enable_secgroups` (Boolean) + + + +### Nested Schema for `snapshot` + +Required: + +- `label` (String) + + + +### Nested Schema for `tags` + +Required: + +- `key` (String) +- `value` (String) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `user_access` + +Required: + +- `access_type` (String) +- `username` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flip_group_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_type` (String) +- `netmask` (Number) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `trunk_tags` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `loader_meta_iso` + +Read-Only: + +- `device_name` (String) +- `path` (String) + + + +### Nested Schema for `os_users` + +Read-Only: + +- `guid` (String) +- `login` (String) +- `password` (String) +- `public_key` (String) + + + +### Nested Schema for `snap_sets` + +Read-Only: + +- `disks` (List of Number) +- `guid` (String) +- `label` (String) +- `timestamp` (Number) + + + +### Nested Schema for `vgpus` + +Read-Only: + +- `account_id` (Number) +- `bus_number` (Number) +- `created_time` (Number) +- `deleted_time` (Number) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `last_claimed_by` (Number) +- `last_update_time` (Number) +- `mode` (String) +- `pci_slot` (Number) +- `pgpuid` (Number) +- `profile_id` (Number) +- `ram` (Number) +- `reference_id` (String) +- `rg_id` (Number) +- `status` (String) +- `type` (String) +- `vmid` (Number) diff --git a/docs/resources/cb_lb.md b/docs/resources/cb_lb.md new file mode 100644 index 00000000..ab6da12b --- /dev/null +++ b/docs/resources/cb_lb.md @@ -0,0 +1,180 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_lb Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_lb (Resource) + + + + + + +## Schema + +### Required + +- `name` (String) +- `rg_id` (Number) + +### Optional + +- `config_reset` (Boolean) +- `desc` (String) +- `enable` (Boolean) +- `extnet_id` (Number) +- `ha_mode` (Boolean) +- `permanently` (Boolean) +- `restart` (Boolean) +- `restore` (Boolean) +- `safe` (Boolean) +- `start` (Boolean) +- `sysctl_params` (List of Map of String) Custom sysctl values for Load Balancer instance. Applied on boot +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) +- `zone_id` (Number) + +### Read-Only + +- `acl` (String) +- `backend_haip` (String) +- `backends` (List of Object) (see [below for nested schema](#nestedatt--backends)) +- `ckey` (String) +- `dp_api_password` (String) +- `dp_api_user` (String) +- `frontend_haip` (String) +- `frontends` (List of Object) (see [below for nested schema](#nestedatt--frontends)) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `lb_id` (Number) +- `manager_id` (Number) +- `manager_type` (String) +- `meta` (List of String) +- `milestones` (Number) +- `part_k8s` (Boolean) +- `primary_node` (List of Object) (see [below for nested schema](#nestedatt--primary_node)) +- `secondary_node` (List of Object) (see [below for nested schema](#nestedatt--secondary_node)) +- `status` (String) +- `tech_status` (String) +- `user_managed` (Boolean) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `backends` + +Read-Only: + +- `algorithm` (String) +- `guid` (String) +- `name` (String) +- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--backends--server_default_settings)) +- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--backends--servers)) + + +### Nested Schema for `backends.server_default_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + +### Nested Schema for `backends.servers` + +Read-Only: + +- `address` (String) +- `check` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--backends--servers--server_settings)) + + +### Nested Schema for `backends.servers.server_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + + + +### Nested Schema for `frontends` + +Read-Only: + +- `backend` (String) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--frontends--bindings)) +- `guid` (String) +- `name` (String) + + +### Nested Schema for `frontends.bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) + + + + +### Nested Schema for `primary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) + + + +### Nested Schema for `secondary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) diff --git a/docs/resources/cb_lb_backend.md b/docs/resources/cb_lb_backend.md new file mode 100644 index 00000000..afe7d7fc --- /dev/null +++ b/docs/resources/cb_lb_backend.md @@ -0,0 +1,86 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_lb_backend Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_lb_backend (Resource) + + + + + + +## Schema + +### Required + +- `lb_id` (Number) ID of the LB instance to backendCreate +- `name` (String) Must be unique among all backends of this LB - name of the new backend to create + +### Optional + +- `algorithm` (String) +- `downinter` (Number) +- `fall` (Number) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `servers` (Block List) (see [below for nested schema](#nestedblock--servers)) +- `slowstart` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `weight` (Number) + +### Read-Only + +- `guid` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `servers` + +Optional: + +- `address` (String) +- `check` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (Block List) (see [below for nested schema](#nestedblock--servers--server_settings)) + +Read-Only: + +- `guid` (String) + + +### Nested Schema for `servers.server_settings` + +Optional: + +- `downinter` (Number) +- `fall` (Number) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + +Read-Only: + +- `guid` (String) + + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_lb_backend_server.md b/docs/resources/cb_lb_backend_server.md new file mode 100644 index 00000000..e1a52ce1 --- /dev/null +++ b/docs/resources/cb_lb_backend_server.md @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_lb_backend_server Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_lb_backend_server (Resource) + + + + + + +## Schema + +### Required + +- `address` (String) IP address of the server. +- `backend_name` (String) Must be unique among all backends of this LB - name of the new backend to create +- `lb_id` (Number) ID of the LB instance to backendCreate +- `name` (String) Must be unique among all servers defined for this backend - name of the server definition to add. +- `port` (Number) Port number on the server + +### Optional + +- `check` (String) set to disabled if this server should be used regardless of its state. +- `downinter` (Number) +- `fall` (Number) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `weight` (Number) + +### Read-Only + +- `guid` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_lb_frontend.md b/docs/resources/cb_lb_frontend.md new file mode 100644 index 00000000..a5e83acf --- /dev/null +++ b/docs/resources/cb_lb_frontend.md @@ -0,0 +1,54 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_lb_frontend Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_lb_frontend (Resource) + + + + + + +## Schema + +### Required + +- `backend_name` (String) +- `lb_id` (Number) ID of the LB instance to backendCreate +- `name` (String) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `bindings` (List of Object) (see [below for nested schema](#nestedatt--bindings)) +- `guid` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) diff --git a/docs/resources/cb_lb_frontend_bind.md b/docs/resources/cb_lb_frontend_bind.md new file mode 100644 index 00000000..2b473902 --- /dev/null +++ b/docs/resources/cb_lb_frontend_bind.md @@ -0,0 +1,44 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_lb_frontend_bind Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_lb_frontend_bind (Resource) + + + + + + +## Schema + +### Required + +- `address` (String) +- `frontend_name` (String) Must be unique among all backends of this LB - name of the new backend to create +- `lb_id` (Number) ID of the LB instance to backendCreate +- `name` (String) +- `port` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `guid` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_multi_image.md b/docs/resources/cb_multi_image.md new file mode 100644 index 00000000..78dded85 --- /dev/null +++ b/docs/resources/cb_multi_image.md @@ -0,0 +1,104 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_multi_image Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_multi_image (Resource) + + + + + + +## Schema + +### Required + +- `name` (String) Name of the multi image +- `target_ids` (List of Number) IDs of real images to link this multi image to + +### Optional + +- `account_id` (Number) Account id to make the image exclusive +- `bootable` (Boolean) Does this image boot OS +- `computeci_id` (Number) +- `enabled` (Boolean) +- `hot_resize` (Boolean) Does this machine supports hot resize +- `password` (String) Optional password for the image +- `shared_with` (List of Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `username` (String) Optional username for the image + +### Read-Only + +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `architecture` (String) +- `boot_type` (String) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `image_type` (String) +- `independent` (Boolean) +- `last_modified` (Number) +- `link_to` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `pool_name` (String) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `reference_id` (String) +- `res_id` (String) +- `res_name` (String) +- `rescuecd` (Boolean) +- `sep_id` (Number) +- `size` (Number) +- `snapshot_id` (String) +- `status` (String) +- `tech_status` (String) +- `to_clean` (Boolean) +- `unc_path` (String) unc path +- `url` (String) +- `version` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/resources/cb_pcidevice.md b/docs/resources/cb_pcidevice.md new file mode 100644 index 00000000..5509840e --- /dev/null +++ b/docs/resources/cb_pcidevice.md @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_pcidevice Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_pcidevice (Resource) + + + + + + +## Schema + +### Required + +- `hw_path` (String) PCI address of the device +- `name` (String) Name of Device +- `node_id` (Number) Node ID +- `rg_id` (Number) Resource GROUP + +### Optional + +- `description` (String) description, just for information +- `device_id` (Number) +- `enable` (Boolean) Enable pci device +- `force_delete` (Boolean) Force delete +- `force_disable` (Boolean) Force disable +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `ckey` (String) +- `compute_id` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `meta` (List of String) +- `status` (String) +- `system_name` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_rg.md b/docs/resources/cb_rg.md new file mode 100644 index 00000000..172b8a1a --- /dev/null +++ b/docs/resources/cb_rg.md @@ -0,0 +1,152 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_rg Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_rg (Resource) + + + + + + +## Schema + +### Required + +- `account_id` (Number) Unique ID of the account, which this resource group belongs to. +- `gid` (Number) Unique ID of the grid, where this resource group is deployed. +- `rg_name` (String) Name of this resource group. Names are case sensitive and unique within the context of a account. + +### Optional + +- `access` (Block Set) (see [below for nested schema](#nestedblock--access)) +- `compute_features` (Set of String) +- `cpu_allocation_parameter` (String) set cpu allocation parameter +- `cpu_allocation_ratio` (Number) set cpu allocation ratio +- `def_net` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--def_net)) +- `def_net_type` (String) Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE. +- `description` (String) User-defined text description of this resource group. +- `enable` (Boolean) enable/disable rg +- `ext_ip` (String) IP address on the external netowrk to request when def_net_type=PRIVATE and ext_net_id is not 0 +- `ext_net_id` (Number) ID of the external network for default ViNS. Pass 0 if def_net_type=PUBLIC or no external connection required for the defult ViNS when def_net_type=PRIVATE +- `force` (Boolean) flag to force deleting resource group +- `ipcidr` (String) Address of the netowrk inside the private network segment (aka ViNS) if def_net_type=PRIVATE +- `owner` (String) username - owner of this RG. Leave blank to set current user as owner +- `permanently` (Boolean) flag to permanently delete resource group +- `resource_limits` (Block List, Max: 1) (see [below for nested schema](#nestedblock--resource_limits)) +- `restore` (Boolean) restore deleted rg +- `sdn_access_group_id` (String) ID of the SDN access group +- `storage_policy` (Block Set) (see [below for nested schema](#nestedblock--storage_policy)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `uniq_pools` (List of String) + +### Read-Only + +- `account_name` (String) Name of the account, which this resource group belongs to. +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `created_by` (String) +- `created_time` (Number) +- `def_net_id` (Number) ID of the default network for this resource group (if any). +- `deleted_by` (String) +- `deleted_time` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `lock_status` (String) +- `milestones` (Number) +- `resource_types` (List of String) +- `rg_id` (Number) +- `secret` (String) +- `status` (String) Current status of this resource group. +- `storage_policy_ids` (List of Number) +- `updated_by` (String) +- `updated_time` (Number) +- `vins` (List of Number) List of VINs deployed in this resource group. +- `vms` (List of Number) List of VM ids in this resource group. + + +### Nested Schema for `access` + +Required: + +- `right` (String) Access rights to set, one of 'R', 'RCX' or 'ARCXDU' +- `user` (String) User or group name to grant access + + + +### Nested Schema for `def_net` + +Required: + +- `net_type` (String) Network type to set. Must be on of 'PRIVATE' or 'PUBLIC'. + +Optional: + +- `net_id` (Number) Network segment ID. If netType is PUBLIC and netId is 0 then default external network segment will be selected. If netType is PRIVATE and netId=0, the first ViNS defined for this RG will be selected. Otherwise, netId identifies either existing external network segment or ViNS. + + + +### Nested Schema for `resource_limits` + +Optional: + +- `cu_c` (Number) MaxCPUCapacity +- `cu_dm` (Number) MaxVDiskCapacity +- `cu_i` (Number) MaxNumPublicIP +- `cu_m` (Number) MaxMemoryCapacity + +Read-Only: + +- `cu_d` (Number) +- `gpu_units` (Number) +- `storage_policy` (Set of Object) (see [below for nested schema](#nestedatt--resource_limits--storage_policy)) + + +### Nested Schema for `resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) + + + + +### Nested Schema for `storage_policy` + +Required: + +- `id` (Number) + +Optional: + +- `limit` (Number) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `email` (String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) diff --git a/docs/resources/cb_security_group.md b/docs/resources/cb_security_group.md new file mode 100644 index 00000000..119b871b --- /dev/null +++ b/docs/resources/cb_security_group.md @@ -0,0 +1,67 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_security_group Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_security_group (Resource) + + + + + + +## Schema + +### Required + +- `account_id` (Number) +- `name` (String) + +### Optional + +- `description` (String) +- `rules` (Block Set) (see [below for nested schema](#nestedblock--rules)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `created_at` (Number) +- `created_by` (String) +- `id` (String) The ID of this resource. +- `security_group_id` (Number) +- `updated_at` (Number) +- `updated_by` (String) + + +### Nested Schema for `rules` + +Required: + +- `direction` (String) + +Optional: + +- `ethertype` (String) +- `port_range_max` (Number) +- `port_range_min` (Number) +- `protocol` (String) +- `remote_ip_prefix` (String) + +Read-Only: + +- `id` (Number) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_sep.md b/docs/resources/cb_sep.md new file mode 100644 index 00000000..cd5f86c3 --- /dev/null +++ b/docs/resources/cb_sep.md @@ -0,0 +1,94 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_sep Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_sep (Resource) + + + + + + +## Schema + +### Required + +- `config` (String) sep config string +- `gid` (Number) grid (platform) ID +- `name` (String) SEP name +- `type` (String) type of storage + +### Optional + +- `access_to_pool` (Block Set, Max: 1) grant or revoke access to pool (see [below for nested schema](#nestedblock--access_to_pool)) +- `account_ids` (Set of Number) lift of account ids to have access to sep +- `consumed_by` (Set of Number) list of consumer nodes IDs +- `desc` (String) sep description +- `enable` (Boolean) enable SEP after creation +- `pools` (Block Set) add/delete pools to/from sep (see [below for nested schema](#nestedblock--pools)) +- `provided_by` (List of Number) list of provider nodes IDs +- `sep_id` (Number) sep type des id +- `shared_with` (List of Number) list of shared with ids +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `guid` (Number) guid +- `id` (String) The ID of this resource. +- `milestones` (Number) milestones +- `multipath_num` (Number) multipath_num +- `obj_status` (String) object status +- `tech_status` (String) tech status + + +### Nested Schema for `access_to_pool` + +Required: + +- `pool_name` (String) pool name +- `rg_id` (Number) resource group id to grant/revoke access to the specified pool sep + +Optional: + +- `account_id_pool` (Number) account id to grant/revoke access to the specified pool sep + + + +### Nested Schema for `pools` + +Required: + +- `access_account_ids` (List of Number) access account ids +- `access_res_group_ids` (List of Number) access res group ids +- `usage_limit` (Number) usage limit + +Optional: + +- `name` (String) name +- `types` (List of String) types +- `uris` (Block Set) uris (see [below for nested schema](#nestedblock--pools--uris)) + + +### Nested Schema for `pools.uris` + +Required: + +- `ip` (String) ip +- `port` (Number) port + + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_sep_config.md b/docs/resources/cb_sep_config.md new file mode 100644 index 00000000..05ad8b71 --- /dev/null +++ b/docs/resources/cb_sep_config.md @@ -0,0 +1,51 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_sep_config Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_sep_config (Resource) + + + + + + +## Schema + +### Required + +- `sep_id` (Number) sep id + +### Optional + +- `config` (String) config json string +- `field_edit` (Block List, Max: 1) (see [below for nested schema](#nestedblock--field_edit)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. + + +### Nested Schema for `field_edit` + +Required: + +- `field_name` (String) field name +- `field_type` (String) field type +- `field_value` (String) field value + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_storage_policy.md b/docs/resources/cb_storage_policy.md new file mode 100644 index 00000000..9a7e83d2 --- /dev/null +++ b/docs/resources/cb_storage_policy.md @@ -0,0 +1,69 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_storage_policy Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_storage_policy (Resource) + + + + + + +## Schema + +### Required + +- `access_seps_pools` (Block Set, Min: 1) (see [below for nested schema](#nestedblock--access_seps_pools)) +- `name` (String) + +### Optional + +- `description` (String) +- `enabled` (Boolean) +- `limit_iops` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `guid` (Number) +- `id` (String) The ID of this resource. +- `status` (String) +- `usage` (List of Object) (see [below for nested schema](#nestedatt--usage)) + + +### Nested Schema for `access_seps_pools` + +Required: + +- `pool_name` (String) +- `sep_id` (Number) + +Read-Only: + +- `sep_name` (String) +- `sep_tech_status` (String) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `usage` + +Read-Only: + +- `accounts` (List of Number) +- `resgroups` (List of Number) diff --git a/docs/resources/cb_trunk.md b/docs/resources/cb_trunk.md new file mode 100644 index 00000000..efedbab2 --- /dev/null +++ b/docs/resources/cb_trunk.md @@ -0,0 +1,56 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_trunk Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_trunk (Resource) + + + + + + +## Schema + +### Required + +- `name` (String) Name of the trunk +- `ovs_bridge` (String) OVS bridge name +- `trunk_tags` (String) List of trunk tags (values between 1-4095) + +### Optional + +- `account_ids` (Set of Number) List of account IDs with access to this trunk +- `description` (String) Description of the trunk +- `enable` (Boolean) Whether the trunk should be enabled +- `mtu` (Number) Maximum Transmission Unit +- `native_vlan_id` (Number) Native VLAN ID +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `created_at` (Number) when the trunk was created +- `created_by` (String) who created the trunk +- `deleted_at` (Number) when the trunk was updated +- `deleted_by` (String) who updated the trunk +- `guid` (Number) GUID +- `id` (String) The ID of this resource. +- `mac` (String) MAC address +- `status` (String) if the trunk is enabled +- `trunk_id` (Number) trunk id +- `updated_at` (Number) when the trunk was updated +- `updated_by` (String) who updated the trunk + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_user.md b/docs/resources/cb_user.md new file mode 100644 index 00000000..6ea73466 --- /dev/null +++ b/docs/resources/cb_user.md @@ -0,0 +1,61 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_user Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_user (Resource) + + + + + + +## Schema + +### Required + +- `emailaddress` (String) email address of the user +- `username` (String) ID of user + +### Optional + +- `apiaccess` (Set of Number) list of apiaccess groups this user belongs to +- `blocked` (Boolean) is the user blocked +- `password` (String) password of user +- `provider_name` (String) provider +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `active` (Boolean) active +- `auth_keys` (List of String) authkeys +- `authkey` (String) authkey +- `ckey` (String) ckey +- `data` (String) data +- `description` (String) description +- `domain` (String) domain +- `gid` (Number) gid +- `groups` (List of String) list of groups this user belongs to +- `guid` (String) guid +- `id` (String) The ID of this resource. +- `last_check` (Number) last_check +- `meta` (List of String) meta +- `mobile` (List of String) mobile +- `protected` (Boolean) protected +- `roles` (List of String) roles +- `service_account` (Boolean) service_account +- `xmpp` (List of String) xmpp + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_vfpool.md b/docs/resources/cb_vfpool.md new file mode 100644 index 00000000..dcdeb787 --- /dev/null +++ b/docs/resources/cb_vfpool.md @@ -0,0 +1,87 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vfpool Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vfpool (Resource) + + + + + + +## Schema + +### Required + +- `name` (String) Name of device + +### Optional + +- `account_access` (Set of Number) List of account IDs +- `config` (Block Set) List of dict describing configuration data (see [below for nested schema](#nestedblock--config)) +- `description` (String) Description +- `enable` (Boolean) +- `rg_access` (Set of Number) List of RG IDs +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `created_time` (Number) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `status` (String) +- `updated_time` (Number) +- `vfpool_id` (Number) +- `vfs` (List of Object) (see [below for nested schema](#nestedatt--vfs)) + + +### Nested Schema for `config` + +Required: + +- `nic_name` (String) +- `node_id` (Number) +- `vf_ids` (List of Number) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `vfs` + +Read-Only: + +- `node_id` (Number) +- `vf_list` (List of Object) (see [below for nested schema](#nestedobjatt--vfs--vf_list)) + + +### Nested Schema for `vfs.vf_list` + +Read-Only: + +- `nic_name` (String) +- `vfs_info` (List of Object) (see [below for nested schema](#nestedobjatt--vfs--vf_list--vfs_info)) + + +### Nested Schema for `vfs.vf_list.vfs_info` + +Read-Only: + +- `claimed` (Boolean) +- `id` (Number) +- `vm_id` (Number) diff --git a/docs/resources/cb_vins.md b/docs/resources/cb_vins.md new file mode 100644 index 00000000..def08bee --- /dev/null +++ b/docs/resources/cb_vins.md @@ -0,0 +1,516 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins (Resource) + + + + + + +## Schema + +### Required + +- `name` (String) name + +### Optional + +- `account_id` (Number) +- `default_qos` (Block List) default qoa (see [below for nested schema](#nestedblock--default_qos)) +- `description` (String) Optional user-defined text description of this ViNS. +- `dns` (Set of String) +- `enable` (Boolean) enable for enable/disable requests +- `enable_secgroups` (Boolean) enable security groups +- `ext_ip` (String) +- `ext_net_id` (Number) +- `force` (Boolean) force for delete request +- `gid` (Number) +- `ip` (Block List) (see [below for nested schema](#nestedblock--ip)) +- `ipcidr` (String) +- `nat_rule` (Block List) (see [below for nested schema](#nestedblock--nat_rule)) +- `permanently` (Boolean) permanently for delete request +- `pre_reservations_num` (Number) +- `rg_id` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) vins id +- `vnfdev_redeploy` (Boolean) +- `vnfdev_reset` (Boolean) +- `vnfdev_restart` (Boolean) +- `vnfdev_start` (Boolean) true to start vnfdev, false to stop vnfdev +- `zone_id` (Number) zone id + +### Read-Only + +- `account_name` (String) account name +- `created_by` (String) created by +- `created_time` (Number) created time +- `default_gw` (String) default gw +- `deleted_by` (String) deleted by +- `deleted_time` (Number) deleted time +- `guid` (Number) guid +- `id` (String) The ID of this resource. +- `lock_status` (String) lock status +- `manager_id` (Number) manager id +- `manager_type` (String) manager type +- `milestones` (Number) milestones +- `netmask` (Number) net mask +- `network` (String) network +- `redundant` (Boolean) redundant +- `rg_name` (String) resource group name +- `routes` (Block List) (see [below for nested schema](#nestedblock--routes)) +- `sec_vnf_dev_id` (Number) +- `status` (String) status +- `updated_by` (String) updated by +- `updated_time` (Number) updated time +- `user_managed` (Boolean) user managed +- `vnf_dev` (List of Object) vnf dev (see [below for nested schema](#nestedatt--vnf_dev)) +- `vnfs` (List of Object) vnfs (see [below for nested schema](#nestedatt--vnfs)) +- `vxlan_id` (Number) vxlan id + + +### Nested Schema for `default_qos` + +Optional: + +- `e_rate` (Number) +- `in_burst` (Number) +- `in_rate` (Number) + +Read-Only: + +- `guid` (String) + + + +### Nested Schema for `ip` + +Required: + +- `type` (String) + +Optional: + +- `compute_id` (Number) +- `ip_addr` (String) +- `mac` (String) + + + +### Nested Schema for `nat_rule` + +Required: + +- `ext_port_start` (Number) +- `int_ip` (String) + +Optional: + +- `ext_port_end` (Number) +- `int_port` (Number) +- `proto` (String) + +Read-Only: + +- `rule_id` (Number) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) + + + +### Nested Schema for `vnf_dev` + +Read-Only: + +- `account_id` (Number) +- `capabilities` (List of String) +- `ckey` (String) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config)) +- `config_saved` (Boolean) +- `custom_precfg` (Boolean) +- `description` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces)) +- `live_migration_job_id` (Number) +- `lock_status` (String) +- `meta` (List of String) +- `milestones` (Number) +- `name` (String) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `vins` (List of Number) +- `vnc_password` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnf_dev.config` + +Read-Only: + +- `mgmt` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config--mgmt)) +- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config--resources)) + + +### Nested Schema for `vnf_dev.config.mgmt` + +Read-Only: + +- `ip_addr` (String) +- `password` (String) +- `ssh_key` (String) +- `user` (String) + + + +### Nested Schema for `vnf_dev.config.resources` + +Read-Only: + +- `cpu` (Number) +- `node_id` (Number) +- `ram` (Number) +- `uuid` (String) + + + + +### Nested Schema for `vnf_dev.interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flipgroup_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_mask` (Number) +- `net_type` (String) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `vnf_dev.interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `vnf_dev.interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_burst` (Number) +- `in_rate` (Number) + + + + + +### Nested Schema for `vnfs` + +Read-Only: + +- `dhcp` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp)) +- `gw` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw)) +- `nat` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat)) + + +### Nested Schema for `vnfs.dhcp` + +Read-Only: + +- `account_id` (Number) +- `ckey` (String) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--devices)) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `lock_status` (String) +- `meta` (List of String) +- `milestones` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.dhcp.config` + +Read-Only: + +- `default_gw` (String) +- `dns` (List of String) +- `ip_end` (String) +- `ip_start` (String) +- `lease` (Number) +- `net_mask` (Number) +- `network` (String) +- `reservations` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--config--reservations)) + + +### Nested Schema for `vnfs.dhcp.config.reservations` + +Read-Only: + +- `account_id` (Number) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + + +### Nested Schema for `vnfs.dhcp.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--devices--primary)) + + +### Nested Schema for `vnfs.dhcp.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.dhcp.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) + + + + +### Nested Schema for `vnfs.gw` + +Read-Only: + +- `account_id` (Number) +- `ckey` (String) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--devices)) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `lock_status` (String) +- `meta` (List of String) +- `milestones` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.gw.config` + +Read-Only: + +- `default_gw` (String) +- `ext_net_id` (Number) +- `ext_net_ip` (String) +- `ext_netmask` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--config--qos)) + + +### Nested Schema for `vnfs.gw.config.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_burst` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `vnfs.gw.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--devices--primary)) + + +### Nested Schema for `vnfs.gw.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.gw.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) + + + + +### Nested Schema for `vnfs.nat` + +Read-Only: + +- `account_id` (Number) +- `ckey` (String) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--devices)) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `lock_status` (String) +- `meta` (List of String) +- `milestones` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.nat.config` + +Read-Only: + +- `net_mask` (Number) +- `network` (String) +- `rules` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--config--rules)) + + +### Nested Schema for `vnfs.nat.config.rules` + +Read-Only: + +- `local_ip` (String) +- `local_port` (Number) +- `protocol` (String) +- `public_port_end` (Number) +- `public_port_start` (Number) +- `rule_id` (Number) +- `vm_id` (Number) +- `vm_name` (String) + + + + +### Nested Schema for `vnfs.nat.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--devices--primary)) + + +### Nested Schema for `vnfs.nat.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.nat.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) diff --git a/docs/resources/cb_vins_static_route.md b/docs/resources/cb_vins_static_route.md new file mode 100644 index 00000000..287722e3 --- /dev/null +++ b/docs/resources/cb_vins_static_route.md @@ -0,0 +1,45 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_vins_static_route Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_vins_static_route (Resource) + + + + + + +## Schema + +### Required + +- `destination` (String) +- `gateway` (String) +- `netmask` (String) +- `vins_id` (Number) Unique ID of the ViNS + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `compute_ids` (List of Number) +- `guid` (String) +- `id` (String) The ID of this resource. +- `route_id` (Number) Unique ID of the static route + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/cb_virtual_image.md b/docs/resources/cb_virtual_image.md new file mode 100644 index 00000000..75f5e637 --- /dev/null +++ b/docs/resources/cb_virtual_image.md @@ -0,0 +1,102 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_virtual_image Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_virtual_image (Resource) + + + + + + +## Schema + +### Required + +- `link_to` (Number) ID of real image to link this virtual image to upon creation +- `name` (String) Name of the rescue disk + +### Optional + +- `account_id` (Number) AccountId to make the image exclusive +- `bootable` (Boolean) Does this image boot OS +- `computeci_id` (Number) +- `enabled` (Boolean) +- `hot_resize` (Boolean) Does this machine supports hot resize +- `password` (String) Optional password for the image +- `shared_with` (List of Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `username` (String) Optional username for the image + +### Read-Only + +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `architecture` (String) binary architecture of this image, one of X86_64 +- `boot_type` (String) Boot type of image bios or uefi +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) List of types of compute suitable for image. Example: [ "KVM_X86" ] +- `gid` (Number) grid (platform) ID where this template should be create in +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `id` (String) The ID of this resource. +- `image_id` (Number) Image id +- `image_type` (String) Image type linux, windows or other +- `independent` (Boolean) +- `last_modified` (Number) +- `milestones` (Number) +- `pool_name` (String) pool for image create +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `reference_id` (String) +- `res_id` (String) +- `res_name` (String) +- `rescuecd` (Boolean) +- `sep_id` (Number) storage endpoint provider ID +- `size` (Number) image size +- `snapshot_id` (String) snapshot id +- `status` (String) status +- `tech_status` (String) tech atatus +- `to_clean` (Boolean) +- `unc_path` (String) unc path +- `url` (String) URL where to download media from +- `version` (String) version + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/resources/cb_zone.md b/docs/resources/cb_zone.md new file mode 100644 index 00000000..cbef45f7 --- /dev/null +++ b/docs/resources/cb_zone.md @@ -0,0 +1,60 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_cb_zone Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_cb_zone (Resource) + + + + + + +## Schema + +### Required + +- `name` (String) + +### Optional + +- `auto_start` (Boolean) +- `description` (String) +- `drs` (Boolean) +- `node_ids` (List of Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `app_id` (String) +- `broadcast_addr` (String) +- `created_time` (Number) +- `decort_url` (String) +- `deletable` (Boolean) +- `domain` (String) +- `drs_name` (String) +- `drs_uid` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `ping_addr` (String) +- `ssl_skip_verify` (Boolean) +- `sso_type` (String) +- `sso_url` (String) +- `status` (String) +- `updated_time` (Number) +- `zone_id` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/disk.md b/docs/resources/disk.md new file mode 100644 index 00000000..e270e66f --- /dev/null +++ b/docs/resources/disk.md @@ -0,0 +1,143 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_disk Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_disk (Resource) + + + + + + +## Schema + +### Required + +- `account_id` (Number) The unique ID of the subscriber-owner of the disk +- `disk_name` (String) Name of disk +- `size_max` (Number) Size in GB +- `storage_policy_id` (Number) ID storage policy under which the disk will be created + +### Optional + +- `desc` (String) Description of disk +- `detach` (Boolean) Detaching the disk from compute +- `iotune` (Block List, Max: 1) (see [below for nested schema](#nestedblock--iotune)) +- `permanently` (Boolean) Whether to completely delete the disk, works only with non attached disks +- `pool` (String) Pool for disk location +- `sep_id` (Number) Storage endpoint provider ID to create disk +- `shareable` (Boolean) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_name` (String) The name of the subscriber '(account') to whom this disk belongs +- `acl` (String) +- `blk_discard` (Boolean) Flag indicating whether blk-discard is enabled for the disk +- `block_size` (String) +- `cache` (String) +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `created_by` (String) +- `created_time` (Number) Created time +- `deleted_by` (String) +- `deleted_time` (Number) Deleted time +- `destruction_time` (Number) Time of final deletion +- `devicename` (String) Name of the device +- `disk_id` (Number) Disk ID. Duplicates the value of the ID parameter +- `gid` (Number) ID of the grid (platform) +- `id` (String) The ID of this resource. +- `image_id` (Number) Image ID +- `images` (List of Number) IDs of images using the disk +- `independent` (Boolean) +- `machine_id` (Number) +- `machine_name` (String) +- `order` (Number) Disk order +- `params` (String) Disk params +- `parent_id` (Number) ID of the parent disk +- `pci_slot` (Number) ID of the pci slot to which the disk is connected +- `present_to` (Map of Number) +- `provision` (String) +- `purge_time` (Number) Time of the last deletion attempt +- `replication` (List of Object) Replication status (see [below for nested schema](#nestedatt--replication)) +- `res_id` (String) Resource ID +- `res_name` (String) Name of the resource +- `role` (String) Disk role +- `sep_type` (String) Type SEP. Defines the type of storage system and contains one of the values set in the cloud platform +- `size_used` (Number) Number of used space, in GB +- `snapshots` (List of Object) (see [below for nested schema](#nestedatt--snapshots)) +- `status` (String) Disk status +- `tech_status` (String) Technical status of the disk +- `to_clean` (Boolean) +- `updated_by` (String) +- `updated_time` (Number) +- `vmid` (Number) Virtual Machine ID (Deprecated) + + +### Nested Schema for `iotune` + +Optional: + +- `read_bytes_sec` (Number) Number of bytes to read per second +- `read_bytes_sec_max` (Number) Maximum number of bytes to read +- `read_iops_sec` (Number) Number of io read operations per second +- `read_iops_sec_max` (Number) Maximum number of io read operations +- `size_iops_sec` (Number) Size of io operations +- `total_bytes_sec` (Number) Total size bytes per second +- `total_bytes_sec_max` (Number) Maximum total size of bytes per second +- `total_iops_sec` (Number) Total number of io operations per second +- `total_iops_sec_max` (Number) Maximum total number of io operations per second +- `write_bytes_sec` (Number) Number of bytes to write per second +- `write_bytes_sec_max` (Number) Maximum number of bytes to write per second +- `write_iops_sec` (Number) Number of write operations per second +- `write_iops_sec_max` (Number) Maximum number of write operations per second + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `compute_id` (String) +- `compute_name` (String) + + + +### Nested Schema for `replication` + +Read-Only: + +- `disk_id` (Number) +- `pool_id` (String) +- `role` (String) +- `self_volume_id` (String) +- `storage_id` (String) +- `volume_id` (String) + + + +### Nested Schema for `snapshots` + +Read-Only: + +- `guid` (String) +- `label` (String) +- `res_id` (String) +- `snap_set_guid` (String) +- `snap_set_time` (Number) +- `timestamp` (Number) diff --git a/docs/resources/disk_snapshot.md b/docs/resources/disk_snapshot.md new file mode 100644 index 00000000..5d34737d --- /dev/null +++ b/docs/resources/disk_snapshot.md @@ -0,0 +1,46 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_disk_snapshot Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_disk_snapshot (Resource) + + + + + + +## Schema + +### Required + +- `disk_id` (Number) The unique ID of the subscriber-owner of the disk +- `label` (String) Name of the snapshot + +### Optional + +- `rollback` (Boolean) Needed in order to make a snapshot rollback +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `timestamp` (Number) Snapshot time + +### Read-Only + +- `guid` (String) ID of the snapshot +- `id` (String) The ID of this resource. +- `res_id` (String) Reference to the snapshot +- `snap_set_guid` (String) The set snapshot ID +- `snap_set_time` (Number) The set time of the snapshot + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/flipgroup.md b/docs/resources/flipgroup.md new file mode 100644 index 00000000..cb297ce8 --- /dev/null +++ b/docs/resources/flipgroup.md @@ -0,0 +1,62 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_flipgroup Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_flipgroup (Resource) + + + + + + +## Schema + +### Required + +- `account_id` (Number) Account ID +- `name` (String) Flipgroup name +- `net_id` (Number) EXTNET or ViNS ID +- `net_type` (String) Network type, EXTNET or VINS + +### Optional + +- `client_ids` (List of Number) List of clients attached to this Flipgroup instance +- `client_type` (String) Type of client, 'compute' ('vins' will be later) +- `desc` (String) Text description of this Flipgroup instance +- `ip` (String) IP address to associate with this group. If empty, the platform will autoselect IP address +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `account_name` (String) +- `conn_id` (Number) +- `conn_type` (String) +- `created_by` (String) +- `created_time` (Number) +- `default_gw` (String) +- `deleted_by` (String) +- `deleted_time` (Number) +- `flipgroup_id` (Number) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `milestones` (Number) +- `network` (String) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/image.md b/docs/resources/image.md new file mode 100644 index 00000000..2e8ef282 --- /dev/null +++ b/docs/resources/image.md @@ -0,0 +1,95 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_image Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_image (Resource) + + + + + + +## Schema + +### Required + +- `account_id` (Number) AccountId to make the image exclusive +- `boot_type` (String) Boot type of image bios or uefi +- `name` (String) Name of the rescue disk +- `storage_policy_id` (Number) ID of the storage policy +- `type` (String) Image type linux, windows or unknown +- `url` (String) URL where to download media from + +### Optional + +- `hot_resize` (Boolean) Does this machine supports hot resize +- `image_id` (Number) image id +- `network_interface_naming` (String) select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming +- `password` (String) Optional password for the image +- `password_dl` (String) password for upload binary media +- `pool_name` (String) pool for image create +- `sep_id` (Number) storage endpoint provider ID +- `sync_mode` (Boolean) Create image from a media identified by URL (in synchronous mode) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `username` (String) Optional username for the image +- `username_dl` (String) username for upload binary media + +### Read-Only + +- `acl` (String) +- `architecture` (String) +- `bootable` (Boolean) +- `cd_presented_to` (String) +- `compute_ci_id` (Number) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `enabled` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `id` (String) The ID of this resource. +- `image_name` (String) +- `independent` (Boolean) +- `last_modified` (Number) +- `link_to` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `res_id` (String) +- `rescuecd` (Boolean) +- `shared_with` (List of Number) +- `size` (Number) +- `snapshot_id` (String) +- `status` (String) +- `tech_status` (String) +- `to_clean` (Boolean) +- `unc_path` (String) +- `version` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/resources/image_from_blank_compute.md b/docs/resources/image_from_blank_compute.md new file mode 100644 index 00000000..f6063b52 --- /dev/null +++ b/docs/resources/image_from_blank_compute.md @@ -0,0 +1,93 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_image_from_blank_compute Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_image_from_blank_compute (Resource) + + + + + + +## Schema + +### Required + +- `boot_type` (String) Boot type of image BIOS or UEFI +- `compute_id` (Number) Compute Id +- `name` (String) Name of the rescue disk +- `storage_policy_id` (Number) Storage policy ID +- `type` (String) Image type linux, windows or unknown + +### Optional + +- `account_id` (Number) AccountId to make the image exclusive +- `async_mode` (Boolean) create an image in async/sync mode +- `hot_resize` (Boolean) Does this machine supports hot resize +- `password` (String) Optional password for the image +- `pool_name` (String) pool for image create +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `username` (String) Optional username for the image + +### Read-Only + +- `acl` (String) +- `architecture` (String) +- `bootable` (Boolean) +- `cd_presented_to` (String) +- `ckey` (String) +- `compute_ci_id` (Number) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `enabled` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `image_name` (String) +- `last_modified` (Number) +- `link_to` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `network_interface_naming` (String) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `res_id` (String) +- `rescuecd` (Boolean) +- `sep_id` (Number) storage endpoint provider ID +- `shared_with` (List of Number) +- `size` (Number) +- `snapshot_id` (String) +- `status` (String) +- `tech_status` (String) +- `to_clean` (Boolean) +- `unc_path` (String) +- `version` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/resources/image_from_platform_disk.md b/docs/resources/image_from_platform_disk.md new file mode 100644 index 00000000..4b73410b --- /dev/null +++ b/docs/resources/image_from_platform_disk.md @@ -0,0 +1,92 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_image_from_platform_disk Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_image_from_platform_disk (Resource) + + + + + + +## Schema + +### Required + +- `boot_type` (String) Boot type of image BIOS or UEFI +- `disk_id` (Number) Disk Id +- `name` (String) Name of the rescue disk +- `type` (String) Image type linux, windows or unknown + +### Optional + +- `account_id` (Number) AccountId to make the image exclusive +- `async_mode` (Boolean) create an image in async/sync mode +- `bootable` (Boolean) bootable image +- `hot_resize` (Boolean) Does this machine supports hot resize +- `password` (String) Optional password for the image +- `pool_name` (String) pool for image create +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `username` (String) Optional username for the image + +### Read-Only + +- `acl` (String) +- `architecture` (String) +- `cd_presented_to` (String) +- `ckey` (String) +- `compute_ci_id` (Number) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `enabled` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `image_name` (String) +- `last_modified` (Number) +- `link_to` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `network_interface_naming` (String) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `res_id` (String) +- `rescuecd` (Boolean) +- `sep_id` (Number) storage endpoint provider ID +- `shared_with` (List of Number) +- `size` (Number) +- `snapshot_id` (String) +- `status` (String) +- `tech_status` (String) +- `to_clean` (Boolean) +- `unc_path` (String) +- `version` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/resources/image_virtual.md b/docs/resources/image_virtual.md new file mode 100644 index 00000000..e29ce402 --- /dev/null +++ b/docs/resources/image_virtual.md @@ -0,0 +1,91 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_image_virtual Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_image_virtual (Resource) + + + + + + +## Schema + +### Required + +- `link_to` (Number) ID of real image to link this virtual image to upon creation +- `name` (String) Name of the rescue disk + +### Optional + +- `account_id` (Number) account_id +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `acl` (String) +- `architecture` (String) +- `boot_type` (String) +- `bootable` (Boolean) +- `cd_presented_to` (String) +- `compute_ci_id` (Number) +- `deleted_time` (Number) +- `desc` (String) +- `drivers` (List of String) +- `enabled` (Boolean) +- `gid` (Number) +- `guid` (Number) +- `history` (List of Object) (see [below for nested schema](#nestedatt--history)) +- `hot_resize` (Boolean) +- `id` (String) The ID of this resource. +- `image_id` (Number) Image id +- `image_name` (String) +- `independent` (Boolean) +- `last_modified` (Number) +- `links_to` (List of Number) +- `milestones` (Number) +- `network_interface_naming` (String) +- `password` (String) +- `pool_name` (String) +- `present_to` (Map of Number) +- `provider_name` (String) +- `purge_attempts` (Number) +- `res_id` (String) +- `rescuecd` (Boolean) +- `sep_id` (Number) +- `shared_with` (List of Number) +- `size` (Number) +- `snapshot_id` (String) +- `status` (String) +- `storage_policy_id` (Number) +- `tech_status` (String) +- `to_clean` (Boolean) +- `type` (String) +- `unc_path` (String) +- `username` (String) +- `version` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `history` + +Read-Only: + +- `guid` (String) +- `id` (Number) +- `timestamp` (Number) diff --git a/docs/resources/k8s.md b/docs/resources/k8s.md new file mode 100644 index 00000000..bc0d595e --- /dev/null +++ b/docs/resources/k8s.md @@ -0,0 +1,229 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8s Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8s (Resource) + + + + + + +## Schema + +### Required + +- `k8sci_id` (Number) ID of the k8s catalog item to base this instance on. +- `name` (String) Name of the cluster. +- `network_plugin` (String) Network plugin to be used +- `rg_id` (Number) Resource group ID that this instance belongs to. +- `storage_policy_id` (Number) ID of the storage policy +- `wg_name` (String) Name for first worker group created with cluster. + +### Optional + +- `additional_sans` (List of String) Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names +- `annotations` (List of String) +- `chipset` (String) Type of the emulated system. Possible values: i440fx, Q35. Default: Q35 +- `cloud_init` (String) Meta data for working group computes, format YAML 'user_data': 1111 +- `cluster_config` (String) is used to define global settings and configurations for the entire cluster. It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. insert a valid JSON string with all levels of nesting. +- `desc` (String) Text description of this instance. +- `extnet_id` (Number) ID of the external network to connect workers to. If omitted network will be chosen by the platfom. +- `extnet_only` (Boolean) Use only selected ExtNet for infrastructure connections +- `ha_mode` (Boolean) Use Highly Available schema for LB deploy +- `init_config` (String) is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting. +- `join_config` (String) is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting. +- `kube_proxy_config` (String) is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting. +- `kubelet_config` (String) is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. insert a valid JSON string with all levels of nesting. +- `labels` (List of String) +- `lb_sysctl_params` (List of Map of String) Custom sysctl values for Load Balancer instance. Applied on boot. +- `masters` (Block List, Max: 1) Master node(s) configuration. (see [below for nested schema](#nestedblock--masters)) +- `oidc_cert` (String) insert ssl certificate in x509 pem format +- `permanently` (Boolean) Determines if cluster should be destroyed +- `start` (Boolean) Start k8s cluster +- `taints` (List of String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) ID of default vins for this instace. +- `with_lb` (Boolean) Create k8s with load balancer if true. +- `workers` (Block List) Worker node(s) configuration. (see [below for nested schema](#nestedblock--workers)) +- `zone_id` (Number) ID of the zone to put the cluster into. + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `bservice_id` (Number) +- `created_by` (String) +- `created_time` (Number) +- `default_wg_id` (Number) ID of default workers group for this instace. +- `deleted_by` (String) +- `deleted_time` (Number) +- `id` (String) The ID of this resource. +- `k8s_ci_name` (String) +- `kubeconfig` (String) Kubeconfig for cluster access. +- `lb_id` (Number) +- `lb_ip` (String) IP address of default load balancer. +- `rg_name` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) + + +### Nested Schema for `masters` + +Required: + +- `cpu` (Number) Node CPU count. +- `disk` (Number) Node boot disk size in GB. +- `num` (Number) Number of nodes to create. Can be either 1, 3 or 5 +- `ram` (Number) Node RAM in MB. + +Optional: + +- `sep_id` (Number) +- `sep_pool` (String) + +Read-Only: + +- `detailed_info` (List of Object) (see [below for nested schema](#nestedatt--masters--detailed_info)) +- `master_id` (Number) +- `name` (String) + + +### Nested Schema for `masters.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--masters--detailed_info--interfaces)) +- `name` (String) +- `natable_vins_ip` (String) +- `natable_vins_network` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `masters.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) + + + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `workers` + +Required: + +- `cpu` (Number) +- `disk` (Number) +- `name` (String) +- `num` (Number) +- `ram` (Number) + +Optional: + +- `annotations` (List of String) +- `chipset` (String) Type of the emulated system. +- `labels` (List of String) +- `sep_id` (Number) +- `sep_pool` (String) +- `taints` (List of String) + +Read-Only: + +- `detailed_info` (List of Object) (see [below for nested schema](#nestedatt--workers--detailed_info)) +- `guid` (String) +- `id` (Number) + + +### Nested Schema for `workers.detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--workers--detailed_info--interfaces)) +- `name` (String) +- `natable_vins_ip` (String) +- `natable_vins_network` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `workers.detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) + + + + + +### Nested Schema for `acl` + +Read-Only: + +- `account_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--account_acl)) +- `k8s_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--k8s_acl)) +- `rg_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--rg_acl)) + + +### Nested Schema for `acl.account_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.k8s_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.rg_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) diff --git a/docs/resources/k8s_cp.md b/docs/resources/k8s_cp.md new file mode 100644 index 00000000..95710bb8 --- /dev/null +++ b/docs/resources/k8s_cp.md @@ -0,0 +1,159 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8s_cp Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8s_cp (Resource) + + + + + + +## Schema + +### Required + +- `k8sci_id` (Number) ID of the k8s catalog item to base this instance on. +- `name` (String) Name of the cluster. +- `network_plugin` (String) Network plugin to be used +- `rg_id` (Number) Resource group ID that this instance belongs to. +- `storage_policy_id` (Number) ID of the storage policy + +### Optional + +- `additional_sans` (List of String) Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names +- `chipset` (String) Type of the emulated system. Possible values: i440fx, Q35. Default: Q35 +- `cluster_config` (String) is used to define global settings and configurations for the entire cluster. It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. insert a valid JSON string with all levels of nesting. +- `cpu` (Number) Node CPU count. +- `desc` (String) Text description of this instance. +- `disk` (Number) Node boot disk size in GB. +- `extnet_id` (Number) ID of the external network to connect workers to. If omitted network will be chosen by the platfom. +- `extnet_only` (Boolean) Use only selected ExtNet for infrastructure connections +- `ha_mode` (Boolean) Use Highly Available schema for LB deploy +- `init_config` (String) is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting. +- `join_config` (String) is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting. +- `kube_proxy_config` (String) is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting. +- `kubelet_config` (String) is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. insert a valid JSON string with all levels of nesting. +- `lb_sysctl_params` (List of Map of String) Custom sysctl values for Load Balancer instance. Applied on boot. +- `num` (Number) Number of VMs to create. Can be either 1, 3 or 5 +- `oidc_cert` (String) insert ssl certificate in x509 pem format +- `permanently` (Boolean) Determines if cluster should be destroyed +- `ram` (Number) Node RAM in MB. +- `sep_id` (Number) Storage Endpoint ID +- `sep_pool` (String) Storage Endpoint Pool +- `start` (Boolean) Start k8s cluster. +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) ID of default vins for this instace. +- `with_lb` (Boolean) Create k8s with load balancer if true. +- `zone_id` (Number) ID of the zone to put the cluster into. + +### Read-Only + +- `account_id` (Number) +- `account_name` (String) +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `bservice_id` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `detailed_info` (List of Object) (see [below for nested schema](#nestedatt--detailed_info)) +- `id` (String) The ID of this resource. +- `k8s_ci_name` (String) +- `k8s_id` (Number) +- `kubeconfig` (String) Kubeconfig for cluster access. +- `lb_id` (Number) +- `lb_ip` (String) IP address of default load balancer. +- `master_id` (Number) Master group ID. +- `master_name` (String) Master group name. +- `rg_name` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `account_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--account_acl)) +- `k8s_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--k8s_acl)) +- `rg_acl` (List of Object) (see [below for nested schema](#nestedobjatt--acl--rg_acl)) + + +### Nested Schema for `acl.account_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.k8s_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `acl.rg_acl` + +Read-Only: + +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + + +### Nested Schema for `detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--detailed_info--interfaces)) +- `name` (String) +- `natable_vins_ip` (String) +- `natable_vins_network` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/resources/k8s_wg.md b/docs/resources/k8s_wg.md new file mode 100644 index 00000000..e81395ea --- /dev/null +++ b/docs/resources/k8s_wg.md @@ -0,0 +1,77 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_k8s_wg Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_k8s_wg (Resource) + + + + + + +## Schema + +### Required + +- `k8s_id` (Number) ID of k8s instance. +- `name` (String) Name of the worker group. +- `storage_policy_id` (Number) ID of the storage policy + +### Optional + +- `annotations` (List of String) +- `chipset` (String) Type of the emulated system. Possible values: i440fx, Q35. Default: Q35 +- `cloud_init` (String) +- `cpu` (Number) Worker node CPU count. +- `disk` (Number) Worker node boot disk size. If unspecified or 0, size is defined by OS image size. +- `labels` (List of String) +- `num` (Number) Number of worker nodes to create. +- `ram` (Number) Worker node RAM in MB. +- `taints` (List of String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `worker_sep_id` (Number) +- `worker_sep_pool` (String) + +### Read-Only + +- `detailed_info` (List of Object) (see [below for nested schema](#nestedatt--detailed_info)) +- `guid` (String) +- `id` (String) The ID of this resource. +- `wg_id` (Number) ID of k8s worker Group. + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `detailed_info` + +Read-Only: + +- `compute_id` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--detailed_info--interfaces)) +- `name` (String) +- `natable_vins_ip` (String) +- `natable_vins_network` (String) +- `status` (String) +- `tech_status` (String) + + +### Nested Schema for `detailed_info.interfaces` + +Read-Only: + +- `def_gw` (String) +- `ip_address` (String) diff --git a/docs/resources/kvmvm.md b/docs/resources/kvmvm.md new file mode 100644 index 00000000..e78187fa --- /dev/null +++ b/docs/resources/kvmvm.md @@ -0,0 +1,490 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_kvmvm Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_kvmvm (Resource) + + + + + + +## Schema + +### Required + +- `cpu` (Number) Number of CPUs to allocate to this compute instance. +- `name` (String) Name of this compute. Compute names are case sensitive and must be unique in the resource group. +- `ram` (Number) Amount of RAM in MB to allocate to this compute instance. +- `rg_id` (Number) ID of the resource group where this compute should be deployed. +- `storage_policy_id` (Number) Storage policy id of compute. The rules of the specified storage policy will be used. + +### Optional + +- `affinity_label` (String) Set affinity label for compute +- `affinity_rules` (Block List) (see [below for nested schema](#nestedblock--affinity_rules)) +- `alt_boot_id` (Number) ID of CD-ROM live image to boot +- `anti_affinity_rules` (Block List) (see [below for nested schema](#nestedblock--anti_affinity_rules)) +- `auto_start_w_node` (Boolean) Flag for start compute after node exits from MAINTENANCE state +- `boot_disk_size` (Number) This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image. +- `boot_type` (String) Type of image upload. +- `cd` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--cd)) +- `chipset` (String) Type of the emulated system. +- `cloud_init` (String) Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases. +- `cpu_pin` (Boolean) Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node. +- `create_blank` (Boolean) If True, the compute is created via kvmx86/createBlank endpoint (without OS image). The image_id field is not required in this case. +- `custom_fields` (String) +- `description` (String) Optional text description of this compute instance. +- `detach_disks` (Boolean) +- `disks` (Block List) (see [below for nested schema](#nestedblock--disks)) +- `enabled` (Boolean) If true - enable compute, else - disable +- `extra_disks` (Set of Number) Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks. +- `force_resize` (Boolean) Flag for resize compute +- `force_stop` (Boolean) Flag for redeploy compute +- `hot_resize` (Boolean) Type of image vm. +- `hp_backed` (Boolean) Use Huge Pages to allocate RAM of the virtual machine. The system must be pre-configured by allocating Huge Pages on the physical node. +- `image_id` (Number) ID of the OS image to base this compute instance on. +- `loader_type` (String) Type of image vm. +- `network` (Block Set) Optional network connection(s) for this compute. You may specify several network blocks, one for each connection. (see [below for nested schema](#nestedblock--network)) +- `network_interface_naming` (String) Name of netfowrk interface. +- `numa_affinity` (String) Rule for VM placement with NUMA affinity. +- `os_version` (String) the OS version installed on the VM +- `pause` (Boolean) +- `pci_devices` (Set of Number) ID of the connected pci devices +- `permanently` (Boolean) +- `pin_to_node` (Boolean) +- `pool` (String) Pool to use if sepId is set, can be also empty if needed to be chosen by system. +- `port_forwarding` (Block Set) (see [below for nested schema](#nestedblock--port_forwarding)) +- `preferred_cpu` (List of Number) Recommended isolated CPUs. Field is ignored if compute.cpupin=False or compute.pinned=False +- `reset` (Boolean) +- `restore` (Boolean) +- `rollback` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--rollback)) +- `security_groups` (Block Set) list of security group IDs to apply to this interface (see [below for nested schema](#nestedblock--security_groups)) +- `sep_id` (Number) ID of SEP to create bootDisk on. Uses image's sepId if not set. +- `snapshot` (Block Set) (see [below for nested schema](#nestedblock--snapshot)) +- `snapshot_delete_async` (Boolean) +- `started` (Boolean) Is compute started. +- `tags` (Block Set) (see [below for nested schema](#nestedblock--tags)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `user_access` (Block Set) (see [below for nested schema](#nestedblock--user_access)) +- `without_boot_disk` (Boolean) If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state. +- `zone_id` (Number) + +### Read-Only + +- `account_id` (Number) ID of the account this compute instance belongs to. +- `account_name` (String) Name of the account this compute instance belongs to. +- `affinity_weight` (Number) +- `arch` (String) +- `boot_disk` (Set of Object) (see [below for nested schema](#nestedatt--boot_disk)) +- `boot_disk_id` (Number) This compute instance boot disk ID. +- `boot_image_id` (Number) +- `boot_order` (List of String) +- `cd_image_id` (Number) +- `clone_reference` (Number) +- `clones` (List of Number) +- `compute_id` (Number) +- `computeci_id` (Number) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `devices` (String) +- `driver` (String) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `interfaces` (List of Object) (see [below for nested schema](#nestedatt--interfaces)) +- `loader_meta_iso` (List of Object) (see [below for nested schema](#nestedatt--loader_meta_iso)) +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `migrationjob` (Number) +- `milestones` (Number) +- `natable_vins_id` (Number) +- `natable_vins_ip` (String) +- `natable_vins_name` (String) +- `natable_vins_network` (String) +- `natable_vins_network_name` (String) +- `need_reboot` (Boolean) +- `numa_node_id` (Number) +- `os_users` (List of Object) Guest OS users provisioned on this compute instance. (see [below for nested schema](#nestedatt--os_users)) +- `pinned` (Boolean) +- `read_only` (Boolean) Shows if compute is in read-only mode. +- `reference_id` (String) +- `registered` (Boolean) +- `res_name` (String) +- `reserved_node_cpus` (List of Number) +- `rg_name` (String) Name of the resource group where this compute instance is located. +- `snap_sets` (List of Object) (see [below for nested schema](#nestedatt--snap_sets)) +- `stateless_sep_id` (Number) +- `stateless_sep_type` (String) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vgpus` (List of Object) List of virtual GPUs (see [below for nested schema](#nestedatt--vgpus)) +- `virtual_image_id` (Number) +- `virtual_image_name` (String) +- `vnc_password` (String) +- `weight` (Number) Priority weight of the compute. Higher value means higher priority and later migration. + + +### Nested Schema for `affinity_rules` + +Required: + +- `key` (String) key that are taken into account when analyzing this rule will be identified +- `mode` (String) EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key' +- `policy` (String) RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule +- `topology` (String) compute or node, for whom rule applies +- `value` (String) value that must match the key to be taken into account when analyzing this rule + + + +### Nested Schema for `anti_affinity_rules` + +Required: + +- `key` (String) key that are taken into account when analyzing this rule will be identified +- `mode` (String) EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key' +- `policy` (String) RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule +- `topology` (String) compute or node, for whom rule applies +- `value` (String) value that must match the key to be taken into account when analyzing this rule + + + +### Nested Schema for `cd` + +Required: + +- `cdrom_id` (Number) + + + +### Nested Schema for `disks` + +Required: + +- `disk_name` (String) Name for disk +- `size` (Number) Disk size in GiB +- `storage_policy_id` (Number) Storage policy id of disk. The rules of the specified storage policy will be used. + +Optional: + +- `desc` (String) Optional description +- `image_id` (Number) Specify image id for create disk from template +- `iotune` (Block List, Max: 1) (see [below for nested schema](#nestedblock--disks--iotune)) +- `permanently` (Boolean) Disk deletion status +- `pool` (String) Pool name; by default will be chosen automatically +- `sep_id` (Number) Storage endpoint provider ID; by default the same with boot disk + +Read-Only: + +- `blk_discard` (Boolean) +- `block_size` (String) +- `bus_number` (Number) Bus number of the disk on virtual bus (6 = boot disk) +- `cache` (String) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `devicename` (String) +- `disk_id` (Number) Disk ID +- `independent` (Boolean) +- `pci_slot` (Number) PCI slot number of the disk +- `present_to` (Map of Number) +- `provision` (String) +- `shareable` (Boolean) +- `size_max` (Number) +- `size_used` (Number) +- `to_clean` (Boolean) +- `updated_time` (Number) + + +### Nested Schema for `disks.iotune` + +Optional: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + + +### Nested Schema for `network` + +Required: + +- `net_id` (Number) ID of the network for this connection. +- `net_type` (String) Type of the network for this connection + +Optional: + +- `enabled` (Boolean) network enable flag +- `ip_address` (String) Optional IP address to assign to this connection. This IP should belong to the selected network and free for use. +- `mac` (String) MAC address associated with this connection. MAC address is assigned automatically. +- `mtu` (Number) Maximum transmission unit, used only for DPDK type, must be 1500-9216 +- `net_mask` (Number) Subnet mask, used only for DPDK and VFNIC network types +- `sdn_interface_id` (String) unique_identifier of LogicalPort on SDN side +- `weight` (Number) weight the network if you need to sort network list, the smallest attach first. zero or null weight attach last + + + +### Nested Schema for `port_forwarding` + +Required: + +- `proto` (String) +- `public_port_start` (Number) + +Optional: + +- `local_port` (Number) +- `public_port_end` (Number) + + + +### Nested Schema for `rollback` + +Required: + +- `label` (String) + + + +### Nested Schema for `security_groups` + +Required: + +- `net_id` (Number) ID of the network +- `net_type` (String) Type of the network +- `security_groups` (Set of Number) + +Optional: + +- `enable_secgroups` (Boolean) + + + +### Nested Schema for `snapshot` + +Required: + +- `label` (String) + + + +### Nested Schema for `tags` + +Required: + +- `key` (String) +- `value` (String) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `user_access` + +Required: + +- `access_type` (String) +- `username` (String) + + + +### Nested Schema for `boot_disk` + +Read-Only: + +- `blk_discard` (Boolean) +- `block_size` (String) +- `bus_number` (Number) +- `cache` (String) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `desc` (String) +- `devicename` (String) +- `disk_id` (Number) +- `disk_name` (String) +- `image_id` (Number) +- `independent` (Boolean) +- `iotune` (List of Object) (see [below for nested schema](#nestedobjatt--boot_disk--iotune)) +- `pci_slot` (Number) +- `permanently` (Boolean) +- `pool` (String) +- `present_to` (Map of Number) +- `provision` (String) +- `sep_id` (Number) +- `shareable` (Boolean) +- `size` (Number) +- `size_max` (Number) +- `size_used` (Number) +- `storage_policy_id` (Number) +- `to_clean` (Boolean) +- `updated_time` (Number) + + +### Nested Schema for `boot_disk.iotune` + +Read-Only: + +- `read_bytes_sec` (Number) +- `read_bytes_sec_max` (Number) +- `read_iops_sec` (Number) +- `read_iops_sec_max` (Number) +- `size_iops_sec` (Number) +- `total_bytes_sec` (Number) +- `total_bytes_sec_max` (Number) +- `total_iops_sec` (Number) +- `total_iops_sec_max` (Number) +- `write_bytes_sec` (Number) +- `write_bytes_sec_max` (Number) +- `write_iops_sec` (Number) +- `write_iops_sec_max` (Number) + + + + +### Nested Schema for `interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flip_group_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_type` (String) +- `netmask` (Number) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `trunk_tags` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `loader_meta_iso` + +Read-Only: + +- `device_name` (String) +- `path` (String) + + + +### Nested Schema for `os_users` + +Read-Only: + +- `guid` (String) +- `login` (String) +- `password` (String) +- `public_key` (String) + + + +### Nested Schema for `snap_sets` + +Read-Only: + +- `disks` (List of Number) +- `guid` (String) +- `label` (String) +- `timestamp` (Number) + + + +### Nested Schema for `vgpus` + +Read-Only: + +- `account_id` (Number) +- `bus_number` (Number) +- `created_time` (Number) +- `deleted_time` (Number) +- `gid` (Number) +- `guid` (Number) +- `id` (Number) +- `last_claimed_by` (Number) +- `last_update_time` (Number) +- `mode` (String) +- `pci_slot` (Number) +- `pgpuid` (Number) +- `profile_id` (Number) +- `ram` (Number) +- `reference_id` (String) +- `rg_id` (Number) +- `status` (String) +- `type` (String) +- `vmid` (Number) diff --git a/docs/resources/lb.md b/docs/resources/lb.md new file mode 100644 index 00000000..efad36f3 --- /dev/null +++ b/docs/resources/lb.md @@ -0,0 +1,184 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_lb Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_lb (Resource) + + + + + + +## Schema + +### Required + +- `name` (String) +- `rg_id` (Number) + +### Optional + +- `config_reset` (Boolean) +- `desc` (String) +- `enable` (Boolean) +- `extnet_id` (Number) +- `ha_mode` (Boolean) +- `permanently` (Boolean) +- `restart` (Boolean) +- `restore` (Boolean) +- `safe` (Boolean) +- `start` (Boolean) +- `sysctl_params` (List of Map of String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vins_id` (Number) +- `zone_id` (Number) + +### Read-Only + +- `account_id` (Number) +- `backend_haip` (String) +- `backends` (List of Object) (see [below for nested schema](#nestedatt--backends)) +- `created_by` (String) +- `created_time` (Number) +- `deleted_by` (String) +- `deleted_time` (Number) +- `dp_api_user` (String) +- `frontend_haip` (String) +- `frontends` (List of Object) (see [below for nested schema](#nestedatt--frontends)) +- `gid` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `image_id` (Number) +- `lb_id` (Number) +- `manager_id` (Number) +- `manager_type` (String) +- `milestones` (Number) +- `part_k8s` (Boolean) +- `primary_node` (List of Object) (see [below for nested schema](#nestedatt--primary_node)) +- `rg_name` (String) +- `secondary_node` (List of Object) (see [below for nested schema](#nestedatt--secondary_node)) +- `status` (String) +- `tech_status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `backends` + +Read-Only: + +- `algorithm` (String) +- `guid` (String) +- `name` (String) +- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--backends--server_default_settings)) +- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--backends--servers)) + + +### Nested Schema for `backends.server_default_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + +### Nested Schema for `backends.servers` + +Read-Only: + +- `address` (String) +- `check` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--backends--servers--server_settings)) + + +### Nested Schema for `backends.servers.server_settings` + +Read-Only: + +- `downinter` (Number) +- `fall` (Number) +- `guid` (String) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + + + + + +### Nested Schema for `frontends` + +Read-Only: + +- `backend` (String) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--frontends--bindings)) +- `guid` (String) +- `name` (String) + + +### Nested Schema for `frontends.bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) + + + + +### Nested Schema for `primary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) + + + +### Nested Schema for `secondary_node` + +Read-Only: + +- `backend_ip` (String) +- `compute_id` (Number) +- `frontend_ip` (String) +- `guid` (String) +- `mgmt_ip` (String) +- `network_id` (Number) diff --git a/docs/resources/lb_backend.md b/docs/resources/lb_backend.md new file mode 100644 index 00000000..73d1f289 --- /dev/null +++ b/docs/resources/lb_backend.md @@ -0,0 +1,86 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_lb_backend Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_lb_backend (Resource) + + + + + + +## Schema + +### Required + +- `lb_id` (Number) ID of the LB instance to backendCreate +- `name` (String) Must be unique among all backends of this LB - name of the new backend to create + +### Optional + +- `algorithm` (String) +- `downinter` (Number) +- `fall` (Number) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `servers` (Block List) (see [below for nested schema](#nestedblock--servers)) +- `slowstart` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `weight` (Number) + +### Read-Only + +- `guid` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `servers` + +Optional: + +- `address` (String) +- `check` (String) +- `name` (String) +- `port` (Number) +- `server_settings` (Block List) (see [below for nested schema](#nestedblock--servers--server_settings)) + +Read-Only: + +- `guid` (String) + + +### Nested Schema for `servers.server_settings` + +Optional: + +- `downinter` (Number) +- `fall` (Number) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `weight` (Number) + +Read-Only: + +- `guid` (String) + + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/lb_backend_server.md b/docs/resources/lb_backend_server.md new file mode 100644 index 00000000..d57a43d3 --- /dev/null +++ b/docs/resources/lb_backend_server.md @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_lb_backend_server Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_lb_backend_server (Resource) + + + + + + +## Schema + +### Required + +- `address` (String) IP address of the server. +- `backend_name` (String) Must be unique among all backends of this LB - name of the new backend to create +- `lb_id` (Number) ID of the LB instance to backendCreate +- `name` (String) Must be unique among all servers defined for this backend - name of the server definition to add. +- `port` (Number) Port number on the server + +### Optional + +- `check` (String) set to disabled if this server should be used regardless of its state. +- `downinter` (Number) +- `fall` (Number) +- `inter` (Number) +- `maxconn` (Number) +- `maxqueue` (Number) +- `rise` (Number) +- `slowstart` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `weight` (Number) + +### Read-Only + +- `guid` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/lb_frontend.md b/docs/resources/lb_frontend.md new file mode 100644 index 00000000..7080f422 --- /dev/null +++ b/docs/resources/lb_frontend.md @@ -0,0 +1,54 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_lb_frontend Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_lb_frontend (Resource) + + + + + + +## Schema + +### Required + +- `backend_name` (String) +- `lb_id` (Number) ID of the LB instance to backendCreate +- `name` (String) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `bindings` (List of Object) (see [below for nested schema](#nestedatt--bindings)) +- `guid` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `bindings` + +Read-Only: + +- `address` (String) +- `guid` (String) +- `name` (String) +- `port` (Number) diff --git a/docs/resources/lb_frontend_bind.md b/docs/resources/lb_frontend_bind.md new file mode 100644 index 00000000..1a663353 --- /dev/null +++ b/docs/resources/lb_frontend_bind.md @@ -0,0 +1,44 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_lb_frontend_bind Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_lb_frontend_bind (Resource) + + + + + + +## Schema + +### Required + +- `address` (String) +- `frontend_name` (String) Must be unique among all backends of this LB - name of the new backend to create +- `lb_id` (Number) ID of the LB instance to backendCreate +- `name` (String) +- `port` (Number) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `guid` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/pfw.md b/docs/resources/pfw.md new file mode 100644 index 00000000..74baf173 --- /dev/null +++ b/docs/resources/pfw.md @@ -0,0 +1,44 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_pfw Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_pfw (Resource) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) ID of compute instance. +- `local_base_port` (Number) Internal base port number. +- `proto` (String) Network protocol, either 'tcp' or 'udp'. +- `public_port_start` (Number) External start port number for the rule. + +### Optional + +- `public_port_end` (Number) End port number (inclusive) for the ranged rule. +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `local_ip` (String) IP address of compute instance. + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/resgroup.md b/docs/resources/resgroup.md new file mode 100644 index 00000000..57371bab --- /dev/null +++ b/docs/resources/resgroup.md @@ -0,0 +1,166 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_resgroup Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_resgroup (Resource) + + + + + + +## Schema + +### Required + +- `account_id` (Number) Unique ID of the account, which this resource group belongs to. +- `gid` (Number) Unique ID of the grid, where this resource group is deployed. +- `name` (String) Name of this resource group. Names are case sensitive and unique within the context of a account. + +### Optional + +- `access` (Block Set) (see [below for nested schema](#nestedblock--access)) +- `def_net` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--def_net)) +- `def_net_type` (String) Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE. +- `description` (String) User-defined text description of this resource group. +- `enable` (Boolean) flag for enable/disable RG +- `ext_ip` (String) IP address on the external netowrk to request when def_net_type=PRIVATE and ext_net_id is not 0 +- `ext_net_id` (Number) ID of the external network for default ViNS. Pass 0 if def_net_type=PUBLIC or no external connection required for the defult ViNS when def_net_type=PRIVATE +- `force` (Boolean) Set to True if you want force delete non-empty RG +- `ipcidr` (String) Address of the netowrk inside the private network segment (aka ViNS) if def_net_type=PRIVATE +- `owner` (String) +- `permanently` (Boolean) Set to True if you want force delete non-empty RG +- `quota` (Block List, Max: 1) Quota settings for this resource group. (see [below for nested schema](#nestedblock--quota)) +- `restore` (Boolean) +- `sdn_access_group_id` (String) ID of the SDN access group +- `storage_policy` (Block Set) (see [below for nested schema](#nestedblock--storage_policy)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `uniq_pools` (List of String) + +### Read-Only + +- `account_name` (String) Name of the account, which this resource group belongs to. +- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl)) +- `compute_features` (List of String) +- `cpu_allocation_parameter` (String) +- `cpu_allocation_ratio` (Number) +- `created_by` (String) +- `created_time` (Number) +- `def_net_id` (Number) ID of the default network for this resource group (if any). +- `deleted_by` (String) +- `deleted_time` (Number) +- `dirty` (Boolean) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `lock_status` (String) +- `milestones` (Number) +- `res_types` (List of String) +- `resource_limits` (List of Object) (see [below for nested schema](#nestedatt--resource_limits)) +- `rg_id` (Number) +- `secret` (String) +- `status` (String) Current status of this resource group. +- `storage_policy_ids` (List of Number) +- `updated_by` (String) +- `updated_time` (Number) +- `vins` (List of Number) List of VINs deployed in this resource group. +- `vms` (List of Number) List of computes deployed in this resource group. + + +### Nested Schema for `access` + +Required: + +- `right` (String) Access rights to set, one of 'R', 'RCX' or 'ARCXDU' +- `user` (String) User or group name to grant access + + + +### Nested Schema for `def_net` + +Required: + +- `net_type` (String) Network type to set. Must be on of 'PRIVATE' or 'PUBLIC'. + +Optional: + +- `net_id` (Number) Network segment ID. If netType is PUBLIC and netId is 0 then default external network segment will be selected. If netType is PRIVATE and netId=0, the first ViNS defined for this RG will be selected. Otherwise, netId identifies either existing external network segment or ViNS. + + + +### Nested Schema for `quota` + +Optional: + +- `cpu` (Number) Limit on the total number of CPUs in this resource group. +- `disk` (Number) Limit on the total volume of virtual storage resources in this resource group, specified in GB. +- `ext_ips` (Number) Limit on the total number of external IP addresses this resource group can use. +- `ram` (Number) Limit on the total amount of RAM in this resource group, specified in MB. + +Read-Only: + +- `cu_d` (Number) Limit on the total volume of storage resources in this resource group, specified in GB. +- `gpu_units` (Number) Limit on the total number of virtual GPUs this resource group can use. + + + +### Nested Schema for `storage_policy` + +Required: + +- `id` (Number) + +Optional: + +- `limit` (Number) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `acl` + +Read-Only: + +- `email` (String) +- `explicit` (Boolean) +- `guid` (String) +- `right` (String) +- `status` (String) +- `type` (String) +- `user_group_id` (String) + + + +### Nested Schema for `resource_limits` + +Read-Only: + +- `cu_c` (Number) +- `cu_d` (Number) +- `cu_dm` (Number) +- `cu_i` (Number) +- `cu_m` (Number) +- `gpu_units` (Number) +- `storage_policy` (Set of Object) (see [below for nested schema](#nestedobjatt--resource_limits--storage_policy)) + + +### Nested Schema for `resource_limits.storage_policy` + +Read-Only: + +- `id` (Number) +- `limit` (Number) diff --git a/docs/resources/sdn_access_group.md b/docs/resources/sdn_access_group.md new file mode 100644 index 00000000..813cae55 --- /dev/null +++ b/docs/resources/sdn_access_group.md @@ -0,0 +1,80 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_access_group Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_access_group (Resource) + + + + + + +## Schema + +### Required + +- `comment` (String) description (comment) of the group +- `display_name` (String) group name + +### Optional + +- `default_security_policy` (Block List, Max: 1) Default security policy configuration (see [below for nested schema](#nestedblock--default_security_policy)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `users` (Block List) managing users who are part of a group (see [below for nested schema](#nestedblock--users)) + +### Read-Only + +- `created_at` (String) Creation timestamp +- `id` (String) The ID of this resource. +- `net_object_access_group` (List of Object) Net object access group configuration (see [below for nested schema](#nestedatt--net_object_access_group)) + + +### Nested Schema for `default_security_policy` + +Optional: + +- `default_acl_drop` (String) Default ACL drop action +- `default_open_session_drop` (Boolean) Default open session drop flag + +Read-Only: + +- `access_group_id` (String) Policy access group ID +- `description` (String) Policy description +- `display_name` (String) Policy display name +- `id` (String) Policy unique identifier +- `version_id` (Number) Policy version identifier + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `users` + +Required: + +- `access_group_role_id` (String) id of the assigned role +- `user_id` (String) user ID + + + +### Nested Schema for `net_object_access_group` + +Read-Only: + +- `access_group_id` (String) +- `id` (String) +- `version_id` (Number) diff --git a/docs/resources/sdn_hypervisor.md b/docs/resources/sdn_hypervisor.md new file mode 100644 index 00000000..4244781a --- /dev/null +++ b/docs/resources/sdn_hypervisor.md @@ -0,0 +1,74 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_hypervisor Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_hypervisor (Resource) + + + + + + +## Schema + +### Required + +- `display_name` (String) +- `name` (String) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `created_at` (String) +- `hostname` (String) +- `id` (String) The ID of this resource. +- `ip` (String) +- `ports` (List of Object) (see [below for nested schema](#nestedatt--ports)) +- `status` (String) +- `synced_at` (String) + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `ports` + +Read-Only: + +- `data` (List of Object) (see [below for nested schema](#nestedobjatt--ports--data)) +- `info` (List of Object) (see [below for nested schema](#nestedobjatt--ports--info)) + + +### Nested Schema for `ports.data` + +Read-Only: + +- `display_name` (String) +- `id` (String) +- `unique_identifier` (String) +- `up` (Boolean) + + + +### Nested Schema for `ports.info` + +Read-Only: + +- `active_ports` (Number) +- `total_ports` (Number) diff --git a/docs/resources/sdn_logical_port.md b/docs/resources/sdn_logical_port.md new file mode 100644 index 00000000..fd23d9b6 --- /dev/null +++ b/docs/resources/sdn_logical_port.md @@ -0,0 +1,136 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_logical_port Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_logical_port (Resource) + + + + + + +## Schema + +### Required + +- `access_group_id` (String) Access Group ID +- `description` (String) Description +- `display_name` (String) Display Name +- `enabled` (Boolean) Whether the logical port should be enabled +- `hypervisor` (String) Hypervisor +- `port_security` (Boolean) Whether the port security is enabled +- `segment_id` (String) Segment ID + +### Optional + +- `adapter_mac` (String) Adapter MAC address +- `force` (Boolean) +- `labels` (Block List, Max: 1) Labels (see [below for nested schema](#nestedblock--labels)) +- `logical_port_addresses` (Block List) (see [below for nested schema](#nestedblock--logical_port_addresses)) +- `migrate` (Boolean) If true, triggers live migration to the hypervisor specified in the 'hypervisor' field. If false, hypervisor changes are applied via the regular update endpoint. +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `unique_identifier` (String) Unique identifier of the logical port + +### Read-Only + +- `access_group_name` (String) Name of the access group +- `address_detection` (Boolean) +- `bindings` (List of Object) (see [below for nested schema](#nestedatt--bindings)) +- `created_at` (String) +- `external_network_id` (String) +- `hypervisor_display_name` (String) +- `id` (String) ID of the logical port +- `live_migration_target_hv` (String) +- `status` (List of Object) (see [below for nested schema](#nestedatt--status)) +- `version_id` (Number) Version ID of the logical port + + +### Nested Schema for `labels` + +Optional: + +- `vm_id` (String) VM ID label +- `vm_name` (String) VM name label + + + +### Nested Schema for `logical_port_addresses` + +Required: + +- `ip` (String) IP address of the logical port +- `ip_type` (String) +- `is_primary` (Boolean) + +Optional: + +- `is_discovered` (Boolean) +- `mac` (String) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `bindings` + +Read-Only: + +- `address_detection` (Boolean) +- `created_at` (String) +- `id` (String) +- `logical_port_addresses` (List of Object) (see [below for nested schema](#nestedobjatt--bindings--logical_port_addresses)) +- `port_security` (Boolean) +- `segment_display_name` (String) +- `segment_id` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `bindings.logical_port_addresses` + +Read-Only: + +- `assigned_at` (String) +- `id` (String) +- `ip` (String) +- `ip_type` (String) +- `is_discovered` (Boolean) +- `is_primary` (Boolean) +- `logical_port_id` (String) +- `mac` (String) + + + + +### Nested Schema for `status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) diff --git a/docs/resources/sdn_network_object_group.md b/docs/resources/sdn_network_object_group.md new file mode 100644 index 00000000..bfe89a00 --- /dev/null +++ b/docs/resources/sdn_network_object_group.md @@ -0,0 +1,721 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_network_object_group Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_network_object_group (Resource) + + + + + + +## Schema + +### Required + +- `access_group_id` (String) +- `description` (String) +- `name` (String) + +### Optional + +- `addresses` (Block List) (see [below for nested schema](#nestedblock--addresses)) +- `l2_connection_ports_bindings` (Block List) (see [below for nested schema](#nestedblock--l2_connection_ports_bindings)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `access_group_name` (String) +- `counters` (List of Object) (see [below for nested schema](#nestedatt--counters)) +- `external_network_ports` (List of Object) (see [below for nested schema](#nestedatt--external_network_ports)) +- `id` (String) The ID of this resource. +- `l2_connection_ports` (List of Object) (see [below for nested schema](#nestedatt--l2_connection_ports)) +- `logical_ports` (List of Object) (see [below for nested schema](#nestedatt--logical_ports)) +- `purpose` (String) +- `security_policies` (List of Object) (see [below for nested schema](#nestedatt--security_policies)) +- `type` (String) +- `version_id` (Number) + + +### Nested Schema for `addresses` + +Required: + +- `net_address_type` (String) + +Optional: + +- `ip_addr` (String) +- `ip_addr_range_end` (String) +- `ip_prefix` (String) +- `mac_addr` (String) + +Read-Only: + +- `id` (String) + + + +### Nested Schema for `l2_connection_ports_bindings` + +Required: + +- `port_id` (String) +- `port_version` (Number) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `counters` + +Read-Only: + +- `addresses_count` (Number) +- `l2_connection_ports_count` (Number) +- `logical_ports_count` (Number) +- `security_policies_count` (Number) +- `security_rules_count` (Number) + + + +### Nested Schema for `external_network_ports` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `bridge_network_name` (String) +- `comment` (String) +- `created_at` (String) +- `default_gateway_ipv4` (String) +- `default_gateway_ipv6` (String) +- `description` (String) +- `enabled` (Boolean) +- `external_network_ports` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports)) +- `hypervisors` (List of String) +- `id` (String) +- `ipv4` (String) +- `mac` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--status)) +- `subnet_v4` (String) +- `subnet_v6` (String) +- `updated_at` (String) +- `version_id` (Number) +- `vlan_tag` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `comment` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `floating_ip` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip)) +- `ipv4` (String) +- `ipv6` (String) +- `ipv6_config` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--ipv6_config)) +- `mac` (String) +- `router_gateaway_port` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--router_gateaway_port)) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `created_at` (String) +- `logical_port` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port)) +- `router` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `adapter_mac` (String) +- `address_detection` (Boolean) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--bindings)) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `exclude_firewall` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--exclude_firewall)) +- `external_network_id` (String) +- `hypervisor` (String) +- `hypervisor_display_name` (String) +- `id` (String) +- `labels` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--labels)) +- `live_migration_target_hv` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--status)) +- `unique_identifier` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.bindings` + +Read-Only: + +- `address_detection` (Boolean) +- `created_at` (String) +- `id` (String) +- `logical_port_addresses` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--bindings--logical_port_addresses)) +- `port_security` (Boolean) +- `segment_display_name` (String) +- `segment_id` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.bindings.logical_port_addresses` + +Read-Only: + +- `assigned_at` (String) +- `id` (String) +- `ip` (String) +- `ip_type` (String) +- `is_discovered` (Boolean) +- `is_primary` (Boolean) +- `logical_port_id` (String) +- `mac` (String) + + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.exclude_firewall` + +Read-Only: + +- `exclusion_reason` (String) +- `logical_port_addresses_excluded` (Boolean) +- `logical_port_excluded` (Boolean) + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.labels` + +Read-Only: + +- `vm_id` (String) +- `vm_name` (String) + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--logical_port--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.logical_port.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `gateaway_ports` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--gateaway_ports)) +- `id` (String) +- `policies` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--policies)) +- `ports` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--ports)) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--status)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.gateaway_ports` + +Read-Only: + +- `created_at` (String) +- `description` (String) +- `external_l4_port_max` (Number) +- `external_l4_port_min` (Number) +- `id` (String) +- `snat_enabled` (Boolean) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--gateaway_ports--status)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.gateaway_ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--gateaway_ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.gateaway_ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.policies` + +Read-Only: + +- `action` (String) +- `created_at` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `id` (String) +- `match` (String) +- `next_ipv4_address` (List of String) +- `next_ipv6_address` (List of String) +- `priority` (Number) +- `updated_at` (String) +- `version_id` (Number) + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.ports` + +Read-Only: + +- `created_at` (String) +- `description` (String) +- `enabled` (Boolean) +- `id` (String) +- `ipv4_address` (String) +- `ipv6_address` (String) +- `ipv6_config` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--ports--ipv6_config)) +- `mac` (String) +- `segment` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--ports--segment)) +- `segment_id` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--ports--status)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.ports.ipv6_config` + +Read-Only: + +- `address_mode` (String) +- `enable_periodic_ra` (Boolean) +- `interval_ra` (Number) +- `router_preference` (String) + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.ports.segment` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `id` (String) +- `subnet_v4` (String) +- `subnet_v6` (String) +- `updated_at` (String) +- `version_id` (Number) + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--external_network_ports--floating_ip--router--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `external_network_ports.external_network_ports.floating_ip.router.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + + +### Nested Schema for `external_network_ports.external_network_ports.ipv6_config` + +Read-Only: + +- `address_mode` (String) +- `enable_periodic_ra` (Boolean) +- `interval_ra` (Number) +- `router_preference` (String) + + + +### Nested Schema for `external_network_ports.external_network_ports.router_gateaway_port` + +Read-Only: + +- `created_at` (String) +- `description` (String) +- `id` (String) +- `router_display_name` (String) +- `router_id` (String) +- `snat_enabled` (Boolean) +- `updated_at` (String) + + + + +### Nested Schema for `external_network_ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--external_network_ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `external_network_ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `l2_connection_ports` + +Read-Only: + +- `access_group_id` (String) +- `created_at` (String) +- `id` (String) +- `l2_external_network` (List of Object) (see [below for nested schema](#nestedobjatt--l2_connection_ports--l2_external_network)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `l2_connection_ports.l2_external_network` + +Read-Only: + +- `bridge_network_name` (String) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `hypervisors` (List of String) +- `id` (String) +- `updated_at` (String) +- `version_id` (Number) +- `vlan_tag` (Number) + + + + +### Nested Schema for `logical_ports` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `adapter_mac` (String) +- `address_detection` (Boolean) +- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--bindings)) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `exclude_firewall` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--exclude_firewall)) +- `external_network_id` (String) +- `hypervisor` (String) +- `hypervisor_display_name` (String) +- `id` (String) +- `labels` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--labels)) +- `live_migration_target_hv` (String) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--status)) +- `unique_identifier` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `logical_ports.bindings` + +Read-Only: + +- `address_detection` (Boolean) +- `created_at` (String) +- `id` (String) +- `logical_port_addresses` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--bindings--logical_port_addresses)) +- `port_security` (Boolean) +- `segment_display_name` (String) +- `segment_id` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `logical_ports.bindings.logical_port_addresses` + +Read-Only: + +- `assigned_at` (String) +- `id` (String) +- `ip` (String) +- `ip_type` (String) +- `is_discovered` (Boolean) +- `is_primary` (Boolean) +- `logical_port_id` (String) +- `mac` (String) + + + + +### Nested Schema for `logical_ports.exclude_firewall` + +Read-Only: + +- `exclusion_reason` (String) +- `logical_port_addresses_excluded` (Boolean) +- `logical_port_excluded` (Boolean) + + + +### Nested Schema for `logical_ports.labels` + +Read-Only: + +- `vm_id` (String) +- `vm_name` (String) + + + +### Nested Schema for `logical_ports.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--logical_ports--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `logical_ports.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) + + + + + +### Nested Schema for `security_policies` + +Read-Only: + +- `access_group_id` (String) +- `access_group_name` (String) +- `applied_net_object_groups` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--applied_net_object_groups)) +- `created_at` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `end_priority` (Number) +- `id` (String) +- `security_rules` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--security_rules)) +- `start_priority` (Number) +- `status` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--status)) +- `type` (String) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `security_policies.applied_net_object_groups` + +Read-Only: + +- `id` (String) +- `name` (String) +- `version_id` (Number) + + + +### Nested Schema for `security_policies.security_rules` + +Read-Only: + +- `access_group_id` (String) +- `action` (String) +- `description` (String) +- `destination_net_object` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--security_rules--destination_net_object)) +- `direction` (String) +- `display_name` (String) +- `enabled` (Boolean) +- `filter` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--security_rules--filter)) +- `id` (String) +- `log_enabled` (Boolean) +- `log_name` (String) +- `log_severity` (String) +- `priority` (Number) +- `security_policy_id` (String) +- `source_net_object` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--security_rules--source_net_object)) +- `statistics_enabled` (Boolean) +- `type` (String) +- `version_id` (Number) + + +### Nested Schema for `security_policies.security_rules.destination_net_object` + +Read-Only: + +- `display_name` (String) +- `net_address_pool_id` (String) +- `net_object_group_id` (String) + + + +### Nested Schema for `security_policies.security_rules.filter` + +Read-Only: + +- `filters` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--security_rules--filter--filters)) +- `name` (String) + + +### Nested Schema for `security_policies.security_rules.filter.filters` + +Read-Only: + +- `all` (Boolean) +- `arp` (Boolean) +- `dhcp` (Boolean) +- `expression` (String) +- `icmp` (Boolean) +- `ip` (Boolean) +- `ip_v4` (Boolean) +- `ip_v6` (Boolean) +- `keep_opened_sessions` (Boolean) +- `nd` (Boolean) +- `tcp` (Boolean) +- `tcp_dst_ports` (List of String) +- `udp` (Boolean) +- `udp_dst_ports` (List of String) + + + + +### Nested Schema for `security_policies.security_rules.source_net_object` + +Read-Only: + +- `display_name` (String) +- `net_address_pool_id` (String) +- `net_object_group_id` (String) + + + + +### Nested Schema for `security_policies.status` + +Read-Only: + +- `hypervisor_status` (String) +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--security_policies--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `security_policies.status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) diff --git a/docs/resources/sdn_segment.md b/docs/resources/sdn_segment.md new file mode 100644 index 00000000..f1a03b79 --- /dev/null +++ b/docs/resources/sdn_segment.md @@ -0,0 +1,167 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_sdn_segment Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_sdn_segment (Resource) + + + + + + +## Schema + +### Required + +- `access_group_id` (String) +- `description` (String) +- `display_name` (String) +- `enabled` (Boolean) + +### Optional + +- `dhcp_v4` (Block List, Max: 1) (see [below for nested schema](#nestedblock--dhcp_v4)) +- `dhcp_v6` (Block List, Max: 1) (see [below for nested schema](#nestedblock--dhcp_v6)) +- `force` (Boolean) +- `subnet_v4` (String) +- `subnet_v6` (String) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `type` (String) + +### Read-Only + +- `access_group_name` (String) +- `created_at` (String) +- `id` (String) The ID of this resource. +- `l2_connection_port` (List of Object) (see [below for nested schema](#nestedatt--l2_connection_port)) +- `logical_ports_info` (List of Object) (see [below for nested schema](#nestedatt--logical_ports_info)) +- `routers_info` (List of Object) (see [below for nested schema](#nestedatt--routers_info)) +- `status` (List of Object) (see [below for nested schema](#nestedatt--status)) +- `updated_at` (String) +- `version_id` (Number) + + +### Nested Schema for `dhcp_v4` + +Required: + +- `enabled` (Boolean) +- `gateway` (String) +- `server_ip` (String) + +Optional: + +- `dns` (List of String) +- `excluded_address_ranges` (List of String) +- `lease_time` (Number) +- `server_mac` (String) + +Read-Only: + +- `id` (String) + + + +### Nested Schema for `dhcp_v6` + +Required: + +- `address_prefix` (String) +- `enabled` (Boolean) + +Optional: + +- `dns` (List of String) +- `lease_time` (Number) +- `server_mac` (String) + +Read-Only: + +- `id` (String) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `l2_connection_port` + +Read-Only: + +- `access_group_id` (String) +- `created_at` (String) +- `created_by` (String) +- `id` (String) +- `l2_external_network` (List of Object) (see [below for nested schema](#nestedobjatt--l2_connection_port--l2_external_network)) +- `updated_at` (String) +- `updated_by` (String) +- `version_id` (Number) + + +### Nested Schema for `l2_connection_port.l2_external_network` + +Read-Only: + +- `bridge_network_name` (String) +- `created_at` (String) +- `created_by` (String) +- `description` (String) +- `display_name` (String) +- `hypervisors` (List of String) +- `id` (String) +- `updated_at` (String) +- `updated_by` (String) +- `version_id` (Number) +- `vlan_tag` (Number) + + + + +### Nested Schema for `logical_ports_info` + +Read-Only: + +- `display_name` (String) +- `id` (String) + + + +### Nested Schema for `routers_info` + +Read-Only: + +- `display_name` (String) +- `id` (String) + + + +### Nested Schema for `status` + +Read-Only: + +- `hypervisors` (List of Object) (see [below for nested schema](#nestedobjatt--status--hypervisors)) +- `operation_status` (String) + + +### Nested Schema for `status.hypervisors` + +Read-Only: + +- `display_name` (String) +- `hypervisor_status` (String) +- `name` (String) +- `operation_status` (String) +- `synced_at` (String) diff --git a/docs/resources/security_group.md b/docs/resources/security_group.md new file mode 100644 index 00000000..8b18029f --- /dev/null +++ b/docs/resources/security_group.md @@ -0,0 +1,67 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_security_group Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_security_group (Resource) + + + + + + +## Schema + +### Required + +- `account_id` (Number) +- `name` (String) + +### Optional + +- `description` (String) +- `rules` (Block Set) (see [below for nested schema](#nestedblock--rules)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `created_at` (Number) +- `created_by` (String) +- `id` (String) The ID of this resource. +- `security_group_id` (Number) +- `updated_at` (Number) +- `updated_by` (String) + + +### Nested Schema for `rules` + +Required: + +- `direction` (String) + +Optional: + +- `ethertype` (String) +- `port_range_max` (Number) +- `port_range_min` (Number) +- `protocol` (String) +- `remote_ip_prefix` (String) + +Read-Only: + +- `id` (Number) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/snapshot.md b/docs/resources/snapshot.md new file mode 100644 index 00000000..cb9be599 --- /dev/null +++ b/docs/resources/snapshot.md @@ -0,0 +1,45 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_snapshot Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_snapshot (Resource) + + + + + + +## Schema + +### Required + +- `compute_id` (Number) ID of the compute instance to create snapshot for. +- `label` (String) text label for snapshot. Must be unique among this compute snapshots. + +### Optional + +- `rollback` (Boolean) is rollback the snapshot +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `delete_async_mode` (Boolean) async mode +- `disks` (List of Number) +- `guid` (String) guid of the snapshot +- `id` (String) The ID of this resource. +- `timestamp` (Number) timestamp + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/docs/resources/vins.md b/docs/resources/vins.md new file mode 100644 index 00000000..bf6bf788 --- /dev/null +++ b/docs/resources/vins.md @@ -0,0 +1,511 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins (Resource) + + + + + + +## Schema + +### Required + +- `name` (String) + +### Optional + +- `account_id` (Number) +- `desc` (String) Optional user-defined text description of this ViNS. +- `dns` (Set of String) +- `enable` (Boolean) +- `enable_secgroups` (Boolean) enable security groups +- `ext_ip_addr` (String) +- `ext_net` (Block List, Max: 1) (see [below for nested schema](#nestedblock--ext_net)) +- `ext_net_id` (Number) +- `force` (Boolean) +- `gid` (Number) +- `ip` (Block List) (see [below for nested schema](#nestedblock--ip)) +- `ipcidr` (String) +- `nat_rule` (Block List) (see [below for nested schema](#nestedblock--nat_rule)) +- `permanently` (Boolean) +- `pre_reservations_num` (Number) +- `restore` (Boolean) +- `rg_id` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) +- `vnfdev_redeploy` (Boolean) +- `vnfdev_restart` (Boolean) +- `zone_id` (Number) ID of the Zone to put ViNS into + +### Read-Only + +- `account_name` (String) Name of the account, which this ViNS belongs to. +- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes)) +- `created_by` (String) +- `created_time` (Number) +- `default_gw` (String) +- `default_qos` (List of Object) (see [below for nested schema](#nestedatt--default_qos)) +- `deleted_by` (String) +- `deleted_time` (Number) +- `guid` (Number) +- `id` (String) The ID of this resource. +- `lock_status` (String) +- `manager_id` (Number) +- `manager_type` (String) +- `milestones` (Number) +- `net_mask` (Number) +- `network` (String) +- `redundant` (Boolean) +- `rg_name` (String) +- `sec_vnf_dev_id` (Number) +- `status` (String) +- `updated_by` (String) +- `updated_time` (Number) +- `user_managed` (Boolean) +- `vins_id` (Number) Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored. +- `vnf_dev` (List of Object) (see [below for nested schema](#nestedatt--vnf_dev)) +- `vnfs` (List of Object) (see [below for nested schema](#nestedatt--vnfs)) +- `vxlan_id` (Number) + + +### Nested Schema for `ext_net` + +Optional: + +- `ext_net_id` (Number) +- `ext_net_ip` (String) + + + +### Nested Schema for `ip` + +Required: + +- `type` (String) + +Optional: + +- `compute_id` (Number) +- `ip_addr` (String) +- `mac_addr` (String) + + + +### Nested Schema for `nat_rule` + +Optional: + +- `ext_port_end` (Number) +- `ext_port_start` (Number) +- `int_ip` (String) +- `int_port` (Number) +- `proto` (String) + +Read-Only: + +- `rule_id` (Number) + + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) + + + +### Nested Schema for `computes` + +Read-Only: + +- `compute_id` (Number) +- `compute_name` (String) + + + +### Nested Schema for `default_qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + +### Nested Schema for `vnf_dev` + +Read-Only: + +- `_ckey` (String) +- `account_id` (Number) +- `capabilities` (List of String) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config)) +- `config_saved` (Boolean) +- `custom_pre_cfg` (Boolean) +- `desc` (String) +- `gid` (Number) +- `guid` (Number) +- `interfaces` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces)) +- `live_migration_job_id` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `vins` (List of Number) +- `vnc_password` (String) +- `vnf_id` (Number) +- `vnf_name` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnf_dev.config` + +Read-Only: + +- `mgmt` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config--mgmt)) +- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--config--resources)) + + +### Nested Schema for `vnf_dev.config.mgmt` + +Read-Only: + +- `ip_addr` (String) +- `password` (String) +- `ssh_key` (String) +- `user` (String) + + + +### Nested Schema for `vnf_dev.config.resources` + +Read-Only: + +- `cpu` (Number) +- `node_id` (Number) +- `ram` (Number) +- `uuid` (String) + + + + +### Nested Schema for `vnf_dev.interfaces` + +Read-Only: + +- `bus_number` (Number) +- `conn_id` (Number) +- `conn_type` (String) +- `def_gw` (String) +- `enable_secgroups` (Boolean) +- `enabled` (Boolean) +- `flipgroup_id` (Number) +- `guid` (String) +- `ip_address` (String) +- `libvirt_settings` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces--libvirt_settings)) +- `listen_ssh` (Boolean) +- `mac` (String) +- `mtu` (Number) +- `name` (String) +- `net_id` (Number) +- `net_mask` (Number) +- `net_type` (String) +- `node_id` (Number) +- `pci_slot` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--vnf_dev--interfaces--qos)) +- `sdn_interface_id` (String) +- `security_groups` (List of Number) +- `target` (String) +- `type` (String) +- `vnfs` (List of Number) + + +### Nested Schema for `vnf_dev.interfaces.libvirt_settings` + +Read-Only: + +- `event_idx` (String) +- `guid` (String) +- `ioeventfd` (String) +- `queues` (Number) +- `rx_queue_size` (Number) +- `tx_queue_size` (Number) +- `txmode` (String) + + + +### Nested Schema for `vnf_dev.interfaces.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + + +### Nested Schema for `vnfs` + +Read-Only: + +- `dhcp` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp)) +- `gw` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw)) +- `nat` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat)) + + +### Nested Schema for `vnfs.dhcp` + +Read-Only: + +- `_ckey` (String) +- `account_id` (Number) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--devices)) +- `dhcp_id` (Number) +- `gid` (Number) +- `guid` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.dhcp.config` + +Read-Only: + +- `default_gw` (String) +- `dns` (List of String) +- `ip_end` (String) +- `ip_start` (String) +- `lease` (Number) +- `netmask` (Number) +- `network` (String) +- `reservations` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--config--reservations)) + + +### Nested Schema for `vnfs.dhcp.config.reservations` + +Read-Only: + +- `account_id` (Number) +- `ip` (String) +- `mac` (String) +- `type` (String) +- `vm_id` (Number) + + + + +### Nested Schema for `vnfs.dhcp.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--dhcp--devices--primary)) + + +### Nested Schema for `vnfs.dhcp.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.dhcp.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) + + + + +### Nested Schema for `vnfs.gw` + +Read-Only: + +- `_ckey` (String) +- `account_id` (Number) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--devices)) +- `gid` (Number) +- `guid` (Number) +- `gw_id` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.gw.config` + +Read-Only: + +- `default_gw` (String) +- `ext_net_id` (Number) +- `ext_net_ip` (String) +- `ext_netmask` (Number) +- `qos` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--config--qos)) + + +### Nested Schema for `vnfs.gw.config.qos` + +Read-Only: + +- `e_rate` (Number) +- `guid` (String) +- `in_brust` (Number) +- `in_rate` (Number) + + + + +### Nested Schema for `vnfs.gw.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--gw--devices--primary)) + + +### Nested Schema for `vnfs.gw.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.gw.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) + + + + +### Nested Schema for `vnfs.nat` + +Read-Only: + +- `_ckey` (String) +- `account_id` (Number) +- `config` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--config)) +- `created_time` (Number) +- `devices` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--devices)) +- `gid` (Number) +- `guid` (Number) +- `lock_status` (String) +- `milestones` (Number) +- `nat_id` (Number) +- `owner_id` (Number) +- `owner_type` (String) +- `pure_virtual` (Boolean) +- `routes` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--routes)) +- `status` (String) +- `tech_status` (String) +- `type` (String) +- `zone_id` (Number) + + +### Nested Schema for `vnfs.nat.config` + +Read-Only: + +- `net_mask` (Number) +- `network` (String) +- `rules` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--config--rules)) + + +### Nested Schema for `vnfs.nat.config.rules` + +Read-Only: + +- `local_ip` (String) +- `local_port` (Number) +- `protocol` (String) +- `public_port_end` (Number) +- `public_port_start` (Number) +- `rule_id` (Number) +- `vm_id` (Number) +- `vm_name` (String) + + + + +### Nested Schema for `vnfs.nat.devices` + +Read-Only: + +- `primary` (List of Object) (see [below for nested schema](#nestedobjatt--vnfs--nat--devices--primary)) + + +### Nested Schema for `vnfs.nat.devices.primary` + +Read-Only: + +- `dev_id` (Number) +- `iface01` (String) +- `iface02` (String) + + + + +### Nested Schema for `vnfs.nat.routes` + +Read-Only: + +- `compute_ids` (List of Number) +- `destination` (String) +- `gateway` (String) +- `guid` (String) +- `netmask` (String) +- `route_id` (Number) diff --git a/docs/resources/vins_static_route.md b/docs/resources/vins_static_route.md new file mode 100644 index 00000000..b6b9de92 --- /dev/null +++ b/docs/resources/vins_static_route.md @@ -0,0 +1,45 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "decort_vins_static_route Resource - terraform-provider-decort" +subcategory: "" +description: |- + +--- + +# decort_vins_static_route (Resource) + + + + + + +## Schema + +### Required + +- `destination` (String) +- `gateway` (String) +- `netmask` (String) +- `vins_id` (Number) Unique ID of the ViNS + +### Optional + +- `route_id` (Number) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `compute_ids` (List of Number) +- `guid` (String) +- `id` (String) The ID of this resource. + + +### Nested Schema for `timeouts` + +Optional: + +- `create` (String) +- `default` (String) +- `delete` (String) +- `read` (String) +- `update` (String) diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..b4adb51f --- /dev/null +++ b/go.mod @@ -0,0 +1,94 @@ +module repository.basistech.ru/BASIS/terraform-provider-decort + +go 1.24.0 + +require ( + github.com/google/uuid v1.6.0 + github.com/hashicorp/go-cty v1.5.0 + github.com/hashicorp/terraform-plugin-docs v0.24.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1 + github.com/sirupsen/logrus v1.9.0 + golang.org/x/net v0.44.0 + repository.basistech.ru/BASIS/decort-golang-sdk v1.15.1 +) + +replace repository.basistech.ru/BASIS/decort-golang-sdk => ../decort-sdk-local + +require ( + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.2.0 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/ProtonMail/go-crypto v1.1.6 // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/bgentry/speakeasy v0.1.0 // indirect + github.com/bmatcuk/doublestar/v4 v4.9.1 // indirect + github.com/cloudflare/circl v1.6.1 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.10 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.28.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/hashicorp/cli v1.1.7 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-checkpoint v0.5.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-plugin v1.7.0 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/hc-install v0.9.2 // indirect + github.com/hashicorp/hcl/v2 v2.24.0 // indirect + github.com/hashicorp/logutils v1.0.0 // indirect + github.com/hashicorp/terraform-exec v0.24.0 // indirect + github.com/hashicorp/terraform-json v0.27.2 // indirect + github.com/hashicorp/terraform-plugin-go v0.29.0 // indirect + github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect + github.com/hashicorp/terraform-registry-address v0.4.0 // indirect + github.com/hashicorp/terraform-svchost v0.1.1 // indirect + github.com/hashicorp/yamux v0.1.2 // indirect + github.com/huandu/xstrings v1.4.0 // indirect + github.com/imdario/mergo v0.3.15 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/oklog/run v1.1.0 // indirect + github.com/posener/complete v1.2.3 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/yuin/goldmark v1.7.7 // indirect + github.com/yuin/goldmark-meta v1.1.0 // indirect + github.com/zclconf/go-cty v1.17.0 // indirect + go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect + go.uber.org/mock v0.6.0 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.30.0 // indirect + golang.org/x/tools v0.37.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect + google.golang.org/grpc v1.75.1 // indirect + google.golang.org/protobuf v1.36.9 // indirect + gopkg.in/yaml.v2 v2.3.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..777e58d2 --- /dev/null +++ b/go.sum @@ -0,0 +1,320 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0= +github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= +github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bmatcuk/doublestar/v4 v4.9.1 h1:X8jg9rRZmJd4yRy7ZeNDRnM+T3ZfHv15JiBJ/avrEXE= +github.com/bmatcuk/doublestar/v4 v4.9.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= +github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= +github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= +github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0= +github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= +github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= +github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60= +github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688= +github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/cli v1.1.7 h1:/fZJ+hNdwfTSfsxMBa9WWMlfjUZbX8/LnUxgAd7lCVU= +github.com/hashicorp/cli v1.1.7/go.mod h1:e6Mfpga9OCT1vqzFuoGZiiF/KaG9CbUfO5s3ghU3YgU= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= +github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-cty v1.5.0 h1:EkQ/v+dDNUqnuVpmS5fPqyY71NXVgT5gf32+57xY8g0= +github.com/hashicorp/go-cty v1.5.0/go.mod h1:lFUCG5kd8exDobgSfyj4ONE/dc822kiYMguVKdHGMLM= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA= +github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hc-install v0.9.2 h1:v80EtNX4fCVHqzL9Lg/2xkp62bbvQMnvPQ0G+OmtO24= +github.com/hashicorp/hc-install v0.9.2/go.mod h1:XUqBQNnuT4RsxoxiM9ZaUk0NX8hi2h+Lb6/c0OZnC/I= +github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE= +github.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/terraform-exec v0.24.0 h1:mL0xlk9H5g2bn0pPF6JQZk5YlByqSqrO5VoaNtAf8OE= +github.com/hashicorp/terraform-exec v0.24.0/go.mod h1:lluc/rDYfAhYdslLJQg3J0oDqo88oGQAdHR+wDqFvo4= +github.com/hashicorp/terraform-json v0.27.2 h1:BwGuzM6iUPqf9JYM/Z4AF1OJ5VVJEEzoKST/tRDBJKU= +github.com/hashicorp/terraform-json v0.27.2/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE= +github.com/hashicorp/terraform-plugin-docs v0.24.0 h1:YNZYd+8cpYclQyXbl1EEngbld8w7/LPOm99GD5nikIU= +github.com/hashicorp/terraform-plugin-docs v0.24.0/go.mod h1:YLg+7LEwVmRuJc0EuCw0SPLxuQXw5mW8iJ5ml/kvi+o= +github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU= +github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM= +github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= +github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1 h1:mlAq/OrMlg04IuJT7NpefI1wwtdpWudnEmjuQs04t/4= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1/go.mod h1:GQhpKVvvuwzD79e8/NZ+xzj+ZpWovdPAe8nfV/skwNU= +github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk= +github.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE= +github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= +github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= +github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= +github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= +github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= +github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= +github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= +github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= +github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU= +github.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= +github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= +github.com/zclconf/go-cty v1.17.0 h1:seZvECve6XX4tmnvRzWtJNHdscMtYEx5R7bnnVyd/d0= +github.com/zclconf/go-cty v1.17.0/go.mod h1:wqFzcImaLTI6A5HfsRwB0nj5n0MRZFwmey8YoFPPs3U= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= +go.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw= +go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= +google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/constants/constants.go b/internal/constants/constants.go new file mode 100644 index 00000000..e7124801 --- /dev/null +++ b/internal/constants/constants.go @@ -0,0 +1,42 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package constants + +// LIMIT_MAX_VINS_PER_RESGROUP set maximum number of VINs instances per Resource Group +const LIMIT_MAX_VINS_PER_RESGROUP = 4 + +// MAX_SSHKEYS_PER_COMPUTE sets maximum number of user:ssh_key pairs to authorize when creating new compute +const MAX_SSHKEYS_PER_COMPUTE = 12 + +// MAX_EXTRA_DISKS_PER_COMPUTE sets maximum number of extra disks that can be added when creating new compute +const MAX_EXTRA_DISKS_PER_COMPUTE = 12 + +// MAX_NETWORKS_PER_COMPUTE sets maximum number of vNICs per compute +const MAX_NETWORKS_PER_COMPUTE = 8 + +// MAX_CPUS_PER_COMPUTE sets maximum number of vCPUs per compute +const MAX_CPUS_PER_COMPUTE = 128 + +// MIN_RAM_PER_COMPUTE sets minimum amount of RAM per compute in MB +const MIN_RAM_PER_COMPUTE = 128 + +// RAM_DIVISIBILITY sets divisibility of RAM value +const RAM_DIVISIBILITY = 128 diff --git a/internal/constants/timeouts.go b/internal/constants/timeouts.go new file mode 100644 index 00000000..06e539f3 --- /dev/null +++ b/internal/constants/timeouts.go @@ -0,0 +1,33 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package constants + +import "time" + +// timeouts for API calls from CRUD functions of Terraform plugin +var Timeout30s = time.Second * 30 +var Timeout60s = time.Second * 60 +var Timeout180s = time.Second * 180 +var Timeout300s = time.Second * 300 +var Timeout600s = time.Second * 600 +var Timeout900s = time.Second * 900 +var Timeout20m = time.Minute * 20 +var Timeout30m = time.Minute * 30 diff --git a/internal/controller/controller.go b/internal/controller/controller.go new file mode 100644 index 00000000..42faa5ce --- /dev/null +++ b/internal/controller/controller.go @@ -0,0 +1,449 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "crypto/tls" + "fmt" + "io" + + "net/http" + "net/url" + "strconv" + "strings" + + log "github.com/sirupsen/logrus" + decort "repository.basistech.ru/BASIS/decort-golang-sdk" + "repository.basistech.ru/BASIS/decort-golang-sdk/config" + "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +// enumerated constants that define authentication modes +const ( + MODE_UNDEF = iota // this is the invalid mode - it should never be seen + MODE_LEGACY + MODE_DECS3O + MODE_JWT + MODE_BVS +) + +type ControllerCfg struct { + controller_url string // always required + auth_mode_code int // always required + auth_mode_txt string // always required, it is a text representation of auth mode + bvs_user string // required for bvs mode + bvs_password string // required for bvs mode + domain string // required for bvs mode + token config.Token // obtained from BVS provider on successful login in bvs mode + path_cfg string // the path of the configuration file entry + path_token string // the path of the token file entry + time_to_refresh int64 // the number of minutes before the expiration of the token, a refresh will be made + legacy_user string // required for legacy mode + legacy_password string // required for legacy mode + legacy_sid string // obtained from DECORT controller on successful login in legacy mode + jwt string // obtained from Outh2 provider on successful login in decs3o mode, required in jwt mode + app_id string // required for decs3o and bvs mode + app_secret string // required for decs3o and bvs mode + oauth2_url string // required for decs3o and bvs mode + decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (decs3o mode) upon successful verification + cc_client *http.Client // assigned when all initial checks successfully passed + caller interfaces.Caller +} + +func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) { + // This function first will check that all required provider parameters for the + // selected authenticator mode are set correctly and initialize ControllerCfg structure + // based on the provided parameters. + // + // Next, it will check for validity of supplied credentials by initiating connection to the specified + // DECORT controller URL and, if succeeded, completes ControllerCfg structure with the rest of computed + // parameters (e.g. JWT, session ID and Oauth2 user name). + // + // The structure created by this function should be used with subsequent calls to decortAPICall() method, + // which is a DECORT authentication mode aware wrapper around standard HTTP requests. + + ret_config := &ControllerCfg{ + controller_url: d.Get("controller_url").(string), + auth_mode_code: MODE_UNDEF, + legacy_user: d.Get("user").(string), + legacy_password: d.Get("password").(string), + legacy_sid: "", + bvs_user: d.Get("bvs_user").(string), + bvs_password: d.Get("bvs_password").(string), + domain: d.Get("domain").(string), + jwt: d.Get("jwt").(string), + app_id: d.Get("app_id").(string), + app_secret: d.Get("app_secret").(string), + oauth2_url: d.Get("oauth2_url").(string), + decort_username: "", + token: config.Token{}, + path_cfg: d.Get("path_cfg").(string), + path_token: d.Get("path_token").(string), + time_to_refresh: int64(d.Get("time_to_refresh").(int)), + } + + allow_unverified_ssl := d.Get("allow_unverified_ssl").(bool) + + if ret_config.controller_url == "" { + return nil, fmt.Errorf("empty DECORT cloud controller URL provided") + } + + // this should have already been done by StateFunc defined in Schema, but we want to be sure + ret_config.auth_mode_txt = strings.ToLower(d.Get("authenticator").(string)) + + switch ret_config.auth_mode_txt { + case "jwt": + if ret_config.jwt == "" { + return nil, fmt.Errorf("authenticator mode 'jwt' specified but no JWT provided") + } + ret_config.auth_mode_code = MODE_JWT + case "decs3o": + if ret_config.oauth2_url == "" { + return nil, fmt.Errorf("authenticator mode 'decs3o' specified but no OAuth2 URL provided") + } + if ret_config.app_id == "" { + return nil, fmt.Errorf("authenticator mode 'decs3o' specified but no Application ID provided") + } + if ret_config.app_secret == "" { + return nil, fmt.Errorf("authenticator mode 'decs3o' specified but no Secret ID provided") + } + ret_config.auth_mode_code = MODE_DECS3O + case "legacy": + // + ret_config.legacy_user = d.Get("user").(string) + if ret_config.legacy_user == "" { + return nil, fmt.Errorf("authenticator mode 'legacy' specified but no user provided") + } + ret_config.legacy_password = d.Get("password").(string) + if ret_config.legacy_password == "" { + return nil, fmt.Errorf("authenticator mode 'legacy' specified but no password provided") + } + ret_config.auth_mode_code = MODE_LEGACY + case "bvs": + if ret_config.bvs_user == "" { + return nil, fmt.Errorf("authenticator mode 'bvs' specified but no user provided") + } + if ret_config.bvs_password == "" { + return nil, fmt.Errorf("authenticator mode 'bvs' specified but no password provided") + } + if ret_config.oauth2_url == "" { + return nil, fmt.Errorf("authenticator mode 'bvs' specified but no bvs URL provided") + } + if ret_config.app_id == "" { + return nil, fmt.Errorf("authenticator mode 'bvs' specified but no Application ID provided") + } + if ret_config.app_secret == "" { + return nil, fmt.Errorf("authenticator mode 'bvs' specified but no Secret ID provided") + } + if ret_config.domain == "" { + return nil, fmt.Errorf("authenticator mode 'bvs' specified but no Domain provided") + } + ret_config.auth_mode_code = MODE_BVS + default: + return nil, fmt.Errorf("unknown authenticator mode %q provided", ret_config.auth_mode_txt) + } + + if allow_unverified_ssl { + log.Warn("ControllerConfigure: allow_unverified_ssl is set - will not check certificates!") + transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} //nolint:gosec + ret_config.cc_client = &http.Client{ + Transport: transCfg, + } + } else { + ret_config.cc_client = &http.Client{} + } + + switch ret_config.auth_mode_code { + case MODE_LEGACY: + ok, err := ret_config.validateLegacyUser() + if !ok { + return nil, err + } + ret_config.decort_username = ret_config.legacy_user + + sdkConf := config.LegacyConfig{ + Username: ret_config.legacy_user, + Password: ret_config.legacy_password, + DecortURL: ret_config.controller_url, + SSLSkipVerify: allow_unverified_ssl, + } + + ret_config.caller = decort.NewLegacy(sdkConf) + + case MODE_JWT: + // + ok, err := ret_config.validateJWT("") + if !ok { + return nil, err + } + case MODE_DECS3O: + // on success getDECS3OJWT will set config.jwt to the obtained JWT, so there is no + // need to set it once again here + // _, err := ret_config.getDECS3OJWT() + // if err != nil { + // return nil, err + // } + // we are not verifying the JWT when parsing because actual verification is done on the + // OVC controller side. Here we do parsing solely to extract Oauth2 user name (claim "user") + // and JWT issuer name (claim "iss") + // parser := jwt.Parser{} + // token, _, err := parser.ParseUnverified(ret_config.jwt, jwt.MapClaims{}) + // if err != nil { + // return nil, err + // } + // if claims, ok := token.Claims.(jwt.MapClaims); ok { + // var tbuf bytes.Buffer + // tbuf.WriteString(claims["username"].(string)) + // tbuf.WriteString("@") + // tbuf.WriteString(claims["iss"].(string)) + // ret_config.decort_username = tbuf.String() + // } else { + // return nil, fmt.Errorf("failed to extract user and iss fields from JWT token in oauth2 mode") + // } + + sdkConf := config.Config{ + AppID: ret_config.app_id, + AppSecret: ret_config.app_secret, + SSOURL: ret_config.oauth2_url, + DecortURL: ret_config.controller_url, + SSLSkipVerify: allow_unverified_ssl, + } + + ret_config.caller = decort.New(sdkConf) + case MODE_BVS: + + sdkConf := config.BVSConfig{ + AppID: ret_config.app_id, + AppSecret: ret_config.app_secret, + SSOURL: ret_config.oauth2_url, + DecortURL: ret_config.controller_url, + SSLSkipVerify: allow_unverified_ssl, + Username: ret_config.bvs_user, + Password: ret_config.bvs_password, + Domain: ret_config.domain, + Token: ret_config.token, + PathCfg: ret_config.path_cfg, + PathToken: ret_config.path_token, + TimeToRefresh: ret_config.time_to_refresh, + } + + ret_config.caller = decort.NewBVS(sdkConf) + default: + // FYI, this should never happen due to all above checks, but we want to be fool proof + return nil, fmt.Errorf("unknown authenticator mode code %d provided", ret_config.auth_mode_code) + } + + // All checks passed successfully, credentials corresponding to the selected authenticator mode + // obtained and validated. + return ret_config, nil +} + +// func (config *ControllerCfg) GetDecortUsername() string { +// return config.decort_username +// } + +// func (config *ControllerCfg) getDECS3OJWT() (string, error) { +// // Obtain JWT from the Oauth2 provider using application ID and application secret provided in config. +// if config.auth_mode_code == MODE_UNDEF { +// return "", fmt.Errorf("getOAuth2JWT method called for undefined authorization mode") +// } +// if config.auth_mode_code != MODE_DECS3O { +// return "", fmt.Errorf("getOAuth2JWT method called for incompatible authorization mode %q", config.auth_mode_txt) +// } + +// params := url.Values{} +// params.Add("grant_type", "client_credentials") +// params.Add("client_id", config.app_id) +// params.Add("client_secret", config.app_secret) +// params.Add("response_type", "id_token") +// params.Add("validity", "3600") +// params_str := params.Encode() + +// req, err := http.NewRequest("POST", config.oauth2_url+"/v1/oauth/access_token", strings.NewReader(params_str)) +// if err != nil { +// return "", err +// } +// req.Header.Set("Content-Type", "application/x-www-form-urlencoded") +// req.Header.Set("Content-Length", strconv.Itoa(len(params_str))) + +// resp, err := config.cc_client.Do(req) +// if err != nil { +// return "", err +// } +// if resp.StatusCode != http.StatusOK { +// // fmt.Println("response Status:", resp.Status) +// // fmt.Println("response Headers:", resp.Header) +// // fmt.Println("response Headers:", req.URL) +// return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q", +// resp.StatusCode, req.URL, config.app_id, params_str) +// } +// defer resp.Body.Close() + +// responseData, err := io.ReadAll(resp.Body) +// if err != nil { +// return "", err +// } + +// // validation successful - store JWT in the corresponding field of the ControllerCfg structure +// config.jwt = strings.TrimSpace(string(responseData)) + +// return config.jwt, nil +// } + +func (config *ControllerCfg) validateJWT(jwt string) (bool, error) { + /* + Validate JWT against DECORT controller. JWT can be supplied as argument to this method. If empty string supplied as + argument, JWT will be taken from config attribute. + DECORT controller URL will always be taken from the config attribute assigned at instantiation. + Validation is accomplished by attempting API call that lists account for the invoking user. + */ + if jwt == "" { + if config.jwt == "" { + return false, fmt.Errorf("validateJWT method called, but no meaningful JWT provided") + } + jwt = config.jwt + } + + if config.oauth2_url == "" { + return false, fmt.Errorf("validateJWT method called, but no OAuth2 URL provided") + } + + req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/account/list", nil) + if err != nil { + return false, err + } + + req.Header.Set("Authorization", fmt.Sprintf("bearer %s", jwt)) + // req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + // req.Header.Set("Content-Length", strconv.Itoa(0)) + + resp, err := config.cc_client.Do(req) + if err != nil { + return false, err + } + if resp.StatusCode != http.StatusOK { + return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q", + resp.StatusCode, req.URL) + } + defer resp.Body.Close() + + return true, nil +} + +func (config *ControllerCfg) validateLegacyUser() (bool, error) { + /* + Validate legacy user by obtaining a session key, which will be used for authenticating subsequent API calls + to DECORT controller. + If successful, the session key is stored in config.legacy_sid and true is returned. If unsuccessful for any + reason, the method will return false and error. + */ + if config.auth_mode_code == MODE_UNDEF { + return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode") + } + if config.auth_mode_code != MODE_LEGACY { + return false, fmt.Errorf("validateLegacyUser method called for incompatible authorization mode %q", config.auth_mode_txt) + } + + params := url.Values{} + params.Add("username", config.legacy_user) + params.Add("password", config.legacy_password) + params_str := params.Encode() + + req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/user/authenticate", strings.NewReader(params_str)) + if err != nil { + return false, err + } + + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("Content-Length", strconv.Itoa(len(params_str))) + + resp, err := config.cc_client.Do(req) + if err != nil { + return false, err + } + if resp.StatusCode != http.StatusOK { + return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q", + resp.StatusCode, config.legacy_user, config.controller_url) + } + defer resp.Body.Close() + + responseData, err := io.ReadAll(req.Body) + if err != nil { + log.Fatal(err) + } + + // validation successful - keep session ID for future use + config.legacy_sid = string(responseData) + + return true, nil +} + +func (config *ControllerCfg) CloudAPI() *cloudapi.CloudAPI { + switch config.auth_mode_code { + case MODE_LEGACY: + client, _ := config.caller.(*decort.LegacyDecortClient) + return client.CloudAPI() + case MODE_DECS3O: + client, _ := config.caller.(*decort.DecortClient) + return client.CloudAPI() + case MODE_BVS: + client, _ := config.caller.(*decort.BVSDecortClient) + return client.CloudAPI() + default: + return &cloudapi.CloudAPI{} + } +} +func (config *ControllerCfg) CloudBroker() *cloudbroker.CloudBroker { + switch config.auth_mode_code { + case MODE_LEGACY: + client, _ := config.caller.(*decort.LegacyDecortClient) + return client.CloudBroker() + case MODE_DECS3O: + client, _ := config.caller.(*decort.DecortClient) + return client.CloudBroker() + case MODE_BVS: + client, _ := config.caller.(*decort.BVSDecortClient) + return client.CloudBroker() + default: + return &cloudbroker.CloudBroker{} + } +} + +func (config *ControllerCfg) SDN() *sdn.SDN { + switch config.auth_mode_code { + case MODE_LEGACY: + client, _ := config.caller.(*decort.LegacyDecortClient) + return client.SDN() + case MODE_DECS3O: + client, _ := config.caller.(*decort.DecortClient) + return client.SDN() + case MODE_BVS: + client, _ := config.caller.(*decort.BVSDecortClient) + return client.SDN() + default: + return &sdn.SDN{} + } +} diff --git a/internal/dc/utils.go b/internal/dc/utils.go new file mode 100644 index 00000000..0f41e398 --- /dev/null +++ b/internal/dc/utils.go @@ -0,0 +1,65 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. + +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Nikita Sorokin, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package dc + +import "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + +func ErrorsToDiagnostics(errs []error) diag.Diagnostics { + if len(errs) == 0 { + return nil + } + + diags := diag.Diagnostics{} + + for _, err := range errs { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Error, + Summary: err.Error(), + }) + } + + return diags +} + +func ErrorsToWarnings(errs []error) Warnings { + w := Warnings{} + + for _, err := range errs { + w.Add(err) + } + + return w +} diff --git a/internal/dc/warnings.go b/internal/dc/warnings.go new file mode 100644 index 00000000..1aac8807 --- /dev/null +++ b/internal/dc/warnings.go @@ -0,0 +1,53 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +//Diagnostics Collector +package dc + +import "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + +type Warnings struct { + diagnostics diag.Diagnostics +} + +func (w *Warnings) Add(err error) { + if w.diagnostics == nil { + w.diagnostics = diag.Diagnostics{} + } + diagFromErr := diag.FromErr(err) + diagFromErr[0].Severity = diag.Warning + w.diagnostics = append(w.diagnostics, diagFromErr[0]) +} + +func (w Warnings) Get() diag.Diagnostics { + return w.diagnostics +} diff --git a/internal/flattens/meta.go b/internal/flattens/meta.go new file mode 100644 index 00000000..09f939de --- /dev/null +++ b/internal/flattens/meta.go @@ -0,0 +1,42 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package flattens + +import "strconv" + +func FlattenMeta(m []interface{}) []string { + output := []string{} + for _, item := range m { + switch d := item.(type) { + case string: + output = append(output, d) + case int: + output = append(output, strconv.Itoa(d)) + case int64: + output = append(output, strconv.FormatInt(d, 10)) + case float64: + output = append(output, strconv.FormatInt(int64(d), 10)) + default: + output = append(output, "") + } + } + return output +} diff --git a/internal/location/api.go b/internal/location/api.go new file mode 100644 index 00000000..e78743c4 --- /dev/null +++ b/internal/location/api.go @@ -0,0 +1,23 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package location + +const LOCATIONS_LIST_API = "/restmachine/cloudapi/locations/list" // Returns list of GridRecord on success diff --git a/internal/location/location.go b/internal/location/location.go new file mode 100644 index 00000000..b44bab5f --- /dev/null +++ b/internal/location/location.go @@ -0,0 +1,53 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package location + +import ( + "context" + "fmt" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +var DefaultGridID int + +func UtilityLocationGetDefaultGridID(ctx context.Context, m interface{}) (int, error) { + c := m.(*controller.ControllerCfg) + req := locations.ListRequest{} + + log.Debug("utilityLocationGetDefaultGridID: retrieving locations list") + locList, err := c.CloudAPI().Locations().List(ctx, req) + if err != nil { + return 0, err + } + + if len(locList.Data) == 0 { + DefaultGridID = 0 + return 0, fmt.Errorf("utilityLocationGetDefaultGridID: retrieved 0 length locations list") + } + + DefaultGridID = int(locList.Data[0].GID) + log.Debugf("utilityLocationGetDefaultGridID: default location GridID %d, name %s", DefaultGridID, locList.Data[0].Name) + + return DefaultGridID, nil +} diff --git a/internal/location/models.go b/internal/location/models.go new file mode 100644 index 00000000..dac3a756 --- /dev/null +++ b/internal/location/models.go @@ -0,0 +1,31 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package location + +type LocationRecord struct { + GridID int `json:"gid"` + Id int `json:"id"` + LocationCode string `json:"locationCode"` + Name string `json:"name"` + Flag string `json:"flag"` +} + +type LocationsListResp []LocationRecord diff --git a/internal/provider/data_sources_map.go b/internal/provider/data_sources_map.go new file mode 100644 index 00000000..51025e8c --- /dev/null +++ b/internal/provider/data_sources_map.go @@ -0,0 +1,327 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package provider + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/audit" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/dpdknet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/flipgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/k8s" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/locations" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/secgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/snapshot" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/stpolicy" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/trunk" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vfpool" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/zone" + accessgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/access_group" + defaultsecuritypolicy "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/default_security_policy" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/hypervisors" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/logicalports" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/netobjgroups" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/segments" + + cb_account "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/account" + cb_audit "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/audit" + cb_disks "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/disks" + cb_dpdknet "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/dpdknet" + cb_extnet "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/extnet" + cb_flipgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/flipgroup" + cb_grid "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/grid" + cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image" + cb_k8ci "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8ci" + cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s" + cb_kvmvm "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/kvmvm" + cb_lb "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/lb" + cb_node "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/node" + cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice" + cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg" + cb_secgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/secgroup" + cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep" + cb_stpolicy "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/stpolicy" + cb_trunk "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/trunk" + cb_user "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/user" + cb_vfpool "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vfpool" + cb_vins "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins" + cb_zone "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/zone" +) + +func newDataSourcesMap() map[string]*schema.Resource { + return map[string]*schema.Resource{ + "decort_account": account.DataSourceAccount(), + "decort_audit": audit.DataSourceAudit(), + "decort_audit_list": audit.DataSourceAuditList(), + "decort_resgroup": rg.DataSourceResgroup(), + "decort_kvmvm": kvmvm.DataSourceCompute(), + "decort_kvmvm_list": kvmvm.DataSourceComputeList(), + "decort_kvmvm_audits": kvmvm.DataSourceComputeAudits(), + "decort_kvmvm_get_audits": kvmvm.DataSourceComputeGetAudits(), + "decort_kvmvm_get_console_url": kvmvm.DataSourceComputeGetConsoleUrl(), + "decort_kvmvm_get_log": kvmvm.DataSourceComputeGetLog(), + "decort_kvmvm_pfw_list": kvmvm.DataSourceComputePfwList(), + "decort_kvmvm_user_list": kvmvm.DataSourceComputeUserList(), + "decort_kvmvm_snapshot_usage": kvmvm.DataSourceComputeSnapshotUsage(), + "decort_k8s": k8s.DataSourceK8s(), + "decort_k8s_list": k8s.DataSourceK8sList(), + "decort_k8s_list_deleted": k8s.DataSourceK8sListDeleted(), + "decort_k8s_wg": k8s.DataSourceK8sWg(), + "decort_k8s_wg_list": k8s.DataSourceK8sWgList(), + "decort_k8s_computes": k8s.DataSourceK8sComputes(), + "decort_k8ci_list": k8s.DataSourceK8CIList(), + "decort_vins": vins.DataSourceVins(), + "decort_vins_list": vins.DataSourceVinsList(), + "decort_vins_audits": vins.DataSourceVinsAudits(), + "decort_vins_ip_list": vins.DataSourceVinsIpList(), + "decort_vins_list_deleted": vins.DataSourceVinsListDeleted(), + "decort_vins_ext_net_list": vins.DataSourceVinsExtNetList(), + "decort_vins_nat_rule_list": vins.DataSourceVinsNatRuleList(), + "decort_vins_static_route_list": vins.DataSourceStaticRouteList(), + "decort_vins_static_route": vins.DataSourceStaticRoute(), + "decort_snapshot_list": snapshot.DataSourceSnapshotList(), + "decort_disk": disks.DataSourceDisk(), + "decort_disk_list": disks.DataSourceDiskList(), + "decort_rg_list": rg.DataSourceRgList(), + "decort_rg_affinity_group_computes": rg.DataSourceRgAffinityGroupComputes(), + "decort_rg_affinity_groups_list": rg.DataSourceRgAffinityGroupsList(), + "decort_rg_affinity_groups_get": rg.DataSourceRgAffinityGroupsGet(), + "decort_rg_audits": rg.DataSourceRgAudits(), + "decort_rg_list_computes": rg.DataSourceRgListComputes(), + "decort_rg_list_deleted": rg.DataSourceRgListDeleted(), + "decort_rg_list_lb": rg.DataSourceRgListLb(), + "decort_rg_list_pfw": rg.DataSourceRgListPfw(), + "decort_rg_list_vins": rg.DataSourceRgListVins(), + "decort_rg_usage": rg.DataSourceRgUsage(), + "decort_disk_list_deleted": disks.DataSourceDiskListDeleted(), + "decort_disk_list_unattached": disks.DataSourceDiskListUnattached(), + "decort_disk_snapshot": disks.DataSourceDiskSnapshot(), + "decort_disk_snapshot_list": disks.DataSourceDiskSnapshotList(), + "decort_disk_replication": disks.DataSourceDiskReplication(), + "decort_account_list": account.DataSourceAccountList(), + "decort_account_computes_list": account.DataSourceAccountComputesList(), + "decort_account_disks_list": account.DataSourceAccountDisksList(), + "decort_account_vins_list": account.DataSourceAccountVinsList(), + "decort_account_audits_list": account.DataSourceAccountAuditsList(), + "decort_account_rg_list": account.DataSourceAccountRGList(), + "decort_account_consumed_units": account.DataSourceAccountConsumedUnits(), + "decort_account_consumed_units_by_type": account.DataSourceAccountConsumedUnitsByType(), + "decort_account_reserved_units": account.DataSourceAccountReservedUnits(), + "decort_account_templates_list": account.DataSourceAccountTemplatessList(), + "decort_account_deleted_list": account.DataSourceAccountDeletedList(), + "decort_account_flipgroups_list": account.DataSourceAccountFlipGroupsList(), + "decort_bservice_list": bservice.DataSourceBasicServiceList(), + "decort_bservice": bservice.DataSourceBasicService(), + "decort_bservice_snapshot_list": bservice.DataSourceBasicServiceSnapshotList(), + "decort_bservice_group": bservice.DataSourceBasicServiceGroup(), + "decort_bservice_deleted_list": bservice.DataSourceBasicServiceDeletedList(), + "decort_dpdknet": dpdknet.DataSourceDPDKNet(), + "decort_dpdknet_list": dpdknet.DataSourceDPDKNetList(), + "decort_extnet_list": extnet.DataSourceExtnetList(), + "decort_extnet_computes_list": extnet.DataSourceExtnetComputesList(), + "decort_extnet": extnet.DataSourceExtnet(), + "decort_extnet_default": extnet.DataSourceExtnetDefault(), + "decort_extnet_reserved_ip_list": extnet.DataSourceExtnetReservedIp(), + "decort_locations_list": locations.DataSourceLocationsList(), + "decort_location_url": locations.DataSourceLocationUrl(), + "decort_image_list": image.DataSourceImageList(), + "decort_image": image.DataSourceImage(), + "decort_lb": lb.DataSourceLB(), + "decort_lb_list": lb.DataSourceLBList(), + "decort_lb_list_deleted": lb.DataSourceLBListDeleted(), + "decort_flipgroup": flipgroup.DataSourceFlipgroup(), + "decort_flipgroup_list": flipgroup.DataSourceFlipGroupList(), + "decort_vfpool": vfpool.DataSourceVFPool(), + "decort_vfpool_list": vfpool.DataSourceVFPoolList(), + "decort_account_resource_consumption_list": account.DataSourceAccountResourceConsumptionList(), + "decort_account_resource_consumption_get": account.DataSourceAccountResourceConsumptionGet(), + "decort_kvmvm_list_deleted": kvmvm.DataSourceComputeListDeleted(), + "decort_kvmvm_vgpu_list": kvmvm.DataSourceComputeVGPUList(), + "decort_kvmvm_pci_device_list": kvmvm.DataSourceComputePCIDeviceList(), + "decort_kvmvm_cpu_alignment_profile": kvmvm.DataSourceComputeCPUAlignmentProfile(), + "decort_k8s_wg_cloud_init": k8s.DataSourceK8sWgCloudInit(), + "decort_rg_resource_consumption_list": rg.DataSourceRGResourceConsumptionList(), + "decort_rg_resource_consumption_get": rg.DataSourceRGResourceConsumptionGet(), + "decort_sep_and_pools_available_list": sep.DataSourceAvailableSEPAndPoolsList(), + "decort_storage_policy": stpolicy.DataSourceStoragePolicy(), + "decort_storage_policy_list": stpolicy.DataSourceStoragePolicyList(), + "decort_security_group": secgroup.DataSourceSecurityGroup(), + "decort_security_group_list": secgroup.DataSourceSecurityGroupList(), + "decort_trunk": trunk.DataSourceTrunk(), + "decort_trunk_list": trunk.DataSourceTrunkList(), + "decort_zone": zone.DataSourceZone(), + "decort_zone_list": zone.DataSourceZoneList(), + + "decort_cb_account": cb_account.DataSourceAccount(), + "decort_cb_account_list": cb_account.DataSourceAccountList(), + "decort_cb_account_computes_list": cb_account.DataSourceAccountComputesList(), + "decort_cb_account_list_deleted": cb_account.DataSourceAccountDeletedList(), + "decort_cb_account_disks_list": cb_account.DataSourceAccountDisksList(), + "decort_cb_account_flipgroups_list": cb_account.DataSourceAccountFlipGroupsList(), + "decort_cb_account_rg_list": cb_account.DataSourceAccountRGList(), + "decort_cb_account_vins_list": cb_account.DataSourceAccountVinsList(), + "decort_cb_account_resource_consumption_get": cb_account.DataSourceAccountResourceConsumptionGet(), + "decort_cb_account_resource_consumption_list": cb_account.DataSourceAccountResourceConsumptionList(), + "decort_cb_account_audits_list": cb_account.DataSourceAccountAuditsList(), + "decort_cb_account_available_templates_list": cb_account.DataSourceAccountAvailableTemplatesList(), + "decort_cb_audit": cb_audit.DataSourceAudit(), + "decort_cb_audit_list": cb_audit.DataSourceAuditList(), + "decort_cb_audit_linked_jobs": cb_audit.DataSourceAuditLinkedJobs(), + "decort_cb_audits_export_to_file": cb_audit.DataSourceAuditsToFile(), + "decort_cb_dpdknet": cb_dpdknet.DataSourceDPDKNet(), + "decort_cb_dpdknet_list": cb_dpdknet.DataSourceDPDKNetList(), + "decort_cb_extnet": cb_extnet.DataSourceExtnetCB(), + "decort_cb_extnet_list": cb_extnet.DataSourceExtnetListCB(), + "decort_cb_extnet_default": cb_extnet.DataSourceExtnetDefaultCB(), + "decort_cb_extnet_reserved_ip_list": cb_extnet.DataSourceExtnetReservedIp(), + "decort_cb_extnet_static_route_list": cb_extnet.DataSourceStaticRouteList(), + "decort_cb_extnet_static_route": cb_extnet.DataSourceStaticRoute(), + "decort_cb_image": cb_image.DataSourceImage(), + "decort_cb_grid": cb_grid.DataSourceGrid(), + "decort_cb_grid_get_status": cb_grid.DataSourceGridGetStatus(), + "decort_cb_grid_post_status": cb_grid.DataSourceGridPostStatus(), + "decort_cb_grid_get_diagnosis": cb_grid.DataSourceGridGetDiagnosis(), + "decort_cb_grid_get_settings": cb_grid.DataSourceGridGetSettings(), + "decort_cb_grid_list": cb_grid.DataSourceGridList(), + "decort_cb_grid_list_emails": cb_grid.DataSourceGridListEmails(), + "decort_cb_grid_list_consumption": cb_grid.DataSourceGridListConsumption(), + "decort_cb_grid_get_consumption": cb_grid.DataSourceGridGetConsumption(), + "decort_cb_image_list": cb_image.DataSourceImageList(), + "decort_cb_kvmvm": cb_kvmvm.DataSourceCompute(), + "decort_cb_kvmvm_affinity_relations": cb_kvmvm.DataSourceComputeAffinityRelations(), + "decort_cb_kvmvm_audits": cb_kvmvm.DataSourceComputeAudits(), + "decort_cb_kvmvm_boot_order_get": cb_kvmvm.DataSourceComputeBootOrderGet(), + "decort_cb_kvmvm_get_audits": cb_kvmvm.DataSourceComputeGetAudits(), + "decort_cb_kvmvm_get_console_url": cb_kvmvm.DataSourceComputeGetConsoleUrl(), + "decort_cb_kvmvm_get_log": cb_kvmvm.DataSourceComputeGetLog(), + "decort_cb_kvmvm_list": cb_kvmvm.DataSourceComputeList(), + "decort_cb_kvmvm_list_deleted": cb_kvmvm.DataSourceComputeListDeleted(), + "decort_cb_kvmvm_migrate_storage_info": cb_kvmvm.DataSourceComputeMigrateStorageInfo(), + "decort_cb_kvmvm_pci_device_list": cb_kvmvm.DataSourceComputePCIDeviceList(), + "decort_cb_kvmvm_pfw_list": cb_kvmvm.DataSourceComputePfwList(), + "decort_cb_kvmvm_snapshot_list": cb_kvmvm.DataSourceComputeSnapshotList(), + "decort_cb_kvmvm_snapshot_usage": cb_kvmvm.DataSourceComputeSnapshotUsage(), + "decort_cb_kvmvm_user_list": cb_kvmvm.DataSourceComputeUserList(), + "decort_cb_kvmvm_vgpu_list": cb_kvmvm.DataSourceComputeVGPUList(), + "decort_cb_kvmvm_cpu_alignment_profile": cb_kvmvm.DataSourceComputeCPUAlignmentProfile(), + "decort_cb_node": cb_node.DataSourceNode(), + "decort_cb_node_list": cb_node.DataSourceNodeList(), + "decort_cb_node_network_info": cb_node.DataSourceNodeNetworkInfo(), + "decort_cb_node_pci_devices": cb_node.DataSourceNodePCIDevices(), + "decort_cb_disk": cb_disks.DataSourceDisk(), + "decort_cb_disk_list": cb_disks.DataSourceDiskList(), + "decort_cb_disk_list_deleted": cb_disks.DataSourceDiskListDeleted(), + "decort_cb_disk_list_unattached": cb_disks.DataSourceDiskListUnattached(), + "decort_cb_disk_snapshot": cb_disks.DataSourceDiskSnapshot(), + "decort_cb_disk_snapshot_list": cb_disks.DataSourceDiskSnapshotList(), + "decort_cb_disk_replication": cb_disks.DataSourceDiskReplication(), + "decort_cb_pcidevice": cb_pcidevice.DataSourcePcidevice(), + "decort_cb_pcidevice_list": cb_pcidevice.DataSourcePcideviceList(), + "decort_cb_rg": cb_rg.DataSourceResgroup(), + "decort_cb_rg_affinity_group_computes": cb_rg.DataSourceRgAffinityGroupComputes(), + "decort_cb_rg_affinity_groups_get": cb_rg.DataSourceRgAffinityGroupsGet(), + "decort_cb_rg_affinity_groups_list": cb_rg.DataSourceRgAffinityGroupsList(), + "decort_cb_rg_resource_consumption_get": cb_rg.DataSourceRGResourceConsumptionGet(), + "decort_cb_rg_resource_consumption_list": cb_rg.DataSourceRGResourceConsumptionList(), + "decort_cb_rg_audits": cb_rg.DataSourceRgAudits(), + "decort_cb_rg_list": cb_rg.DataSourceRgList(), + "decort_cb_rg_list_deleted": cb_rg.DataSourceRgListDeleted(), + "decort_cb_rg_list_computes": cb_rg.DataSourceRgListComputes(), + "decort_cb_rg_list_lb": cb_rg.DataSourceRgListLb(), + "decort_cb_rg_list_pfw": cb_rg.DataSourceRgListPfw(), + "decort_cb_rg_list_vins": cb_rg.DataSourceRgListVins(), + "decort_cb_rg_usage": cb_rg.DataSourceRgUsage(), + "decort_cb_sep_list": cb_sep.DataSourceSepList(), + "decort_cb_sep": cb_sep.DataSourceSep(), + "decort_cb_sep_and_pools_available_list": cb_sep.DataSourceAvailableSEPAndPoolsList(), + "decort_cb_sep_consumption": cb_sep.DataSourceSepConsumption(), + "decort_cb_sep_disk_list": cb_sep.DataSourceSepDiskList(), + "decort_cb_sep_config": cb_sep.DataSourceSepConfig(), + "decort_cb_sep_pool": cb_sep.DataSourceSepPool(), + "decort_cb_sep_template": cb_sep.DataSourceSepTemplate(), + "decort_cb_lb": cb_lb.DataSourceLB(), + "decort_cb_lb_list": cb_lb.DataSourceLBList(), + "decort_cb_lb_list_deleted": cb_lb.DataSourceLBListDeleted(), + "decort_cb_flipgroup_list": cb_flipgroup.DataSourceFlipgroupList(), + "decort_cb_flipgroup": cb_flipgroup.DataSourceFlipgroup(), + "decort_cb_security_group": cb_secgroup.DataSourceSecurityGroup(), + "decort_cb_security_group_list": cb_secgroup.DataSourceSecurityGroupList(), + "decort_cb_storage_policy": cb_stpolicy.DataSourceStoragePolicy(), + "decort_cb_storage_policy_list": cb_stpolicy.DataSourceStoragePolicyList(), + "decort_cb_trunk": cb_trunk.DataSourceTrunk(), + "decort_cb_trunk_list": cb_trunk.DataSourceTrunkList(), + "decort_cb_user": cb_user.DataSourceUser(), + "decort_cb_user_get_audit": cb_user.DataSourceUserGetAudit(), + "decort_cb_user_list": cb_user.DataSourceUserList(), + "decort_cb_vfpool": cb_vfpool.DataSourceVFPool(), + "decort_cb_vfpool_list": cb_vfpool.DataSourceVFPoolList(), + "decort_cb_vins": cb_vins.DataSourceVins(), + "decort_cb_vins_list": cb_vins.DataSourceVinsList(), + "decort_cb_vins_audits": cb_vins.DataSourceVinsAudits(), + "decort_cb_vins_ip_list": cb_vins.DataSourceVinsIpList(), + "decort_cb_vins_list_deleted": cb_vins.DataSourceVinsListDeleted(), + "decort_cb_vins_ext_net_list": cb_vins.DataSourceVinsExtNetList(), + "decort_cb_vins_nat_rule_list": cb_vins.DataSourceVinsNatRuleList(), + "decort_cb_vins_static_route": cb_vins.DataSourceStaticRoute(), + "decort_cb_vins_static_route_list": cb_vins.DataSourceStaticRouteList(), + "decort_cb_k8ci": cb_k8ci.DataSourceK8CI(), + "decort_cb_k8ci_list": cb_k8ci.DataSourceK8CIList(), + "decort_cb_k8ci_list_deleted": cb_k8ci.DataSourceK8CIListDeleted(), + "decort_cb_k8s": cb_k8s.DataSourceK8s(), + "decort_cb_k8s_list": cb_k8s.DataSourceK8sList(), + "decort_cb_k8s_list_deleted": cb_k8s.DataSourceK8sListDeleted(), + "decort_cb_k8s_wg": cb_k8s.DataSourceK8sWg(), + "decort_cb_k8s_wg_cloud_init": cb_k8s.DataSourceK8sWgCloudInit(), + "decort_cb_k8s_wg_list": cb_k8s.DataSourceK8sWgList(), + "decort_cb_k8s_computes": cb_k8s.DataSourceK8sComputes(), + "decort_cb_zone": cb_zone.DataSourceZone(), + "decort_cb_zone_list": cb_zone.DataSourceZoneList(), + "decort_cb_zone_cpu_alignment_profile": cb_zone.DataSourceZoneCPUAlignmentProfile(), + "decort_cb_zone_cpu_alignment_profile_list": cb_zone.DataSourceZoneCPUAlignmentProfileList(), + "decort_cb_zone_cpu_alignment_profile_test": cb_zone.DataSourceZoneCPUAlignmentProfileTest(), + + "decort_sdn_access_group": accessgroup.DataSourceAccessGroup(), + "decort_sdn_access_group_list": accessgroup.DataSourceAccessGroupList(), + "decort_sdn_access_group_user_list": accessgroup.DataSourceAccessGroupUserList(), + "decort_sdn_default_security_policy_list": defaultsecuritypolicy.DataSourceDefaultSecurityPolicyList(), + "decort_sdn_segment": segments.DataSourceSegment(), + "decort_sdn_segment_list": segments.DataSourceSegmentList(), + + "decort_sdn_hypervisor": hypervisors.DataSourceHypervisor(), + "decort_sdn_hypervisor_list": hypervisors.DataSourceHypervisorList(), + + "decort_sdn_logical_port": logicalports.DataSourceLogicalPort(), + "decort_sdn_logical_port_get_by_unique_identifier": logicalports.DataSourceLogicalPortByUniqueID(), + "decort_sdn_logical_port_list": logicalports.DataSourceLogicalPortList(), + + "decort_sdn_network_object_group": netobjgroups.DataSourceNetworkObjectGroup(), + "decort_sdn_network_object_group_list": netobjgroups.DataSourceNetworkObjectGroupList(), + } +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go new file mode 100644 index 00000000..b276d30a --- /dev/null +++ b/internal/provider/provider.go @@ -0,0 +1,169 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package provider + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "golang.org/x/net/context" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/location" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" +) + +func Provider() *schema.Provider { + return &schema.Provider{ + Schema: map[string]*schema.Schema{ + "authenticator": { + Type: schema.TypeString, + Required: true, + StateFunc: statefuncs.StateFuncToLower, + ValidateFunc: validation.StringInSlice([]string{"decs3o", "legacy", "jwt", "bvs"}, true), // ignore case while validating + Description: "Authentication mode to use when connecting to DECORT cloud API. Should be one of 'decs3o', 'legacy', 'jwt' or 'bvs'.", + }, + + "oauth2_url": { + Type: schema.TypeString, + Optional: true, + StateFunc: statefuncs.StateFuncToLower, + DefaultFunc: schema.EnvDefaultFunc("DECORT_OAUTH2_URL", nil), + Description: "OAuth2 application URL in 'decs3o' and 'bvs' authentication mode.", + }, + + "controller_url": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: statefuncs.StateFuncToLower, + DefaultFunc: schema.EnvDefaultFunc("DECORT_CONTROLLER_URL", nil), + Description: "URL of DECORT Cloud controller to use. API calls will be directed to this URL.", + }, + + "user": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("DECORT_USER", nil), + Description: "User name for DECORT cloud API operations in 'legacy' authentication mode.", + }, + + "password": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("DECORT_PASSWORD", nil), + Description: "User password for DECORT cloud API operations in 'legacy' authentication mode.", + }, + + "bvs_user": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("DECORT_BVS_USER", nil), + Description: "User name for DECORT cloud API operations in 'bvs' authentication mode.", + }, + + "bvs_password": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("DECORT_BVS_PASSWORD", nil), + Description: "User password for DECORT cloud API operations in 'bvs' authentication mode.", + }, + + "domain": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("DECORT_DOMAIN", nil), + Description: "User password for DECORT cloud API operations in 'bvs' authentication mode.", + }, + + "app_id": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_ID", nil), + Description: "Application ID to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode.", + }, + + "app_secret": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_SECRET", nil), + Description: "Application secret to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode.", + }, + + "jwt": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("DECORT_JWT", nil), + Description: "JWT to access DECORT cloud API in 'jwt' authentication mode.", + }, + + "allow_unverified_ssl": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only!", + }, + + "path_cfg": { + Type: schema.TypeString, + Optional: true, + Description: "The path of the configuration file entry", + }, + + "path_token": { + Type: schema.TypeString, + Optional: true, + Description: "The path of the token file entry", + }, + + "time_to_refresh": { + Type: schema.TypeInt, + Optional: true, + Description: "The number of minutes before the expiration of the token, a refresh will be made", + }, + }, + + ResourcesMap: newResourcesMap(), + + DataSourcesMap: newDataSourcesMap(), + + ConfigureContextFunc: providerConfigure, + } +} + +func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { + decsController, err := controller.ControllerConfigure(d) + if err != nil { + return nil, diag.FromErr(err) + } + + gridId, err := location.UtilityLocationGetDefaultGridID(ctx, decsController) + if err != nil { + return nil, diag.FromErr(err) + } + if gridId == 0 { + return nil, diag.FromErr(fmt.Errorf("providerConfigure: invalid default Grid ID = 0")) + } + + return decsController, nil +} diff --git a/internal/provider/resource_map.go b/internal/provider/resource_map.go new file mode 100644 index 00000000..631dc2eb --- /dev/null +++ b/internal/provider/resource_map.go @@ -0,0 +1,137 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package provider + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/flipgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/k8s" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/pfw" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/secgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/snapshot" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vins" + accessgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/access_group" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/hypervisors" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/logicalports" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/netobjgroups" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/sdn/segments" + + cb_account "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/account" + cb_disks "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/disks" + cb_dpdknet "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/dpdknet" + cb_extnet "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/extnet" + cb_flipgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/flipgroup" + cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image" + cb_k8ci "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8ci" + cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s" + cb_kvmvm "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/kvmvm" + cb_lb "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/lb" + cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice" + cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg" + cb_secgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/secgroup" + cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep" + cb_stpolicy "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/stpolicy" + cb_trunk "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/trunk" + cb_user "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/user" + cb_vfpool "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vfpool" + cb_vins "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins" + cb_zone "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/zone" +) + +func newResourcesMap() map[string]*schema.Resource { + return map[string]*schema.Resource{ + "decort_resgroup": rg.ResourceResgroup(), + "decort_kvmvm": kvmvm.ResourceCompute(), + "decort_disk": disks.ResourceDisk(), + "decort_disk_snapshot": disks.ResourceDiskSnapshot(), + //"decort_disk_replication": disks.ResourceDiskReplication(), + "decort_vins": vins.ResourceVins(), + "decort_pfw": pfw.ResourcePfw(), + "decort_k8s": k8s.ResourceK8s(), + "decort_k8s_wg": k8s.ResourceK8sWg(), + "decort_k8s_cp": k8s.ResourceK8sCP(), + "decort_snapshot": snapshot.ResourceSnapshot(), + "decort_account": account.ResourceAccount(), + "decort_bservice": bservice.ResourceBasicService(), + "decort_bservice_group": bservice.ResourceBasicServiceGroup(), + "decort_image": image.ResourceImage(), + "decort_image_from_blank_compute": image.ResourceImageFromBlankCompute(), + "decort_image_from_platform_disk": image.ResourceImageFromPlatformDisk(), + "decort_image_virtual": image.ResourceImageVirtual(), + "decort_lb": lb.ResourceLB(), + "decort_lb_backend": lb.ResourceLBBackend(), + "decort_lb_backend_server": lb.ResourceLBBackendServer(), + "decort_lb_frontend": lb.ResourceLBFrontend(), + "decort_lb_frontend_bind": lb.ResourceLBFrontendBind(), + "decort_flipgroup": flipgroup.ResourceFlipgroup(), + "decort_vins_static_route": vins.ResourceStaticRoute(), + "decort_security_group": secgroup.ResourceSecurityGroup(), + + "decort_cb_account": cb_account.ResourceAccount(), + "decort_cb_dpdknet": cb_dpdknet.ResourceDPDKNet(), + "decort_cb_extnet": cb_extnet.ResourceExtnetCB(), + "decort_cb_extnet_static_route": cb_extnet.ResourceStaticRoute(), + "decort_cb_disk": cb_disks.ResourceDisk(), + "decort_cb_disk_snapshot": cb_disks.ResourceDiskSnapshot(), + //"decort_cb_disk_replication": cb_disks.ResourceDiskReplication(), + "decort_cb_image": cb_image.ResourceImage(), + "decort_cb_image_from_blank_compute": cb_image.ResourceImageFromBlankCompute(), + "decort_cb_image_from_platform_disk": cb_image.ResourceImageFromPlatformDisk(), + "decort_cb_virtual_image": cb_image.ResourceVirtualImage(), + "decort_cb_cdrom_image": cb_image.ResourceCDROMImage(), + "decort_cb_multi_image": cb_image.ResourceMultiImage(), + "decort_cb_pcidevice": cb_pcidevice.ResourcePcidevice(), + "decort_cb_sep": cb_sep.ResourceSep(), + "decort_cb_sep_config": cb_sep.ResourceSepConfig(), + "decort_cb_kvmvm": cb_kvmvm.ResourceCompute(), + "decort_cb_vins": cb_vins.ResourceVins(), + "decort_cb_k8ci": cb_k8ci.ResourceK8CI(), + "decort_cb_k8s_cp": cb_k8s.ResourceK8sCP(), + "decort_cb_k8s_wg": cb_k8s.ResourceK8sWg(), + "decort_cb_vins_static_route": cb_vins.ResourceStaticRoute(), + "decort_cb_flipgroup": cb_flipgroup.ResourceFlipgroup(), + "decort_cb_lb": cb_lb.ResourceLB(), + "decort_cb_lb_backend": cb_lb.ResourceLBBackend(), + "decort_cb_lb_backend_server": cb_lb.ResourceLBBackendServer(), + "decort_cb_lb_frontend": cb_lb.ResourceLBFrontend(), + "decort_cb_lb_frontend_bind": cb_lb.ResourceLBFrontendBind(), + "decort_cb_rg": cb_rg.ResourceResgroup(), + "decort_cb_storage_policy": cb_stpolicy.ResourceStoragePolicy(), + "decort_cb_security_group": cb_secgroup.ResourceSecurityGroup(), + "decort_cb_trunk": cb_trunk.ResourceTrunk(), + "decort_cb_user": cb_user.ResourceUser(), + "decort_cb_vfpool": cb_vfpool.ResourceVFPool(), + "decort_cb_zone": cb_zone.ResourceZone(), + + "decort_sdn_segment": segments.ResourceSegment(), + "decort_sdn_access_group": accessgroup.ResourceAccessGroup(), + "decort_sdn_hypervisor": hypervisors.ResourceHypervisor(), + "decort_sdn_logical_port": logicalports.ResourceLogicalPort(), + "decort_sdn_network_object_group": netobjgroups.ResourceNetworkObjectGroup(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account.go b/internal/service/cloudapi/account/data_source_account.go new file mode 100644 index 00000000..8543493f --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account.go @@ -0,0 +1,379 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + acc, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenAccount(d, *acc) + d.SetId(strconv.Itoa(int(acc.ID))) + + return nil +} + +func aclSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "can_be_deleted": { + Type: schema.TypeBool, + Computed: true, + }, + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "emails": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + } + + return res +} + +func resourceLimitsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } + + return res +} + +func sepsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func computesSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "started": { + Type: schema.TypeInt, + Computed: true, + }, + "stopped": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func machinesSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "halted": { + Type: schema.TypeInt, + Computed: true, + }, + "running": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func dataSourceAccountSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + }, + + "dc_location": { + Type: schema.TypeString, + Computed: true, + }, + // "resources": { + // Type: schema.TypeList, + // Computed: true, + // Elem: &schema.Resource{ + // Schema: resourcesSchemaMake(), + // }, + // }, + "zone_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "default_zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclSchemaMake(), + }, + }, + "company": { + Type: schema.TypeString, + Computed: true, + }, + "companyurl": { + Type: schema.TypeString, + Computed: true, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deactivation_time": { + Type: schema.TypeFloat, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "displayname": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: resourceLimitsSchemaMake(), + }, + }, + "send_access_emails": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computesSchemaMake(), + }, + }, + "machines": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: machinesSchemaMake(), + }, + }, + "vinses": { + Type: schema.TypeInt, + Computed: true, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } + return res +} + +func DataSourceAccount() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_audits_list.go b/internal/service/cloudapi/account/data_source_account_audits_list.go new file mode 100644 index 00000000..21ca7a5b --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_audits_list.go @@ -0,0 +1,128 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func flattenAccountAuditsList(aal account.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, aa := range aal { + temp := map[string]interface{}{ + "call": aa.Call, + "responsetime": aa.ResponseTime, + "statuscode": aa.StatusCode, + "timestamp": aa.Timestamp, + "user": aa.User, + } + res = append(res, temp) + } + return res + +} + +func dataSourceAccountAuditsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountAuditsList, err := utilityAccountAuditsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountAuditsList(accountAuditsList)) + + return nil +} + +func dataSourceAccountAuditsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "call": { + Type: schema.TypeString, + Computed: true, + }, + "responsetime": { + Type: schema.TypeFloat, + Computed: true, + }, + "statuscode": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } + return res +} + +func DataSourceAccountAuditsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountAuditsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountAuditsListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_computes_list.go b/internal/service/cloudapi/account/data_source_account_computes_list.go new file mode 100644 index 00000000..6f65152d --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_computes_list.go @@ -0,0 +1,263 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func flattenAccountComputesList(acl *account.ListComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, acc := range acl.Data { + temp := map[string]interface{}{ + "account_id": acc.AccountID, + "account_name": acc.AccountName, + "cpus": acc.CPUs, + "created_by": acc.CreatedBy, + "created_time": acc.CreatedTime, + "deleted_by": acc.DeletedBy, + "deleted_time": acc.DeletedTime, + "compute_id": acc.ComputeID, + "compute_name": acc.ComputeName, + "ram": acc.RAM, + "registered": acc.Registered, + "rg_id": acc.RGID, + "rg_name": acc.RGName, + "status": acc.Status, + "tech_status": acc.TechStatus, + "total_disks_size": acc.TotalDisksSize, + "updated_by": acc.UpdatedBy, + "updated_time": acc.UpdatedTime, + "user_managed": acc.UserManaged, + "vins_connected": acc.VINSConnected, + } + res = append(res, temp) + } + return res + +} + +func dataSourceAccountComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountComputesList, err := utilityAccountComputesListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountComputesList(accountComputesList)) + d.Set("entry_count", accountComputesList.EntryCount) + + return nil +} + +func dataSourceAccountComputesListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by compute ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by compute name", + }, + "rg_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by RG name", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by tech. status", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by IP address", + }, + "extnet_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by extnet name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by extnet ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "cpus": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "total_disks_size": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vins_connected": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceAccountComputesList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountComputesListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountComputesListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_consumed_units.go b/internal/service/cloudapi/account/data_source_account_consumed_units.go new file mode 100644 index 00000000..7d4ed6f5 --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_consumed_units.go @@ -0,0 +1,111 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountConsumedUnitsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountConsumedUnits, err := utilityAccountConsumedUnitsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("cu_c", accountConsumedUnits.CUC) + d.Set("cu_d", accountConsumedUnits.CUD) + d.Set("cu_dm", accountConsumedUnits.CUDM) + d.Set("cu_i", accountConsumedUnits.CUI) + d.Set("cu_m", accountConsumedUnits.CUM) + d.Set("gpu_units", accountConsumedUnits.GPUUnits) + + return nil +} + +func dataSourceAccountConsumedUnitsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + } + return res +} + +func DataSourceAccountConsumedUnits() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountConsumedUnitsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountConsumedUnitsSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_consumed_units_by_type.go b/internal/service/cloudapi/account/data_source_account_consumed_units_by_type.go new file mode 100644 index 00000000..7c246caf --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_consumed_units_by_type.go @@ -0,0 +1,91 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountConsumedUnitsByTypeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + result, err := utilityAccountConsumedUnitsByTypeCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("cu_result", result) + + return nil +} + +func dataSourceAccountConsumedUnitsByTypeSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "cu_type": { + Type: schema.TypeString, + Required: true, + Description: "cloud unit resource type", + }, + "cu_result": { + Type: schema.TypeFloat, + Computed: true, + }, + } + return res +} + +func DataSourceAccountConsumedUnitsByType() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountConsumedUnitsByTypeRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountConsumedUnitsByTypeSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_deleted_list.go b/internal/service/cloudapi/account/data_source_account_deleted_list.go new file mode 100644 index 00000000..96ed76b6 --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_deleted_list.go @@ -0,0 +1,78 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountDeletedListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountDeletedList, err := utilityAccountDeletedListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountList(accountDeletedList)) + d.Set("entry_count", accountDeletedList.EntryCount) + + return nil +} + +func dataSourceAccountDeletedListSchemaMake() map[string]*schema.Schema { + temp := dataSourceAccountListSchemaMake() + delete(temp, "status") + return temp +} + +func DataSourceAccountDeletedList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountDeletedListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountDeletedListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_disks_list.go b/internal/service/cloudapi/account/data_source_account_disks_list.go new file mode 100644 index 00000000..971fac92 --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_disks_list.go @@ -0,0 +1,177 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func flattenAccountDisksList(adl *account.ListDisks) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, ad := range adl.Data { + temp := map[string]interface{}{ + "disk_id": ad.ID, + "disk_name": ad.Name, + "pool": ad.Pool, + "sep_id": ad.SEPID, + "shareable": ad.Shareable, + "size_max": ad.SizeMax, + "type": ad.Type, + } + res = append(res, temp) + } + return res + +} + +func dataSourceAccountDisksListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountDisksList, err := utilityAccountDisksListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountDisksList(accountDisksList)) + d.Set("entry_count", accountDisksList.EntryCount) + + return nil +} + +func dataSourceAccountDisksListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "disk_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by disk ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by disk name", + }, + "disk_max_size": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by disk max size", + }, + "type": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by disk type", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceAccountDisksList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountDisksListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountDisksListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_flipgroups_list.go b/internal/service/cloudapi/account/data_source_account_flipgroups_list.go new file mode 100644 index 00000000..5fdc2246 --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_flipgroups_list.go @@ -0,0 +1,258 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func flattenAccountFlipGroupsList(afgl *account.ListFLIPGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, afg := range afgl.Data { + temp := map[string]interface{}{ + "account_id": afg.AccountID, + "client_type": afg.ClientType, + "conn_type": afg.ConnType, + "created_by": afg.CreatedBy, + "created_time": afg.CreatedTime, + "default_gw": afg.DefaultGW, + "deleted_by": afg.DeletedBy, + "deleted_time": afg.DeletedTime, + "desc": afg.Description, + "gid": afg.GID, + "guid": afg.GUID, + "fg_id": afg.ID, + "ip": afg.IP, + "milestones": afg.Milestones, + "fg_name": afg.Name, + "net_id": afg.NetID, + "net_type": afg.NetType, + "netmask": afg.NetMask, + "status": afg.Status, + "updated_by": afg.UpdatedBy, + "updated_time": afg.UpdatedTime, + } + res = append(res, temp) + } + return res + +} + +func dataSourceAccountFlipGroupsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountFlipGroupsList, err := utilityAccountFlipGroupsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountFlipGroupsList(accountFlipGroupsList)) + d.Set("entry_count", accountFlipGroupsList.EntryCount) + + return nil +} + +func dataSourceAccountFlipGroupsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ViNS ID", + }, + "vins_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by ViNS name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by extnet ID", + }, + "by_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by IP", + }, + "flipgroup_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by flipgroup ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "fg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "fg_name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceAccountFlipGroupsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountFlipGroupsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountFlipGroupsListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_get_resource_consumption.go b/internal/service/cloudapi/account/data_source_account_get_resource_consumption.go new file mode 100644 index 00000000..a0925483 --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_get_resource_consumption.go @@ -0,0 +1,149 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountResourceConsumptionGetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountResourceConsumptionRec, err := utilityAccountResourceConsumptionGetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenResourceConsumption(d, accountResourceConsumptionRec) + return nil +} + +func dataSourceAccountResourceConsumptionGetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + }, + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceAccResourceSchemaMake(), + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceAccResourceSchemaMake(), + }, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceResourceLimitsSchemaMake(), + }, + }, + } + + return res +} + +func dataSourceResourceLimitsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } + + return res +} + +func DataSourceAccountResourceConsumptionGet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountResourceConsumptionGetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountResourceConsumptionGetSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_list.go b/internal/service/cloudapi/account/data_source_account_list.go new file mode 100644 index 00000000..a44d0c59 --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_list.go @@ -0,0 +1,251 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func flattenAccountList(al *account.ListAccounts) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, acc := range al.Data { + temp := map[string]interface{}{ + "acl": flattenRgAcl(acc.ACL), + "compute_features": acc.ComputeFeatures, + "created_time": acc.CreatedTime, + "desc": acc.Description, + "deleted_time": acc.DeletedTime, + "deleted_by": acc.DeletedBy, + "account_id": acc.ID, + "account_name": acc.Name, + "status": acc.Status, + "updated_time": acc.UpdatedTime, + "updated_by": acc.UpdatedBy, + "zone_ids": acc.ZoneIDs, + } + res = append(res, temp) + } + return res +} + +func flattenRgAcl(rgAcls []account.ListRecordACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, rgAcl := range rgAcls { + temp := map[string]interface{}{ + "explicit": rgAcl.IsExplicit, + "guid": rgAcl.GUID, + "right": rgAcl.Rights, + "status": rgAcl.Status, + "type": rgAcl.Type, + "user_group_id": rgAcl.UgroupID, + } + res = append(res, temp) + } + return res +} + +func dataSourceAccountListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountList, err := utilityAccountListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountList(accountList)) + d.Set("entry_count", accountList.EntryCount) + + return nil +} + +func dataSourceAccountListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "acl": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by ACL", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "zone_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceAccountList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_reserved_units.go b/internal/service/cloudapi/account/data_source_account_reserved_units.go new file mode 100644 index 00000000..8e2ec66b --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_reserved_units.go @@ -0,0 +1,111 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountReservedUnitsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountReservedUnits, err := utilityAccountReservedUnitsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("cu_c", accountReservedUnits.CUC) + d.Set("cu_d", accountReservedUnits.CUD) + d.Set("cu_dm", accountReservedUnits.CUDM) + d.Set("cu_i", accountReservedUnits.CUI) + d.Set("cu_m", accountReservedUnits.CUM) + d.Set("gpu_units", accountReservedUnits.GPUUnits) + + return nil +} + +func dataSourceAccountReservedUnitsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + } + return res +} + +func DataSourceAccountReservedUnits() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountReservedUnitsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountReservedUnitsSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_resource_consumption_list.go b/internal/service/cloudapi/account/data_source_account_resource_consumption_list.go new file mode 100644 index 00000000..ad3736e7 --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_resource_consumption_list.go @@ -0,0 +1,195 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountResourceConsumptionListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountResourceConsumptionList, err := utilityAccountResourceConsumptionListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccResourceConsumption(accountResourceConsumptionList)) + d.Set("entry_count", accountResourceConsumptionList.EntryCount) + return nil +} + +func dataSourceAccountResourceConsumptionListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceAccResourceSchemaMake(), + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceAccResourceSchemaMake(), + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceSepsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + } + return res +} + +func dataSourceAccResourceSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "ext_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + + "policies": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceSepsSchemaMake(), + }, + }, + }, + }, + }, + + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceSepsSchemaMake(), + }, + }, + } + return res +} + +func DataSourceAccountResourceConsumptionList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountResourceConsumptionListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountResourceConsumptionListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_rg_list.go b/internal/service/cloudapi/account/data_source_account_rg_list.go new file mode 100644 index 00000000..1f3b6680 --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_rg_list.go @@ -0,0 +1,368 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func flattenAccountRGList(argl *account.ListRG) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, arg := range argl.Data { + temp := map[string]interface{}{ + "computes": flattenAccRGComputes(arg.Computes), + "resources": flattenAccRGResources(arg.Resources), + "created_by": arg.CreatedBy, + "created_time": arg.CreatedTime, + "desc": arg.Description, + "deleted_by": arg.DeletedBy, + "deleted_time": arg.DeletedTime, + "rg_id": arg.RGID, + "milestones": arg.Milestones, + "rg_name": arg.RGName, + "status": arg.Status, + "updated_by": arg.UpdatedBy, + "updated_time": arg.UpdatedTime, + "vinses": arg.VINSes, + } + res = append(res, temp) + } + return res + +} + +func flattenAccRGComputes(argc account.RGComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "started": argc.Started, + "stopped": argc.Stopped, + } + res = append(res, temp) + return res +} + +func flattenAccResourceHack(r account.LimitsRG) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": r.CPU, + "disksize": r.DiskSize, + "extips": r.ExtIPs, + "gpu": r.GPU, + "ram": r.RAM, + //"seps": flattenAccountSeps(r.SEPs), + } + res = append(res, temp) + return res +} + +func flattenAccResourceRg(r account.Resource) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": r.CPU, + "disksize": r.DiskSize, + "extips": r.ExtIPs, + "gpu": r.GPU, + "ram": r.RAM, + } + res = append(res, temp) + return res +} + +func flattenAccRGResources(argr account.RGResources) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "consumed": flattenAccResourceRg(argr.Consumed), + "limits": flattenAccResourceHack(argr.Limits), + "reserved": flattenAccResourceRg(argr.Reserved), + } + res = append(res, temp) + return res +} + +func dataSourceAccountRGListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountRGList, err := utilityAccountRGListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountRGList(accountRGList)) + d.Set("entry_count", accountRGList.EntryCount) + + return nil +} + +func dataSourceAccountRGListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ViNS ID", + }, + "vm_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by VM ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "started": { + Type: schema.TypeInt, + Computed: true, + }, + "stopped": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "resources": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disksize": { + Type: schema.TypeInt, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + + "limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disksize": { + Type: schema.TypeInt, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disksize": { + Type: schema.TypeInt, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vinses": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceAccountRGList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountRGListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountRGListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_templates_list.go b/internal/service/cloudapi/account/data_source_account_templates_list.go new file mode 100644 index 00000000..42069e19 --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_templates_list.go @@ -0,0 +1,191 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func flattenAccountTemplatesList(atl *account.ListTemplates) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(atl.Data)) + for _, at := range atl.Data { + temp := map[string]interface{}{ + "unc_path": at.UNCPath, + "account_id": at.AccountID, + "desc": at.Description, + "template_id": at.ID, + "template_name": at.Name, + "public": at.Public, + "size": at.Size, + "status": at.Status, + "type": at.Type, + "username": at.Username, + } + res = append(res, temp) + } + return res + +} + +func dataSourceAccountTemplatesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountTemplatesList, err := utilityAccountTemplatesListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountTemplatesList(accountTemplatesList)) + d.Set("entry_count", accountTemplatesList.EntryCount) + return nil +} + +func dataSourceAccountTemplatesListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "include_deleted": { + Type: schema.TypeBool, + Optional: true, + }, + "image_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by image id", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "type": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by type", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "template_id": { + Type: schema.TypeInt, + Computed: true, + }, + "template_name": { + Type: schema.TypeString, + Computed: true, + }, + "public": { + Type: schema.TypeBool, + Computed: true, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceAccountTemplatessList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountTemplatesListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountTemplatesListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/data_source_account_vins_list.go b/internal/service/cloudapi/account/data_source_account_vins_list.go new file mode 100644 index 00000000..cda7ca66 --- /dev/null +++ b/internal/service/cloudapi/account/data_source_account_vins_list.go @@ -0,0 +1,238 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func flattenAccountVinsList(avl *account.ListVINS) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, av := range avl.Data { + temp := map[string]interface{}{ + "account_id": av.AccountID, + "account_name": av.AccountName, + "computes": av.Computes, + "created_by": av.CreatedBy, + "created_time": av.CreatedTime, + "deleted_by": av.DeletedBy, + "deleted_time": av.DeletedTime, + "external_ip": av.ExternalIP, + "extnet_id": av.ExtnetId, + "free_ips": av.FreeIPs, + "vin_id": av.ID, + "vin_name": av.Name, + "network": av.Network, + "pri_vnf_dev_id": av.PriVNFDevID, + "rg_id": av.RGID, + "rg_name": av.RGName, + "status": av.Status, + "updated_by": av.UpdatedBy, + "updated_time": av.UpdatedTime, + } + res = append(res, temp) + } + return res + +} + +func dataSourceAccountVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountVinsList, err := utilityAccountVinsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountVinsList(accountVinsList)) + d.Set("entry_count", accountVinsList.EntryCount) + + return nil +} + +func dataSourceAccountVinsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ViNS ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by external IP", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "computes": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "vin_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vin_name": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "pri_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceAccountVinsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountVinsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountVinsListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/flattens.go b/internal/service/cloudapi/account/flattens.go new file mode 100644 index 00000000..b64035be --- /dev/null +++ b/internal/service/cloudapi/account/flattens.go @@ -0,0 +1,242 @@ +package account + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" +) + +func flattenAccount(d *schema.ResourceData, acc account.RecordAccount) error { + d.Set("dc_location", acc.DCLocation) + d.Set("desc", acc.Description) + d.Set("acl", flattenAccAcl(acc.ACL)) + d.Set("company", acc.Company) + d.Set("companyurl", acc.CompanyURL) + d.Set("compute_features", acc.ComputeFeatures) + d.Set("created_by", acc.CreatedBy) + d.Set("created_time", acc.CreatedTime) + d.Set("deactivation_time", acc.DeactivationTime) + d.Set("desc", acc.Description) + d.Set("deleted_by", acc.DeletedBy) + d.Set("deleted_time", acc.DeletedTime) + d.Set("displayname", acc.DisplayName) + d.Set("enable", flattenEnabled(acc.Status)) + d.Set("guid", acc.GUID) + d.Set("account_id", acc.ID) + d.Set("account_name", acc.Name) + d.Set("resource_limits", flattenAccResourceLimits(acc.ResourceLimits)) + d.Set("send_access_emails", acc.SendAccessEmails) + d.Set("status", acc.Status) + d.Set("updated_by", acc.UpdatedBy) + d.Set("updated_time", acc.UpdatedTime) + d.Set("version", acc.Version) + d.Set("vins", acc.VINS) + d.Set("vinses", acc.VINSes) + d.Set("computes", flattenAccComputes(acc.Computes)) + d.Set("machines", flattenAccMachines(acc.Machines)) + d.Set("cpu_allocation_parameter", acc.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", acc.CPUAllocationRatio) + d.Set("default_zone_id", acc.DefaultZoneID) + d.Set("storage_policy_ids", acc.StoragePolicyIDs) + d.Set("zone_ids", flattenZones(acc.ZoneIDs)) + + if username, ok := d.GetOk("username"); ok { + d.Set("username", username) + } else { + d.Set("username", acc.ACL[0].UgroupID) + } + + return nil +} + +func flattenAccountResource(d *schema.ResourceData, acc account.RecordAccount) error { + d.Set("dc_location", acc.DCLocation) + d.Set("desc", acc.Description) + d.Set("acl", flattenAccAcl(acc.ACL)) + d.Set("company", acc.Company) + d.Set("companyurl", acc.CompanyURL) + d.Set("compute_features", acc.ComputeFeatures) + d.Set("created_by", acc.CreatedBy) + d.Set("created_time", acc.CreatedTime) + d.Set("deactivation_time", acc.DeactivationTime) + d.Set("desc", acc.Description) + d.Set("deleted_by", acc.DeletedBy) + d.Set("deleted_time", acc.DeletedTime) + d.Set("displayname", acc.DisplayName) + d.Set("enable", flattenEnabled(acc.Status)) + d.Set("guid", acc.GUID) + d.Set("account_id", acc.ID) + d.Set("account_name", acc.Name) + d.Set("resource_limits", flattenAccResourceLimits(acc.ResourceLimits)) + d.Set("send_access_emails", acc.SendAccessEmails) + d.Set("status", acc.Status) + d.Set("updated_by", acc.UpdatedBy) + d.Set("updated_time", acc.UpdatedTime) + d.Set("version", acc.Version) + d.Set("vins", acc.VINS) + d.Set("vinses", acc.VINSes) + d.Set("computes", flattenAccComputes(acc.Computes)) + d.Set("machines", flattenAccMachines(acc.Machines)) + d.Set("cpu_allocation_parameter", acc.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", acc.CPUAllocationRatio) + d.Set("default_zone_id", acc.DefaultZoneID) + d.Set("storage_policy_ids", acc.StoragePolicyIDs) + d.Set("zone_ids", flattenZonesInResource(acc.ZoneIDs)) + + return nil +} + +func flattenEnabled(status string) bool { + return status == "CONFIRMED" +} + +func flattenAccComputes(acs account.Computes) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "started": acs.Started, + "stopped": acs.Stopped, + } + res = append(res, temp) + return res +} + +func flattenAccMachines(ams account.Machines) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "running": ams.Running, + "halted": ams.Halted, + } + res = append(res, temp) + return res +} + +func flattenAccAcl(acls []account.RecordACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, acls := range acls { + temp := map[string]interface{}{ + "can_be_deleted": acls.CanBeDeleted, + "explicit": acls.IsExplicit, + "guid": acls.GUID, + "right": acls.Rights, + "status": acls.Status, + "type": acls.Type, + "emails": acls.Emails, + "user_group_id": acls.UgroupID, + } + res = append(res, temp) + } + return res +} + +func flattenResourceConsumption(d *schema.ResourceData, acc *account.RecordResourceConsumption) { + d.Set("account_id", acc.AccountID) + d.Set("consumed", flattenAccResource(acc.Consumed)) + d.Set("reserved", flattenAccResource(acc.Reserved)) + d.Set("resource_limits", flattenAccResourceLimits(acc.ResourceLimits)) +} + +func flattenAccResourceLimits(rl account.ResourceLimits) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cu_c": rl.CUC, + "cu_d": rl.CUD, + "cu_dm": rl.CUDM, + "cu_i": rl.CUI, + "cu_m": rl.CUM, + "gpu_units": rl.GPUUnits, + "storage_policy": flattenSTPolicy(rl.StoragePolicy), + } + res = append(res, temp) + return res + +} + +func flattenSTPolicy(ast []account.StoragePolicyItem) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ast)) + for _, item := range ast { + temp := map[string]interface{}{ + "id": item.ID, + "limit": item.Limit, + } + res = append(res, temp) + } + return res +} + +func flattenAccountSeps(seps map[string]map[string]account.DiskUsage) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for sepKey, sepVal := range seps { + for dataKey, dataVal := range sepVal { + temp := map[string]interface{}{ + "sep_id": sepKey, + "data_name": dataKey, + "disk_size": dataVal.DiskSize, + "disk_size_max": dataVal.DiskSizeMax, + } + res = append(res, temp) + } + } + return res +} + +func flattenAccResource(r account.Resource) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": r.CPU, + "disk_size": r.DiskSize, + "disk_size_max": r.DiskSizeMax, + "ext_ips": r.ExtIPs, + "gpu": r.GPU, + "ram": r.RAM, + "seps": flattenAccountSeps(r.SEPs), + "policies": flattenAccountPolicies(r.Policies), + } + res = append(res, temp) + return res +} + +func flattenAccountPolicies(policies map[string]account.Policy) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for k, dataVal := range policies { + temp := map[string]interface{}{ + "id": k, + "disk_size": dataVal.DiskSize, + "disk_size_max": dataVal.DiskSizeMax, + "seps": flattenAccountSeps(dataVal.SEPs), + } + res = append(res, temp) + } + return res +} + +func flattenAccResourceConsumption(lrc *account.ListResourceConsumption) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(lrc.Data)) + for _, rc := range lrc.Data { + temp := map[string]interface{}{ + "consumed": flattenAccResource(rc.Consumed), + "reserved": flattenAccResource(rc.Reserved), + "account_id": rc.AccountID, + } + res = append(res, temp) + } + return res +} + +func flattenZones(zones []account.ZoneID) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, zone := range zones { + temp := map[string]interface{}{ + "id": zone.ID, + "name": zone.Name, + } + res = append(res, temp) + } + return res +} + +func flattenZonesInResource(zones []account.ZoneID) []int64 { + res := make([]int64, 0) + for _, zone := range zones { + res = append(res, zone.ID) + } + return res +} diff --git a/internal/service/cloudapi/account/resource_account.go b/internal/service/cloudapi/account/resource_account.go new file mode 100644 index 00000000..48f5aa6b --- /dev/null +++ b/internal/service/cloudapi/account/resource_account.go @@ -0,0 +1,706 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + return diag.Errorf( + "Only users with admin privileges are able to create accounts. Contact your platform administrator.\nUse 'terraform import decort_account. ' command to import existing account configuration") +} + +func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccountRead: called for account with ID: %v", d.Id()) + + // c := m.(*controller.ControllerCfg) + + acc, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch acc.Status { + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceAccountCreate(ctx, d, m) + case status.Destroying: + return diag.Errorf("The account is in progress with status: %s", acc.Status) + case status.Deleted: + // id, _ := strconv.ParseUint(d.Id(), 10, 64) + + // req := account.RestoreRequest{ + // AccountID: id, + // } + + // _, err := c.CloudAPI().Account().Restore(ctx, req) + // if err != nil { + // return diag.FromErr(err) + // } + + // hasChanged = true + case status.Disabled: + log.Debugf("The account is in status: %s, troubles may occur with update. Please, enable account first.", acc.Status) + case status.Confirmed: + } + + if hasChanged { + acc, err = utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + flattenAccountResource(d, *acc) + + return nil +} + +func resourceAccountDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccountDelete") + c := m.(*controller.ControllerCfg) + + _, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + req := account.DeleteRequest{ + AccountID: uint64(d.Get("account_id").(int)), + Permanently: d.Get("permanently").(bool), + } + + taskID, err := c.CloudAPI().Account().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskID, `"`), + } + + for { + time.Sleep(time.Second * 5) + task, err := c.CloudAPI().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceAccountDelete: delete account - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot delete account: %v", task.Error)) + } + break + } + } + + d.SetId("") + + return nil +} + +func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccountUpdate") + c := m.(*controller.ControllerCfg) + + acc, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + + hasChanged := false + + switch acc.Status { + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceAccountCreate(ctx, d, m) + case status.Destroying: + return diag.Errorf("The account is in progress with status: %s", acc.Status) + case status.Deleted: + if d.Get("restore").(bool) { + req := account.RestoreRequest{ + AccountID: accountId, + } + + taskID, err := c.CloudAPI().Account().Restore(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskID, `"`), + } + + for { + time.Sleep(time.Second * 5) + task, err := c.CloudAPI().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceAccountUpdate: restore account - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot restore account: %v", task.Error)) + } + break + } + } + + hasChanged = true + } + case status.Disabled: + log.Debugf("The account is in status: %s, troubles may occur with update. Please, enable account first.", acc.Status) + case status.Confirmed: + } + + if hasChanged { + acc, err = utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChange("enable") { + reqSwitch := account.DisableEnableRequest{ + AccountID: accountId, + } + enable := d.Get("enable").(bool) + + if enable { + + _, err := c.CloudAPI().Account().Enable(ctx, reqSwitch) + if err != nil { + return diag.FromErr(err) + + } + } else { + + _, err := c.CloudAPI().Account().Disable(ctx, reqSwitch) + if err != nil { + return diag.FromErr(err) + } + + } + } + + req := account.UpdateRequest{ + AccountID: accountId, + } + + updated := false + + if d.HasChange("account_name") { + req.Name = d.Get("account_name").(string) + updated = true + } + + if d.HasChange("desc") { + req.Description = d.Get("desc").(string) + updated = true + } + + if d.HasChange("resource_limits") { + resLimit := d.Get("resource_limits").([]interface{})[0] + resLimitConv := resLimit.(map[string]interface{}) + + if resLimitConv["cu_m"] != nil { + maxMemCap := int(resLimitConv["cu_m"].(float64)) + if maxMemCap == 0 { + req.MaxMemoryCapacity = -1 + } else { + req.MaxMemoryCapacity = int64(maxMemCap) + } + updated = true + } + if resLimitConv["cu_d"] != nil { + maxDiskCap := int(resLimitConv["cu_d"].(float64)) + if maxDiskCap == 0 { + req.MaxVDiskCapacity = -1 + } else { + req.MaxVDiskCapacity = int64(maxDiskCap) + } + updated = true + } + if resLimitConv["cu_c"] != nil { + maxCPUCap := int(resLimitConv["cu_c"].(float64)) + if maxCPUCap == 0 { + req.MaxCPUCapacity = -1 + } else { + req.MaxCPUCapacity = int64(maxCPUCap) + } + updated = true + } + if resLimitConv["cu_i"] != nil { + maxNumPublicIP := int(resLimitConv["cu_i"].(float64)) + if maxNumPublicIP == 0 { + req.MaxNumPublicIP = -1 + } else { + req.MaxNumPublicIP = int64(maxNumPublicIP) + } + updated = true + } + if resLimitConv["gpu_units"] != nil { + gpuUnits := int(resLimitConv["gpu_units"].(float64)) + if gpuUnits == 0 { + req.GPUUnits = -1 + } else { + req.GPUUnits = int64(gpuUnits) + } + updated = true + } + } + + if d.HasChange("send_access_emails") { + req.SendAccessEmails = d.Get("send_access_emails").(bool) + updated = true + } + + if updated { + _, err := c.CloudAPI().Account().Update(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("default_zone_id") { + req.DefaultZoneID = uint64(d.Get("default_zone_id").(int)) + updated = true + } + + if updated { + _, err := c.CloudAPI().Account().Update(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("users") { + deletedUsers := make([]interface{}, 0) + addedUsers := make([]interface{}, 0) + updatedUsers := make([]interface{}, 0) + + old, new_ := d.GetChange("users") + oldConv := old.([]interface{}) + newConv := new_.([]interface{}) + for _, el := range oldConv { + if !isContainsUser(newConv, el) { + deletedUsers = append(deletedUsers, el) + } + } + for _, el := range newConv { + if !isContainsUser(oldConv, el) { + duplicate := false + for _, user := range acc.ACL { + if user.UgroupID == el.(map[string]interface{})["user_id"].(string) { + duplicate = true + } + } + if !duplicate { + addedUsers = append(addedUsers, el) + } + } else { + if isChangedUser(oldConv, el) { + updatedUsers = append(updatedUsers, el) + } + } + } + + if len(deletedUsers) > 0 { + for _, user := range deletedUsers { + userConv := user.(map[string]interface{}) + + req := account.DeleteUserRequest{ + AccountID: accountId, + UserID: userConv["user_id"].(string), + } + _, err := c.CloudAPI().Account().DeleteUser(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if len(addedUsers) > 0 { + for _, user := range addedUsers { + userConv := user.(map[string]interface{}) + + req := account.AddUserRequest{ + AccountID: accountId, + UserID: userConv["user_id"].(string), + AccessType: strings.ToUpper(userConv["access_type"].(string)), + } + + _, err := c.CloudAPI().Account().AddUser(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if len(updatedUsers) > 0 { + for _, user := range updatedUsers { + userConv := user.(map[string]interface{}) + + req := account.UpdateUserRequest{ + AccountID: accountId, + UserID: userConv["user_id"].(string), + AccessType: strings.ToUpper(userConv["access_type"].(string)), + } + + _, err := c.CloudAPI().Account().UpdateUser(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + } + + return resourceAccountRead(ctx, d, m) +} + +func isContainsUser(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["user_id"].(string) == elConv["user_id"].(string) { + return true + } + } + return false +} + +func isChangedUser(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["user_id"].(string) == elConv["user_id"].(string) && + (!strings.EqualFold(elOldConv["access_type"].(string), elConv["access_type"].(string))) { + return true + } + } + return false +} + +func resourceAccountSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_name": { + Type: schema.TypeString, + Required: true, + Description: "account name", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Description: "description", + }, + "emailaddress": { + Type: schema.TypeString, + Optional: true, + Description: "email", + }, + "send_access_emails": { + Type: schema.TypeBool, + Optional: true, + Description: "if true send emails when a user is granted access to resources", + }, + "users": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "user_id": { + Type: schema.TypeString, + Required: true, + }, + "access_type": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "default_zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "email", + }, + "zone_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + Description: "restore a deleted account", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "whether to completely delete the account", + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "enable/disable account", + }, + "resource_limits": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "dc_location": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclSchemaMake(), + }, + }, + "company": { + Type: schema.TypeString, + Computed: true, + }, + "companyurl": { + Type: schema.TypeString, + Computed: true, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deactivation_time": { + Type: schema.TypeFloat, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "displayname": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computesSchemaMake(), + }, + }, + "machines": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: machinesSchemaMake(), + }, + }, + "vinses": { + Type: schema.TypeInt, + Computed: true, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } +} + +func ResourceAccount() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceAccountCreate, + ReadContext: resourceAccountRead, + UpdateContext: resourceAccountUpdate, + DeleteContext: resourceAccountDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceAccountSchemaMake(), + } +} diff --git a/internal/service/cloudapi/account/utility_account.go b/internal/service/cloudapi/account/utility_account.go new file mode 100644 index 00000000..092cdb7c --- /dev/null +++ b/internal/service/cloudapi/account/utility_account.go @@ -0,0 +1,68 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.RecordAccount, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + if (strconv.Itoa(d.Get("account_id").(int))) != "0" { + id = uint64(d.Get("account_id").(int)) + } else { + idParsed, _ := strconv.Atoi(d.Id()) + id = uint64(idParsed) + } + + req := account.GetRequest{ + AccountID: id, + } + + log.Debugf("utilityAccountCheckPresence: load account") + account, err := c.CloudAPI().Account().Get(ctx, req) + if err != nil { + return nil, err + } + + return account, nil +} diff --git a/internal/service/cloudapi/account/utility_account_audits_list.go b/internal/service/cloudapi/account/utility_account_audits_list.go new file mode 100644 index 00000000..46eeaa61 --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_audits_list.go @@ -0,0 +1,62 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountAuditsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAudits, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + id = uint64(d.Get("account_id").(int)) + + req := account.AuditsRequest{ + AccountID: id, + } + + log.Debugf("utilityAccountAuditsListCheckPresence: load account list") + accountAuditsList, err := c.CloudAPI().Account().Audits(ctx, req) + if err != nil { + return nil, err + } + + return accountAuditsList, nil +} diff --git a/internal/service/cloudapi/account/utility_account_computes_list.go b/internal/service/cloudapi/account/utility_account_computes_list.go new file mode 100644 index 00000000..306f9fa1 --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_computes_list.go @@ -0,0 +1,106 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListComputes, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + id = uint64(d.Get("account_id").(int)) + + req := account.ListComputesRequest{ + AccountID: id, + } + + if compute_id, ok := d.GetOk("compute_id"); ok { + req.ComputeID = uint64(compute_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if rg_name, ok := d.GetOk("rg_name"); ok { + req.RGName = rg_name.(string) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if ip_address, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ip_address.(string) + } + + if extnet_name, ok := d.GetOk("extnet_name"); ok { + req.ExtNetName = extnet_name.(string) + } + + if extnet_id, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnet_id.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityAccountComputesListCheckPresence: load account list") + accountComputesList, err := c.CloudAPI().Account().ListComputes(ctx, req) + if err != nil { + return nil, err + } + + return accountComputesList, nil +} diff --git a/internal/service/cloudapi/account/utility_account_consumed_units.go b/internal/service/cloudapi/account/utility_account_consumed_units.go new file mode 100644 index 00000000..8957c592 --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_consumed_units.go @@ -0,0 +1,62 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountConsumedUnitsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ResourceLimits, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + id = uint64(d.Get("account_id").(int)) + + req := account.GetConsumedAccountUnitsRequest{ + AccountID: id, + } + + log.Debugf("utilityAccountConsumedUnitsCheckPresence: load account list") + accountConsumedUnits, err := c.CloudAPI().Account().GetConsumedAccountUnits(ctx, req) + if err != nil { + return nil, err + } + + return accountConsumedUnits, nil +} diff --git a/internal/service/cloudapi/account/utility_account_consumed_units_by_type.go b/internal/service/cloudapi/account/utility_account_consumed_units_by_type.go new file mode 100644 index 00000000..ee441c5c --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_consumed_units_by_type.go @@ -0,0 +1,66 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + "strings" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountConsumedUnitsByTypeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (float64, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + var cuType string + + id = uint64(d.Get("account_id").(int)) + cuType = strings.ToUpper(d.Get("cu_type").(string)) + + req := account.GetConsumedCloudUnitsByTypeRequest{ + AccountID: id, + CUType: cuType, + } + + log.Debugf("utilityAccountConsumedUnitsByTypeCheckPresence") + result, err := c.CloudAPI().Account().GetConsumedCloudUnitsByType(ctx, req) + if err != nil { + return 0, err + } + + return result, nil +} diff --git a/internal/service/cloudapi/account/utility_account_deleted_list.go b/internal/service/cloudapi/account/utility_account_deleted_list.go new file mode 100644 index 00000000..6ddbdaa1 --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_deleted_list.go @@ -0,0 +1,80 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListAccounts, error) { + c := m.(*controller.ControllerCfg) + + req := account.ListDeletedRequest{} + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if acl, ok := d.GetOk("acl"); ok { + req.ACL = acl.(string) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + log.Debugf("utilityAccountDeletedListCheckPresence: load") + accountDeletedList, err := c.CloudAPI().Account().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + return accountDeletedList, nil +} diff --git a/internal/service/cloudapi/account/utility_account_disks_list.go b/internal/service/cloudapi/account/utility_account_disks_list.go new file mode 100644 index 00000000..506e16fe --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_disks_list.go @@ -0,0 +1,88 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountDisksListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListDisks, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + id = uint64(d.Get("account_id").(int)) + + req := account.ListDisksRequest{ + AccountID: id, + } + + if disk_id, ok := d.GetOk("disk_id"); ok { + req.DiskID = uint64(disk_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if disk_max_size, ok := d.GetOk("disk_max_size"); ok { + req.DiskMaxSize = uint64(disk_max_size.(int)) + } + + if typeVal, ok := d.GetOk("type"); ok { + req.Type = typeVal.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + accountDisksList, err := c.CloudAPI().Account().ListDisks(ctx, req) + if err != nil { + return nil, err + } + + return accountDisksList, nil +} diff --git a/internal/service/cloudapi/account/utility_account_flip_groups.go b/internal/service/cloudapi/account/utility_account_flip_groups.go new file mode 100644 index 00000000..ea30177b --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_flip_groups.go @@ -0,0 +1,98 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountFlipGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListFLIPGroups, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + id = uint64(d.Get("account_id").(int)) + + req := account.ListFLIPGroupsRequest{ + AccountID: id, + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if vins_id, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vins_id.(int)) + } + + if vins_name, ok := d.GetOk("vins_name"); ok { + req.VINSName = vins_name.(string) + } + + if extnet_id, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnet_id.(int)) + } + + if by_ip, ok := d.GetOk("by_ip"); ok { + req.ByIP = by_ip.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if flipgroup_id, ok := d.GetOk("flipgroup_id"); ok { + req.FLIPGroupID = uint64(flipgroup_id.(int)) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityAccountFlipGroupsListCheckPresence") + accountFlipGroupsList, err := c.CloudAPI().Account().ListFLIPGroups(ctx, req) + if err != nil { + return nil, err + } + + return accountFlipGroupsList, nil +} diff --git a/internal/service/cloudapi/account/utility_account_get_resource_consumption.go b/internal/service/cloudapi/account/utility_account_get_resource_consumption.go new file mode 100644 index 00000000..77727425 --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_get_resource_consumption.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountResourceConsumptionGetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.RecordResourceConsumption, error) { + c := m.(*controller.ControllerCfg) + + id := uint64(d.Get("account_id").(int)) + + req:= account.GetResourceConsumptionRequest { + AccountID: id, + } + + log.Debugf("utilityAccountResourceConsumptionGetCheckPresence: load") + accountResourceConsumptionRec, err := c.CloudAPI().Account().GetResourceConsumption(ctx, req) + if err != nil { + return nil, err + } + + return accountResourceConsumptionRec, nil +} diff --git a/internal/service/cloudapi/account/utility_account_list.go b/internal/service/cloudapi/account/utility_account_list.go new file mode 100644 index 00000000..48a68d10 --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_list.go @@ -0,0 +1,87 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListAccounts, error) { + c := m.(*controller.ControllerCfg) + req := account.ListRequest{} + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if acl, ok := d.GetOk("acl"); ok { + req.ACL = acl.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + log.Debugf("utilityAccountListCheckPresence: load account list") + accountList, err := c.CloudAPI().Account().List(ctx, req) + if err != nil { + return nil, err + } + + return accountList, nil +} diff --git a/internal/service/cloudapi/account/utility_account_reserved_units.go b/internal/service/cloudapi/account/utility_account_reserved_units.go new file mode 100644 index 00000000..97b3b433 --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_reserved_units.go @@ -0,0 +1,62 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountReservedUnitsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ResourceLimits, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + id = uint64(d.Get("account_id").(int)) + + req := account.GetReservedAccountUnitsRequest{ + AccountID: id, + } + + log.Debugf("utilityAccountReservedUnitsCheckPresence: load units") + accountReservedUnits, err := c.CloudAPI().Account().GetReservedAccountUnits(ctx, req) + if err != nil { + return nil, err + } + + return accountReservedUnits, nil +} diff --git a/internal/service/cloudapi/account/utility_account_resource_consumption_list.go b/internal/service/cloudapi/account/utility_account_resource_consumption_list.go new file mode 100644 index 00000000..119fa77b --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_resource_consumption_list.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountResourceConsumptionListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListResourceConsumption, error) { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityAccountResourceConsumptionListCheckPresence: load") + accountResourceConsumptionList, err := c.CloudAPI().Account().ListResourceConsumption(ctx) + if err != nil { + return nil, err + } + + return accountResourceConsumptionList, nil +} diff --git a/internal/service/cloudapi/account/utility_account_rg_list.go b/internal/service/cloudapi/account/utility_account_rg_list.go new file mode 100644 index 00000000..28087cc4 --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_rg_list.go @@ -0,0 +1,94 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountRGListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListRG, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + id = uint64(d.Get("account_id").(int)) + + req := account.ListRGRequest{ + AccountID: id, + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if vins_id, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vins_id.(int)) + } + + if vm_id, ok := d.GetOk("vm_id"); ok { + req.VMID = uint64(vm_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + log.Debugf("utilityAccountRGListCheckPresence: load account list") + accountRGList, err := c.CloudAPI().Account().ListRG(ctx, req) + if err != nil { + return nil, err + } + + return accountRGList, nil +} diff --git a/internal/service/cloudapi/account/utility_account_templates_list.go b/internal/service/cloudapi/account/utility_account_templates_list.go new file mode 100644 index 00000000..624707df --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_templates_list.go @@ -0,0 +1,83 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountTemplatesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListTemplates, error) { + c := m.(*controller.ControllerCfg) + + id := uint64(d.Get("account_id").(int)) + + req := account.ListTemplatesRequest{ + AccountID: id, + } + + if include_deleted, ok := d.GetOk("include_deleted"); ok { + req.IncludeDeleted = include_deleted.(bool) + } + if imageId, ok := d.GetOk("image_id"); ok { + req.ImageID = uint64(imageId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if typeTemplates, ok := d.GetOk("type"); ok { + req.Type = typeTemplates.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityAccountTemplatesListCheckPresence: load") + accountTemplatesList, err := c.CloudAPI().Account().ListTemplates(ctx, req) + if err != nil { + return nil, err + } + + return accountTemplatesList, nil +} diff --git a/internal/service/cloudapi/account/utility_account_vins_list.go b/internal/service/cloudapi/account/utility_account_vins_list.go new file mode 100644 index 00000000..cb4b978b --- /dev/null +++ b/internal/service/cloudapi/account/utility_account_vins_list.go @@ -0,0 +1,90 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListVINS, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + id = uint64(d.Get("account_id").(int)) + + req := account.ListVINSRequest{ + AccountID: id, + } + + if vins_id, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vins_id.(int)) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if ext_ip, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = ext_ip.(string) + } + + log.Debugf("utilityAccountVinsListCheckPresence: load account list") + accountVinsList, err := c.CloudAPI().Account().ListVINS(ctx, req) + if err != nil { + return nil, err + } + + return accountVinsList, nil +} diff --git a/internal/service/cloudapi/audit/data_source_audit.go b/internal/service/cloudapi/audit/data_source_audit.go new file mode 100644 index 00000000..e7f8145b --- /dev/null +++ b/internal/service/cloudapi/audit/data_source_audit.go @@ -0,0 +1,132 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAuditRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + auditRec, err := utilityAuditCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + flattenAudit(d, auditRec) + d.SetId(d.Get("audit_guid").(string)) + + return nil +} + +func DataSourceAudit() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAuditRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAuditSchemaMake(), + } +} + +func dataSourceAuditSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "audit_guid": { + Type: schema.TypeString, + Required: true, + Description: "audit guid", + }, + + "args": { + Type: schema.TypeString, + Computed: true, + }, + "call": { + Type: schema.TypeString, + Computed: true, + }, + "correlation_id": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "kwargs": { + Type: schema.TypeString, + Computed: true, + }, + "remote_addr": { + Type: schema.TypeString, + Computed: true, + }, + "responsetime": { + Type: schema.TypeFloat, + Computed: true, + }, + "result": { + Type: schema.TypeString, + Computed: true, + }, + "status_code": { + Type: schema.TypeInt, + Computed: true, + }, + "tags": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "timestamp_end": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + } +} diff --git a/internal/service/cloudapi/audit/data_source_audit_list.go b/internal/service/cloudapi/audit/data_source_audit_list.go new file mode 100644 index 00000000..fe5cb753 --- /dev/null +++ b/internal/service/cloudapi/audit/data_source_audit_list.go @@ -0,0 +1,244 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAuditListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + auditList, err := utilityAuditListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAuditList(auditList)) + d.Set("entry_count", auditList.EntryCount) + + return nil +} + +func DataSourceAuditList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAuditListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAuditListSchemaMake(), + } +} + +func dataSourceAuditListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "timestamp_at": { + Type: schema.TypeInt, + Optional: true, + Description: "find all audits after point in time (unixtime)", + }, + "timestamp_to": { + Type: schema.TypeInt, + Optional: true, + Description: "find all audits before point in time (unixtime)", + }, + "user": { + Type: schema.TypeString, + Optional: true, + Description: "find by user (Mongo RegExp supported)", + }, + "call": { + Type: schema.TypeString, + Optional: true, + Description: "find by api endpoint (Mongo RegExp supported)", + }, + "min_status_code": { + Type: schema.TypeInt, + Optional: true, + Description: "find by HTTP min status code", + }, + "max_status_code": { + Type: schema.TypeInt, + Optional: true, + Description: "find by HTTP max status code", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "request_id": { + Type: schema.TypeString, + Optional: true, + Description: "request id", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "resgroup_id": { + Type: schema.TypeInt, + Optional: true, + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + }, + "service_id": { + Type: schema.TypeInt, + Optional: true, + }, + "k8s_id": { + Type: schema.TypeInt, + Optional: true, + }, + "flipgroup_id": { + Type: schema.TypeInt, + Optional: true, + }, + "lb_id": { + Type: schema.TypeInt, + Optional: true, + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + }, + "exclude_audit_lines": { + Type: schema.TypeBool, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "resgroup_id": { + Type: schema.TypeInt, + Computed: true, + }, + "call": { + Type: schema.TypeString, + Computed: true, + }, + "correlation_id": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "responsetime": { + Type: schema.TypeFloat, + Computed: true, + }, + "status_code": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + "ttl": { + Type: schema.TypeString, + Computed: true, + }, + "args": { + Type: schema.TypeString, + Computed: true, + }, + "kwargs": { + Type: schema.TypeString, + Computed: true, + }, + "result": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp_end": { + Type: schema.TypeFloat, + Computed: true, + }, + "remote_addr": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry count", + }, + } +} diff --git a/internal/service/cloudapi/audit/flattens.go b/internal/service/cloudapi/audit/flattens.go new file mode 100644 index 00000000..c51bfaf1 --- /dev/null +++ b/internal/service/cloudapi/audit/flattens.go @@ -0,0 +1,80 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/audit" +) + +func flattenAudit(d *schema.ResourceData, au *audit.RecordAudit) { + log.Debugf("flattenAudit: decoded audit guid %s", d.Get("audit_guid").(string)) + + d.Set("args", au.Arguments) + d.Set("call", au.Call) + d.Set("correlation_id", au.CorrelationID) + d.Set("guid", au.GUID) + d.Set("kwargs", au.Kwargs) + d.Set("remote_addr", au.RemoteAddr) + d.Set("responsetime", au.ResponseTime) + d.Set("result", au.Result) + d.Set("status_code", au.StatusCode) + d.Set("tags", au.Tags) + d.Set("timestamp", au.Timestamp) + d.Set("timestamp_end", au.TimestampEnd) + d.Set("user", au.User) +} + +func flattenAuditList(au *audit.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(au.Data)) + for _, item := range au.Data { + temp := map[string]interface{}{ + "args": item.Args, + "call": item.Call, + "correlation_id": item.CorrelationID, + "guid": item.GUID, + "kwargs": item.Kwargs, + "remote_addr": item.RemoteAddr, + "result": item.Result, + "responsetime": item.ResponseTime, + "status_code": item.StatusCode, + "timestamp": item.Timestamp, + "timestamp_end": item.TimestampEnd, + "ttl": item.TTL, + "user": item.User, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/audit/utility_audit.go b/internal/service/cloudapi/audit/utility_audit.go new file mode 100644 index 00000000..73f537cf --- /dev/null +++ b/internal/service/cloudapi/audit/utility_audit.go @@ -0,0 +1,62 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/audit" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAuditCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*audit.RecordAudit, error) { + c := m.(*controller.ControllerCfg) + req := audit.GetRequest{} + + if d.Id() != "" { + req.AuditGuid = d.Id() + } else { + req.AuditGuid = d.Get("audit_guid").(string) + } + + log.Debugf("utilityAuditCheckPresence: load audit") + auditInfo, err := c.CloudAPI().Audit().Get(ctx, req) + if err != nil { + return nil, err + } + + return auditInfo, nil +} diff --git a/internal/service/cloudapi/audit/utility_audit_list.go b/internal/service/cloudapi/audit/utility_audit_list.go new file mode 100644 index 00000000..fe099a56 --- /dev/null +++ b/internal/service/cloudapi/audit/utility_audit_list.go @@ -0,0 +1,117 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/audit" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAuditListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*audit.ListAudits, error) { + c := m.(*controller.ControllerCfg) + req := audit.ListRequest{} + + if timestampAt, ok := d.GetOk("timestamp_at"); ok { + req.TimestampAt = uint64(timestampAt.(int)) + } + if timestampTo, ok := d.GetOk("timestamp_to"); ok { + req.TimestampTo = uint64(timestampTo.(int)) + } + if user, ok := d.GetOk("user"); ok { + req.User = user.(string) + } + if call, ok := d.GetOk("call"); ok { + req.Call = call.(string) + } + if minStatusCode, ok := d.GetOk("min_status_code"); ok { + req.MinStatusCode = uint64(minStatusCode.(int)) + } + if maxStatusCode, ok := d.GetOk("max_status_code"); ok { + req.MaxStatusCode = uint64(maxStatusCode.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if Page, ok := d.GetOk("page"); ok { + req.Page = uint64(Page.(int)) + } + if RequestID, ok := d.GetOk("request_id"); ok { + req.RequestID = RequestID.(string) + } + if Size, ok := d.GetOk("size"); ok { + req.Size = uint64(Size.(int)) + } + if resgroupID, ok := d.GetOk("resgroup_id"); ok { + req.RGID = uint64(resgroupID.(int)) + } + if computeID, ok := d.GetOk("compute_id"); ok { + req.ComputeID = uint64(computeID.(int)) + } + if accountID, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountID.(int)) + } + if vinsID, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vinsID.(int)) + } + if serviceID, ok := d.GetOk("service_id"); ok { + req.ServiceID = uint64(serviceID.(int)) + } + if k8sID, ok := d.GetOk("k8s_id"); ok { + req.K8SID = uint64(k8sID.(int)) + } + if flipgroupID, ok := d.GetOk("flipgroup_id"); ok { + req.FLIPGroupID = uint64(flipgroupID.(int)) + } + if lbID, ok := d.GetOk("lb_id"); ok { + req.LBID = uint64(lbID.(int)) + } + if sepID, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepID.(int)) + } + if excludeAuditLines, ok := d.GetOk("exclude_audit_lines"); ok { + req.ExcludeAuditLines = excludeAuditLines.(bool) + } + + log.Debugf("utilityAuditListCheckPresence: load audit list") + auditList, err := c.CloudAPI().Audit().List(ctx, req) + if err != nil { + return nil, err + } + + return auditList, nil +} diff --git a/internal/service/cloudapi/bservice/data_source_bservice.go b/internal/service/cloudapi/bservice/data_source_bservice.go new file mode 100644 index 00000000..15a6181c --- /dev/null +++ b/internal/service/cloudapi/bservice/data_source_bservice.go @@ -0,0 +1,302 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + bs, err := utilityBasicServiceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(bs.ID, 10)) + + flattenService(d, bs) + + return nil +} + +func dataSourceBasicServiceSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "service_id": { + Type: schema.TypeInt, + Required: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "base_domain": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "compgroup_id": { + Type: schema.TypeInt, + Computed: true, + }, + "compgroup_name": { + Type: schema.TypeString, + Computed: true, + }, + "compgroup_role": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "cpu_total": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_total": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "computes": { + Type: schema.TypeInt, + Computed: true, + }, + "consistency": { + Type: schema.TypeBool, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + // "groups_name": { + // Type: schema.TypeList, + // Computed: true, + // Elem: &schema.Schema{ + // Type: schema.TypeString, + // }, + // }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "service_name": { + Type: schema.TypeString, + Computed: true, + }, + "parent_srv_id": { + Type: schema.TypeInt, + Computed: true, + }, + "parent_srv_type": { + Type: schema.TypeString, + Computed: true, + }, + "ram_total": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + "valid": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + + "ssh_key": { + Type: schema.TypeString, + Computed: true, + }, + "ssh_user": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + } + return res +} + +func DataSourceBasicService() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceBasicServiceRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceBasicServiceSchemaMake(), + } +} diff --git a/internal/service/cloudapi/bservice/data_source_bservice_deleted_list.go b/internal/service/cloudapi/bservice/data_source_bservice_deleted_list.go new file mode 100644 index 00000000..31c51ae6 --- /dev/null +++ b/internal/service/cloudapi/bservice/data_source_bservice_deleted_list.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceBasicServiceDeletedListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + basicServiceDeletedList, err := utilityBasicServiceDeletedListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenBasicServiceList(basicServiceDeletedList)) + d.Set("entry_count", basicServiceDeletedList.EntryCount) + + return nil +} + +func dataSourceBasicServiceDeletedListSchemaMake() map[string]*schema.Schema { + temp := dataSourceBasicServiceListSchemaMake() + + delete(temp, "by_id") + delete(temp, "name") + delete(temp, "rg_name") + delete(temp, "status") + delete(temp, "tech_status") + delete(temp, "account_name") + + return temp +} + +func DataSourceBasicServiceDeletedList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceBasicServiceDeletedListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceBasicServiceDeletedListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/bservice/data_source_bservice_group.go b/internal/service/cloudapi/bservice/data_source_bservice_group.go new file mode 100644 index 00000000..c504740b --- /dev/null +++ b/internal/service/cloudapi/bservice/data_source_bservice_group.go @@ -0,0 +1,310 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceBasicServiceGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + bsg, err := utilityBasicServiceGroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("account_id", bsg.AccountID) + d.Set("account_name", bsg.AccountName) + d.Set("computes", flattenBSGroupComputes(bsg.Computes)) + d.Set("consistency", bsg.Consistency) + d.Set("cpu", bsg.CPU) + d.Set("created_by", bsg.CreatedBy) + d.Set("created_time", bsg.CreatedTime) + d.Set("deleted_by", bsg.DeletedBy) + d.Set("deleted_time", bsg.DeletedTime) + d.Set("disk", bsg.Disk) + d.Set("driver", bsg.Driver) + d.Set("extnets", bsg.ExtNets) + d.Set("gid", bsg.GID) + d.Set("guid", bsg.GUID) + d.Set("image_id", bsg.ImageID) + d.Set("milestones", bsg.Milestones) + d.Set("compgroup_name", bsg.Name) + d.Set("parents", bsg.Parents) + d.Set("ram", bsg.RAM) + d.Set("rg_id", bsg.RGID) + d.Set("rg_name", bsg.RGName) + d.Set("role", bsg.Role) + d.Set("sep_id", bsg.SEPID) + d.Set("seq_no", bsg.SeqNo) + d.Set("status", bsg.Status) + d.Set("tech_status", bsg.TechStatus) + d.Set("timeout_start", bsg.TimeoutStart) + d.Set("updated_by", bsg.UpdatedBy) + d.Set("updated_time", bsg.UpdatedTime) + d.Set("vinses", bsg.VINSes) + return nil +} + +func flattenBSGroupOSUsers(bsgosus bservice.ListOSUsers) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, bsgosu := range bsgosus { + temp := map[string]interface{}{ + "login": bsgosu.Login, + "password": bsgosu.Password, + } + res = append(res, temp) + } + + return res +} + +func flattenBSGroupComputes(bsgcs bservice.ListGroupComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, bsgc := range bsgcs { + temp := map[string]interface{}{ + "id": bsgc.ID, + "ip_addresses": bsgc.IPAddresses, + "name": bsgc.Name, + "os_users": flattenBSGroupOSUsers(bsgc.OSUsers), + "chipset": bsgc.Chipset, + } + res = append(res, temp) + } + return res +} + +func dataSourceBasicServiceGroupSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "service_id": { + Type: schema.TypeInt, + Required: true, + }, + "compgroup_id": { + Type: schema.TypeInt, + Required: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "ip_addresses": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "chipset": { + Type: schema.TypeString, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "login": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "consistency": { + Type: schema.TypeBool, + Computed: true, + }, + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "disk": { + Type: schema.TypeInt, + Computed: true, + }, + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "extnets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "compgroup_name": { + Type: schema.TypeString, + Computed: true, + }, + "parents": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "seq_no": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "timeout_start": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vinses": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } + return res +} + +func DataSourceBasicServiceGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceBasicServiceGroupRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceBasicServiceGroupSchemaMake(), + } +} diff --git a/internal/service/cloudapi/bservice/data_source_bservice_list.go b/internal/service/cloudapi/bservice/data_source_bservice_list.go new file mode 100644 index 00000000..0974b53a --- /dev/null +++ b/internal/service/cloudapi/bservice/data_source_bservice_list.go @@ -0,0 +1,279 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func flattenBasicServiceList(bsl *bservice.ListBasicServices) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, bs := range bsl.Data { + temp := map[string]interface{}{ + "account_id": bs.AccountID, + "account_name": bs.AccountName, + "base_domain": bs.BaseDomain, + "created_by": bs.CreatedBy, + "created_time": bs.CreatedTime, + "deleted_by": bs.DeletedBy, + "deleted_time": bs.DeletedTime, + "gid": bs.GID, + "groups": bs.Groups, + "guid": bs.GUID, + "service_id": bs.ID, + "service_name": bs.Name, + "parent_srv_id": bs.ParentSrvID, + "parent_srv_type": bs.ParentSrvType, + "rg_id": bs.RGID, + "rg_name": bs.RGName, + "ssh_user": bs.SSHUser, + "status": bs.Status, + "tech_status": bs.TechStatus, + "updated_by": bs.UpdatedBy, + "updated_time": bs.UpdatedTime, + "user_managed": bs.UserManaged, + "zone_id": bs.ZoneID, + } + res = append(res, temp) + } + return res +} + +func dataSourceBasicServiceListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + basicServiceList, err := utilityBasicServiceListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenBasicServiceList(basicServiceList)) + d.Set("entry_count", basicServiceList.EntryCount) + + return nil +} + +func dataSourceBasicServiceListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by bservice name", + }, + "rg_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by resource group name", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by tech status", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by account name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the account to query for BasicService instances", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the resource group to query for BasicService instances", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "base_domain": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "service_id": { + Type: schema.TypeInt, + Computed: true, + }, + "service_name": { + Type: schema.TypeString, + Computed: true, + }, + "parent_srv_id": { + Type: schema.TypeInt, + Computed: true, + }, + "parent_srv_type": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "ssh_user": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceBasicServiceList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceBasicServiceListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceBasicServiceListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/bservice/data_source_bservice_snapshot_list.go b/internal/service/cloudapi/bservice/data_source_bservice_snapshot_list.go new file mode 100644 index 00000000..0df055fb --- /dev/null +++ b/internal/service/cloudapi/bservice/data_source_bservice_snapshot_list.go @@ -0,0 +1,110 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceBasicServiceSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + basicServiceSnapshotList, err := utilityBasicServiceSnapshotListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenBasicServiceSnapshotsList(basicServiceSnapshotList)) + d.Set("entry_count", basicServiceSnapshotList.EntryCount) + return nil +} + +func dataSourceBasicServiceSnapshotListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "service_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the BasicService instance", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + "valid": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceBasicServiceSnapshotList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceBasicServiceSnapshotListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceBasicServiceSnapshotListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/bservice/flattens.go b/internal/service/cloudapi/bservice/flattens.go new file mode 100644 index 00000000..42f13064 --- /dev/null +++ b/internal/service/cloudapi/bservice/flattens.go @@ -0,0 +1,140 @@ +package bservice + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" +) + +func flattenResourceBasicServiceGroup(d *schema.ResourceData, bsg *bservice.RecordGroup) { + d.Set("account_id", bsg.AccountID) + d.Set("account_name", bsg.AccountName) + d.Set("computes", flattenBSGroupComputes(bsg.Computes)) + d.Set("consistency", bsg.Consistency) + d.Set("cpu", bsg.CPU) + d.Set("created_by", bsg.CreatedBy) + d.Set("created_time", bsg.CreatedTime) + d.Set("deleted_by", bsg.DeletedBy) + d.Set("deleted_time", bsg.DeletedTime) + d.Set("disk", bsg.Disk) + d.Set("driver", bsg.Driver) + d.Set("extnets", bsg.ExtNets) + d.Set("gid", bsg.GID) + d.Set("guid", bsg.GUID) + d.Set("image_id", bsg.ImageID) + d.Set("milestones", bsg.Milestones) + d.Set("compgroup_name", bsg.Name) + d.Set("compgroup_id", bsg.ID) + d.Set("parents", bsg.Parents) + d.Set("ram", bsg.RAM) + d.Set("rg_id", bsg.RGID) + d.Set("rg_name", bsg.RGName) + d.Set("role", bsg.Role) + d.Set("sep_id", bsg.SEPID) + d.Set("sep_pool", bsg.PoolName) + d.Set("seq_no", bsg.SeqNo) + d.Set("status", bsg.Status) + d.Set("tech_status", bsg.TechStatus) + d.Set("timeout_start", bsg.TimeoutStart) + d.Set("updated_by", bsg.UpdatedBy) + d.Set("updated_time", bsg.UpdatedTime) + d.Set("vinses", bsg.VINSes) +} + +func flattenGroups(groups bservice.ListGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, group := range groups { + temp := map[string]interface{}{ + "computes": group.Computes, + "consistency": group.Consistency, + "id": group.ID, + "name": group.Name, + "status": group.Status, + "tech_status": group.TechStatus, + } + res = append(res, temp) + } + return res +} + +func flattenService(d *schema.ResourceData, bs *bservice.RecordBasicService) { + d.Set("account_id", bs.AccountID) + d.Set("account_name", bs.AccountName) + d.Set("base_domain", bs.BaseDomain) + d.Set("computes", flattenBasicServiceComputes(bs.Computes)) + d.Set("cpu_total", bs.CPUTotal) + d.Set("created_by", bs.CreatedBy) + d.Set("created_time", bs.CreatedTime) + d.Set("deleted_by", bs.DeletedBy) + d.Set("deleted_time", bs.DeletedTime) + d.Set("disk_total", bs.DiskTotal) + d.Set("gid", bs.GID) + d.Set("groups", flattenGroups(bs.Groups)) + d.Set("guid", bs.GUID) + d.Set("milestones", bs.Milestones) + d.Set("service_name", bs.Name) + d.Set("service_id", bs.ID) + d.Set("parent_srv_id", bs.ParentSrvID) + d.Set("parent_srv_type", bs.ParentSrvType) + d.Set("ram_total", bs.RAMTotal) + d.Set("rg_id", bs.RGID) + d.Set("rg_name", bs.RGName) + d.Set("snapshots", flattenBasicServiceSnapshots(bs.Snapshots)) + d.Set("ssh_key", bs.SSHKey) + d.Set("ssh_user", bs.SSHUser) + d.Set("status", bs.Status) + d.Set("tech_status", bs.TechStatus) + d.Set("updated_by", bs.UpdatedBy) + d.Set("updated_time", bs.UpdatedTime) + d.Set("user_managed", bs.UserManaged) + d.Set("zone_id", bs.ZoneID) +} + +func flattenBasicServiceComputes(bscs bservice.ListComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, bsc := range bscs { + temp := map[string]interface{}{ + "account_id": bsc.AccountID, + "architecture": bsc.Architecture, + "compgroup_id": bsc.CompGroupID, + "compgroup_name": bsc.CompGroupName, + "compgroup_role": bsc.CompGroupRole, + "id": bsc.ID, + "name": bsc.Name, + "rg_id": bsc.RGID, + "node_id": bsc.NodeID, + "status": bsc.Status, + "tech_status": bsc.TechStatus, + } + res = append(res, temp) + } + + return res +} + +func flattenBasicServiceSnapshots(bsrvss bservice.ListSnapshots) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(bsrvss)) + for _, bsrvs := range bsrvss { + temp := map[string]interface{}{ + "guid": bsrvs.GUID, + "label": bsrvs.Label, + "timestamp": bsrvs.Timestamp, + "valid": bsrvs.Valid, + } + res = append(res, temp) + } + return res +} + +func flattenBasicServiceSnapshotsList(bsrvss *bservice.ListInfoSnapshots) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(bsrvss.Data)) + for _, bsrvs := range bsrvss.Data { + temp := map[string]interface{}{ + "guid": bsrvs.GUID, + "label": bsrvs.Label, + "timestamp": bsrvs.Timestamp, + "valid": bsrvs.Valid, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/bservice/resource_bservice.go b/internal/service/cloudapi/bservice/resource_bservice.go new file mode 100644 index 00000000..468793f3 --- /dev/null +++ b/internal/service/cloudapi/bservice/resource_bservice.go @@ -0,0 +1,759 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceBasicServiceCreate") + c := m.(*controller.ControllerCfg) + req := bservice.CreateRequest{} + + haveRGID, err := existRGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveRGID { + return diag.Errorf("resourceBasicServiceCreate: can't create basic service because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + + req.Name = d.Get("service_name").(string) + req.RGID = uint64(d.Get("rg_id").(int)) + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + if sshKey, ok := d.GetOk("ssh_key"); ok { + req.SSHKey = sshKey.(string) + } + if sshUser, ok := d.GetOk("ssh_user"); ok { + req.SSHUser = sshUser.(string) + } + + serviceId, err := c.CloudAPI().BService().Create(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(serviceId, 10)) + d.Set("service_id", serviceId) + + service, err := utilityBasicServiceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + warnings := dc.Warnings{} + enable := d.Get("enable").(bool) + + if enable && (service.Status == status.Disabled || service.Status == status.Created) { + log.Debugf("trying to enable bservice %v", serviceId) + _, err := c.CloudAPI().BService().Enable(ctx, bservice.EnableRequest{ + ServiceID: serviceId, + }) + + if err != nil { + warnings.Add(err) + } + } + if d.Get("start").(bool) { + log.Debugf("trying to start bservice %v", serviceId) + + if !enable { + warnings.Add(errors.New("can not start bservice that is not enabled. Set enable = true and start = true to enable and start bservice")) + } + + if enable { + _, err := c.CloudAPI().BService().Start(ctx, bservice.StartRequest{ + ServiceID: serviceId, + }) + + if err != nil { + warnings.Add(err) + } + } + } + + return append(warnings.Get(), resourceBasicServiceRead(ctx, d, m)...) +} + +func resourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceBasicServiceRead") + + // c := m.(*controller.ControllerCfg) + + bs, err := utilityBasicServiceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch bs.Status { + case status.Modeled: + return diag.Errorf("The basic service is in status: %s, please, contact support for more information", bs.Status) + case status.Created: + case status.Enabled: + case status.Enabling: + case status.Disabled: + log.Debugf("The basic service is in status: %s, troubles can occur with the update. Please, enable bservice first.", bs.Status) + case status.Disabling: + log.Debugf("The basic service is in status: %s, troubles can occur with the update.", bs.Status) + case status.Deleted: + // id, _ := strconv.ParseUint(d.Id(), 10, 64) + // restoreReq := bservice.RestoreRequest{ + // ServiceID: id, + // } + // enableReq := bservice.EnableRequest{ + // ServiceID: id, + // } + + // _, err := c.CloudAPI().BService().Restore(ctx, restoreReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // _, err = c.CloudAPI().BService().Enable(ctx, enableReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // hasChanged = true + case status.Deleting: + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceBasicServiceCreate(ctx, d, m) + case status.Destroying: + return diag.Errorf("The basic service is in progress with status: %s", bs.Status) + case status.Restoring: + case status.Reconfiguring: + } + + if hasChanged { + bs, err = utilityBasicServiceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + flattenService(d, bs) + + return nil +} + +func resourceBasicServiceDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceBasicServiceDelete") + c := m.(*controller.ControllerCfg) + + _, err := utilityBasicServiceCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + req := bservice.DeleteRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + Permanently: d.Get("permanently").(bool), + } + + _, err = c.CloudAPI().BService().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceBasicServiceUpdate") + c := m.(*controller.ControllerCfg) + + haveRGID, err := existRGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveRGID { + return diag.Errorf("resourceBasicServiceUpdate: can't create basic service because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + + bs, err := utilityBasicServiceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch bs.Status { + case status.Modeled: + return diag.Errorf("The basic service is in status: %s, please, contact support for more information", bs.Status) + case status.Created: + case status.Enabled: + case status.Enabling: + case status.Disabled: + log.Debugf("The basic service is in status: %s, troubles can occur with the update. Please, enable bservice first.", bs.Status) + case status.Disabling: + log.Debugf("The basic service is in status: %s, troubles can occur with the update.", bs.Status) + case status.Deleted: + if d.Get("restore").(bool) { + restoreReq := bservice.RestoreRequest{ + ServiceID: bs.ID, + } + _, err := c.CloudAPI().BService().Restore(ctx, restoreReq) + if err != nil { + return diag.FromErr(err) + } + + hasChanged = true + + if d.Get("enable").(bool) { + enableReq := bservice.EnableRequest{ + ServiceID: bs.ID, + } + _, err = c.CloudAPI().BService().Enable(ctx, enableReq) + if err != nil { + return diag.FromErr(err) + } + } + + if d.Get("start").(bool) { + startReq := bservice.StartRequest{ + ServiceID: bs.ID, + } + _, err = c.CloudAPI().BService().Start(ctx, startReq) + if err != nil { + return diag.FromErr(err) + } + } + } + case status.Deleting: + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceBasicServiceCreate(ctx, d, m) + case status.Destroying: + return diag.Errorf("The basic service is in progress with status: %s", bs.Status) + case status.Restoring: + case status.Reconfiguring: + } + + if hasChanged { + bs, err = utilityBasicServiceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChange("enable") { + if d.Get("enable").(bool) { + req := bservice.EnableRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } + + _, err := c.CloudAPI().BService().Enable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := bservice.DisableRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } + + _, err := c.CloudAPI().BService().Disable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("zone_id") { + zoneID := uint64(d.Get("zone_id").(int)) + + start := d.Get("start").(bool) + if start { + reqStop := bservice.StopRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } + + _, err := c.CloudAPI().BService().Stop(ctx, reqStop) + if err != nil { + return diag.FromErr(err) + } + } + + req := bservice.MigrateToZoneRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + ZoneID: zoneID, + } + + _, err = c.CloudAPI().BService().MigrateToZone(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + if start { + startReq := bservice.StartRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } + + _, err = c.CloudAPI().BService().Start(ctx, startReq) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("start") { + if d.Get("start").(bool) { + req := bservice.StartRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } + + _, err := c.CloudAPI().BService().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := bservice.StopRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } + + _, err := c.CloudAPI().BService().Stop(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("snapshots") { + deletedSnapshots := make([]interface{}, 0) + addedSnapshots := make([]interface{}, 0) + updatedSnapshots := make([]interface{}, 0) + + old, new := d.GetChange("snapshots") + oldConv := old.([]interface{}) + newConv := new.([]interface{}) + for _, el := range oldConv { + if !isContainsSnapshot(newConv, el) { + deletedSnapshots = append(deletedSnapshots, el) + } + } + for _, el := range newConv { + if !isContainsSnapshot(oldConv, el) { + addedSnapshots = append(addedSnapshots, el) + } else { + if isRollback(oldConv, el) { + updatedSnapshots = append(updatedSnapshots, el) + } + } + } + + if len(deletedSnapshots) > 0 { + for _, snapshot := range deletedSnapshots { + snapshotConv := snapshot.(map[string]interface{}) + req := bservice.SnapshotDeleteRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + Label: snapshotConv["label"].(string), + } + + _, err := c.CloudAPI().BService().SnapshotDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if len(addedSnapshots) > 0 { + for _, snapshot := range addedSnapshots { + snapshotConv := snapshot.(map[string]interface{}) + req := bservice.SnapshotCreateRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + Label: snapshotConv["label"].(string), + } + + _, err := c.CloudAPI().BService().SnapshotCreate(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if len(updatedSnapshots) > 0 { + for _, snapshot := range updatedSnapshots { + snapshotConv := snapshot.(map[string]interface{}) + req := bservice.SnapshotRollbackRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + Label: snapshotConv["label"].(string), + } + + _, err := c.CloudAPI().BService().SnapshotRollback(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + return resourceBasicServiceRead(ctx, d, m) +} + +func isContainsSnapshot(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["guid"].(string) == elConv["guid"].(string) { + return true + } + } + return false +} + +func isRollback(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["guid"].(string) == elConv["guid"].(string) && + elOldConv["rollback"].(bool) != elConv["rollback"].(bool) && + elConv["rollback"].(bool) { + return true + } + } + return false +} + +func resourceBasicServiceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the service", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the Resource Group where this service will be placed", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of the zone where this service will be placed", + }, + "ssh_key": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "SSH key to deploy for the specified user. Same key will be deployed to all computes of the service.", + }, + "ssh_user": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "name of the user to deploy SSH key for. Pass empty string if no SSH key deployment is required", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "if set to False, Basic service will be deleted to recycle bin. Otherwise destroyed immediately", + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Enable service. Enabling a service technically means setting model status of all computes and service itself to ENABLED. It does not start computes.", + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Restores BasicService instance", + }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Start service. Starting a service technically means starting computes from all service groups according to group relations", + }, + "service_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "base_domain": { + Type: schema.TypeString, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "compgroup_id": { + Type: schema.TypeInt, + Computed: true, + }, + "compgroup_name": { + Type: schema.TypeString, + Computed: true, + }, + "compgroup_role": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "cpu_total": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_total": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "computes": { + Type: schema.TypeInt, + Computed: true, + }, + "consistency": { + Type: schema.TypeBool, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "parent_srv_id": { + Type: schema.TypeInt, + Computed: true, + }, + "parent_srv_type": { + Type: schema.TypeString, + Computed: true, + }, + "ram_total": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "rollback": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + "valid": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + } +} + +func ResourceBasicService() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceBasicServiceCreate, + ReadContext: resourceBasicServiceRead, + UpdateContext: resourceBasicServiceUpdate, + DeleteContext: resourceBasicServiceDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceBasicServiceSchemaMake(), + } +} diff --git a/internal/service/cloudapi/bservice/resource_bservice_group.go b/internal/service/cloudapi/bservice/resource_bservice_group.go new file mode 100644 index 00000000..90cf7489 --- /dev/null +++ b/internal/service/cloudapi/bservice/resource_bservice_group.go @@ -0,0 +1,646 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators" +) + +func resourceBasicServiceGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceBasicServiceGroupCreate") + + c := m.(*controller.ControllerCfg) + req := bservice.GroupAddRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + Name: d.Get("compgroup_name").(string), + Count: uint64(d.Get("comp_count").(int)), + CPU: uint64(d.Get("cpu").(int)), + RAM: uint64(d.Get("ram").(int)), + Disk: uint64(d.Get("disk").(int)), + ImageID: uint64(d.Get("image_id").(int)), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + if role, ok := d.GetOk("role"); ok { + req.Role = role.(string) + } + + if timeoutStart, ok := d.GetOk("timeout_start"); ok { + req.TimeoutStart = uint64(timeoutStart.(int)) + } + + ///4.4.0 + if sepId, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepId.(int)) + } + + if sepPool, ok := d.GetOk("sep_pool"); ok { + req.SEPPool = sepPool.(string) + } + + if cloudInit, ok := d.GetOk("cloud_init"); ok { + req.UserData = cloudInit.(string) + } + /// + + if vinses, ok := d.GetOk("vinses"); ok { + res := []uint64{} + for _, vins := range vinses.([]interface{}) { + res = append(res, uint64(vins.(int))) + } + + req.VINSes = res + } + if extnets, ok := d.GetOk("extnets"); ok { + res := []uint64{} + for _, enet := range extnets.([]interface{}) { + res = append(res, uint64(enet.(int))) + } + + req.ExtNets = res + } + + if chipset, ok := d.GetOk("chipset"); ok { + req.Chipset = chipset.(string) + } + + compgroupId, err := c.CloudAPI().BService().GroupAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(compgroupId, 10)) + d.Set("compgroup_id", compgroupId) + + serviceId := uint64(d.Get("service_id").(int)) + + if d.Get("start").(bool) { + log.Debugf("trying to start bservice group %v", compgroupId) + _, err := c.CloudAPI().BService().GroupStart(ctx, bservice.GroupStartRequest{ + ServiceID: serviceId, + CompGroupID: compgroupId, + }) + + if err != nil { + return diag.FromErr(err) + } + } + + return resourceBasicServiceGroupRead(ctx, d, m) +} + +func resourceBasicServiceGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceBasicServiceGroupRead") + + bsg, err := utilityBasicServiceGroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenResourceBasicServiceGroup(d, bsg) + + return nil +} + +func resourceBasicServiceGroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceBasicServiceGroupDelete") + + bsg, err := utilityBasicServiceGroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := bservice.GroupRemoveRequest{ + ServiceID: bsg.ServiceID, + CompGroupID: bsg.ID, + } + + _, err = c.CloudAPI().BService().GroupRemove(ctx, req) + if err != nil { + return diag.FromErr(err) + } + d.SetId("") + + return nil +} + +func resourceBasicServiceGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceBasicServiceGroupEdit") + c := m.(*controller.ControllerCfg) + + if d.HasChange("comp_count") { + req := bservice.GroupResizeRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + Count: int64(d.Get("comp_count").(int)), + Chipset: d.Get("chipset").(string), + Mode: d.Get("mode").(string), + } + + _, err := c.CloudAPI().BService().GroupResize(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("start") { + start := d.Get("start").(bool) + if start { + req := bservice.GroupStartRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + } + + _, err := c.CloudAPI().BService().GroupStart(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := bservice.GroupStopRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + Force: d.Get("force_stop").(bool), + } + + _, err := c.CloudAPI().BService().GroupStop(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChanges("compgroup_name", "ram", "cpu", "disk", "role") { + req := bservice.GroupUpdateRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + Name: d.Get("compgroup_name").(string), + Role: d.Get("role").(string), + CPU: uint64(d.Get("cpu").(int)), + RAM: uint64(d.Get("ram").(int)), + Disk: uint64(d.Get("disk").(int)), + Force: d.Get("force_update").(bool), + } + + _, err := c.CloudAPI().BService().GroupUpdate(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("extnets") { + extnets := d.Get("extnets").([]interface{}) + + res := []uint64{} + for _, enet := range extnets { + res = append(res, uint64(enet.(int))) + } + + req := bservice.GroupUpdateExtNetRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + ExtNets: res, + } + + _, err := c.CloudAPI().BService().GroupUpdateExtNet(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("vinses") { + vinses := d.Get("vinses").([]interface{}) + + res := []uint64{} + for _, vins := range vinses { + res = append(res, uint64(vins.(int))) + } + + req := bservice.GroupUpdateVINSRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + VINSes: res, + } + + _, err := c.CloudAPI().BService().GroupUpdateVINS(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("parents") { + deletedParents := make([]interface{}, 0) + addedParents := make([]interface{}, 0) + + old, new := d.GetChange("parents") + oldConv := old.([]interface{}) + newConv := new.([]interface{}) + for _, el := range oldConv { + if !isContainsParent(newConv, el) { + deletedParents = append(deletedParents, el) + } + } + for _, el := range newConv { + if !isContainsParent(oldConv, el) { + addedParents = append(addedParents, el) + } + } + + if len(deletedParents) > 0 { + for _, parent := range deletedParents { + parentConv := parent.(int) + + req := bservice.GroupParentRemoveRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + ParentID: uint64(parentConv), + } + + _, err := c.CloudAPI().BService().GroupParentRemove(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if len(addedParents) > 0 { + for _, parent := range addedParents { + parentConv := parent.(int) + + req := bservice.GroupParentAddRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + ParentID: uint64(parentConv), + } + + _, err := c.CloudAPI().BService().GroupParentAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + if d.HasChange("remove_computes") { + rcs := d.Get("remove_computes").([]interface{}) + if len(rcs) > 0 { + for _, rc := range rcs { + req := bservice.GroupComputeRemoveRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + ComputeID: uint64(rc.(int)), + } + + _, err := c.CloudAPI().BService().GroupComputeRemove(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + return resourceBasicServiceGroupRead(ctx, d, m) +} + +func isContainsParent(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(int) + elConv := el.(int) + if elOldConv == elConv { + return true + } + } + return false +} + +func resourceBasicServiceGroupSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "service_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the Basic Service to add a group to", + }, + "compgroup_name": { + Type: schema.TypeString, + Required: true, + Description: "name of the Compute Group to add", + }, + "comp_count": { + Type: schema.TypeInt, + Required: true, + Description: "computes number. Defines how many computes must be there in the group", + }, + "cpu": { + Type: schema.TypeInt, + Required: true, + Description: "compute CPU number. All computes in the group have the same CPU count", + }, + "ram": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.All( + validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + validators.DivisibleBy(constants.RAM_DIVISIBILITY), + ), + Description: "compute RAM volume in MB. All computes in the group have the same RAM volume", + }, + "disk": { + Type: schema.TypeInt, + Required: true, + Description: "compute boot disk size in GB", + }, + "image_id": { + Type: schema.TypeInt, + Required: true, + Description: "OS image ID to create computes from", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "storage policy id of compute. The rules of the specified storage policy will be used.", + }, + ///4.4.0 + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + }, + "sep_pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool to use if sepId is set, can be also empty if needed to be chosen by system", + }, + "cloud_init": { + Type: schema.TypeString, + Optional: true, + Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.", + }, + "chipset": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"i440fx", "Q35"}, false), + Default: "Q35", + Description: "Chipset for virtual machines.", + }, + /// + "role": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "group role tag. Can be empty string, does not have to be unique", + }, + "timeout_start": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "time of Compute Group readiness", + }, + "extnets": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "list of external networks to connect computes to", + }, + "vinses": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "list of ViNSes to connect computes to", + }, + "mode": { + Type: schema.TypeString, + Optional: true, + Default: "RELATIVE", + ValidateFunc: validation.StringInSlice([]string{"RELATIVE", "ABSOLUTE"}, false), + Description: "(RELATIVE;ABSOLUTE) either delta or absolute value of computes", + }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Start the specified Compute Group within BasicService", + }, + "force_stop": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "force stop Compute Group", + }, + "force_update": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "force resize Compute Group", + }, + "parents": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "remove_computes": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "compgroup_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "chipset": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "ip_addresses": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "login": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "consistency": { + Type: schema.TypeBool, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "seq_no": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func ResourceBasicServiceGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceBasicServiceGroupCreate, + ReadContext: resourceBasicServiceGroupRead, + UpdateContext: resourceBasicServiceGroupUpdate, + DeleteContext: resourceBasicServiceGroupDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceBasicServiceGroupSchemaMake(), + } +} diff --git a/internal/service/cloudapi/bservice/resource_check_input_values.go b/internal/service/cloudapi/bservice/resource_check_input_values.go new file mode 100644 index 00000000..67f37534 --- /dev/null +++ b/internal/service/cloudapi/bservice/resource_check_input_values.go @@ -0,0 +1,24 @@ +package bservice + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + + req := rg.ListRequest{} + + rgList, err := c.CloudAPI().RG().List(ctx, req) + if err != nil { + return false, err + } + + rgId := uint64(d.Get("rg_id").(int)) + + return len(rgList.FilterByID(rgId).Data) != 0, nil +} diff --git a/internal/service/cloudapi/bservice/utility_bservicce_deleted_list.go b/internal/service/cloudapi/bservice/utility_bservicce_deleted_list.go new file mode 100644 index 00000000..63522b71 --- /dev/null +++ b/internal/service/cloudapi/bservice/utility_bservicce_deleted_list.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityBasicServiceDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*bservice.ListBasicServices, error) { + c := m.(*controller.ControllerCfg) + req := bservice.ListDeletedRequest{} + + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if rgId, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgId.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityBasicServiceDeletedListCheckPresence") + basicServiceDeletedList, err := c.CloudAPI().BService().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return basicServiceDeletedList, nil +} diff --git a/internal/service/cloudapi/bservice/utility_bservice.go b/internal/service/cloudapi/bservice/utility_bservice.go new file mode 100644 index 00000000..866ce6c2 --- /dev/null +++ b/internal/service/cloudapi/bservice/utility_bservice.go @@ -0,0 +1,67 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityBasicServiceCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*bservice.RecordBasicService, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + if (strconv.Itoa(d.Get("service_id").(int))) != "0" { + id = uint64(d.Get("service_id").(int)) + } else { + id, _ = strconv.ParseUint(d.Id(), 10, 64) + } + + req := bservice.GetRequest{ + ServiceID: id, + } + + log.Debugf("utilityBasicServiceCheckPresence") + bservice, err := c.CloudAPI().BService().Get(ctx, req) + if err != nil { + return nil, err + } + + return bservice, nil +} diff --git a/internal/service/cloudapi/bservice/utility_bservice_group.go b/internal/service/cloudapi/bservice/utility_bservice_group.go new file mode 100644 index 00000000..47d748e8 --- /dev/null +++ b/internal/service/cloudapi/bservice/utility_bservice_group.go @@ -0,0 +1,67 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityBasicServiceGroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*bservice.RecordGroup, error) { + c := m.(*controller.ControllerCfg) + + req := bservice.GroupGetRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } + + if (strconv.Itoa(d.Get("compgroup_id").(int))) != "0" { + req.CompGroupID = uint64(d.Get("compgroup_id").(int)) + } else { + comGroupID, _ := strconv.ParseUint(d.Id(), 10, 64) + req.CompGroupID = comGroupID + } + + log.Debugf("utilityBasicServiceGroupCheckPresence") + bserviceGroup, err := c.CloudAPI().BService().GroupGet(ctx, req) + if err != nil { + return nil, err + } + + return bserviceGroup, nil +} diff --git a/internal/service/cloudapi/bservice/utility_bservice_list.go b/internal/service/cloudapi/bservice/utility_bservice_list.go new file mode 100644 index 00000000..8519d276 --- /dev/null +++ b/internal/service/cloudapi/bservice/utility_bservice_list.go @@ -0,0 +1,99 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityBasicServiceListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*bservice.ListBasicServices, error) { + c := m.(*controller.ControllerCfg) + req := bservice.ListRequest{} + + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if rgId, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgId.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if rg_name, ok := d.GetOk("rg_name"); ok { + req.RGName = rg_name.(string) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if acc_name, ok := d.GetOk("account_name"); ok { + req.AccountName = acc_name.(string) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + log.Debugf("utilityBasicServiceListCheckPresence") + basicServiceList, err := c.CloudAPI().BService().List(ctx, req) + if err != nil { + return nil, err + } + + return basicServiceList, nil +} diff --git a/internal/service/cloudapi/bservice/utility_bservice_snapshot_list.go b/internal/service/cloudapi/bservice/utility_bservice_snapshot_list.go new file mode 100644 index 00000000..73c70831 --- /dev/null +++ b/internal/service/cloudapi/bservice/utility_bservice_snapshot_list.go @@ -0,0 +1,64 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package bservice + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityBasicServiceSnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*bservice.ListInfoSnapshots, error) { + c := m.(*controller.ControllerCfg) + var id uint64 + + if serviceId, ok := d.GetOk("service_id"); ok { + id = uint64(serviceId.(int)) + } + + req := bservice.SnapshotListRequest{ + ServiceID: id, + } + + log.Debugf("utilityBasicServiceSnapshotListCheckPresence") + basicServiceSnapshotList, err := c.CloudAPI().BService().SnapshotList(ctx, req) + if err != nil { + return nil, err + } + + return basicServiceSnapshotList, nil +} diff --git a/internal/service/cloudapi/disks/data_source_disk.go b/internal/service/cloudapi/disks/data_source_disk.go new file mode 100644 index 00000000..489be98c --- /dev/null +++ b/internal/service/cloudapi/disks/data_source_disk.go @@ -0,0 +1,507 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + // "net/url" + + "github.com/google/uuid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + flattenDisk(d, disk) + + return nil +} + +func dataSourceDiskSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the subscriber '(account') to whom this disk belongs", + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + // "boot_partition": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of disk partitions", + // }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Deleted time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of disk", + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of final deletion", + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the device", + }, + // "disk_path": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk path", + // }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + // "guid": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Disk ID on the storage side", + // }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image ID", + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "IDs of images using the disk", + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to read per second", + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to read", + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of io read operations per second", + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of io read operations", + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Size of io operations", + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total size bytes per second", + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total size of bytes per second", + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total number of io operations per second", + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total number of io operations per second", + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to write per second", + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to write per second", + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of write operations per second", + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of write operations per second", + }, + }, + }, + }, + // "iqn": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk IQN", + // }, + // "login": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Login to access the disk", + // }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "Milestones", + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of disk", + }, + "machine_id": { + Type: schema.TypeInt, + Computed: true, + }, + "machine_name": { + Type: schema.TypeString, + Computed: true, + }, + "order": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk order", + }, + "params": { + Type: schema.TypeString, + Computed: true, + Description: "Disk params", + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the parent disk", + }, + // "passwd": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Password to access the disk", + // }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the pci slot to which the disk is connected", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Description: "Pool for disk location", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + // "purge_attempts": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of deletion attempts", + // }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of the last deletion attempt", + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + // "reality_device_number": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Reality device number", + // }, + // "reference_id": { + // Type: schema.TypeString, + // Computed: true, + // Description: "ID of the reference to the disk", + // }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Resource ID", + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource", + }, + "role": { + Type: schema.TypeString, + Computed: true, + Description: "Disk role", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Storage endpoint provider ID to create disk", + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type SEP. Defines the type of storage system and contains one of the values set in the cloud platform", + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "size_available": { + Type: schema.TypeFloat, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Size in GB", + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + Description: "Number of used space, in GB", + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Disk status", + }, + "storage_policy_id": { + Type: schema.TypeFloat, + Computed: true, + Description: "Storage policy ID", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "Technical status of the disk", + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + Description: "Virtual Machine ID (Deprecated)", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + } + + return rets +} + +func DataSourceDisk() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskSchemaMake(), + } +} diff --git a/internal/service/cloudapi/disks/data_source_disk_list.go b/internal/service/cloudapi/disks/data_source_disk_list.go new file mode 100644 index 00000000..9da19c45 --- /dev/null +++ b/internal/service/cloudapi/disks/data_source_disk_list.go @@ -0,0 +1,592 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDiskListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskList, err := utilityDiskListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDiskList(diskList)) + d.Set("entry_count", diskList.EntryCount) + + return nil +} + +func dataSourceDiskListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by account name", + }, + "disk_max_size": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by max disk size", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "shared": { + Type: schema.TypeBool, + Optional: true, + Description: "Find by shared field", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the account the disks belong to", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Description: "find by sep ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Description: "find by pool name", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Optional: true, + Description: "storage policy ID ", + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by compute ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by rg ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the subscriber '(account') to whom this disk belongs", + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + // "boot_partition": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of disk partitions", + // }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Deleted time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of disk", + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of final deletion", + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the device", + }, + // "disk_path": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk path", + // }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + // "guid": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Disk ID on the storage side", + // }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image ID", + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "IDs of images using the disk", + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to read per second", + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to read", + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of io read operations per second", + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of io read operations", + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Size of io operations", + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total size bytes per second", + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total size of bytes per second", + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total number of io operations per second", + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total number of io operations per second", + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to write per second", + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to write per second", + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of write operations per second", + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of write operations per second", + }, + }, + }, + }, + // "iqn": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk IQN", + // }, + // "login": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Login to access the disk", + // }, + "machine_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Machine ID", + }, + "machine_name": { + Type: schema.TypeString, + Computed: true, + Description: "Machine name", + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "Milestones", + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of disk", + }, + "order": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk order", + }, + "params": { + Type: schema.TypeString, + Computed: true, + Description: "Disk params", + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the parent disk", + }, + // "passwd": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Password to access the disk", + // }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the pci slot to which the disk is connected", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Description: "Pool for disk location", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + // "purge_attempts": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of deletion attempts", + // }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of the last deletion attempt", + }, + // "reality_device_number": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Reality device number", + // }, + // "reference_id": { + // Type: schema.TypeString, + // Computed: true, + // Description: "ID of the reference to the disk", + // }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Resource ID", + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource", + }, + "role": { + Type: schema.TypeString, + Computed: true, + Description: "Disk role", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Storage endpoint provider ID to create disk", + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type SEP. Defines the type of storage system and contains one of the values set in the cloud platform", + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "size_available": { + Type: schema.TypeFloat, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Size in GB", + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + Description: "Number of used space, in GB", + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Disk status", + }, + "storage_policy_id": { + Type: schema.TypeFloat, + Computed: true, + Description: "Storage policy ID", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "Technical status of the disk", + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + Description: "Virtual Machine ID (Deprecated)", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceDiskList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/disks/data_source_disk_list_unattached.go b/internal/service/cloudapi/disks/data_source_disk_list_unattached.go new file mode 100644 index 00000000..fad4876f --- /dev/null +++ b/internal/service/cloudapi/disks/data_source_disk_list_unattached.go @@ -0,0 +1,484 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDiskListUnattachedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskListUnattached, err := utilityDiskListUnattachedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDiskListUnattached(diskListUnattached)) + d.Set("entry_count", diskListUnattached.EntryCount) + + return nil +} + +func DataSourceDiskListUnattached() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskListUnattachedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskListUnattachedSchemaMake(), + } +} + +func dataSourceDiskListUnattachedSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by account name", + }, + "disk_max_size": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by max disk size", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the account the disks belong to", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Description: "find by sep ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Description: "find by pool name", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Optional: true, + Description: "storage policy ID ", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "_meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "Meta parameters", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the account the disks belong to", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the subscriber '(account') to whom this disk belongs", + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of disk partitions", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Deleted time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of disk", + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of final deletion", + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + Description: "Disk path", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk ID on the storage side", + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image ID", + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "IDs of images using the disk", + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to read per second", + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to read", + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of io read operations per second", + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of io read operations", + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Size of io operations", + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total size bytes per second", + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total size of bytes per second", + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total number of io operations per second", + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total number of io operations per second", + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to write per second", + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to write per second", + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of write operations per second", + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of write operations per second", + }, + }, + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + Description: "Disk IQN", + }, + "login": { + Type: schema.TypeString, + Computed: true, + Description: "Login to access the disk", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "Milestones", + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of disk", + }, + "order": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk order", + }, + "params": { + Type: schema.TypeString, + Computed: true, + Description: "Disk params", + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the parent disk", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + Description: "Password to access the disk", + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the pci slot to which the disk is connected", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Description: "Pool for disk location", + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of deletion attempts", + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of the last deletion attempt", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + Description: "Reality device number", + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the reference to the disk", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Resource ID", + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource", + }, + "role": { + Type: schema.TypeString, + Computed: true, + Description: "Disk role", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Storage endpoint provider ID to create disk", + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + Description: "shareable", + }, + "cache": { + Type: schema.TypeString, + Computed: true, + Description: "Cache mode for the disk", + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Size in GB", + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + Description: "Number of used space, in GB", + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Disk status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "Technical status of the disk", + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + Description: "Virtual Machine ID (Deprecated)", + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} diff --git a/internal/service/cloudapi/disks/data_source_disk_replication.go b/internal/service/cloudapi/disks/data_source_disk_replication.go new file mode 100644 index 00000000..e0bbd28f --- /dev/null +++ b/internal/service/cloudapi/disks/data_source_disk_replication.go @@ -0,0 +1,475 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceDiskReplicationRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("dataSourceDiskReplicationRead: called for disk with ID: %s", d.Id()) + c := m.(*controller.ControllerCfg) + + req := disks.ReplicationStatusRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + } + + status, err := c.CloudAPI().Disks().ReplicationStatus(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + disk, err := utilityDiskReplicaCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenDiskReplica(d, disk, status) + + log.Debugf("dataSourceDiskReplicationRead: read complete for disk with ID: %s", d.Id()) + + return nil +} + +func dataSourceDiskReplicationSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "Id of primary disk", + }, + "replica_disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "Id of secondary disk", + }, + "status_replication": { + Type: schema.TypeString, + Computed: true, + Description: "Status of replication", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the subscriber '(account') to whom this disk belongs", + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + // "boot_partition": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of disk partitions", + // }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Deleted time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of disk", + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of final deletion", + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the device", + }, + // "disk_path": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk path", + // }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + // "guid": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Disk ID on the storage side", + // }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image ID", + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "IDs of images using the disk", + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to read per second", + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to read", + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of io read operations per second", + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of io read operations", + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Size of io operations", + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total size bytes per second", + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total size of bytes per second", + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total number of io operations per second", + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total number of io operations per second", + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to write per second", + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to write per second", + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of write operations per second", + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of write operations per second", + }, + }, + }, + }, + // "iqn": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk IQN", + // }, + // "login": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Login to access the disk", + // }, + // "milestones": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Milestones", + // }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of disk", + }, + "order": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk order", + }, + "params": { + Type: schema.TypeString, + Computed: true, + Description: "Disk params", + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the parent disk", + }, + // "passwd": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Password to access the disk", + // }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the pci slot to which the disk is connected", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Description: "Pool for disk location", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + // "purge_attempts": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of deletion attempts", + // }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of the last deletion attempt", + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + // "reality_device_number": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Reality device number", + // }, + // "reference_id": { + // Type: schema.TypeString, + // Computed: true, + // Description: "ID of the reference to the disk", + // }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Resource ID", + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource", + }, + "role": { + Type: schema.TypeString, + Computed: true, + Description: "Disk role", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Storage endpoint provider ID to create disk", + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type SEP. Defines the type of storage system and contains one of the values set in the cloud platform", + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Size in GB", + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + Description: "Number of used space, in GB", + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Disk status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "Technical status of the disk", + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + Description: "Virtual Machine ID (Deprecated)", + }, + } + + return rets +} + +func DataSourceDiskReplication() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskReplicationRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskReplicationSchemaMake(), + } +} diff --git a/internal/service/cloudapi/disks/data_source_disk_snapshot.go b/internal/service/cloudapi/disks/data_source_disk_snapshot.go new file mode 100644 index 00000000..736fa1ee --- /dev/null +++ b/internal/service/cloudapi/disks/data_source_disk_snapshot.go @@ -0,0 +1,126 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + var snapshot disks.ItemSnapshot + label := d.Get("label").(string) + for _, sn := range disk.Snapshots { + if label == sn.Label { + snapshot = sn + break + } + } + if label != snapshot.Label { + return diag.Errorf("Snapshot with label \"%v\" not found", label) + } + + id := uuid.New() + d.SetId(id.String()) + + flattenDiskSnapshot(d, snapshot) + + return nil +} + +func DataSourceDiskSnapshot() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskSnapshotRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskSnapshotSchemaMake(), + } +} + +func dataSourceDiskSnapshotSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "label": { + Type: schema.TypeString, + Required: true, + Description: "Name of the snapshot", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + } + return rets +} diff --git a/internal/service/cloudapi/disks/data_source_disk_snapshot_list.go b/internal/service/cloudapi/disks/data_source_disk_snapshot_list.go new file mode 100644 index 00000000..37993030 --- /dev/null +++ b/internal/service/cloudapi/disks/data_source_disk_snapshot_list.go @@ -0,0 +1,119 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDiskSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDiskSnapshotList(disk.Snapshots)) + return nil +} + +func DataSourceDiskSnapshotList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskSnapshotListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskSnapshotListSchemaMake(), + } +} + +func dataSourceDiskSnapshotListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + }, + }, + }, + } + return rets +} diff --git a/internal/service/cloudapi/disks/data_source_list_deleted.go b/internal/service/cloudapi/disks/data_source_list_deleted.go new file mode 100644 index 00000000..8f6ffc42 --- /dev/null +++ b/internal/service/cloudapi/disks/data_source_list_deleted.go @@ -0,0 +1,562 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDiskListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskList, err := utilityDiskListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDiskList(diskList)) + d.Set("entry_count", diskList.EntryCount) + + return nil +} + +func dataSourceDiskDeletedListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by disk ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by disk name", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by account name", + }, + "disk_max_size": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by max disk size", + }, + "shared": { + Type: schema.TypeBool, + Optional: true, + Description: "Find shared disks", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the account the disks belong to", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the subscriber '(account') to whom this disk belongs", + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + // "boot_partition": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of disk partitions", + // }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Deleted time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of disk", + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of final deletion", + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the device", + }, + // "disk_path": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk path", + // }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + // "guid": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Disk ID on the storage side", + // }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image ID", + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "IDs of images using the disk", + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to read per second", + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to read", + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of io read operations per second", + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of io read operations", + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Size of io operations", + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total size bytes per second", + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total size of bytes per second", + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total number of io operations per second", + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total number of io operations per second", + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to write per second", + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to write per second", + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of write operations per second", + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of write operations per second", + }, + }, + }, + }, + // "iqn": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk IQN", + // }, + // "login": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Login to access the disk", + // }, + "machine_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Machine ID", + }, + "machine_name": { + Type: schema.TypeString, + Computed: true, + Description: "Machine name", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "Milestones", + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of disk", + }, + "order": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk order", + }, + "params": { + Type: schema.TypeString, + Computed: true, + Description: "Disk params", + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the parent disk", + }, + // "passwd": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Password to access the disk", + // }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the pci slot to which the disk is connected", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Description: "Pool for disk location", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + // "purge_attempts": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of deletion attempts", + // }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of the last deletion attempt", + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + // "reality_device_number": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Reality device number", + // }, + // "reference_id": { + // Type: schema.TypeString, + // Computed: true, + // Description: "ID of the reference to the disk", + // }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Resource ID", + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource", + }, + "role": { + Type: schema.TypeString, + Computed: true, + Description: "Disk role", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Storage endpoint provider ID to create disk", + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type SEP. Defines the type of storage system and contains one of the values set in the cloud platform", + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "size_available": { + Type: schema.TypeFloat, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Size in GB", + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + Description: "Number of used space, in GB", + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Disk status", + }, + "storage_policy_id": { + Type: schema.TypeFloat, + Computed: true, + Description: "Storage policy ID", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "Technical status of the disk", + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + Description: "Virtual Machine ID (Deprecated)", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceDiskListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + ReadContext: dataSourceDiskListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskDeletedListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/disks/flattens.go b/internal/service/cloudapi/disks/flattens.go new file mode 100644 index 00000000..20764d0a --- /dev/null +++ b/internal/service/cloudapi/disks/flattens.go @@ -0,0 +1,313 @@ +package disks + +import ( + "encoding/json" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenDiskSnapshot(d *schema.ResourceData, snapshot disks.ItemSnapshot) { + d.Set("timestamp", snapshot.TimeStamp) + d.Set("guid", snapshot.GUID) + d.Set("res_id", snapshot.ResID) + d.Set("snap_set_guid", snapshot.SnapSetGUID) + d.Set("snap_set_time", snapshot.SnapSetTime) +} + +func flattenDiskListUnattached(ul *disks.ListDisksUnattached) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ul.Data)) + for _, unattachedDisk := range ul.Data { + unattachedDiskAcl, _ := json.Marshal(unattachedDisk.ACL) + tmp := map[string]interface{}{ + "_meta": flattens.FlattenMeta(unattachedDisk.Meta), + "account_id": unattachedDisk.AccountID, + "account_name": unattachedDisk.AccountName, + "acl": string(unattachedDiskAcl), + "discard": unattachedDisk.Discard, + "block_size": unattachedDisk.BlockSize, + "boot_partition": unattachedDisk.BootPartition, + "created_time": unattachedDisk.CreatedTime, + "deleted_time": unattachedDisk.DeletedTime, + "desc": unattachedDisk.Description, + "destruction_time": unattachedDisk.DestructionTime, + "disk_path": unattachedDisk.DiskPath, + "gid": unattachedDisk.GID, + "guid": unattachedDisk.GUID, + "disk_id": unattachedDisk.ID, + "image_id": unattachedDisk.ImageID, + "images": unattachedDisk.Images, + "iotune": flattenIOTune(unattachedDisk.IOTune), + "iqn": unattachedDisk.IQN, + "login": unattachedDisk.Login, + "milestones": unattachedDisk.Milestones, + "disk_name": unattachedDisk.Name, + "order": unattachedDisk.Order, + "params": unattachedDisk.Params, + "parent_id": unattachedDisk.ParentID, + "passwd": unattachedDisk.Password, + "pci_slot": unattachedDisk.PCISlot, + "pool": unattachedDisk.Pool, + "present_to": unattachedDisk.PresentTo, + "provision": unattachedDisk.Provision, + "purge_attempts": unattachedDisk.PurgeAttempts, + "purge_time": unattachedDisk.PurgeTime, + "reality_device_number": unattachedDisk.RealityDeviceNumber, + "reference_id": unattachedDisk.ReferenceID, + "res_id": unattachedDisk.ResID, + "res_name": unattachedDisk.ResName, + "role": unattachedDisk.Role, + "sep_id": unattachedDisk.SEPID, + "shareable": unattachedDisk.Shareable, + "cache": unattachedDisk.Cache, + "size_max": unattachedDisk.SizeMax, + "size_used": unattachedDisk.SizeUsed, + "snapshots": flattenDiskSnapshotList(unattachedDisk.Snapshots), + "status": unattachedDisk.Status, + "to_clean": unattachedDisk.ToClean, + "tech_status": unattachedDisk.TechStatus, + "vmid": unattachedDisk.VMID, + } + res = append(res, tmp) + } + return res +} + +func flattenDisk(d *schema.ResourceData, disk *disks.RecordDisk) { + diskAcl, _ := json.Marshal(disk.ACL) + d.Set("account_id", disk.AccountID) + d.Set("account_name", disk.AccountName) + d.Set("acl", string(diskAcl)) + d.Set("discard", disk.Discard) + d.Set("block_size", disk.BlockSize) + // d.Set("boot_partition", disk.BootPartition) + d.Set("computes", flattenDiskComputes(disk.Computes)) + d.Set("created_by", disk.CreatedBy) + d.Set("created_time", disk.CreatedTime) + d.Set("deleted_by", disk.DeletedBy) + d.Set("deleted_time", disk.DeletedTime) + d.Set("desc", disk.Description) + d.Set("destruction_time", disk.DestructionTime) + d.Set("devicename", disk.DeviceName) + // d.Set("disk_path", disk.DiskPath) + d.Set("gid", disk.GID) + // d.Set("guid", disk.GUID) + d.Set("disk_id", disk.ID) + d.Set("image_id", disk.ImageID) + d.Set("images", disk.Images) + d.Set("iotune", flattenIOTune(disk.IOTune)) + // d.Set("iqn", disk.IQN) + // d.Set("login", disk.Login) + d.Set("independent", disk.Independent) + d.Set("machine_id", disk.MachineID) + d.Set("machine_name", disk.MachineName) + d.Set("disk_name", disk.Name) + d.Set("order", disk.Order) + d.Set("params", disk.Params) + d.Set("parent_id", disk.ParentID) + // d.Set("passwd", disk.Passwd) + d.Set("pci_slot", disk.PCISlot) + d.Set("pool", disk.Pool) + d.Set("present_to", disk.PresentTo) + d.Set("provision", disk.Provision) + // d.Set("purge_attempts", disk.PurgeAttempts) + d.Set("purge_time", disk.PurgeTime) + d.Set("replication", flattenDiskReplication(disk.Replication)) + // d.Set("reality_device_number", disk.RealityDeviceNumber) + // d.Set("reference_id", disk.ReferenceID) + d.Set("res_id", disk.ResID) + d.Set("res_name", disk.ResName) + d.Set("role", disk.Role) + d.Set("sep_id", disk.SepID) + d.Set("sep_type", disk.SepType) + d.Set("size_max", disk.SizeMax) + d.Set("size_used", disk.SizeUsed) + d.Set("shareable", disk.Shareable) + d.Set("cache", disk.Cache) + d.Set("snapshots", flattenDiskSnapshotList(disk.Snapshots)) + d.Set("status", disk.Status) + d.Set("storage_policy_id", disk.StoragePolicyID) + d.Set("tech_status", disk.TechStatus) + d.Set("vmid", disk.VMID) + d.Set("updated_by", disk.UpdatedBy) + d.Set("updated_time", disk.UpdatedTime) + d.Set("to_clean", disk.ToClean) +} + +func flattenDiskReplication(rep disks.ItemReplication) []map[string]interface{} { + res := []map[string]interface{}{ + { + "disk_id": rep.DiskID, + "pool_id": rep.PoolID, + "role": rep.Role, + "self_volume_id": rep.SelfVolumeID, + "storage_id": rep.StorageID, + "volume_id": rep.VolumeID, + }, + } + return res +} + +func flattenDiskReplica(d *schema.ResourceData, disk *disks.RecordDisk, statusReplication string) { + diskAcl, _ := json.Marshal(disk.ACL) + d.Set("account_id", disk.AccountID) + d.Set("account_name", disk.AccountName) + d.Set("acl", string(diskAcl)) + // d.Set("boot_partition", disk.BootPartition) + d.Set("computes", flattenDiskComputes(disk.Computes)) + d.Set("created_time", disk.CreatedTime) + d.Set("deleted_time", disk.DeletedTime) + d.Set("desc", disk.Description) + d.Set("destruction_time", disk.DestructionTime) + d.Set("devicename", disk.DeviceName) + // d.Set("disk_path", disk.DiskPath) + d.Set("gid", disk.GID) + // d.Set("guid", disk.GUID) + d.Set("replica_disk_id", disk.ID) + d.Set("image_id", disk.ImageID) + d.Set("images", disk.Images) + d.Set("iotune", flattenIOTune(disk.IOTune)) + // d.Set("iqn", disk.IQN) + // d.Set("login", disk.Login) + // d.Set("milestones", disk.Milestones) + d.Set("disk_name", disk.Name) + d.Set("order", disk.Order) + d.Set("params", disk.Params) + d.Set("parent_id", disk.ParentID) + // d.Set("passwd", disk.Passwd) + d.Set("pci_slot", disk.PCISlot) + d.Set("pool", disk.Pool) + d.Set("present_to", disk.PresentTo) + // d.Set("purge_attempts", disk.PurgeAttempts) + d.Set("purge_time", disk.PurgeTime) + d.Set("replication", flattenDiskReplication(disk.Replication)) + // d.Set("reality_device_number", disk.RealityDeviceNumber) + // d.Set("reference_id", disk.ReferenceID) + d.Set("res_id", disk.ResID) + d.Set("res_name", disk.ResName) + d.Set("role", disk.Role) + d.Set("sep_id", disk.SepID) + d.Set("sep_type", disk.SepType) + d.Set("size_max", disk.SizeMax) + d.Set("size_used", disk.SizeUsed) + d.Set("shareable", disk.Shareable) + d.Set("cache", disk.Cache) + d.Set("snapshots", flattenDiskSnapshotList(disk.Snapshots)) + d.Set("status", disk.Status) + d.Set("status_replication", statusReplication) + d.Set("tech_status", disk.TechStatus) + d.Set("vmid", disk.VMID) +} + +func flattenDiskSnapshotList(sl disks.ListSnapshots) []interface{} { + res := make([]interface{}, 0, len(sl)) + for _, snapshot := range sl { + temp := map[string]interface{}{ + "guid": snapshot.GUID, + "label": snapshot.Label, + "res_id": snapshot.ResID, + "snap_set_guid": snapshot.SnapSetGUID, + "snap_set_time": snapshot.SnapSetTime, + "timestamp": snapshot.TimeStamp, + } + res = append(res, temp) + } + + return res +} + +func flattenDiskList(dl *disks.ListDisks) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(dl.Data)) + for _, disk := range dl.Data { + diskAcl, _ := json.Marshal(disk.ACL) + temp := map[string]interface{}{ + "account_id": disk.AccountID, + "account_name": disk.AccountName, + "acl": string(diskAcl), + "discard": disk.Discard, + "block_size": disk.BlockSize, + "computes": flattenDiskComputes(disk.Computes), + "created_by": disk.CreatedBy, + "created_time": disk.CreatedTime, + "deleted_by": disk.DeletedBy, + "deleted_time": disk.DeletedTime, + "desc": disk.Description, + "destruction_time": disk.DestructionTime, + "devicename": disk.DeviceName, + "gid": disk.GID, + "disk_id": disk.ID, + "image_id": disk.ImageID, + "images": disk.Images, + "independent": disk.Independent, + "iotune": flattenIOTune(disk.IOTune), + "machine_id": disk.MachineID, + "machine_name": disk.MachineName, + "milestones": disk.Milestones, + "disk_name": disk.Name, + "order": disk.Order, + "params": disk.Params, + "parent_id": disk.ParentID, + "pci_slot": disk.PCISlot, + "pool": disk.Pool, + "present_to": disk.PresentTo, + "provision": disk.Provision, + "purge_time": disk.PurgeTime, + "replication": flattenDiskReplication(disk.Replication), + "res_id": disk.ResID, + "res_name": disk.ResName, + "role": disk.Role, + "sep_id": disk.SepID, + "sep_type": disk.SepType, + "shareable": disk.Shareable, + "cache": disk.Cache, + "size_available": disk.SizeAvailable, + "size_max": disk.SizeMax, + "size_used": disk.SizeUsed, + "snapshots": flattenDiskSnapshotList(disk.Snapshots), + "status": disk.Status, + "storage_policy_id": disk.StoragePolicyID, + "tech_status": disk.TechStatus, + "vmid": disk.VMID, + "updated_by": disk.UpdatedBy, + "updated_time": disk.UpdatedTime, + "to_clean": disk.ToClean, + } + res = append(res, temp) + } + return res +} + +func flattenIOTune(iot disks.IOTune) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "read_bytes_sec": iot.ReadBytesSec, + "read_bytes_sec_max": iot.ReadBytesSecMax, + "read_iops_sec": iot.ReadIOPSSec, + "read_iops_sec_max": iot.ReadIOPSSecMax, + "size_iops_sec": iot.SizeIOPSSec, + "total_bytes_sec": iot.TotalBytesSec, + "total_bytes_sec_max": iot.TotalBytesSecMax, + "total_iops_sec": iot.TotalIOPSSec, + "total_iops_sec_max": iot.TotalIOPSSecMax, + "write_bytes_sec": iot.WriteBytesSec, + "write_bytes_sec_max": iot.WriteBytesSecMax, + "write_iops_sec": iot.WriteIOPSSec, + "write_iops_sec_max": iot.WriteIOPSSecMax, + } + + res = append(res, temp) + return res +} + +func flattenDiskComputes(computes map[string]string) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for computeKey, computeVal := range computes { + temp := map[string]interface{}{ + "compute_id": computeKey, + "compute_name": computeVal, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/disks/old_schemas.go b/internal/service/cloudapi/disks/old_schemas.go new file mode 100644 index 00000000..2b292f3d --- /dev/null +++ b/internal/service/cloudapi/disks/old_schemas.go @@ -0,0 +1,430 @@ +package disks + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceDiskV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "disk_name": { + Type: schema.TypeString, + Required: true, + Description: "Name of disk", + }, + "size_max": { + Type: schema.TypeInt, + Required: true, + Description: "Size in GB", + }, + "gid": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "ID of the grid (platform)", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Pool for disk location", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Storage endpoint provider ID to create disk", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Description of disk", + }, + "type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"D", "B", "T"}, false), + Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data, T=Temp'", + }, + "detach": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Detaching the disk from compute", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Whether to completely delete the disk, works only with non attached disks", + }, + "shareable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Number of bytes to read per second", + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum number of bytes to read", + }, + "read_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Number of io read operations per second", + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum number of io read operations", + }, + "size_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Size of io operations", + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Total size bytes per second", + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum total size of bytes per second", + }, + "total_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Total number of io operations per second", + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum total number of io operations per second", + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Number of bytes to write per second", + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum number of bytes to write per second", + }, + "write_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Number of write operations per second", + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum number of write operations per second", + }, + }, + }, + }, + "present_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk ID. Duplicates the value of the ID parameter", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the subscriber '(account') to whom this disk belongs", + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + // "boot_partition": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of disk partitions", + // }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Deleted time", + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of final deletion", + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the device", + }, + // "disk_path": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk path", + // }, + // "guid": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Disk ID on the storage side", + // }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image ID", + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "IDs of images using the disk", + }, + // "iqn": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk IQN", + // }, + // "login": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Login to access the disk", + // }, + // "milestones": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Milestones", + // }, + "order": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk order", + }, + "params": { + Type: schema.TypeString, + Computed: true, + Description: "Disk params", + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the parent disk", + }, + // "passwd": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Password to access the disk", + // }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the pci slot to which the disk is connected", + }, + // "purge_attempts": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of deletion attempts", + // }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of the last deletion attempt", + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + // "reality_device_number": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Reality device number", + // }, + // "reference_id": { + // Type: schema.TypeString, + // Computed: true, + // Description: "ID of the reference to the disk", + // }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Resource ID", + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource", + }, + "role": { + Type: schema.TypeString, + Computed: true, + Description: "Disk role", + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type SEP. Defines the type of storage system and contains one of the values set in the cloud platform", + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + Description: "Number of used space, in GB", + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Disk status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "Technical status of the disk", + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + Description: "Virtual Machine ID (Deprecated)", + }, + }, + } +} + +func resourceDiskV2() *schema.Resource { + s := resourceDiskSchemaMake() + s["blk_discard"] = &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + } + return &schema.Resource{Schema: s} +} diff --git a/internal/service/cloudapi/disks/resource_check_input_values.go b/internal/service/cloudapi/disks/resource_check_input_values.go new file mode 100644 index 00000000..a06024c2 --- /dev/null +++ b/internal/service/cloudapi/disks/resource_check_input_values.go @@ -0,0 +1,61 @@ +package disks + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + accountId := uint64(d.Get("account_id").(int)) + req := account.ListRequest{} + + accountList, err := c.CloudAPI().Account().List(ctx, req) + if err != nil { + return false, err + } + + return len(accountList.FilterByID(accountId).Data) != 0, nil +} + +func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + gid := uint64(d.Get("gid").(int)) + req := locations.ListRequest{} + + locationList, err := c.CloudAPI().Locations().List(ctx, req) + if err != nil { + return false, err + } + + return len(locationList.FilterByGID(gid).Data) != 0, nil +} + +func existDiskID(ctx context.Context, diskId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + req := disks.ListRequest{ + ByID: diskId, + } + + diskList, err := c.CloudAPI().Disks().List(ctx, req) + if err != nil { + return err + } + + if len(diskList.Data) == 0 { + return fmt.Errorf("resourceDiskReplication: can't create or update Disk replication because DiskID %d is not allowed or does not exist", diskId) + } + + if diskList.Data[0].SepType != "TATLIN" { + return fmt.Errorf("resourceDiskReplication: can't create or update Disk replication because DiskID %d is not TATLIN SEP Type", diskId) + } + + return nil +} diff --git a/internal/service/cloudapi/disks/resource_disk.go b/internal/service/cloudapi/disks/resource_disk.go new file mode 100644 index 00000000..bb85ee67 --- /dev/null +++ b/internal/service/cloudapi/disks/resource_disk.go @@ -0,0 +1,857 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + "fmt" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + req := disks.CreateRequest{} + + haveAccount, err := existAccountID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + if !haveAccount { + return diag.Errorf("resourceDiskCreate: can't create Disk because AccountID %d is not allowed or does not exist", d.Get("account_id").(int)) + } + + req.AccountID = uint64(d.Get("account_id").(int)) + req.Name = d.Get("disk_name").(string) + req.StoragePolicyID = uint64(d.Get("storage_policy_id").(int)) + req.Size = uint64(d.Get("size_max").(int)) + + if sepId, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepId.(int)) + } + + if poolName, ok := d.GetOk("pool"); ok { + req.Pool = poolName.(string) + } + + argVal, argSet := d.GetOk("desc") + if argSet { + req.Description = argVal.(string) + } + + diskId, err := c.CloudAPI().Disks().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(diskId, 10)) + + if iotuneRaw, ok := d.GetOk("iotune"); ok { + iot := iotuneRaw.([]interface{})[0] + iotune := iot.(map[string]interface{}) + req := disks.LimitIORequest{ + DiskID: diskId, + IOPS: uint64(iotune["total_iops_sec"].(int)), + ReadBytesSec: uint64(iotune["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotune["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotune["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotune["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotune["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotune["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotune["total_bytes_sec_max"].(int)), + TotalIOPSSecMax: uint64(iotune["total_iops_sec_max"].(int)), + TotalIOPSSec: uint64(iotune["total_iops_sec"].(int)), + WriteBytesSec: uint64(iotune["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotune["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotune["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotune["write_iops_sec_max"].(int)), + } + + _, err := c.CloudAPI().Disks().LimitIO(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if shareable := d.Get("shareable"); shareable.(bool) == true { + req := disks.ShareRequest{ + DiskID: diskId, + } + + _, err := c.CloudAPI().Disks().Share(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceDiskRead(ctx, d, m) +} + +func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + // c := m.(*controller.ControllerCfg) + warnings := dc.Warnings{} + + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChangeState := false + + switch disk.Status { + case status.Destroyed, status.Purged: + d.Set("disk_id", 0) + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceDiskCreate(ctx, d, m) + case status.Deleted: + // hasChangeState = true + // req := disks.RestoreRequest{ + // DiskID: disk.ID, + // } + + // if reason, ok := d.GetOk("reason"); ok { + // req.Reason = reason.(string) + // } else { + // req.Reason = "Terraform automatic restore" + // } + + // _, err := c.CloudAPI().Disks().Restore(ctx, req) + // if err != nil { + // warnings.Add(err) + // } + case status.Assigned: + case status.Modeled: + return diag.Errorf("The disk is in status: %s, please, contact support for more information", disk.Status) + case status.Creating: + case status.Created: + case status.Allocated: + case status.Unallocated: + } + + if hasChangeState { + disk, err = utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + flattenDisk(d, disk) + + return warnings.Get() +} + +func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + warnings := dc.Warnings{} + + haveAccount, err := existAccountID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + if !haveAccount { + return diag.Errorf("resourceDiskUpdate: can't update Disk because AccountID %d is not allowed or does not exist", d.Get("account_id").(int)) + } + + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChangeState := false + + switch disk.Status { + case status.Destroyed, status.Purged: + d.Set("disk_id", 0) + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceDiskCreate(ctx, d, m) + case status.Deleted: + hasChangeState = true + req := disks.RestoreRequest{ + DiskID: disk.ID, + } + + _, err := c.CloudAPI().Disks().Restore(ctx, req) + if err != nil { + warnings.Add(err) + } + case status.Assigned: + case status.Modeled: + return diag.Errorf("The disk is in status: %s, please, contact support for more information", disk.Status) + case status.Creating: + case status.Created: + case status.Allocated: + case status.Unallocated: + } + + if hasChangeState { + disk, err = utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChange("storage_policy_id") { + req := disks.ChangeDiskStoragePolicyRequest{ + DiskID: disk.ID, + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + _, err := c.CloudAPI().Disks().ChangeDiskStoragePolicy(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("size_max") { + oldSize, newSize := d.GetChange("size_max") + if oldSize.(int) < newSize.(int) { + log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB", + d.Id(), oldSize.(int), newSize.(int)) + req := disks.ResizeRequest{ + DiskID: disk.ID, + Size: uint64(newSize.(int)), + } + + _, err := c.CloudAPI().Disks().Resize2(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.Set("size_max", newSize) + } else if oldSize.(int) > newSize.(int) { + return diag.FromErr(fmt.Errorf("resourceDiskUpdate: Disk ID %s - reducing disk size is not allowed", d.Id())) + } + } + + if d.HasChange("disk_name") { + req := disks.RenameRequest{ + DiskID: disk.ID, + Name: d.Get("disk_name").(string), + } + + _, err := c.CloudAPI().Disks().Rename(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("iotune") { + iot := d.Get("iotune").([]interface{})[0] + iotune := iot.(map[string]interface{}) + req := disks.LimitIORequest{ + DiskID: disk.ID, + IOPS: uint64(iotune["total_iops_sec"].(int)), + ReadBytesSec: uint64(iotune["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotune["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotune["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotune["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotune["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotune["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotune["total_bytes_sec_max"].(int)), + TotalIOPSSecMax: uint64(iotune["total_iops_sec_max"].(int)), + TotalIOPSSec: uint64(iotune["total_iops_sec"].(int)), + WriteBytesSec: uint64(iotune["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotune["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotune["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotune["write_iops_sec_max"].(int)), + } + + _, err := c.CloudAPI().Disks().LimitIO(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shareable") { + oldShare, newShare := d.GetChange("shareable") + if oldShare.(bool) == false && newShare.(bool) == true { + req := disks.ShareRequest{DiskID: disk.ID} + + _, err := c.CloudAPI().Disks().Share(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + if oldShare.(bool) == true && newShare.(bool) == false { + req := disks.UnshareRequest{DiskID: disk.ID} + + _, err := c.CloudAPI().Disks().Unshare(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + return resourceDiskRead(ctx, d, m) +} + +func resourceDiskDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + if disk.Status == status.Destroyed || disk.Status == status.Purged { + return nil + } + + req := disks.DeleteRequest{ + DiskID: disk.ID, + Detach: d.Get("detach").(bool), + Permanently: d.Get("permanently").(bool), + } + + c := m.(*controller.ControllerCfg) + _, err = c.CloudAPI().Disks().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceDiskSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID storage policy under which the disk will be created", + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "disk_name": { + Type: schema.TypeString, + Required: true, + Description: "Name of disk", + }, + "size_max": { + Type: schema.TypeInt, + Required: true, + Description: "Size in GB", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Pool for disk location", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Storage endpoint provider ID to create disk", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Description of disk", + }, + "detach": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Detaching the disk from compute", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Whether to completely delete the disk, works only with non attached disks", + }, + "shareable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Number of bytes to read per second", + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum number of bytes to read", + }, + "read_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Number of io read operations per second", + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum number of io read operations", + }, + "size_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Size of io operations", + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Total size bytes per second", + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum total size of bytes per second", + }, + "total_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Total number of io operations per second", + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum total number of io operations per second", + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Number of bytes to write per second", + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum number of bytes to write per second", + }, + "write_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Number of write operations per second", + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Maximum number of write operations per second", + }, + }, + }, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk ID. Duplicates the value of the ID parameter", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the subscriber '(account') to whom this disk belongs", + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + // "boot_partition": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of disk partitions", + // }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Deleted time", + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of final deletion", + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the device", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + // "disk_path": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk path", + // }, + // "guid": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Disk ID on the storage side", + // }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image ID", + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "IDs of images using the disk", + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + // "iqn": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk IQN", + // }, + // "login": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Login to access the disk", + // }, + // "milestones": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Milestones", + // }, + "machine_id": { + Type: schema.TypeInt, + Computed: true, + }, + "machine_name": { + Type: schema.TypeString, + Computed: true, + }, + "order": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk order", + }, + "params": { + Type: schema.TypeString, + Computed: true, + Description: "Disk params", + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the parent disk", + }, + // "passwd": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Password to access the disk", + // }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the pci slot to which the disk is connected", + }, + // "purge_attempts": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of deletion attempts", + // }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of the last deletion attempt", + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + // "reality_device_number": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Reality device number", + // }, + // "reference_id": { + // Type: schema.TypeString, + // Computed: true, + // Description: "ID of the reference to the disk", + // }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Resource ID", + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource", + }, + "role": { + Type: schema.TypeString, + Computed: true, + Description: "Disk role", + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type SEP. Defines the type of storage system and contains one of the values set in the cloud platform", + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + Description: "Number of used space, in GB", + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Disk status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "Technical status of the disk", + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + Description: "Virtual Machine ID (Deprecated)", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + Description: "Discard mode of the disk", + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + } + + return rets +} + +func ResourceDisk() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 3, + + CreateContext: resourceDiskCreate, + ReadContext: resourceDiskRead, + UpdateContext: resourceDiskUpdate, + DeleteContext: resourceDiskDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceDiskSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceDiskV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceDiskUpgradeV1, + Version: 1, + }, + { + Type: resourceDiskV2().CoreConfigSchema().ImpliedType(), + Upgrade: resourceDiskUpgradeV2, + Version: 2, + }, + }, + } +} diff --git a/internal/service/cloudapi/disks/resource_disk_replication.go b/internal/service/cloudapi/disks/resource_disk_replication.go new file mode 100644 index 00000000..4bdb230a --- /dev/null +++ b/internal/service/cloudapi/disks/resource_disk_replication.go @@ -0,0 +1,631 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceDiskReplicationCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskId := uint64(d.Get("disk_id").(int)) + + log.Debugf("resourceDiskReplicationCreate: called for disk with ID: %d", diskId) + + c := m.(*controller.ControllerCfg) + + err := existDiskID(ctx, diskId, m) + if err != nil { + return diag.FromErr(err) + } + + reqCreate := disks.ReplicateRequest{ + DiskID: diskId, + Name: d.Get("disk_name").(string), + SepID: uint64(d.Get("sep_id").(int)), + PoolName: d.Get("pool_name").(string), + } + + diskReplicaId, err := c.CloudAPI().Disks().Replicate(ctx, reqCreate) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(diskReplicaId, 10)) + d.Set("replica_disk_id", diskReplicaId) + + log.Debugf("resourceDiskReplicationCreate: create replica complete for disk with ID: %d", diskId) + + warnings := dc.Warnings{} + + if start, ok := d.GetOk("start"); ok && !start.(bool) { + log.Debugf("resourceDiskReplicationCreate: replication between disk with ID: %d and replica with ID: %d, try to stop", diskId, diskReplicaId) + reqStop := disks.ReplicationStopRequest{ + DiskID: diskId, + } + _, err = c.CloudAPI().Disks().ReplicationStop(ctx, reqStop) + if err != nil { + warnings.Add(err) + } + log.Debugf("resourceDiskReplicationCreate: replication between disk with ID: %d and replica with ID: %d, stoped", diskId, diskReplicaId) + } + return append(resourceDiskReplicationRead(ctx, d, m), warnings.Get()...) +} + +func resourceDiskReplicationRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDiskReplicationRead: called for disk with ID: %s", d.Id()) + c := m.(*controller.ControllerCfg) + + req := disks.ReplicationStatusRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + } + + status, err := c.CloudAPI().Disks().ReplicationStatus(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + diskReplica, err := utilityDiskReplicaCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenDiskReplica(d, diskReplica, status) + + log.Debugf("resourceDiskReplicationRead: read complete for disk with ID: %s", d.Id()) + return nil +} + +func resourceDiskReplicationUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskId := uint64(d.Get("disk_id").(int)) + log.Debugf("resourceDiskReplicationUpdate: called for disk with ID: %d", diskId) + + err := existDiskID(ctx, diskId, m) + if err != nil { + return diag.FromErr(err) + } + + if d.HasChange("start") { + if err := utilityDiskReplicationUpdateStartStop(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("pause") { + if err := utilityDiskReplicationUpdatePause(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("reverse") { + if err := utilityDiskReplicationUpdateReverse(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + log.Debugf("resourceDiskReplicationUpdate: read complete for disk with ID: %d", diskId) + return resourceDiskReplicationRead(ctx, d, m) +} + +func resourceDiskReplicationDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskId := uint64(d.Get("disk_id").(int)) + log.Debugf("resourceDiskReplicationDelete: called for disk with ID: %d", diskId) + + disk, err := utilityDiskReplicaCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + + if d.Get("start").(bool) { + reqStop := disks.ReplicationStopRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + } + + log.Debugf("resourceDiskReplicationDelete: stop replication for disk with ID: %d", diskId) + _, err = c.CloudAPI().Disks().ReplicationStop(ctx, reqStop) + if err != nil { + return diag.FromErr(err) + } + log.Debugf("resourceDiskReplicationDelete: stop replication for disk with ID: %d, complete", diskId) + } + + reqDelete := disks.DeleteRequest{ + DiskID: disk.ID, + Detach: d.Get("detach").(bool), + Permanently: d.Get("permanently").(bool), + } + + log.Debugf("resourceDiskReplicationDelete: delete disk replica for disk with ID: %d", diskId) + _, err = c.CloudAPI().Disks().Delete(ctx, reqDelete) + if err != nil { + return diag.FromErr(err) + } + log.Debugf("resourceDiskReplicationDelete: delete disk replica for disk with ID: %d, complete", diskId) + + d.SetId("") + + return nil +} + +func resourceDiskReplicationSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "Id of primary disk", + }, + "disk_name": { + Type: schema.TypeString, + Required: true, + Description: "Name of disk replica", + }, + "sep_id": { + Type: schema.TypeInt, + Required: true, + Description: "Storage endpoint provider ID to create disk replica", + }, + "pool_name": { + Type: schema.TypeString, + Required: true, + Description: "Pool for disk location", + }, + "pause": { + Type: schema.TypeBool, + Optional: true, + Description: "Resume replication", + }, + "reverse": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Reverse replication", + }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Start/Stop replication", + }, + "detach": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Detach disk from machine first", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Delete disk permanently", + }, + "replica_disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Id of replica disk", + }, + "status_replication": { + Type: schema.TypeString, + Computed: true, + Description: "Status of replication", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the subscriber '(account') to whom this disk belongs", + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + // "boot_partition": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of disk partitions", + // }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Deleted time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of disk", + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of final deletion", + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the device", + }, + // "disk_path": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk path", + // }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + // "guid": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Disk ID on the storage side", + // }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image ID", + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "IDs of images using the disk", + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to read per second", + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to read", + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of io read operations per second", + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of io read operations", + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Size of io operations", + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total size bytes per second", + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total size of bytes per second", + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total number of io operations per second", + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total number of io operations per second", + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to write per second", + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to write per second", + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of write operations per second", + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of write operations per second", + }, + }, + }, + }, + // "iqn": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk IQN", + // }, + // "login": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Login to access the disk", + // }, + // "milestones": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Milestones", + // }, + "order": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk order", + }, + "params": { + Type: schema.TypeString, + Computed: true, + Description: "Disk params", + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the parent disk", + }, + // "passwd": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Password to access the disk", + // }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the pci slot to which the disk is connected", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + // "purge_attempts": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of deletion attempts", + // }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of the last deletion attempt", + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + // "reality_device_number": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Reality device number", + // }, + // "reference_id": { + // Type: schema.TypeString, + // Computed: true, + // Description: "ID of the reference to the disk", + // }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Resource ID", + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource", + }, + "role": { + Type: schema.TypeString, + Computed: true, + Description: "Disk role", + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type SEP. Defines the type of storage system and contains one of the values set in the cloud platform", + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Size in GB", + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + Description: "Number of used space, in GB", + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Disk status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "Technical status of the disk", + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + Description: "Virtual Machine ID (Deprecated)", + }, + } + + return rets +} + +func ResourceDiskReplication() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceDiskReplicationCreate, + ReadContext: resourceDiskReplicationRead, + UpdateContext: resourceDiskReplicationUpdate, + DeleteContext: resourceDiskReplicationDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceDiskReplicationSchemaMake(), + } +} diff --git a/internal/service/cloudapi/disks/resource_disk_snapshot.go b/internal/service/cloudapi/disks/resource_disk_snapshot.go new file mode 100644 index 00000000..7507a324 --- /dev/null +++ b/internal/service/cloudapi/disks/resource_disk_snapshot.go @@ -0,0 +1,243 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceDiskSnapshotCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + snapshots := disk.Snapshots + snapshot := disks.ItemSnapshot{} + label := d.Get("label").(string) + for _, sn := range snapshots { + if label == sn.Label { + snapshot = sn + break + } + } + if label != snapshot.Label { + return diag.Errorf("Snapshot with label \"%v\" not found", label) + } + + if rollback := d.Get("rollback").(bool); rollback { + req := disks.SnapshotRollbackRequest{ + DiskID: disk.ID, + Label: label, + TimeStamp: uint64(d.Get("timestamp").(int)), + } + + log.Debugf("resourceDiskCreate: Snapshot rollback with label %s", label) + _, err := c.CloudAPI().Disks().SnapshotRollback(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + return resourceDiskSnapshotRead(ctx, d, m) +} + +func resourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + snapshots := disk.Snapshots + snapshot := disks.ItemSnapshot{} + label := d.Get("label").(string) + for _, sn := range snapshots { + if label == sn.Label { + snapshot = sn + break + } + } + if label != snapshot.Label { + return diag.Errorf("Snapshot with label \"%v\" not found", label) + } + + flattenDiskSnapshot(d, snapshot) + + return nil +} + +func resourceDiskSnapshotUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + snapshots := disk.Snapshots + snapshot := disks.ItemSnapshot{} + label := d.Get("label").(string) + for _, sn := range snapshots { + if label == sn.Label { + snapshot = sn + break + } + } + + if label != snapshot.Label { + return diag.Errorf("Snapshot with label \"%v\" not found", label) + } + + if d.HasChange("rollback") && d.Get("rollback").(bool) == true { + req := disks.SnapshotRollbackRequest{ + DiskID: disk.ID, + Label: label, + TimeStamp: uint64(d.Get("timestamp").(int)), + } + + log.Debugf("resourceDiskUpdtae: Snapshot rollback with label %s", label) + _, err := c.CloudAPI().Disks().SnapshotRollback(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceDiskSnapshotRead(ctx, d, m) +} + +func resourceDiskSnapshotDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + req := disks.SnapshotDeleteRequest{ + DiskID: disk.ID, + Label: d.Get("label").(string), + } + + _, err = c.CloudAPI().Disks().SnapshotDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceDiskSnapshotSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "label": { + Type: schema.TypeString, + Required: true, + //ForceNew: true, + Description: "Name of the snapshot", + }, + "rollback": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Needed in order to make a snapshot rollback", + }, + "timestamp": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Snapshot time", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + } + return rets +} + +func ResourceDiskSnapshot() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceDiskSnapshotCreate, + ReadContext: resourceDiskSnapshotRead, + UpdateContext: resourceDiskSnapshotUpdate, + DeleteContext: resourceDiskSnapshotDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceDiskSnapshotSchemaMake(), + } +} diff --git a/internal/service/cloudapi/disks/state_upgraders.go b/internal/service/cloudapi/disks/state_upgraders.go new file mode 100644 index 00000000..b7bc3bf8 --- /dev/null +++ b/internal/service/cloudapi/disks/state_upgraders.go @@ -0,0 +1,28 @@ +package disks + +import ( + "context" + + log "github.com/sirupsen/logrus" +) + +func resourceDiskUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceDiskUpgradeV1: upgrading state") + rawState["present_to"] = make(map[string]uint64) + + return rawState, nil +} + +func resourceDiskUpgradeV2(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceDiskUpgradeV2: upgrading state") + if v, ok := rawState["blk_discard"].(bool); ok { + if v { + rawState["discard"] = "unmap" + } else { + rawState["discard"] = "ignore" + } + } + delete(rawState, "blk_discard") + + return rawState, nil +} diff --git a/internal/service/cloudapi/disks/utility_disk.go b/internal/service/cloudapi/disks/utility_disk.go new file mode 100644 index 00000000..e28b7527 --- /dev/null +++ b/internal/service/cloudapi/disks/utility_disk.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.RecordDisk, error) { + c := m.(*controller.ControllerCfg) + req := disks.GetRequest{} + + if d.Get("disk_id") != nil { + if d.Get("disk_id").(int) == 0 { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DiskID = id + } else { + req.DiskID = uint64(d.Get("disk_id").(int)) + } + } else { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DiskID = id + } + + log.Debugf("utilityDiskCheckPresence: load disk") + disk, err := c.CloudAPI().Disks().Get(ctx, req) + if err != nil { + return nil, err + } + + return disk, nil +} diff --git a/internal/service/cloudapi/disks/utility_disk_list.go b/internal/service/cloudapi/disks/utility_disk_list.go new file mode 100644 index 00000000..cb7ff343 --- /dev/null +++ b/internal/service/cloudapi/disks/utility_disk_list.go @@ -0,0 +1,102 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.ListDisks, error) { + c := m.(*controller.ControllerCfg) + req := disks.ListRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if account_name, ok := d.GetOk("account_name"); ok { + req.AccountName = account_name.(string) + } + if disk_max_size, ok := d.GetOk("disk_max_size"); ok { + req.DiskMaxSize = int64(disk_max_size.(int)) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if shared, ok := d.GetOk("shared"); ok { + req.Shared = shared.(bool) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if sepId, ok := d.GetOk("sep_id"); ok { + req.AccountID = uint64(sepId.(int)) + } + if pool_name, ok := d.GetOk("pool_name"); ok { + req.Pool = pool_name.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if storagePolicyID, ok := d.GetOk("storage_policy_id"); ok { + req.StoragePolicyID = uint64(storagePolicyID.(int)) + } + if rgID, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgID.(int)) + } + if computeID, ok := d.GetOk("compute_id"); ok { + req.ComputeID = uint64(computeID.(int)) + } + + log.Debugf("utilityDiskListCheckPresence: load disk list") + diskList, err := c.CloudAPI().Disks().List(ctx, req) + if err != nil { + return nil, err + } + + return diskList, nil +} diff --git a/internal/service/cloudapi/disks/utility_disk_list_deleted.go b/internal/service/cloudapi/disks/utility_disk_list_deleted.go new file mode 100644 index 00000000..a3b9af9f --- /dev/null +++ b/internal/service/cloudapi/disks/utility_disk_list_deleted.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDiskListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.ListDisks, error) { + c := m.(*controller.ControllerCfg) + req := disks.ListDeletedRequest{} + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_name, ok := d.GetOk("account_name"); ok { + req.AccountName = account_name.(string) + } + + if disk_max_size, ok := d.GetOk("disk_max_size"); ok { + req.DiskMaxSize = int64(disk_max_size.(int)) + } + + if shared, ok := d.GetOk("shared"); ok { + req.Shared = shared.(bool) + } + + log.Debugf("utilityDiskListDeletedCheckPresence: load disk list") + diskList, err := c.CloudAPI().Disks().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return diskList, nil +} diff --git a/internal/service/cloudapi/disks/utility_disk_list_unattached.go b/internal/service/cloudapi/disks/utility_disk_list_unattached.go new file mode 100644 index 00000000..a5ca36f4 --- /dev/null +++ b/internal/service/cloudapi/disks/utility_disk_list_unattached.go @@ -0,0 +1,57 @@ +package disks + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDiskListUnattachedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.ListDisksUnattached, error) { + c := m.(*controller.ControllerCfg) + req := disks.ListUnattachedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if account_name, ok := d.GetOk("account_name"); ok { + req.AccountName = account_name.(string) + } + if disk_max_size, ok := d.GetOk("disk_max_size"); ok { + req.DiskMaxSize = int64(disk_max_size.(int)) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if sepId, ok := d.GetOk("sep_id"); ok { + req.AccountID = uint64(sepId.(int)) + } + if pool_name, ok := d.GetOk("pool_name"); ok { + req.Pool = pool_name.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if storagePolicyID, ok := d.GetOk("storage_policy_id"); ok { + req.StoragePolicyID = uint64(storagePolicyID.(int)) + } + + log.Debugf("utilityDiskListUnattachedCheckPresence: load disk Unattached list") + unattachedList, err := c.CloudAPI().Disks().ListUnattached(ctx, req) + if err != nil { + return nil, err + } + + return unattachedList, nil +} diff --git a/internal/service/cloudapi/disks/utility_disk_replica.go b/internal/service/cloudapi/disks/utility_disk_replica.go new file mode 100644 index 00000000..0644c4a7 --- /dev/null +++ b/internal/service/cloudapi/disks/utility_disk_replica.go @@ -0,0 +1,174 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDiskReplicationUpdateStartStop(ctx context.Context, d *schema.ResourceData, m interface{}) error { + diskId := uint64(d.Get("disk_id").(int)) + targetDiskId, _ := strconv.ParseUint(d.Id(), 10, 64) + + log.Debugf("utilityDiskReplicationUpdateStartStop: start update for disk replica with ID: %d", diskId) + c := m.(*controller.ControllerCfg) + + start, ok := d.GetOk("start") + + if ok && start.(bool) { + log.Debugf("utilityDiskReplicationUpdateStartStop: start disk replication from Disk with ID: %d to Disk with ID: %d", diskId, targetDiskId) + req := disks.ReplicationStartRequest{ + DiskID: diskId, + TargetDiskID: targetDiskId, + } + _, err := c.CloudAPI().Disks().ReplicationStart(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicationUpdateStartStop: start disk replication from Disk with ID: %d to Disk with ID: %d, complete", diskId, targetDiskId) + } + + if ok && !start.(bool) { + log.Debugf("utilityDiskReplicationUpdateStartStop: stop disk replication from Disk with ID: %d to Disk with ID: %d", targetDiskId, diskId) + req := disks.ReplicationStopRequest{ + DiskID: targetDiskId, + } + _, err := c.CloudAPI().Disks().ReplicationStop(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicationUpdateStartStop: stop disk replication from Disk with ID: %d to Disk with ID: %d, complete", targetDiskId, diskId) + } + + log.Debugf("utilityDiskReplicationUpdateStartStop: complete update for disk replica with ID: %d", diskId) + return nil +} + +func utilityDiskReplicationUpdatePause(ctx context.Context, d *schema.ResourceData, m interface{}) error { + diskId := uint64(d.Get("disk_id").(int)) + log.Debugf("utilityDiskReplicationUpdatePause: start update for disk replica with ID: %d", diskId) + c := m.(*controller.ControllerCfg) + + pause, ok := d.GetOk("pause") + + if ok && pause.(bool) { + log.Debugf("utilityDiskReplicationUpdatePause: pause disk replication with ID: %d", diskId) + req := disks.ReplicationSuspendRequest{ + DiskID: diskId, + } + _, err := c.CloudAPI().Disks().ReplicationSuspend(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicationUpdatePause: pause disk replication with ID: %d, complete", diskId) + } + + if ok && !pause.(bool) { + log.Debugf("utilityDiskReplicationUpdatePause: resume disk replication with ID: %d", diskId) + req := disks.ReplicationResumeRequest{ + DiskID: diskId, + } + _, err := c.CloudAPI().Disks().ReplicationResume(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicationUpdatePause: resume disk replication with ID: %d, complete", diskId) + } + + log.Debugf("utilityDiskReplicationUpdatePause: complete update for disk replica with ID: %d", diskId) + return nil +} + +func utilityDiskReplicationUpdateReverse(ctx context.Context, d *schema.ResourceData, m interface{}) error { + diskId := uint64(d.Get("disk_id").(int)) + targetDiskId, _ := strconv.ParseUint(d.Id(), 10, 64) + + log.Debugf("utilityDiskReplicaUpdateReverse: start update for disk replica with ID: %d", diskId) + c := m.(*controller.ControllerCfg) + + reverse, ok := d.GetOk("reverse") + + if ok && reverse.(bool) { + log.Debugf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d", diskId, targetDiskId) + req := disks.ReplicationReverseRequest{ + DiskID: diskId, + } + _, err := c.CloudAPI().Disks().ReplicationReverse(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d, complete", diskId, targetDiskId) + } + + if ok && !reverse.(bool) { + log.Debugf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d", targetDiskId, diskId) + req := disks.ReplicationReverseRequest{ + DiskID: targetDiskId, + } + _, err := c.CloudAPI().Disks().ReplicationReverse(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d, complete", targetDiskId, diskId) + } + + log.Debugf("utilityDiskReplicaUpdateReverse: complete update for disk replica with ID: %d", diskId) + return nil +} + +func utilityDiskReplicaCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.RecordDisk, error) { + c := m.(*controller.ControllerCfg) + + req := disks.GetRequest{} + + if d.Id() != "" { + diskId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DiskID = diskId + } else { + req.DiskID = uint64(d.Get("replica_disk_id").(int)) + } + + log.Debugf("utilityDiskReplicaCheckPresence: load disk") + disk, err := c.CloudAPI().Disks().Get(ctx, req) + if err != nil { + return nil, err + } + + return disk, nil +} diff --git a/internal/service/cloudapi/dpdknet/data_source_dpdk.go b/internal/service/cloudapi/dpdknet/data_source_dpdk.go new file mode 100644 index 00000000..7add04a3 --- /dev/null +++ b/internal/service/cloudapi/dpdknet/data_source_dpdk.go @@ -0,0 +1,153 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package dpdknet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDPDKNetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + dpdk, err := utilityDPDKNetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + flattenDPDKNet(d, dpdk) + + return nil +} + +func dataSourceDPDKNetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "dpdk_id": { + Type: schema.TypeInt, + Required: true, + Description: "The unique ID of the subscriber-owner of the DPDK network", + }, + "account_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of accounts with access", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of DPDK network", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "DPDK network ID on the storage side", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of network", + }, + "rg_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of resource groups with access", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "DPDK network status", + }, + "ovs_bridge": { + Type: schema.TypeString, + Computed: true, + Description: "OVS bridge in which interfaces for computers created", + }, + "vlan_id": { + Type: schema.TypeInt, + Computed: true, + Description: "vlan ID", + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Compute IDs which uses this DPDK network", + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Updated time", + }, + } + + return res +} + +func DataSourceDPDKNet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDPDKNetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDPDKNetSchemaMake(), + } +} diff --git a/internal/service/cloudapi/dpdknet/data_source_dpdk_list.go b/internal/service/cloudapi/dpdknet/data_source_dpdk_list.go new file mode 100644 index 00000000..35c5dd1b --- /dev/null +++ b/internal/service/cloudapi/dpdknet/data_source_dpdk_list.go @@ -0,0 +1,212 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package dpdknet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDPDKNetListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + dpdkList, err := utilityDPDKNetListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDPDKNetList(dpdkList)) + d.Set("entry_count", dpdkList.EntryCount) + + return nil +} + +func dataSourceDPDKNetListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "gid": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by GID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Description: "Find by description", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "compute_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Find by compute IDs", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dpdk_id": { + Type: schema.TypeInt, + Required: true, + Description: "The unique ID of the subscriber-owner of the DPDK network", + }, + "account_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of accounts with access", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of DPDK network", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "DPDK network ID on the storage side", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of network", + }, + "rg_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of resource groups with access", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "DPDK network status", + }, + "ovs_bridge": { + Type: schema.TypeString, + Computed: true, + Description: "OVS bridge in which interfaces for computers created", + }, + "vlan_id": { + Type: schema.TypeInt, + Computed: true, + Description: "vlan ID", + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Compute IDs which uses this DPDK network", + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Updated time", + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceDPDKNetList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDPDKNetListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDPDKNetListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/dpdknet/flattens.go b/internal/service/cloudapi/dpdknet/flattens.go new file mode 100644 index 00000000..062002b9 --- /dev/null +++ b/internal/service/cloudapi/dpdknet/flattens.go @@ -0,0 +1,44 @@ +package dpdknet + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + dpdk "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/dpdknet" +) + +func flattenDPDKNet(d *schema.ResourceData, dpdk *dpdk.RecordDPDKNet) { + d.Set("dpdk_id", dpdk.ID) + d.Set("account_access", dpdk.AccountAccess) + d.Set("created_time", dpdk.CreatedTime) + d.Set("desc", dpdk.Description) + d.Set("gid", dpdk.GID) + d.Set("guid", dpdk.GUID) + d.Set("name", dpdk.Name) + d.Set("rg_access", dpdk.RGAccess) + d.Set("status", dpdk.Status) + d.Set("ovs_bridge", dpdk.OVSBridge) + d.Set("vlan_id", dpdk.VlanID) + d.Set("compute_ids", dpdk.ComputeIDs) + d.Set("updated_time", dpdk.UpdatedTime) +} + +func flattenDPDKNetList(list *dpdk.ListDPDKNet) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list.Data)) + for _, dpdk := range list.Data { + temp := map[string]interface{}{ + "dpdk_id": dpdk.ID, + "account_access": dpdk.AccountAccess, + "desc": dpdk.Description, + "gid": dpdk.GID, + "guid": dpdk.GUID, + "name": dpdk.Name, + "rg_access": dpdk.RGAccess, + "status": dpdk.Status, + "ovs_bridge": dpdk.OVSBridge, + "vlan_id": dpdk.VlanID, + "compute_ids": dpdk.ComputeIDs, + "updated_time": dpdk.UpdatedTime, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/dpdknet/utility_dpdk.go b/internal/service/cloudapi/dpdknet/utility_dpdk.go new file mode 100644 index 00000000..f2849987 --- /dev/null +++ b/internal/service/cloudapi/dpdknet/utility_dpdk.go @@ -0,0 +1,68 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package dpdknet + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + dpdk "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/dpdknet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDPDKNetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*dpdk.RecordDPDKNet, error) { + c := m.(*controller.ControllerCfg) + req := dpdk.GetRequest{} + + if d.Get("dpdk_id") != nil { + if d.Get("dpdk_id").(int) == 0 { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DPDKID = id + } else { + req.DPDKID = uint64(d.Get("dpdk_id").(int)) + } + } else { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DPDKID = id + } + + log.Debugf("utilityDPDKCheckPresence: get DPDK network") + dpdk, err := c.CloudAPI().DPDKNet().Get(ctx, req) + if err != nil { + return nil, err + } + + return dpdk, nil +} diff --git a/internal/service/cloudapi/dpdknet/utility_dpdk_list.go b/internal/service/cloudapi/dpdknet/utility_dpdk_list.go new file mode 100644 index 00000000..a38c2c29 --- /dev/null +++ b/internal/service/cloudapi/dpdknet/utility_dpdk_list.go @@ -0,0 +1,87 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package dpdknet + +import ( + "context" + + log "github.com/sirupsen/logrus" + dpdk "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/dpdknet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDPDKNetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*dpdk.ListDPDKNet, error) { + c := m.(*controller.ControllerCfg) + req := dpdk.ListRequest{} + + if byID, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byID.(int)) + } + if GID, ok := d.GetOk("gid"); ok { + req.GID = uint64(GID.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if desc, ok := d.GetOk("description"); ok { + req.Description = desc.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if computeIDs, ok := d.GetOk("compute_ids"); ok { + IDs := computeIDs.([]interface{}) + for _, ID := range IDs { + req.ComputeIDs = append(req.ComputeIDs, uint64(ID.(int))) + } + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityDPDKListCheckPresence: load DPDK network list") + dpdkList, err := c.CloudAPI().DPDKNet().List(ctx, req) + if err != nil { + return nil, err + } + + return dpdkList, nil +} diff --git a/internal/service/cloudapi/extnet/data_source_extnet.go b/internal/service/cloudapi/extnet/data_source_extnet.go new file mode 100644 index 00000000..c2a44a16 --- /dev/null +++ b/internal/service/cloudapi/extnet/data_source_extnet.go @@ -0,0 +1,369 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceExtnetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + e, err := utilityExtnetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(e.ID, 10)) + flattenExtnet(d, e) + + return nil +} + +func dataSourceExtnetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "net_id": { + Type: schema.TypeInt, + Required: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "meta", + }, + "check_ips": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "default": { + Type: schema.TypeBool, + Computed: true, + }, + "default_qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "e_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dns": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "excluded": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ipcidr": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "net_name": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "network_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "primary": { + Type: schema.TypeInt, + Computed: true, + }, + "secondary": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "pre_reservations_num": { + Type: schema.TypeInt, + Computed: true, + }, + "prefix": { + Type: schema.TypeInt, + Computed: true, + }, + "pri_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "reservations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "domainname": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "vlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dhcp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "ntp": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "redundant": { + Type: schema.TypeBool, + Computed: true, + }, + "sec_vnfdev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + }, + "pre_reservations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "domain_name": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } + return res +} + +func DataSourceExtnet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceExtnetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceExtnetSchemaMake(), + } +} diff --git a/internal/service/cloudapi/extnet/data_source_extnet_computes_list.go b/internal/service/cloudapi/extnet/data_source_extnet_computes_list.go new file mode 100644 index 00000000..8f4ad351 --- /dev/null +++ b/internal/service/cloudapi/extnet/data_source_extnet_computes_list.go @@ -0,0 +1,167 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceExtnetComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + extnetComputesList, err := utilityExtnetComputesListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenExtnetComputesList(extnetComputesList)) + d.Set("entry_count", extnetComputesList.EntryCount) + return nil +} + +func dataSourceExtnetComputesListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "filter by account ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by compute ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "extnets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ipaddr": { + Type: schema.TypeString, + Computed: true, + }, + "ipcidr": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceExtnetComputesList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceExtnetComputesListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceExtnetComputesListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/extnet/data_source_extnet_default.go b/internal/service/cloudapi/extnet/data_source_extnet_default.go new file mode 100644 index 00000000..f9e05fde --- /dev/null +++ b/internal/service/cloudapi/extnet/data_source_extnet_default.go @@ -0,0 +1,86 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + "strconv" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceExtnetDefaultRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + extnetId, err := utilityExtnetDefaultCheckPresence(ctx, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + extnetIdInt, err := strconv.ParseInt(extnetId, 10, 32) + if err != nil { + return diag.FromErr(err) + } + d.Set("net_id", extnetIdInt) + + return nil +} + +func dataSourceExtnetDefaultSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceExtnetDefault() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceExtnetDefaultRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceExtnetDefaultSchemaMake(), + } +} diff --git a/internal/service/cloudapi/extnet/data_source_extnet_list.go b/internal/service/cloudapi/extnet/data_source_extnet_list.go new file mode 100644 index 00000000..e03f1663 --- /dev/null +++ b/internal/service/cloudapi/extnet/data_source_extnet_list.go @@ -0,0 +1,169 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceExtnetListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + extnetList, err := utilityExtnetListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenExtnetList(extnetList)) + d.Set("entry_count", extnetList.EntryCount) + + return nil +} + +func dataSourceExtnetListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by account ID", + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "network": { + Type: schema.TypeString, + Optional: true, + }, + "vlan_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by VLAN ID", + }, + "vnfdev_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by VnfDEV ID", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "ovs_bridge": { + Type: schema.TypeString, + Optional: true, + Description: "Name of the openVswitch bridge", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ipcidr": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceExtnetList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceExtnetListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceExtnetListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/extnet/data_source_extnet_reserved_ip.go b/internal/service/cloudapi/extnet/data_source_extnet_reserved_ip.go new file mode 100644 index 00000000..36511c13 --- /dev/null +++ b/internal/service/cloudapi/extnet/data_source_extnet_reserved_ip.go @@ -0,0 +1,137 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceExtnetReservedIpRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + reservedList, err := utilityExtnetReservedIpCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenExtnetReservedIp(reservedList)) + + return nil +} + +func dataSourceExtnetReservedIpSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "reservations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "domain_name": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + } + return res +} + +func DataSourceExtnetReservedIp() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceExtnetReservedIpRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceExtnetReservedIpSchemaMake(), + } +} diff --git a/internal/service/cloudapi/extnet/flattens.go b/internal/service/cloudapi/extnet/flattens.go new file mode 100644 index 00000000..573c70a0 --- /dev/null +++ b/internal/service/cloudapi/extnet/flattens.go @@ -0,0 +1,182 @@ +package extnet + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenExtnet(d *schema.ResourceData, e *extnet.RecordExtNet) { + d.Set("ckey", e.CKey) + d.Set("meta", flattens.FlattenMeta(e.Meta)) + d.Set("check_ips", e.CheckIPs) + d.Set("default", e.Default) + d.Set("default_qos", flattenExtnetDefaultQos(e.DefaultQOS)) + d.Set("desc", e.Description) + d.Set("dns", e.DNS) + d.Set("excluded", flattenExcluded(e.Excluded)) + d.Set("free_ips", e.FreeIPs) + d.Set("gateway", e.Gateway) + d.Set("gid", e.GID) + d.Set("guid", e.GUID) + d.Set("ipcidr", e.IPCIDR) + d.Set("milestones", e.Milestones) + d.Set("net_name", e.Name) + d.Set("network", e.Network) + d.Set("network_ids", flattenNetworkIDs(e.NetworkIDs)) + d.Set("ntp", e.NTP) + d.Set("pre_reservations_num", e.PreReservationsNum) + d.Set("prefix", e.Prefix) + d.Set("pri_vnf_dev_id", e.PriVNFDevID) + d.Set("reservations", flattenExtnetReservations(e.Reservations)) + d.Set("shared_with", e.SharedWith) + d.Set("status", e.Status) + d.Set("vlan_id", e.VLANID) + d.Set("vnfs", flattenExtnetVNFS(e.VNFs)) + d.Set("zone_id", e.ZoneID) + d.Set("pre_reservations", flattenExtnetReservations(e.PreReservations)) + d.Set("sec_vnfdev_id", e.SecVNFDevID) + d.Set("redundant", e.Redundant) + d.Set("mtu", e.MTU) +} + +func flattenExcluded(ex []extnet.Excluded) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ex)) + for _, item := range ex { + temp := map[string]interface{}{ + "client_type": item.ClientType, + "mac": item.MAC, + "ip": item.IP, + "type": item.Type, + "vm_id": item.VMID, + } + res = append(res, temp) + } + + return res +} + +func flattenExtnetReservations(ers extnet.ListReservations) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ers)) + for _, er := range ers { + temp := map[string]interface{}{ + "account_id": er.AccountID, + "client_type": er.ClientType, + "domainname": er.DomainName, + "hostname": er.Hostname, + "desc": er.Description, + "ip": er.IP, + "mac": er.MAC, + "type": er.Type, + "vm_id": er.VMID, + } + res = append(res, temp) + } + + return res +} + +func flattenExtnetDefaultQos(edqos extnet.QOS) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "e_rate": edqos.ERate, + "e_burst": edqos.EBurst, + "guid": edqos.GUID, + "in_burst": edqos.InBurst, + "in_rate": edqos.InRate, + } + res = append(res, temp) + return res +} + +func flattenExtnetVNFS(evnfs extnet.VNFs) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "dhcp": evnfs.DHCP, + } + res = append(res, temp) + return res +} + +func flattenExtnetsComputes(ecs extnet.ListExtNetExtends) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ecs)) + for _, ec := range ecs { + temp := map[string]interface{}{ + "net_id": ec.ID, + "ipaddr": ec.IPAddr, + "ipcidr": ec.IPCIDR, + "name": ec.Name, + } + res = append(res, temp) + } + return res +} + +func flattenExtnetComputesList(ecl *extnet.ListExtNetComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ecl.Data)) + for _, ec := range ecl.Data { + temp := map[string]interface{}{ + "account_id": ec.AccountID, + "account_name": ec.AccountName, + "extnets": flattenExtnetsComputes(ec.ExtNets), + "id": ec.ID, + "name": ec.Name, + "rg_id": ec.RGID, + "rg_name": ec.RGName, + } + res = append(res, temp) + } + return res +} + +func flattenExtnetList(el *extnet.ListExtNets) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(el.Data)) + for _, e := range el.Data { + temp := map[string]interface{}{ + "net_id": e.ID, + "ipcidr": e.IPCIDR, + "name": e.Name, + "status": e.Status, + "free_ips": e.FreeIPs, + } + res = append(res, temp) + } + return res +} + +func flattenExtnetReservedIp(el []extnet.RecordReservedIP) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(el)) + for _, e := range el { + reservations := make([]map[string]interface{}, 0, len(e.Reservations)) + for _, r := range e.Reservations { + temp := map[string]interface{}{ + "account_id": r.AccountID, + "client_type": r.ClientType, + "domain_name": r.DomainName, + "hostname": r.Hostname, + "ip": r.IP, + "mac": r.Mac, + "type": r.Type, + "vm_id": r.VMID, + } + reservations = append(reservations, temp) + } + item := map[string]interface{}{ + "extnet_id": e.ExtnetID, + "reservations": reservations, + } + res = append(res, item) + } + return res +} + +func flattenNetworkIDs(ex extnet.NetworkIDs) []map[string]interface{} { + res := make([]map[string]interface{}, 0, 1) + temp := map[string]interface{}{ + "primary": ex.Primary, + "secondary": ex.Secondary, + } + res = append(res, temp) + + return res +} diff --git a/internal/service/cloudapi/extnet/utility_extnet.go b/internal/service/cloudapi/extnet/utility_extnet.go new file mode 100644 index 00000000..d3161743 --- /dev/null +++ b/internal/service/cloudapi/extnet/utility_extnet.go @@ -0,0 +1,58 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityExtnetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*extnet.RecordExtNet, error) { + c := m.(*controller.ControllerCfg) + req := extnet.GetRequest{ + NetID: uint64(d.Get("net_id").(int)), + } + + log.Debugf("utilityExtnetCheckPresence") + extnet, err := c.CloudAPI().ExtNet().Get(ctx, req) + if err != nil { + return nil, err + } + + return extnet, nil +} diff --git a/internal/service/cloudapi/extnet/utility_extnet_computes_list.go b/internal/service/cloudapi/extnet/utility_extnet_computes_list.go new file mode 100644 index 00000000..4f9a2d8f --- /dev/null +++ b/internal/service/cloudapi/extnet/utility_extnet_computes_list.go @@ -0,0 +1,74 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityExtnetComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*extnet.ListExtNetComputes, error) { + c := m.(*controller.ControllerCfg) + req := extnet.ListComputesRequest{ + AccountID: uint64(d.Get("account_id").(int)), + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + if compute_id, ok := d.GetOk("compute_id"); ok { + req.ComputeID = uint64(compute_id.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityExtnetComputesListCheckPresence") + extnetComputesList, err := c.CloudAPI().ExtNet().ListComputes(ctx, req) + if err != nil { + return nil, err + } + + return extnetComputesList, nil +} diff --git a/internal/service/cloudapi/extnet/utility_extnet_default.go b/internal/service/cloudapi/extnet/utility_extnet_default.go new file mode 100644 index 00000000..c8893eb1 --- /dev/null +++ b/internal/service/cloudapi/extnet/utility_extnet_default.go @@ -0,0 +1,53 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityExtnetDefaultCheckPresence(ctx context.Context, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityExtnetDefaultCheckPresence") + res, err := c.CloudAPI().ExtNet().GetDefault(ctx) + if err != nil { + return "", err + } + + return strconv.FormatUint(res, 10), nil +} diff --git a/internal/service/cloudapi/extnet/utility_extnet_list.go b/internal/service/cloudapi/extnet/utility_extnet_list.go new file mode 100644 index 00000000..902720b2 --- /dev/null +++ b/internal/service/cloudapi/extnet/utility_extnet_list.go @@ -0,0 +1,93 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityExtnetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*extnet.ListExtNets, error) { + c := m.(*controller.ControllerCfg) + req := extnet.ListRequest{} + + if accountID, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountID.(int)) + } + if byID, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byID.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if network, ok := d.GetOk("network"); ok { + req.Network = network.(string) + } + if vlanID, ok := d.GetOk("vlan_id"); ok { + req.VLANID = uint64(vlanID.(int)) + } + if vnfDevID, ok := d.GetOk("vnfdev_id"); ok { + req.VNFDevID = uint64(vnfDevID.(int)) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if ovsBridge, ok := d.GetOk("ovs_bridge"); ok { + req.OVSBridge = ovsBridge.(string) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + log.Debugf("utilityExtnetListCheckPresence") + extnetList, err := c.CloudAPI().ExtNet().List(ctx, req) + if err != nil { + return nil, err + } + + return extnetList, nil +} diff --git a/internal/service/cloudapi/extnet/utility_extnet_reserved_ip.go b/internal/service/cloudapi/extnet/utility_extnet_reserved_ip.go new file mode 100644 index 00000000..db52e60b --- /dev/null +++ b/internal/service/cloudapi/extnet/utility_extnet_reserved_ip.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityExtnetReservedIpCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]extnet.RecordReservedIP, error) { + c := m.(*controller.ControllerCfg) + req := extnet.GetReservedIP{ + AccountID: uint64(d.Get("account_id").(int)), + } + + if extNetID, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extNetID.(int)) + } + + log.Debugf("utilityExtnetReservedIpCheckPresence") + res, err := c.CloudAPI().ExtNet().GetReservedIP(ctx, req) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/internal/service/cloudapi/flipgroup/data_source_flipgroup.go b/internal/service/cloudapi/flipgroup/data_source_flipgroup.go new file mode 100644 index 00000000..354a1128 --- /dev/null +++ b/internal/service/cloudapi/flipgroup/data_source_flipgroup.go @@ -0,0 +1,176 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceFlipgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + fg, err := utilityFlipgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenFlipgroup(d, fg) + d.SetId(fmt.Sprint(fg.ID)) + + return nil +} + +func dataSourceFlipgroupSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "flipgroup_id": { + Type: schema.TypeInt, + Required: true, + Description: "Flipgroupd ID", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "client_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func DataSourceFlipgroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceFlipgroupRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout180s, + Default: &constants.Timeout180s, + }, + + Schema: dataSourceFlipgroupSchemaMake(), + } +} diff --git a/internal/service/cloudapi/flipgroup/data_source_flipgroup_list.go b/internal/service/cloudapi/flipgroup/data_source_flipgroup_list.go new file mode 100644 index 00000000..93437ddd --- /dev/null +++ b/internal/service/cloudapi/flipgroup/data_source_flipgroup_list.go @@ -0,0 +1,241 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceFlipgroupList(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + fg_list, err := utilityFlipgroupListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + d.Set("items", flattenFlipgroupList(fg_list)) + d.Set("entry_count", fg_list.EntryCount) + + return nil +} + +func dataSourceFlipgroupListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by Name", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ViNS ID", + }, + "vins_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by ViNS name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ExtNetID", + }, + "by_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by IP-address", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Account id", + }, + "conn_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Conn id", + }, + "client_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "client_ids", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Status", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "flipgroup_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "client_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "net_mask": { + Type: schema.TypeInt, + Computed: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func DataSourceFlipGroupList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceFlipgroupList, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout180s, + Default: &constants.Timeout180s, + }, + + Schema: dataSourceFlipgroupListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/flipgroup/flattens.go b/internal/service/cloudapi/flipgroup/flattens.go new file mode 100644 index 00000000..715311e9 --- /dev/null +++ b/internal/service/cloudapi/flipgroup/flattens.go @@ -0,0 +1,97 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/flipgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenFlipgroup(d *schema.ResourceData, fg *flipgroup.RecordFLIPGroup) { + d.Set("account_id", fg.AccountID) + d.Set("account_name", fg.AccountName) + d.Set("client_ids", fg.ClientIDs) + d.Set("client_type", fg.ClientType) + d.Set("conn_id", fg.ConnID) + d.Set("conn_type", fg.ConnType) + d.Set("created_by", fg.CreatedBy) + d.Set("created_time", fg.CreatedTime) + d.Set("default_gw", fg.DefaultGW) + d.Set("deleted_by", fg.DeletedBy) + d.Set("deleted_time", fg.DeletedTime) + d.Set("desc", fg.Description) + d.Set("gid", fg.GID) + d.Set("guid", fg.GUID) + d.Set("flipgroup_id", fg.ID) + d.Set("ip", fg.IP) + d.Set("milestones", fg.Milestones) + d.Set("name", fg.Name) + d.Set("net_id", fg.NetID) + d.Set("net_type", fg.NetType) + d.Set("network", fg.Network) + d.Set("status", fg.Status) + d.Set("updated_by", fg.UpdatedBy) + d.Set("updated_time", fg.UpdatedTime) +} + +func flattenFlipgroupList(fg_list *flipgroup.ListFLIPGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, fg := range fg_list.Data { + temp := map[string]interface{}{ + "ckey": fg.CKey, + "meta": flattens.FlattenMeta(fg.Meta), + "account_id": fg.AccountID, + "client_ids": fg.ClientIDs, + "client_type": fg.ClientType, + "conn_id": fg.ConnID, + "conn_type": fg.ConnType, + "default_gw": fg.DefaultGW, + "desc": fg.Description, + "gid": fg.GID, + "guid": fg.GUID, + "flipgroup_id": fg.ID, + "ip": fg.IP, + "milestones": fg.Milestones, + "name": fg.Name, + "net_id": fg.NetID, + "net_type": fg.NetType, + "net_mask": fg.NetMask, + "status": fg.Status, + } + res = append(res, temp) + } + + return res +} diff --git a/internal/service/cloudapi/flipgroup/resource_flipgroup.go b/internal/service/cloudapi/flipgroup/resource_flipgroup.go new file mode 100644 index 00000000..4cf53573 --- /dev/null +++ b/internal/service/cloudapi/flipgroup/resource_flipgroup.go @@ -0,0 +1,302 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/flipgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + + log "github.com/sirupsen/logrus" +) + +func resourceFlipgroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceFlipgroupCreate called with name: %s, accountID %v", d.Get("name").(string), d.Get("account_id").(int)) + + c := m.(*controller.ControllerCfg) + req := flipgroup.CreateRequest{ + AccountID: uint64(d.Get("account_id").(int)), + Name: d.Get("name").(string), + NetType: d.Get("net_type").(string), + NetID: uint64(d.Get("net_id").(int)), + IP: d.Get("ip").(string), + Description: d.Get("desc").(string), + } + + resp, err := c.CloudAPI().FLIPGroup().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(fmt.Sprint(resp.ID)) + + var warnings dc.Warnings + + if clientType, ok := d.GetOk("client_type"); ok { + req.ClientType = clientType.(string) + } + + if client_ids, ok := d.GetOk("client_ids"); ok { + casted := client_ids.([]interface{}) + addComputesAfterCreation(ctx, &warnings, c, casted, resp.ID) + } + + defer resourceFlipgroupRead(ctx, d, m) + return warnings.Get() +} + +func resourceFlipgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + fg, err := utilityFlipgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenFlipgroup(d, fg) + + return nil +} + +func resourceFlipgroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceFlipgroupUpdate called with id: %v", d.Get("flipgroup_id").(int)) + c := m.(*controller.ControllerCfg) + fg, err := utilityFlipgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + var warnings dc.Warnings + basicUpdate := false + req := flipgroup.EditRequest{FLIPGroupID: fg.ID} + + if d.HasChange("desc") { + req.Description = d.Get("desc").(string) + basicUpdate = true + } + + if d.HasChange("name") { + req.Name = d.Get("name").(string) + basicUpdate = true + } + + if basicUpdate { + _, err := c.CloudAPI().FLIPGroup().Edit(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("client_ids") { + handleClientIDsUpdate(ctx, d, c, fg, &warnings) + } + + defer resourceFlipgroupRead(ctx, d, m) + return warnings.Get() +} + +func resourceFlipgroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceFlipgroupDelete called with id: %v", d.Get("flipgroup_id").(int)) + c := m.(*controller.ControllerCfg) + + fg, err := utilityFlipgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + req := flipgroup.DeleteRequest{ + FLIPGroupID: fg.ID, + } + + _, err = c.CloudAPI().FLIPGroup().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceFlipgroupSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "Account ID", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Flipgroup name", + }, + "net_id": { + Type: schema.TypeInt, + Required: true, + Description: "EXTNET or ViNS ID", + }, + "net_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS"}, true), + Description: "Network type, EXTNET or VINS", + }, + "client_type": { + Type: schema.TypeString, + Optional: true, + Default: "compute", + Description: "Type of client, 'compute' ('vins' will be later)", + ValidateFunc: validation.StringInSlice([]string{"compute"}, true), + }, + "ip": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "IP address to associate with this group. If empty, the platform will autoselect IP address", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Text description of this Flipgroup instance", + }, + "client_ids": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of clients attached to this Flipgroup instance", + }, + "flipgroup_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func ResourceFlipgroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + CreateContext: resourceFlipgroupCreate, + ReadContext: resourceFlipgroupRead, + UpdateContext: resourceFlipgroupUpdate, + DeleteContext: resourceFlipgroupDelete, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout300s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceFlipgroupSchemaMake(), + } +} diff --git a/internal/service/cloudapi/flipgroup/utility_flipgroup.go b/internal/service/cloudapi/flipgroup/utility_flipgroup.go new file mode 100644 index 00000000..2e43e04d --- /dev/null +++ b/internal/service/cloudapi/flipgroup/utility_flipgroup.go @@ -0,0 +1,202 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/flipgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + + log "github.com/sirupsen/logrus" +) + +func handleClientIDsUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, fg *flipgroup.RecordFLIPGroup, warn *dc.Warnings) { + addedClients := make([]interface{}, 0) + removedClients := make([]interface{}, 0) + + old_set, new_set := d.GetChange("client_ids") + oldSlice := old_set.([]interface{}) + newSlice := new_set.([]interface{}) + + for _, oldElem := range oldSlice { + if !containsClient(newSlice, oldElem) { + removedClients = append(removedClients, oldElem) + } + } + + for _, newElem := range newSlice { + if !containsClient(oldSlice, newElem) { + addedClients = append(addedClients, newElem) + } + } + + log.Debugf("Found client_ids change with %v deletion(s) and %v addition(s) [flipgroupID=%v]", len(removedClients), len(addedClients), fg.ID) + + if len(addedClients) > 0 { + for _, id := range addedClients { + req := flipgroup.ComputeAddRequest{ + FLIPGroupID: fg.ID, + ComputeID: uint64(id.(int)), + } + + if _, err := c.CloudAPI().FLIPGroup().ComputeAdd(ctx, req); err != nil { + warn.Add(err) + } + } + } + + if len(removedClients) > 0 { + for _, id := range removedClients { + req := flipgroup.ComputeRemoveRequest{ + FLIPGroupID: fg.ID, + ComputeID: uint64(id.(int)), + } + + if _, err := c.CloudAPI().FLIPGroup().ComputeRemove(ctx, req); err != nil { + warn.Add(err) + } + } + } +} + +func containsClient(set []interface{}, check interface{}) bool { + for _, elem := range set { + elemConv := elem.(int) + checkConv := check.(int) + if elemConv == checkConv { + return true + } + } + + return false +} + +func addComputesAfterCreation(ctx context.Context, warnings *dc.Warnings, c *controller.ControllerCfg, compute_ids []interface{}, flipgroupID uint64) { + if len(compute_ids) == 0 { + return + } + + log.Debugf("Adding %v computes to flipgroup [id=%v]...", len(compute_ids), flipgroupID) + + for _, elem := range compute_ids { + compute_id := uint64(elem.(int)) + req := flipgroup.ComputeAddRequest{ + FLIPGroupID: flipgroupID, + ComputeID: compute_id, + } + + _, err := c.CloudAPI().FLIPGroup().ComputeAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } +} + +func utilityFlipgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*flipgroup.RecordFLIPGroup, error) { + c := m.(*controller.ControllerCfg) + req := flipgroup.GetRequest{} + + if d.Id() == "" { + req.FLIPGroupID = uint64(d.Get("flipgroup_id").(int)) + } else { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.FLIPGroupID = id + } + + fg, err := c.CloudAPI().FLIPGroup().Get(ctx, req) + if err != nil { + return nil, err + } + + return fg, err +} + +func utilityFlipgroupListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*flipgroup.ListFLIPGroups, error) { + c := m.(*controller.ControllerCfg) + req := flipgroup.ListRequest{} + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if vinsId, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vinsId.(int)) + } + if vinsName, ok := d.GetOk("vins_name"); ok { + req.VINSName = vinsName.(string) + } + if extNetId, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extNetId.(int)) + } + if byIp, ok := d.GetOk("by_ip"); ok { + req.ByIP = byIp.(string) + } + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountId = uint64(accountId.(int)) + } + if connId, ok := d.GetOk("conn_id"); ok { + req.ConnId = uint64(connId.(int)) + } + if cliensId, ok := d.GetOk("client_ids"); ok { + cliensIds := cliensId.([]interface{}) + for _, elem := range cliensIds { + req.ClientIDs = append(req.ClientIDs, uint64(elem.(int))) + } + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + fg_list, err := c.CloudAPI().FLIPGroup().List(ctx, req) + if err != nil { + return nil, err + } + + return fg_list, err +} diff --git a/internal/service/cloudapi/image/data_source_image.go b/internal/service/cloudapi/image/data_source_image.go new file mode 100644 index 00000000..3a55ef4b --- /dev/null +++ b/internal/service/cloudapi/image/data_source_image.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + image, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(int(image.ID))) + + flattenImage(d, image) + + return nil +} + +func DataSourceImage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceImageRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceImageExtendSchemaMake(), + } +} diff --git a/internal/service/cloudapi/image/data_source_image_list.go b/internal/service/cloudapi/image/data_source_image_list.go new file mode 100644 index 00000000..77ffc9f0 --- /dev/null +++ b/internal/service/cloudapi/image/data_source_image_list.go @@ -0,0 +1,175 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceImageListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + imageList, err := utilityImageListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenImageList(imageList)) + d.Set("entry_count", imageList.EntryCount) + + return nil +} + +func dataSourceImageListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by Storage Endpoint ID", + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "architecture": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by architecture", + }, + "type_image": { + Type: schema.TypeList, + Optional: true, + Description: "Filter by image type", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "image_size": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by image size", + }, + "sep_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by SEP name", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by pool", + }, + "public": { + Type: schema.TypeBool, + Optional: true, + Description: "Find public/private images", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Description: "Find hot resizable images", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Description: "Find bootable images", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: "find by enabled True or False", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "image list", + Elem: &schema.Resource{ + Schema: dataSourceImageSchemaMake(), + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return rets +} + +func DataSourceImageList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceImageListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceImageListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/image/flattens.go b/internal/service/cloudapi/image/flattens.go new file mode 100644 index 00000000..b8c2ff7e --- /dev/null +++ b/internal/service/cloudapi/image/flattens.go @@ -0,0 +1,115 @@ +package image + +import ( + "encoding/json" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" +) + +func flattenHistory(history []image.History) []map[string]interface{} { + temp := make([]map[string]interface{}, 0) + for _, item := range history { + t := map[string]interface{}{ + "id": item.ID, + "guid": item.GUID, + "timestamp": item.Timestamp, + } + + temp = append(temp, t) + } + return temp +} + +func flattenImage(d *schema.ResourceData, img *image.RecordImage) { + cdPresentedTo, _ := json.Marshal(img.CdPresentedTo) + + d.Set("unc_path", img.UNCPath) + d.Set("account_id", img.AccountID) + d.Set("acl", FlattenACL(img.ACL)) + d.Set("architecture", img.Architecture) + d.Set("boot_type", img.BootType) + d.Set("bootable", img.Bootable) + d.Set("compute_ci_id", img.ComputeCIID) + d.Set("cd_presented_to", string(cdPresentedTo)) + d.Set("deleted_time", img.DeletedTime) + d.Set("desc", img.Description) + d.Set("drivers", img.Drivers) + d.Set("enabled", img.Enabled) + d.Set("gid", img.GID) + d.Set("guid", img.GUID) + d.Set("history", flattenHistory(img.History)) + d.Set("hot_resize", img.HotResize) + d.Set("image_id", img.ID) + d.Set("independent", img.Independent) + d.Set("last_modified", img.LastModified) + d.Set("link_to", img.LinkTo) + d.Set("links_to", img.LinksTo) + d.Set("milestones", img.Milestones) + d.Set("image_name", img.Name) + d.Set("network_interface_naming", img.NetworkInterfaceNaming) + d.Set("password", img.Password) + d.Set("pool_name", img.Pool) + d.Set("provider_name", img.ProviderName) + d.Set("purge_attempts", img.PurgeAttempts) + d.Set("present_to", img.PresentTo) + d.Set("res_id", img.ResID) + d.Set("rescuecd", img.RescueCD) + d.Set("sep_id", img.SepID) + d.Set("shared_with", img.SharedWith) + d.Set("size", img.Size) + d.Set("snapshot_id", img.SnapshotID) + d.Set("status", img.Status) + d.Set("storage_policy_id", img.StoragePolicyID) + d.Set("tech_status", img.TechStatus) + d.Set("to_clean", img.ToClean) + d.Set("image_type", img.Type) + d.Set("username", img.Username) + d.Set("version", img.Version) +} + +func flattenImageList(il *image.ListImages) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, img := range il.Data { + temp := map[string]interface{}{ + "account_id": img.AccountID, + "architecture": img.Architecture, + "boot_type": img.BootType, + "bootable": img.Bootable, + "cdrom": img.CDROM, + "desc": img.Description, + "drivers": img.Drivers, + "hot_resize": img.HotResize, + "image_id": img.ID, + "link_to": img.LinkTo, + "image_name": img.Name, + "network_interface_naming": img.NetworkInterfaceNaming, + "pool_name": img.Pool, + "sep_id": img.SepID, + "size": img.Size, + "status": img.Status, + "storage_policy_id": img.StoragePolicyID, + "image_type": img.Type, + "username": img.Username, + "virtual": img.Virtual, + } + res = append(res, temp) + } + return res +} + +func FlattenACL(acl interface{}) string { + switch d := acl.(type) { + case string: + return d + case int: + return strconv.Itoa(d) + case int64: + return strconv.FormatInt(d, 10) + case float64: + return strconv.FormatInt(int64(d), 10) + default: + return "" + } +} diff --git a/internal/service/cloudapi/image/image_ds_subresource.go b/internal/service/cloudapi/image/image_ds_subresource.go new file mode 100644 index 00000000..fb242e2b --- /dev/null +++ b/internal/service/cloudapi/image/image_ds_subresource.go @@ -0,0 +1,241 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func dataSourceImageExtendSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "image_id": { + Type: schema.TypeInt, + Required: true, + }, + "show_all": { + Type: schema.TypeBool, + Default: false, + Optional: true, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + }, + "bootable": { + Type: schema.TypeBool, + Computed: true, + }, + "compute_ci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "links_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "pool_name": { + Type: schema.TypeString, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_id": { + Type: schema.TypeInt, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + } +} diff --git a/internal/service/cloudapi/image/image_item_subresource.go b/internal/service/cloudapi/image/image_item_subresource.go new file mode 100644 index 00000000..45d322c3 --- /dev/null +++ b/internal/service/cloudapi/image/image_item_subresource.go @@ -0,0 +1,148 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func dataSourceImageSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Owner account id", + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + Description: "Image architecture", + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + Description: "Boot image type", + }, + "bootable": { + Type: schema.TypeBool, + Computed: true, + Description: "Flag, true if image is bootable, otherwise - false", + }, + "cdrom": { + Type: schema.TypeBool, + Computed: true, + Description: "Flag, true if image is cdrom image, otherwise - false", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Image description", + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "Image drivers", + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + Description: "Flag, true if image supports hot resize, else if not", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image id", + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + Description: "For virtual images, id image, which current image linked", + }, + "links_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + Description: "Image name", + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "pool_name": { + Type: schema.TypeString, + Computed: true, + Description: "Image pool", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image storage endpoint id", + }, + "size": { + Type: schema.TypeInt, + Computed: true, + Description: "Image size", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Image status", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "Image type", + }, + "username": { + Type: schema.TypeString, + Computed: true, + Description: "username", + }, + "virtual": { + Type: schema.TypeBool, + Computed: true, + Description: "True if image is virtula, otherwise - else", + }, + } +} diff --git a/internal/service/cloudapi/image/image_rs_subresource.go b/internal/service/cloudapi/image/image_rs_subresource.go new file mode 100644 index 00000000..d3f3cd7d --- /dev/null +++ b/internal/service/cloudapi/image/image_rs_subresource.go @@ -0,0 +1,150 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceImageSchemaMake(sch map[string]*schema.Schema) map[string]*schema.Schema { + delete(sch, "show_all") + sch["name"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + } + + sch["url"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "URL where to download media from", + } + + sch["image_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "image id", + } + + sch["boot_type"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true), + Description: "Boot type of image bios or uefi", + } + + sch["type"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "unknown"}, true), + Description: "Image type linux, windows or unknown", + } + + sch["storage_policy_id"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + Description: "ID of the storage policy", + } + + sch["hot_resize"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + } + + sch["username"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + } + + sch["password"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + } + + sch["account_id"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + Description: "AccountId to make the image exclusive", + } + + sch["username_dl"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "username for upload binary media", + } + + sch["password_dl"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "password for upload binary media", + } + + sch["pool_name"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + } + + sch["sep_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + } + + sch["network_interface_naming"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, true), + Description: "select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming", + } + + sch["sync_mode"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Create image from a media identified by URL (in synchronous mode)", + } + + return sch +} diff --git a/internal/service/cloudapi/image/image_virtual_rs_subresource.go b/internal/service/cloudapi/image/image_virtual_rs_subresource.go new file mode 100644 index 00000000..87bf63b5 --- /dev/null +++ b/internal/service/cloudapi/image/image_virtual_rs_subresource.go @@ -0,0 +1,67 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceImageVirtualSchemaMake(sch map[string]*schema.Schema) map[string]*schema.Schema { + delete(sch, "show_all") + + sch["name"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + } + + sch["link_to"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + Description: "ID of real image to link this virtual image to upon creation", + } + + sch["account_id"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + Description: "Account ID", + } + + sch["image_id"] = &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + Description: "Image id", + } + + return sch +} diff --git a/internal/service/cloudapi/image/old_schemas.go b/internal/service/cloudapi/image/old_schemas.go new file mode 100644 index 00000000..c637ed4b --- /dev/null +++ b/internal/service/cloudapi/image/old_schemas.go @@ -0,0 +1,782 @@ +package image + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" +) + +func resourceImageFromBlankComputeSchemaV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + Description: "Compute Id", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "boot_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true), + Description: "Boot type of image BIOS or UEFI", + }, + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "other"}, true), + Description: "Image type linux, windows or other", + }, + + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "async_mode": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "create an image in async/sync mode", + }, + + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "bootable": { + Type: schema.TypeBool, + Computed: true, + }, + "compute_ci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceImageFromBlankDiskSchemaV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "Disk Id", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "boot_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true), + Description: "Boot type of image BIOS or UEFI", + }, + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "other"}, true), + Description: "Image type linux, windows or other", + }, + "architecture": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"X86_64"}, true), + Description: "binary architecture of this image, one of X86_64", + }, + + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "drivers": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86"}, false), // observe case while validating + Type: schema.TypeString, + }, + Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "bootable image", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "async_mode": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "create an image in async/sync mode", + }, + + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "compute_ci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceImageExtendSchemaV1() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "image_id": { + Type: schema.TypeInt, + Required: true, + }, + "show_all": { + Type: schema.TypeBool, + Default: false, + Optional: true, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + }, + "bootable": { + Type: schema.TypeBool, + Computed: true, + }, + "compute_ci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "pool_name": { + Type: schema.TypeString, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + } +} +func resourceMainImageSchemaV1(sch map[string]*schema.Schema) map[string]*schema.Schema { + delete(sch, "show_all") + sch["name"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + } + + sch["url"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "URL where to download media from", + } + + sch["image_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "image id", + } + + sch["boot_type"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true), + Description: "Boot type of image bios or uefi", + } + + sch["type"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "other"}, true), + Description: "Image type linux, windows or other", + } + + sch["hot_resize"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + } + + sch["username"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + } + + sch["password"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + } + + sch["account_id"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + Description: "AccountId to make the image exclusive", + } + + sch["username_dl"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "username for upload binary media", + } + + sch["password_dl"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "password for upload binary media", + } + + sch["pool_name"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + } + + sch["sep_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + } + + sch["architecture"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"X86_64"}, true), + Description: "binary architecture of this image, one of X86_64", + } + + sch["drivers"] = &schema.Schema{ + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + } + + sch["network_interface_naming"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, true), + Description: "select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming", + } + + return sch +} + +func resourceImageSchemaV1() *schema.Resource { + return &schema.Resource{Schema: resourceMainImageSchemaV1(dataSourceImageExtendSchemaV1())} +} + +func resourceMainImageVirtualSchemaV1(sch map[string]*schema.Schema) map[string]*schema.Schema { + delete(sch, "show_all") + sch["name"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + } + + sch["link_to"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + Description: "ID of real image to link this virtual image to upon creation", + } + + sch["image_id"] = &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + Description: "Image id", + } + + return sch +} + +func resourceImageVirtualSchemaV1() *schema.Resource { + return &schema.Resource{Schema: resourceMainImageVirtualSchemaV1(dataSourceImageExtendSchemaV1())} +} diff --git a/internal/service/cloudapi/image/resource_check_input_values.go b/internal/service/cloudapi/image/resource_check_input_values.go new file mode 100644 index 00000000..e2137586 --- /dev/null +++ b/internal/service/cloudapi/image/resource_check_input_values.go @@ -0,0 +1,89 @@ +package image + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + accountId := uint64(d.Get("account_id").(int)) + req := account.ListRequest{} + + accounts, err := c.CloudAPI().Account().List(ctx, req) + if err != nil { + return false, err + } + + return len(accounts.FilterByID(accountId).Data) != 0, nil +} + +func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + gid := uint64(d.Get("gid").(int)) + req := locations.ListRequest{} + + locationList, err := c.CloudAPI().Locations().List(ctx, req) + if err != nil { + return false, err + } + + return len(locationList.FilterByGID(gid).Data) != 0, nil +} + +func existComputeID(ctx context.Context, computeId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + req := compute.GetRequest{ComputeID: computeId} + + // check for compute existence + computeRecord, err := c.CloudAPI().Compute().Get(ctx, req) + if err != nil { + return fmt.Errorf("ComputeID %d is not allowed or does not exist", computeId) + } + + // check if compute was created as blank + computeImageId := computeRecord.ImageID + bootImageId := -1 + for _, d := range computeRecord.Disks { + if computeRecord.Chipset == "i440fx" { + if d.PCISlot == 6 { + bootImageId = int(d.ImageID) + break + } + } else { + if d.BusNumber == 6 { + bootImageId = int(d.ImageID) + break + } + } + } + + if computeImageId != 0 && bootImageId != 0 { + return fmt.Errorf("ComputeID %d is not allowed because it is not blank compute (either compute imageId or boot imageId are not zero)", computeId) + } + + return nil +} + +func existDiskID(ctx context.Context, diskId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + req := disks.ListRequest{ByID: diskId} + + diskList, err := c.CloudAPI().Disks().List(ctx, req) + if err != nil { + return err + } + + if len(diskList.Data) != 1 { + return fmt.Errorf("diskId %d is not allowed or doesn't exist", diskId) + } + + return nil +} diff --git a/internal/service/cloudapi/image/resource_image.go b/internal/service/cloudapi/image/resource_image.go new file mode 100644 index 00000000..a2e06665 --- /dev/null +++ b/internal/service/cloudapi/image/resource_image.go @@ -0,0 +1,303 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string)) + + haveAccountID, err := existAccountID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveAccountID { + return diag.Errorf("resourceImageCreate: can't create Image because AccountID %d is not allowed or does not exist", d.Get("account_id").(int)) + } + + c := m.(*controller.ControllerCfg) + req := image.CreateRequest{ + AccountID: uint64(d.Get("account_id").(int)), + Name: d.Get("name").(string), + URL: d.Get("url").(string), + BootType: d.Get("boot_type").(string), + ImageType: d.Get("type").(string), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + if hotresize, ok := d.GetOk("hot_resize"); ok { + req.HotResize = hotresize.(bool) + } + if username, ok := d.GetOk("username"); ok { + req.Username = username.(string) + } + if password, ok := d.GetOk("password"); ok { + req.Password = password.(string) + } + if usernameDL, ok := d.GetOk("username_dl"); ok { + req.UsernameDL = usernameDL.(string) + } + if passwordDL, ok := d.GetOk("password_dl"); ok { + req.PasswordDL = passwordDL.(string) + } + if sepId, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepId.(int)) + } + if poolName, ok := d.GetOk("pool_name"); ok { + req.Pool = poolName.(string) + } + if networkInterfaceNaming, ok := d.GetOk("network_interface_naming"); ok { + req.NetworkInterfaceNaming = networkInterfaceNaming.(string) + } + + syncMode := d.Get("sync_mode").(bool) + var imageId uint64 + + if syncMode { + if err != nil { + return diag.FromErr(err) + } + imageId, err = c.CloudAPI().Image().Create(ctx, req) + log.Debugf("resourceImageCreate: imageID = %d", imageId) + if err != nil { + return diag.FromErr(err) + } + } else { + if err != nil { + return diag.FromErr(err) + } + taskID, err := c.CloudAPI().Image().AsyncCreate(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskID, `"`), + } + + for { + time.Sleep(time.Second * 15) + task, err := c.CloudAPI().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceAccountDelete: delete account - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot delete account: %v", task.Error)) + } + id, err := task.Result.ID() + imageId = uint64(id) + if err != nil { + return diag.FromErr(err) + } + break + } + } + } + + d.SetId(strconv.FormatUint(imageId, 10)) + d.Set("image_id", imageId) + + _, err = utilityImageCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + return resourceImageRead(ctx, d, m) +} + +func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageRead: called for %s id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if img == nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Creating: + case status.Created: + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceImageCreate(ctx, d, m) + } + + flattenImage(d, img) + + return nil +} + +func resourceImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + _, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := image.DeleteRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } + + _, err = c.CloudAPI().Image().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceImageRename(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceImageEditName: called for %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*controller.ControllerCfg) + req := image.RenameRequest{ + ImageID: uint64(d.Get("image_id").(int)), + Name: d.Get("name").(string), + } + + _, err := c.CloudAPI().Image().Rename(ctx, req) + if err != nil { + return err + } + + return nil +} + +func resourceImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageUpdate: called for %s, id: %s", d.Get("name").(string), d.Id()) + + haveGID, err := existGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveGID { + return diag.Errorf("resourceImageUpdate: can't update Image because GID %d is not allowed or does not exist", d.Get("gid").(int)) + } + + haveAccountID, err := existAccountID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveAccountID { + return diag.Errorf("resourceImageUpdate: can't update Image because AccountID %d is not allowed or does not exist", d.Get("account_id").(int)) + } + + image, err := utilityImageCheckPresence(ctx, d, m) + if image == nil { + if err != nil { + return diag.FromErr(err) + } + return nil + } + + switch image.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", image.Status) + case status.Creating: + case status.Created: + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceImageCreate(ctx, d, m) + } + + if d.HasChange("name") { + err := resourceImageRename(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceImageRead(ctx, d, m) +} + +func ResourceImage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceImageCreate, + ReadContext: resourceImageRead, + UpdateContext: resourceImageUpdate, + DeleteContext: resourceImageDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceImageSchemaMake(dataSourceImageExtendSchemaMake()), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceImageSchemaV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourcePresentToUpgradeV1, + Version: 1, + }, + }, + } +} diff --git a/internal/service/cloudapi/image/resource_image_from_blank_compute.go b/internal/service/cloudapi/image/resource_image_from_blank_compute.go new file mode 100644 index 00000000..1c313a80 --- /dev/null +++ b/internal/service/cloudapi/image/resource_image_from_blank_compute.go @@ -0,0 +1,522 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceImageFromBlankComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeId := uint64(d.Get("compute_id").(int)) + name := d.Get("name").(string) + + log.Debugf("resourceImageFromBlankComputeCreate: called for image %s", name) + + err := existComputeID(ctx, computeId, m) + if err != nil { + return diag.Errorf("resourceImageFromBlankComputeCreate: can't create Image: %v", err) + } + + if _, ok := d.GetOk("account_id"); ok { + haveAccountID, err := existAccountID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveAccountID { + return diag.Errorf("resourceImageFromBlankComputeCreate: can't create Image because AccountID %d is not allowed or does not exist", d.Get("account_id").(int)) + } + } + + c := m.(*controller.ControllerCfg) + req := compute.CreateTemplateFromBlankRequest{ + ComputeID: computeId, + Name: name, + BootType: d.Get("boot_type").(string), + ImageType: d.Get("type").(string), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + if username, ok := d.GetOk("username"); ok { + req.Username = username.(string) + } + if password, ok := d.GetOk("password"); ok { + req.Password = password.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if poolName, ok := d.GetOk("pool_name"); ok { + req.PoolName = poolName.(string) + } + if hotresize, ok := d.GetOk("hot_resize"); ok { + req.HotResize = hotresize.(bool) + } + + var imageId uint64 + asyncMode := d.Get("async_mode").(bool) + if !asyncMode { + imageId, err = c.CloudAPI().Compute().CreateTemplateFromBlank(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } else { + taskId, err := c.CloudAPI().Compute().CreateTemplateFromBlankAsync(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskId, `"`), + } + + for { + task, err := c.CloudAPI().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceImageFromBlankComputeCreate: instance creating - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot create image instance: %v", task.Error)) + } + + id, err := task.Result.ID() + imageId = uint64(id) + if err != nil { + return diag.FromErr(err) + } + break + } + + time.Sleep(time.Second * 20) + } + } + + d.SetId(strconv.FormatUint(imageId, 10)) + d.Set("image_id", imageId) + + _, err = utilityImageCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + return resourceImageFromBlankComputeRead(ctx, d, m) +} + +func resourceImageFromBlankComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromBlankComputeRead: called for %s id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if img == nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Creating: + case status.Created: + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceImageCreate(ctx, d, m) + } + + flattenImage(d, img) + + return nil +} + +func resourceImageFromBlankComputeDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromBlankComputeDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + _, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := image.DeleteRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } + + _, err = c.CloudAPI().Image().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceImageFromBlankComputeRename(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceImageFromBlankComputeRename: called for %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*controller.ControllerCfg) + req := image.RenameRequest{ + ImageID: uint64(d.Get("image_id").(int)), + Name: d.Get("name").(string), + } + + _, err := c.CloudAPI().Image().Rename(ctx, req) + if err != nil { + return err + } + + return nil +} + +func resourceImageFromBlankComputeUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromBlankComputeUpdate: called for %s, id: %s", d.Get("name").(string), d.Id()) + + // we do not allow change of compute_id, but allow resource update after import + old, _ := d.GetChange("compute_id") + if old.(int) != 0 && d.HasChange("compute_id") { + return diag.Errorf("resourceImageFromBlankComputeUpdate: can't update Image because compute_id is not allowed to be changed") + } + + image, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch image.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", image.Status) + case status.Creating: + case status.Created: + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceImageCreate(ctx, d, m) + } + + if d.HasChange("name") { + err := resourceImageFromBlankComputeRename(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceImageFromBlankComputeRead(ctx, d, m) +} + +func ResourceImageFromBlankCompute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceImageFromBlankComputeCreate, + ReadContext: resourceImageFromBlankComputeRead, + UpdateContext: resourceImageFromBlankComputeUpdate, + DeleteContext: resourceImageFromBlankComputeDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout30m, + Read: &constants.Timeout900s, + Update: &constants.Timeout900s, + Delete: &constants.Timeout900s, + Default: &constants.Timeout900s, + }, + + Schema: resourceImageFromBlankComputeSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceImageFromBlankComputeSchemaV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourcePresentToUpgradeV1, + Version: 1, + }, + }, + } +} + +func resourceImageFromBlankComputeSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + Description: "Compute Id", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "Storage policy ID", + }, + "boot_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true), + Description: "Boot type of image BIOS or UEFI", + }, + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "unknown"}, true), + Description: "Image type linux, windows or unknown", + }, + + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "async_mode": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "create an image in async/sync mode", + }, + + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "bootable": { + Type: schema.TypeBool, + Computed: true, + }, + "compute_ci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "links_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + } +} diff --git a/internal/service/cloudapi/image/resource_image_from_platform_disk.go b/internal/service/cloudapi/image/resource_image_from_platform_disk.go new file mode 100644 index 00000000..8b45f8ad --- /dev/null +++ b/internal/service/cloudapi/image/resource_image_from_platform_disk.go @@ -0,0 +1,500 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceImageFromPlatformDiskCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskId := uint64(d.Get("disk_id").(int)) + name := d.Get("name").(string) + + log.Debugf("resourceImageFromPlatformDiskCreate: called for image %s", name) + + err := existDiskID(ctx, diskId, m) + if err != nil { + return diag.Errorf("resourceImageFromPlatformDiskCreate: can't create Image: %v", err) + } + + if _, ok := d.GetOk("account_id"); ok { + haveAccountID, err := existAccountID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveAccountID { + return diag.Errorf("resourceImageFromPlatformDiskCreate: can't create Image because AccountID %d is not allowed or does not exist", d.Get("account_id").(int)) + } + } + + c := m.(*controller.ControllerCfg) + req := disks.FromPlatformDiskRequest{ + DiskID: diskId, + Name: name, + BootType: d.Get("boot_type").(string), + ImageType: d.Get("type").(string), + Bootable: d.Get("bootable").(bool), // default value - true + } + + if username, ok := d.GetOk("username"); ok { + req.Username = username.(string) + } + if password, ok := d.GetOk("password"); ok { + req.Password = password.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if poolName, ok := d.GetOk("pool_name"); ok { + req.PoolName = poolName.(string) + } + if hotresize, ok := d.GetOk("hot_resize"); ok { + req.HotResize = hotresize.(bool) + } + + var imageId uint64 + asyncMode := d.Get("async_mode").(bool) + if !asyncMode { + imageId, err = c.CloudAPI().Disks().FromPlatformDisk(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } else { + taskId, err := c.CloudAPI().Disks().FromPlatformDiskAsync(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskId, `"`), + } + + for { + task, err := c.CloudAPI().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceImageFromPlatformDiskCreate: instance creating - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot create image instance: %v", task.Error)) + } + + id, err := task.Result.ID() + imageId = uint64(id) + if err != nil { + return diag.FromErr(err) + } + break + } + + time.Sleep(time.Second * 20) + } + } + + d.SetId(strconv.FormatUint(imageId, 10)) + d.Set("image_id", imageId) + + _, err = utilityImageCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + return resourceImageFromPlatformDiskRead(ctx, d, m) +} + +func resourceImageFromPlatformDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromPlatformDiskRead: called for %s id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if img == nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Creating: + case status.Created: + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + flattenImage(d, img) + + return nil +} + +func resourceImageFromPlatformDiskDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromPlatformDiskDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + _, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := image.DeleteRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } + + _, err = c.CloudAPI().Image().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceImageFromPlatformDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromPlatformDiskUpdate: called for %s, id: %s", d.Get("name").(string), d.Id()) + + // we do not allow change of disk_id, but allow resource update after import + old, _ := d.GetChange("disk_id") + if old.(int) != 0 && d.HasChange("disk_id") { + return diag.Errorf("resourceImageFromPlatformDiskUpdate: can't update Image because disk_id is not allowed to be changed") + } + + image, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch image.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", image.Status) + case status.Creating: + case status.Created: + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + if d.HasChange("name") { + err := resourceImageRename(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceImageFromPlatformDiskRead(ctx, d, m) +} + +func ResourceImageFromPlatformDisk() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceImageFromPlatformDiskCreate, + ReadContext: resourceImageFromPlatformDiskRead, + UpdateContext: resourceImageFromPlatformDiskUpdate, + DeleteContext: resourceImageFromPlatformDiskDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout30m, + Read: &constants.Timeout900s, + Update: &constants.Timeout900s, + Delete: &constants.Timeout900s, + Default: &constants.Timeout900s, + }, + + Schema: resourceImageFromPlatformDiskSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceImageFromBlankDiskSchemaV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourcePresentToUpgradeV1, + Version: 1, + }, + }, + } +} + +func resourceImageFromPlatformDiskSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "Disk Id", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "boot_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true), + Description: "Boot type of image BIOS or UEFI", + }, + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "unknown"}, true), + Description: "Image type linux, windows or unknown", + }, + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "bootable image", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "async_mode": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "create an image in async/sync mode", + }, + + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "compute_ci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "links_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + } +} diff --git a/internal/service/cloudapi/image/resource_image_virtual.go b/internal/service/cloudapi/image/resource_image_virtual.go new file mode 100644 index 00000000..1aae5628 --- /dev/null +++ b/internal/service/cloudapi/image/resource_image_virtual.go @@ -0,0 +1,139 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceImageVirtualCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageVirtualCreate: called for image %s", d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + req := image.CreateVirtualRequest{ + Name: d.Get("name").(string), + TargetID: uint64(d.Get("link_to").(int)), + AccountID: uint64(d.Get("account_id").(int)), + } + + imageId, err := c.CloudAPI().Image().CreateVirtual(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(imageId, 10)) + d.Set("image_id", imageId) + + _, err = utilityImageCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + return resourceImageRead(ctx, d, m) +} + +func resourceImageVirtualUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageUpdate: called for %s, id: %s", d.Get("name").(string), d.Id()) + + if d.HasChange("name") { + err := resourceImageRename(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("link_to") { + err := resourceImageVirtualLink(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceImageRead(ctx, d, m) +} + +func resourceImageVirtualLink(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceVirtualImageLink: called for %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*controller.ControllerCfg) + req := image.LinkRequest{ + ImageID: uint64(d.Get("image_id").(int)), + TargetID: uint64(d.Get("link_to").(int)), + } + + _, err := c.CloudAPI().Image().Link(ctx, req) + if err != nil { + return err + } + + return nil +} + +func ResourceImageVirtual() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceImageVirtualCreate, + ReadContext: resourceImageRead, + UpdateContext: resourceImageVirtualUpdate, + DeleteContext: resourceImageDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceImageVirtualSchemaMake(dataSourceImageExtendSchemaMake()), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceImageVirtualSchemaV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourcePresentToUpgradeV1, + Version: 1, + }, + }, + } +} diff --git a/internal/service/cloudapi/image/state_upgraders.go b/internal/service/cloudapi/image/state_upgraders.go new file mode 100644 index 00000000..4ed85d99 --- /dev/null +++ b/internal/service/cloudapi/image/state_upgraders.go @@ -0,0 +1,14 @@ +package image + +import ( + "context" + + log "github.com/sirupsen/logrus" +) + +func resourcePresentToUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourcePresentToUpgradeV1: upgrading state") + rawState["present_to"] = make(map[string]uint64) + + return rawState, nil +} diff --git a/internal/service/cloudapi/image/utility_image.go b/internal/service/cloudapi/image/utility_image.go new file mode 100644 index 00000000..5723d3e3 --- /dev/null +++ b/internal/service/cloudapi/image/utility_image.go @@ -0,0 +1,65 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.RecordImage, error) { + c := m.(*controller.ControllerCfg) + req := image.GetRequest{} + + if (strconv.Itoa(d.Get("image_id").(int))) != "0" { + req.ImageID = uint64(d.Get("image_id").(int)) + } else { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.ImageID = id + } + + if showAll, ok := d.GetOk("show_all"); ok { + req.ShowAll = showAll.(bool) + } + + image, err := c.CloudAPI().Image().Get(ctx, req) + if err != nil { + return nil, err + } + + return image, nil +} diff --git a/internal/service/cloudapi/image/utility_image_list.go b/internal/service/cloudapi/image/utility_image_list.go new file mode 100644 index 00000000..95603e69 --- /dev/null +++ b/internal/service/cloudapi/image/utility_image_list.go @@ -0,0 +1,119 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.ListImages, error) { + c := m.(*controller.ControllerCfg) + req := image.ListRequest{} + + if sepID, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepID.(int)) + } + + if byID, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byID.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if typeImage, ok := d.GetOk("type_image"); ok { + for _, v := range typeImage.([]interface{}) { + req.TypeImage = append(req.TypeImage, v.(string)) + } + } + + if imageSize, ok := d.GetOk("image_size"); ok { + req.ImageSize = uint64(imageSize.(int)) + } + + if sepName, ok := d.GetOk("sep_name"); ok { + req.SEPName = sepName.(string) + } + + if pool, ok := d.GetOk("pool"); ok { + req.Pool = pool.(string) + } + + if public, ok := d.GetOkExists("public"); ok { + req.Public = public.(bool) + } + + if hotResize, ok := d.GetOkExists("hot_resize"); ok { + req.HotResize = hotResize.(bool) + } + + if bootable, ok := d.GetOkExists("bootable"); ok { + req.Bootable = bootable.(bool) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if enabled, ok := d.GetOkExists("enabled"); ok { + req.Enabled = enabled.(bool) + } + if storagePolicyID, ok := d.GetOk("storage_policy_id"); ok { + req.StoragePolicyID = uint64(storagePolicyID.(int)) + } + + log.Debugf("utilityImageListCheckPresence: load image list") + imageList, err := c.CloudAPI().Image().List(ctx, req) + if err != nil { + return nil, err + } + + return imageList, nil +} diff --git a/internal/service/cloudapi/k8s/data_source_k8ci_list.go b/internal/service/cloudapi/k8s/data_source_k8ci_list.go new file mode 100644 index 00000000..2a4a102b --- /dev/null +++ b/internal/service/cloudapi/k8s/data_source_k8ci_list.go @@ -0,0 +1,180 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8CIListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + list, err := utilityK8CIListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(uuid.New().String()) + flattenK8CIList(d, list) + d.Set("entry_count", list.EntryCount) + + return nil +} + +func dataSourceK8CIListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "worker_driver": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by worker driver", + }, + "master_driver": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by master driver", + }, + "network_plugin": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by network plugin", + }, + "include_disabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Include deleted k8cis in result", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "k8ci_id": { + Type: schema.TypeInt, + Computed: true, + Description: "K8CI ID", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "K8CI name", + }, + "lb_image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "LB Image ID", + }, + "network_plugins": { + Type: schema.TypeList, + Computed: true, + Description: "List of available network plugins", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "K8CI Status", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func DataSourceK8CIList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8CIListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8CIListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/k8s/data_source_k8s.go b/internal/service/cloudapi/k8s/data_source_k8s.go new file mode 100644 index 00000000..44f75119 --- /dev/null +++ b/internal/service/cloudapi/k8s/data_source_k8s.go @@ -0,0 +1,465 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func dataSourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + cluster, err := utilityDataK8sCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId(strconv.FormatUint(cluster.ID, 10)) + + k8sList, err := utilityK8sListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + curK8s := k8s.ItemK8SCluster{} + for _, k8sCluster := range k8sList.Data { + if k8sCluster.ID == cluster.ID { + curK8s = k8sCluster + } + } + if curK8s.ID == 0 { + return diag.Errorf("Cluster with id %d not found in List clusters", cluster.ID) + } + + d.Set("vins_id", curK8s.VINSID) + + masterComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Masters.DetailedInfo)) + workersComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Workers)) + for _, masterNode := range cluster.K8SGroups.Masters.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, masterNode.ID) + if err != nil { + return diag.FromErr(err) + } + masterComputeList = append(masterComputeList, *compute) + } + for _, worker := range cluster.K8SGroups.Workers { + for _, info := range worker.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) + if err != nil { + return diag.FromErr(err) + } + workersComputeList = append(workersComputeList, *compute) + } + } + + c := m.(*controller.ControllerCfg) + k8sId, _ := strconv.ParseUint(d.Id(), 10, 64) + + getConfigReq := k8s.GetConfigRequest{K8SID: k8sId} + + kubeconfig, err := c.CloudAPI().K8S().GetConfig(ctx, getConfigReq) + if err != nil { + log.Warnf("could not get kubeconfig: %v", err) + } + + d.Set("kubeconfig", kubeconfig) + if cluster.LBID != 0 { + getLbReq := lb.GetRequest{LBID: cluster.LBID} + lb, err := c.CloudAPI().LB().Get(ctx, getLbReq) + if err != nil { + return diag.FromErr(err) + } + + d.Set("extnet_id", lb.ExtNetID) + d.Set("lb_ip", lb.PrimaryNode.FrontendIP) + } + + flattenK8sData(d, *cluster, masterComputeList, workersComputeList) + return nil +} + +func aclListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func aclGroupSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclListSchemaMake(), + }, + }, + "k8s_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclListSchemaMake(), + }, + }, + "rg_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclListSchemaMake(), + }, + }, + } +} + +func detailedInfoSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: interfacesSchemaMake(), + }, + }, + "natable_vins_ip": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func interfacesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func masterGroupSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: detailedInfoSchemaMake(), + }, + }, + "disk": { + Type: schema.TypeInt, + Computed: true, + }, + "master_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "num": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func k8sGroupListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "annotations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: detailedInfoSchemaMake(), + }, + }, + "disk": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "num": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + } +} + +func dataSourceK8sSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + }, + + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclGroupSchemaMake(), + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "bservice_id": { + Type: schema.TypeInt, + Computed: true, + }, + "k8sci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.", + }, + "k8s_ci_name": { + Type: schema.TypeString, + Computed: true, + }, + "masters": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: masterGroupSchemaMake(), + }, + }, + "workers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: k8sGroupListSchemaMake(), + }, + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lb_ip": { + Type: schema.TypeString, + Computed: true, + Description: "IP address of default load balancer.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "network_plugin": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "kubeconfig": { + Type: schema.TypeString, + Computed: true, + Description: "Kubeconfig for cluster access.", + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func DataSourceK8s() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sSchemaMake(), + } +} diff --git a/internal/service/cloudapi/k8s/data_source_k8s_computes.go b/internal/service/cloudapi/k8s/data_source_k8s_computes.go new file mode 100644 index 00000000..5151d430 --- /dev/null +++ b/internal/service/cloudapi/k8s/data_source_k8s_computes.go @@ -0,0 +1,119 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sComputesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(fmt.Sprint(cluster.ID)) + flattenK8sDataComputes(d, cluster) + + return nil +} + +func computesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "group_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func dataSourceK8sComputesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + }, + "masters": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computesSchemaMake(), + }, + }, + "workers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computesSchemaMake(), + }, + }, + } +} + +func DataSourceK8sComputes() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sComputesRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout60s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sComputesSchemaMake(), + } +} diff --git a/internal/service/cloudapi/k8s/data_source_k8s_list.go b/internal/service/cloudapi/k8s/data_source_k8s_list.go new file mode 100644 index 00000000..b65cc561 --- /dev/null +++ b/internal/service/cloudapi/k8s/data_source_k8s_list.go @@ -0,0 +1,362 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + k8sList, err := utilityK8sListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenK8sList(d, k8sList) + + return nil +} + +func serviceAccountSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func k8sWorkersGroupsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "annotations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: detailedInfoSchemaMake(), + }, + }, + "disk": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "detailed_info_id": { + Type: schema.TypeInt, + Computed: true, + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "num": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + } +} + +func createK8sListSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by IP address", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "lb_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by LB ID", + }, + "bservice_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by BService ID", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by tech. status", + }, + "includedeleted": { + Type: schema.TypeBool, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "bservice_id": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_name": { + Type: schema.TypeString, + Computed: true, + }, + "network_plugin": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "service_account": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: serviceAccountSchemaMake(), + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "workers_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: k8sWorkersGroupsSchemaMake(), + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceK8sListSchemaMake() map[string]*schema.Schema { + k8sListSchema := createK8sListSchema() + return k8sListSchema +} + +func DataSourceK8sList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go b/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go new file mode 100644 index 00000000..babdb6be --- /dev/null +++ b/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go @@ -0,0 +1,78 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + k8sList, err := utilityK8sListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenK8sList(d, k8sList) + + return nil +} + +func dataSourceK8sListDeletedSchemaMake() map[string]*schema.Schema { + k8sListDeleted := createK8sListSchema() + delete(k8sListDeleted, "includedeleted") + delete(k8sListDeleted, "status") + return k8sListDeleted +} + +func DataSourceK8sListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudapi/k8s/data_source_k8s_wg.go b/internal/service/cloudapi/k8s/data_source_k8s_wg.go new file mode 100644 index 00000000..1ef9548c --- /dev/null +++ b/internal/service/cloudapi/k8s/data_source_k8s_wg.go @@ -0,0 +1,151 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("dataSourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int)) + + wg, workersComputeList, err := utilityDataK8sWgCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("wg_id").(int))) + + flattenWg(d, *wg, workersComputeList) + + return nil +} + +func dataSourceK8sWgSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of k8s instance.", + }, + "wg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of k8s worker Group.", + }, + + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the worker group.", + }, + + "num": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of worker nodes to create.", + }, + + "cpu": { + Type: schema.TypeInt, + Computed: true, + Description: "Worker node CPU count.", + }, + + "ram": { + Type: schema.TypeInt, + Computed: true, + Description: "Worker node RAM in MB.", + }, + + "disk": { + Type: schema.TypeInt, + Computed: true, + Description: "Worker node boot disk size. If unspecified or 0, size is defined by OS image size.", + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: detailedInfoSchemaMake(), + }, + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "annotations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + } +} + +func DataSourceK8sWg() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sWgRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sWgSchemaMake(), + } +} diff --git a/internal/service/cloudapi/k8s/data_source_k8s_wg_cloud_init.go b/internal/service/cloudapi/k8s/data_source_k8s_wg_cloud_init.go new file mode 100644 index 00000000..873940f6 --- /dev/null +++ b/internal/service/cloudapi/k8s/data_source_k8s_wg_cloud_init.go @@ -0,0 +1,94 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sWgCloudInitRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("dataSourceK8sWgCloudInitRead: called with k8s id %d and wg id %d", d.Get("k8s_id").(int), d.Get("wg_id").(int)) + + metaData, err := utilityK8sWgCloudInitCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("cloud_init", metaData) + + return nil +} + +func dataSourceK8sWgCloudInitSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + Description: "Kubernetes cluster ID", + }, + "wg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the workers compute group", + }, + "cloud_init": { + Type: schema.TypeString, + Computed: true, + Description: "Worker group Cloud init", + }, + } +} + +func DataSourceK8sWgCloudInit() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sWgCloudInitRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sWgCloudInitSchemaMake(), + } +} diff --git a/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go b/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go new file mode 100644 index 00000000..427a069d --- /dev/null +++ b/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go @@ -0,0 +1,109 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sWgListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + wgList, err := utilityK8sWgListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("k8s_id").(int))) + + workersComputeList := make(map[uint64][]compute.RecordCompute) + for _, worker := range wgList { + workersComputeList[worker.ID] = make([]compute.RecordCompute, 0, len(worker.DetailedInfo)) + for _, info := range worker.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) + if err != nil { + return diag.FromErr(err) + } + workersComputeList[worker.ID] = append(workersComputeList[worker.ID], *compute) + } + } + flattenItemsWg(d, wgList, workersComputeList) + return nil +} + +func wgSchemaMake() map[string]*schema.Schema { + wgSchema := dataSourceK8sWgSchemaMake() + delete(wgSchema, "k8s_id") + wgSchema["wg_id"] = &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + Description: "ID of k8s worker Group.", + } + return wgSchema +} + +func dataSourceK8sWgListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: wgSchemaMake(), + }, + }, + } +} + +func DataSourceK8sWgList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sWgListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sWgListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/k8s/flattens.go b/internal/service/cloudapi/k8s/flattens.go new file mode 100644 index 00000000..0b3456d7 --- /dev/null +++ b/internal/service/cloudapi/k8s/flattens.go @@ -0,0 +1,468 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8ci" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" +) + +func flattenK8CIItems(list *k8ci.ListK8CI) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list.Data)) + for _, item := range list.Data { + temp := map[string]interface{}{ + "k8ci_id": item.ID, + "name": item.Name, + "lb_image_id": item.LBImageID, + "network_plugins": item.NetworkPlugins, + "status": item.Status, + "desc": item.Description, + "created_time": item.CreatedTime, + "version": item.Version, + } + + res = append(res, temp) + } + + return res +} + +func flattenK8CIList(d *schema.ResourceData, list *k8ci.ListK8CI) { + d.Set("items", flattenK8CIItems(list)) +} + +func flattenK8sDataComputes(d *schema.ResourceData, cluster *k8s.RecordK8S) { + d.Set("k8s_id", cluster.ID) + d.Set("masters", flattenMasterComputes(cluster)) + d.Set("workers", flattenWorkerComputes(cluster)) +} + +func flattenMasterComputes(cluster *k8s.RecordK8S) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(cluster.K8SGroups.Masters.DetailedInfo)) + for _, comp := range cluster.K8SGroups.Masters.DetailedInfo { + temp := map[string]interface{}{ + "id": comp.ID, + "name": comp.Name, + "status": comp.Status, + "tech_status": comp.TechStatus, + "group_name": cluster.K8SGroups.Masters.Name, + } + res = append(res, temp) + } + + return res +} + +func flattenWorkerComputes(cluster *k8s.RecordK8S) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(cluster.K8SGroups.Workers)) + for _, wg := range cluster.K8SGroups.Workers { + for _, comp := range wg.DetailedInfo { + temp := map[string]interface{}{ + "id": comp.ID, + "name": comp.Name, + "status": comp.Status, + "tech_status": comp.TechStatus, + "group_name": wg.Name, + } + res = append(res, temp) + } + } + + return res +} + +func flattenAclList(aclList k8s.ListACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(aclList)) + for _, acl := range aclList { + temp := map[string]interface{}{ + "explicit": acl.Explicit, + "guid": acl.GUID, + "right": acl.Right, + "status": acl.Status, + "type": acl.Type, + "user_group_id": acl.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenAcl(acl k8s.RecordACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "account_acl": flattenAclList(acl.AccountACL), + "k8s_acl": flattenAclList(acl.K8SACL), + "rg_acl": flattenAclList(acl.RGACL), + } + + res = append(res, temp) + return res +} + +func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(interfaces)) + for _, interfaceCompute := range interfaces { + temp := map[string]interface{}{ + "def_gw": interfaceCompute.DefGW, + "ip_address": interfaceCompute.IPAddress, + } + res = append(res, temp) + } + + return res +} + +func flattenDetailedInfo(detailedInfoList k8s.ListDetailedInfo, computes []compute.RecordCompute) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(detailedInfoList)) + if computes != nil { + for i, detailedInfo := range detailedInfoList { + temp := map[string]interface{}{ + "compute_id": detailedInfo.ID, + "name": detailedInfo.Name, + "status": detailedInfo.Status, + "tech_status": detailedInfo.TechStatus, + "interfaces": flattenInterfaces(computes[i].Interfaces), + "natable_vins_ip": computes[i].NatableVINSIP, + "natable_vins_network": computes[i].NatableVINSNetwork, + } + res = append(res, temp) + } + } else { + for _, detailedInfo := range detailedInfoList { + temp := map[string]interface{}{ + "compute_id": detailedInfo.ID, + "name": detailedInfo.Name, + "status": detailedInfo.Status, + "tech_status": detailedInfo.TechStatus, + } + res = append(res, temp) + } + } + + return res +} + +func flattenMasterGroup(mastersGroup k8s.MasterGroup, masters []compute.RecordCompute) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": mastersGroup.CPU, + "detailed_info": flattenDetailedInfo(mastersGroup.DetailedInfo, masters), + "disk": mastersGroup.Disk, + "master_id": mastersGroup.ID, + "name": mastersGroup.Name, + "num": mastersGroup.Num, + "ram": mastersGroup.RAM, + } + + res = append(res, temp) + return res +} + +func flattenK8sGroup(k8SGroupList k8s.ListK8SGroups, workers []compute.RecordCompute) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(k8SGroupList)) + for _, k8sGroup := range k8SGroupList { + labels := make([]string, 0) + for _, label := range k8sGroup.Labels { + if strings.HasPrefix(label, "workersGroupName") { + continue + } + + labels = append(labels, label) + } + temp := map[string]interface{}{ + "annotations": k8sGroup.Annotations, + "cpu": k8sGroup.CPU, + "detailed_info": flattenDetailedInfo(k8sGroup.DetailedInfo, workers), + "disk": k8sGroup.Disk, + "guid": k8sGroup.GUID, + "id": k8sGroup.ID, + "labels": labels, + "name": k8sGroup.Name, + "num": k8sGroup.Num, + "ram": k8sGroup.RAM, + "taints": k8sGroup.Taints, + } + + res = append(res, temp) + } + return res +} + +// func flattenK8sGroups(k8sGroups k8s.RecordK8SGroups, masters []compute.RecordCompute, workers []compute.RecordCompute) []map[string]interface{} { +// res := make([]map[string]interface{}, 0) +// temp := map[string]interface{}{ +// "masters": flattenMasterGroup(k8sGroups.Masters, masters), +// "workers": flattenK8sGroup(k8sGroups.Workers, workers), +// } +// res = append(res, temp) +// return res +// } + +func flattenK8sData(d *schema.ResourceData, cluster k8s.RecordK8S, masters []compute.RecordCompute, workers []compute.RecordCompute) { + d.Set("acl", flattenAcl(cluster.ACL)) + d.Set("account_id", cluster.AccountID) + d.Set("account_name", cluster.AccountName) + d.Set("bservice_id", cluster.BServiceID) + d.Set("k8sci_id", cluster.CIID) + d.Set("created_by", cluster.CreatedBy) + d.Set("created_time", cluster.CreatedTime) + d.Set("desc", cluster.Description) + d.Set("deleted_by", cluster.DeletedBy) + d.Set("deleted_time", cluster.DeletedTime) + d.Set("k8s_ci_name", cluster.K8CIName) + d.Set("masters", flattenMasterGroup(cluster.K8SGroups.Masters, masters)) + d.Set("workers", flattenK8sGroup(cluster.K8SGroups.Workers, workers)) + d.Set("lb_id", cluster.LBID) + d.Set("name", cluster.Name) + d.Set("network_plugin", cluster.NetworkPlugin) + d.Set("rg_id", cluster.RGID) + d.Set("rg_name", cluster.RGName) + d.Set("status", cluster.Status) + d.Set("tech_status", cluster.TechStatus) + d.Set("updated_by", cluster.UpdatedBy) + d.Set("updated_time", cluster.UpdatedTime) + d.Set("highly_available_lb", cluster.HighlyAvailableLB) + d.Set("address_vip", flattenAddressVIP(cluster.AddressVIP)) + d.Set("extnet_only", cluster.ExtnetOnly) + d.Set("with_lb", cluster.WithLB) + d.Set("zone_id", cluster.ZoneID) +} + +func flattenAddressVIP(addressVIP k8s.K8SAddressVIP) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "backend_ip": addressVIP.BackendIP, + "frontend_ip": addressVIP.FrontendIP, + } + res = append(res, temp) + return res +} + +func flattenServiceAccount(serviceAccount k8s.RecordServiceAccount) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "guid": serviceAccount.GUID, + "password": serviceAccount.Password, + "username": serviceAccount.Username, + } + res = append(res, temp) + return res +} + +func flattenWorkersGroup(workersGroups k8s.ListK8SGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(workersGroups)) + for _, worker := range workersGroups { + temp := map[string]interface{}{ + "annotations": worker.Annotations, + "cpu": worker.CPU, + "detailed_info": flattenDetailedInfo(worker.DetailedInfo, nil), + "disk": worker.Disk, + "guid": worker.GUID, + "detailed_info_id": worker.ID, + "labels": worker.Labels, + "name": worker.Name, + "num": worker.Num, + "ram": worker.RAM, + "taints": worker.Taints, + } + res = append(res, temp) + } + return res +} + +func flattenK8sItems(k8sItems *k8s.ListK8SClusters) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(k8sItems.Data)) + for _, item := range k8sItems.Data { + temp := map[string]interface{}{ + "account_id": item.AccountID, + "account_name": item.AccountName, + "acl": item.ACL, + "bservice_id": item.BServiceID, + "ci_id": item.CIID, + "created_by": item.CreatedBy, + "created_time": item.CreatedTime, + "deleted_by": item.DeletedBy, + "deleted_time": item.DeletedTime, + "desc": item.Description, + "extnet_id": item.ExtNetID, + "gid": item.GID, + "guid": item.GUID, + "k8s_id": item.ID, + "lb_id": item.LBID, + "milestones": item.Milestones, + "k8s_name": item.Name, + "network_plugin": item.NetworkPlugin, + "rg_id": item.RGID, + "rg_name": item.RGName, + "service_account": flattenServiceAccount(item.ServiceAccount), + "status": item.Status, + "tech_status": item.TechStatus, + "updated_by": item.UpdatedBy, + "updated_time": item.UpdatedTime, + "vins_id": item.VINSID, + "zone_id": item.ZoneID, + "workers_groups": flattenWorkersGroup(item.WorkersGroup), + } + + res = append(res, temp) + } + return res +} + +func flattenK8sList(d *schema.ResourceData, k8sItems *k8s.ListK8SClusters) { + d.Set("items", flattenK8sItems(k8sItems)) + d.Set("entry_count", k8sItems.EntryCount) +} + +func flattenResourceK8sCP(d *schema.ResourceData, k8s k8s.RecordK8S, masters []compute.RecordCompute) { + d.Set("acl", flattenAcl(k8s.ACL)) + d.Set("account_id", k8s.AccountID) + d.Set("account_name", k8s.AccountName) + d.Set("k8sci_id", k8s.CIID) + d.Set("bservice_id", k8s.BServiceID) + d.Set("created_by", k8s.CreatedBy) + d.Set("created_time", k8s.CreatedTime) + d.Set("desc", k8s.Description) + d.Set("deleted_by", k8s.DeletedBy) + d.Set("deleted_time", k8s.DeletedTime) + d.Set("k8s_ci_name", k8s.K8CIName) + d.Set("with_lb", k8s.LBID != 0) + d.Set("lb_id", k8s.LBID) + d.Set("k8s_id", k8s.ID) + d.Set("name", k8s.Name) + d.Set("rg_id", k8s.RGID) + d.Set("rg_name", k8s.RGName) + d.Set("status", k8s.Status) + d.Set("tech_status", k8s.TechStatus) + d.Set("updated_by", k8s.UpdatedBy) + d.Set("updated_time", k8s.UpdatedTime) + d.Set("network_plugin", k8s.NetworkPlugin) + d.Set("zone_id", k8s.ZoneID) + + flattenCPParams(d, k8s.K8SGroups.Masters, masters) +} + +func flattenCPParams(d *schema.ResourceData, mastersGroup k8s.MasterGroup, masters []compute.RecordCompute) { + d.Set("cpu", mastersGroup.CPU) + d.Set("detailed_info", flattenDetailedInfo(mastersGroup.DetailedInfo, masters)) + d.Set("disk", mastersGroup.Disk) + d.Set("master_id", mastersGroup.ID) + d.Set("master_name", mastersGroup.Name) + d.Set("num", mastersGroup.Num) + d.Set("ram", mastersGroup.RAM) + d.Set("master_id", mastersGroup.ID) +} + +func flattenResourceK8s(d *schema.ResourceData, k8s k8s.RecordK8S, masters []compute.RecordCompute, workers []compute.RecordCompute) { + wg_name := k8s.K8SGroups.Workers[0].Name + + d.Set("acl", flattenAcl(k8s.ACL)) + d.Set("account_id", k8s.AccountID) + d.Set("account_name", k8s.AccountName) + d.Set("k8sci_id", k8s.CIID) + d.Set("wg_name", wg_name) + d.Set("bservice_id", k8s.BServiceID) + d.Set("created_by", k8s.CreatedBy) + d.Set("created_time", k8s.CreatedTime) + d.Set("desc", k8s.Description) + d.Set("deleted_by", k8s.DeletedBy) + d.Set("deleted_time", k8s.DeletedTime) + d.Set("k8s_ci_name", k8s.K8CIName) + d.Set("masters", flattenMasterGroup(k8s.K8SGroups.Masters, masters)) + d.Set("workers", flattenK8sGroup(k8s.K8SGroups.Workers, workers)) + d.Set("with_lb", k8s.LBID != 0) + d.Set("lb_id", k8s.LBID) + d.Set("name", k8s.Name) + d.Set("rg_id", k8s.RGID) + d.Set("rg_name", k8s.RGName) + d.Set("status", k8s.Status) + d.Set("tech_status", k8s.TechStatus) + d.Set("updated_by", k8s.UpdatedBy) + d.Set("updated_time", k8s.UpdatedTime) + d.Set("default_wg_id", k8s.K8SGroups.Workers[0].ID) + d.Set("network_plugin", k8s.NetworkPlugin) + d.Set("zone_id", k8s.ZoneID) +} + +func flattenWg(d *schema.ResourceData, wg k8s.ItemK8SGroup, computes []compute.RecordCompute) { + labels := make([]string, 0, len(wg.Labels)) + for _, label := range wg.Labels { + if strings.HasPrefix(label, "workersGroupName") { + continue + } + + labels = append(labels, label) + } + + d.Set("annotations", wg.Annotations) + d.Set("cpu", wg.CPU) + d.Set("detailed_info", flattenDetailedInfo(wg.DetailedInfo, computes)) + d.Set("disk", wg.Disk) + d.Set("guid", wg.GUID) + d.Set("labels", labels) + d.Set("name", wg.Name) + d.Set("num", wg.Num) + d.Set("ram", wg.RAM) + d.Set("taints", wg.Taints) +} + +func flattenWgList(wgList k8s.ListK8SGroups, computesMap map[uint64][]compute.RecordCompute) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(wgList)) + for _, wg := range wgList { + computes := computesMap[wg.ID] + temp := map[string]interface{}{ + "annotations": wg.Annotations, + "cpu": wg.CPU, + "wg_id": wg.ID, + "detailed_info": flattenDetailedInfo(wg.DetailedInfo, computes), + "disk": wg.Disk, + "guid": wg.GUID, + "labels": wg.Labels, + "name": wg.Name, + "num": wg.Num, + "ram": wg.RAM, + "taints": wg.Taints, + } + + res = append(res, temp) + } + return res +} + +func flattenItemsWg(d *schema.ResourceData, wgList k8s.ListK8SGroups, computes map[uint64][]compute.RecordCompute) { + d.Set("items", flattenWgList(wgList, computes)) +} diff --git a/internal/service/cloudapi/k8s/models.go b/internal/service/cloudapi/k8s/models.go new file mode 100644 index 00000000..2e9c8fe5 --- /dev/null +++ b/internal/service/cloudapi/k8s/models.go @@ -0,0 +1,262 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "encoding/json" + "fmt" + "strconv" +) + +type K8sNodeRecord struct { + ID int `json:"id"` + Name string `json:"name"` + Disk int `json:"disk"` + Cpu int `json:"cpu"` + Num int `json:"num"` + Ram int `json:"ram"` + // coming in future updates (curr. version 4.0.2) + // Labels []interface{} `json:"labels"` + // Annotations []interface{} `json:"annotations"` + // Taints []interface{} `json:"taints"` + DetailedInfo []struct { + ID int `json:"id"` + Name string `json:"name"` + } `json:"detailedInfo"` + SepID int `json:"SepId"` + SepPool string `json:"SepPool"` +} + +// K8sRecord represents k8s instance +type K8sRecord struct { + AccountID int `json:"accountId"` + AccountName string `json:"accountName"` + CI int `json:"ciId"` + ID int `json:"id"` + Groups struct { + Masters K8sNodeRecord `json:"masters"` + Workers []K8sNodeRecord `json:"workers"` + } `json:"k8sGroups"` + LbID int `json:"lbId"` + Name string `json:"name"` + RgID int `json:"rgId"` + RgName string `json:"rgName"` + VinsID int `json:"vinsId"` +} + +type K8sRecordList []K8sRecord + +// LbRecord represents load balancer instance +type LbRecord struct { + ID int `json:"id"` + Name string `json:"name"` + RgID int `json:"rgId"` + VinsID int `json:"vinsId"` + ExtNetID int `json:"extnetId"` + PrimaryNode struct { + BackendIP string `json:"backendIp"` + ComputeID int `json:"computeId"` + FrontendIP string `json:"frontendIp"` + NetworkID int `json:"networkId"` + } `json:"primaryNode"` +} + +// Blasphemous workaround for parsing Result value +type TaskResult int + +func (r *TaskResult) UnmarshalJSON(b []byte) error { + if b[0] == '"' { + b := b[1 : len(b)-1] + if len(b) == 0 { + *r = 0 + return nil + } + n, err := strconv.Atoi(string(b)) + if err != nil { + return err + } + *r = TaskResult(n) + } else if b[0] == '[' { + res := []interface{}{} + if err := json.Unmarshal(b, &res); err != nil { + return err + } + if n, ok := res[0].(float64); ok { + *r = TaskResult(n) + } else { + return fmt.Errorf("could not unmarshal %v into int", res[0]) + } + } + + return nil +} + +// AsyncTask represents a long task completion status +type AsyncTask struct { + AuditID string `json:"auditId"` + Completed bool `json:"completed"` + Error string `json:"error"` + Log []string `json:"log"` + Result TaskResult `json:"result"` + Stage string `json:"stage"` + Status string `json:"status"` + UpdateTime uint64 `json:"updateTime"` + UpdatedTime uint64 `json:"updatedTime"` +} + +type SshKeyConfig struct { + User string + SshKey string + UserShell string +} + +// FromSDK +type K8SGroup struct { + Annotations []string `json:"annotations"` + CPU uint64 `json:"cpu"` + DetailedInfo DetailedInfoList `json:"detailedInfo"` + Disk uint64 `json:"disk"` + GUID string `json:"guid"` + ID uint64 `json:"id"` + Labels []string `json:"labels"` + Name string `json:"name"` + Num uint64 `json:"num"` + RAM uint64 `json:"ram"` + Taints []string `json:"taints"` +} + +type K8SGroupList []K8SGroup + +type DetailedInfo struct { + ID uint64 `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` +} + +type DetailedInfoList []DetailedInfo + +type K8SRecord struct { + ACL ACLGroup `json:"ACL"` + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + BServiceID uint64 `json:"bserviceId"` + CIID uint64 `json:"ciId"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + ID uint64 `json:"id"` + K8CIName string `json:"k8ciName"` + K8SGroups K8SGroups `json:"k8sGroups"` + LBID uint64 `json:"lbId"` + Name string `json:"name"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` +} + +type K8SRecordList []K8SRecord + +type K8SGroups struct { + Masters MasterGroup `json:"masters"` + Workers K8SGroupList `json:"workers"` +} + +type MasterGroup struct { + CPU uint64 `json:"cpu"` + DetailedInfo DetailedInfoList `json:"detailedInfo"` + Disk uint64 `json:"disk"` + ID uint64 `json:"id"` + Name string `json:"name"` + Num uint64 `json:"num"` + RAM uint64 `json:"ram"` +} + +type ACLGroup struct { + AccountACL ACLList `json:"accountAcl"` + K8SACL ACLList `json:"k8sAcl"` + RGACL ACLList `json:"rgAcl"` +} + +type ACL struct { + Explicit bool `json:"explicit"` + GUID string `json:"guid"` + Right string `json:"right"` + Status string `json:"status"` + Type string `json:"type"` + UserGroupID string `json:"userGroupId"` +} + +type ACLList []ACL + +type K8SItem struct { + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + ACL []interface{} `json:"acl"` + BServiceID uint64 `json:"bserviceId"` + CIID uint64 `json:"ciId"` + Config interface{} `json:"config"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + Description string `json:"desc"` + ExtNetID uint64 `json:"extnetId"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LBID uint64 `json:"lbId"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + ServiceAccount ServiceAccount `json:"serviceAccount"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + VINSID uint64 `json:"vinsId"` + WorkersGroup K8SGroupList `json:"workersGroups"` +} + +type ServiceAccount struct { + GUID string `json:"guid"` + Password string `json:"password"` + Username string `json:"username"` +} + +type K8SList []K8SItem diff --git a/internal/service/cloudapi/k8s/node_subresource.go b/internal/service/cloudapi/k8s/node_subresource.go new file mode 100644 index 00000000..8790bcd6 --- /dev/null +++ b/internal/service/cloudapi/k8s/node_subresource.go @@ -0,0 +1,194 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators" +) + +func nodeMasterDefault() K8sNodeRecord { + return K8sNodeRecord{ + Num: 1, + Cpu: 2, + Ram: 2048, + Disk: 0, + } +} + +func nodeWorkerDefault() K8sNodeRecord { + return K8sNodeRecord{ + Num: 1, + Cpu: 1, + Ram: 1024, + Disk: 0, + } +} + +func parseDefaultNode(nodeList []interface{}) K8sNodeRecord { + node := nodeList[0].(map[string]interface{}) + + return K8sNodeRecord{ + Num: node["num"].(int), + Cpu: node["cpu"].(int), + Ram: node["ram"].(int), + Disk: node["disk"].(int), + SepID: node["sep_id"].(int), + SepPool: node["sep_pool"].(string), + } +} + +func mastersSchemaMake() map[string]*schema.Schema { + masters := masterGroupSchemaMake() + masters["num"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntInSlice([]int{1, 3, 5}), + Description: "Number of nodes to create. Can be either 1, 3 or 5", + } + masters["sep_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + } + masters["sep_pool"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + } + masters["cpu"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "Node CPU count.", + } + masters["ram"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + ValidateFunc: validation.All( + validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + validators.DivisibleBy(constants.RAM_DIVISIBILITY), + ), + Description: "Node RAM in MB.", + } + masters["disk"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "Node boot disk size in GB.", + } + + return masters +} + +func workersSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "num": { + Type: schema.TypeInt, + Required: true, + }, + "ram": { + Type: schema.TypeInt, + ValidateFunc: validation.All( + validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + validators.DivisibleBy(constants.RAM_DIVISIBILITY), + ), + Required: true, + }, + "cpu": { + Type: schema.TypeInt, + Required: true, + }, + "disk": { + Type: schema.TypeInt, + Required: true, + }, + "annotations": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: detailedInfoSchemaMake(), + }, + }, + "chipset": { + Type: schema.TypeString, + Optional: true, + Description: "Type of the emulated system.", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + }, + "sep_pool": { + Type: schema.TypeString, + Optional: true, + }, + } +} diff --git a/internal/service/cloudapi/k8s/old_schemas.go b/internal/service/cloudapi/k8s/old_schemas.go new file mode 100644 index 00000000..09db0a03 --- /dev/null +++ b/internal/service/cloudapi/k8s/old_schemas.go @@ -0,0 +1,396 @@ +package k8s + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceK8sCPSchemaV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the cluster.", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "Resource group ID that this instance belongs to.", + }, + "k8sci_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "ID of the k8s catalog item to base this instance on.", + }, + "network_plugin": { + Type: schema.TypeString, + Required: true, + Description: "Network plugin to be used", + ValidateFunc: validation.StringInSlice([]string{"flannel", "weavenet", "calico"}, true), + }, + "num": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.IntInSlice([]int{1, 3}), + Description: "Number of VMs to create. Can be either 1 or 3", + }, + "cpu": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Node CPU count.", + }, + "ram": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Node RAM in MB.", + }, + "disk": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Node boot disk size in GB.", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Storage Endpoint ID", + }, + "sep_pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Storage Endpoint Pool", + }, + "with_lb": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Create k8s with load balancer if true.", + }, + "extnet_only": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Use only selected ExtNet for infrastructure connections", + }, + // /4.4.0 + "cloud_init": { + Type: schema.TypeString, + Optional: true, + Description: "Meta data for working group computes, format YAML 'user_data': 1111", + }, + "join_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting.", + }, + "kube_proxy_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting.", + }, + "kubelet_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. insert a valid JSON string with all levels of nesting.", + }, + "cluster_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to define global settings and configurations for the entire cluster. It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. insert a valid JSON string with all levels of nesting.", + }, + "init_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting.", + }, + "additional_sans": { + Type: schema.TypeList, + Optional: true, + Description: "Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ha_mode": { + Type: schema.TypeBool, + Optional: true, + Description: "Use Highly Available schema for LB deploy", + }, + "lb_sysctl_params": { + Type: schema.TypeString, + Optional: true, + Description: "Custom sysctl values for Load Balancer instance. Applied on boot.", + }, + "oidc_cert": { + Type: schema.TypeString, + Optional: true, + Description: "insert ssl certificate in x509 pem format", + }, + //// + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + //ForceNew: true, + Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Description: "Text description of this instance.", + }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Start k8s cluster.", + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "natable_vins_ip": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "master_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Master group ID.", + }, + "master_name": { + Type: schema.TypeString, + Computed: true, + Description: "Master group name.", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "k8s_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "rg_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "bservice_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_ci_name": { + Type: schema.TypeString, + Computed: true, + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lb_ip": { + Type: schema.TypeString, + Computed: true, + Description: "IP address of default load balancer.", + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "kubeconfig": { + Type: schema.TypeString, + Computed: true, + Description: "Kubeconfig for cluster access.", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of default vins for this instace.", + }, + }, + } +} diff --git a/internal/service/cloudapi/k8s/resource_check_input_values.go b/internal/service/cloudapi/k8s/resource_check_input_values.go new file mode 100644 index 00000000..fe79edaa --- /dev/null +++ b/internal/service/cloudapi/k8s/resource_check_input_values.go @@ -0,0 +1,69 @@ +package k8s + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8ci" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func existK8sID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + k8sID := uint64(d.Get("k8s_id").(int)) + req := k8s.ListRequest{} + + k8sList, err := c.CloudAPI().K8S().List(ctx, req) + if err != nil { + return false, err + } + + return len(k8sList.FilterByID(k8sID).Data) != 0, nil +} + +func existK8sCIID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + k8sciID := uint64(d.Get("k8sci_id").(int)) + req := k8ci.ListRequest{} + + k8sciList, err := c.CloudAPI().K8CI().List(ctx, req) + if err != nil { + return false, err + } + + return len(k8sciList.FilterByID(k8sciID).Data) != 0, nil +} + +func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + rgID := uint64(d.Get("rg_id").(int)) + req := rg.ListRequest{} + + rgList, err := c.CloudAPI().RG().List(ctx, req) + if err != nil { + return false, err + } + + return len(rgList.FilterByID(rgID).Data) != 0, nil +} + +func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + extNetID := uint64(d.Get("extnet_id").(int)) + + if extNetID == 0 { + return true, nil + } + + c := m.(*controller.ControllerCfg) + req := extnet.ListRequest{} + + extNetList, err := c.CloudAPI().ExtNet().List(ctx, req) + if err != nil { + return false, err + } + + return len(extNetList.FilterByID(extNetID).Data) != 0, nil +} diff --git a/internal/service/cloudapi/k8s/resource_k8s.go b/internal/service/cloudapi/k8s/resource_k8s.go new file mode 100644 index 00000000..3582643f --- /dev/null +++ b/internal/service/cloudapi/k8s/resource_k8s.go @@ -0,0 +1,938 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sCreate: called with name %s, rg %d", d.Get("name").(string), d.Get("rg_id").(int)) + + haveRGID, err := existRGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveRGID { + return diag.Errorf("resourceK8sCreate: can't create k8s cluster because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + + haveK8sciID, err := existK8sCIID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveK8sciID { + return diag.Errorf("resourceK8sCreate: can't create k8s cluster because K8sCIID %d is not allowed or does not exist", d.Get("k8sci_id").(int)) + } + + if _, ok := d.GetOk("extnet_id"); ok { + haveExtNetID, err := existExtNetID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveExtNetID { + return diag.Errorf("resourceK8sCreate: can't create k8s cluster because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int)) + } + } + + c := m.(*controller.ControllerCfg) + createReq := k8s.CreateRequest{} + + createReq.Name = d.Get("name").(string) + createReq.RGID = uint64(d.Get("rg_id").(int)) + createReq.K8SCIID = uint64(d.Get("k8sci_id").(int)) + createReq.WorkerGroupName = d.Get("wg_name").(string) + createReq.NetworkPlugin = d.Get("network_plugin").(string) + createReq.StoragePolicyID = uint64(d.Get("storage_policy_id").(int)) + + var masterNode K8sNodeRecord + if masters, ok := d.GetOk("masters"); ok { + masterNode = parseDefaultNode(masters.([]interface{})) + } else { + masterNode = nodeMasterDefault() + } + createReq.MasterNum = uint(masterNode.Num) + createReq.MasterCPU = uint(masterNode.Cpu) + createReq.MasterRAM = uint64(masterNode.Ram) + createReq.MasterDisk = uint(masterNode.Disk) + createReq.MasterSEPID = uint64(masterNode.SepID) + createReq.MasterSEPPool = masterNode.SepPool + + var workerNode K8sNodeRecord + if workers, ok := d.GetOk("workers"); ok { + workerNode = parseDefaultNode(workers.([]interface{})) + } else { + workerNode = nodeWorkerDefault() + } + + createReq.WorkerNum = uint(workerNode.Num) + createReq.WorkerCPU = uint(workerNode.Cpu) + createReq.WorkerRAM = uint64(workerNode.Ram) + createReq.WorkerDisk = uint(workerNode.Disk) + createReq.WorkerSEPID = uint64(workerNode.SepID) + createReq.WorkerSEPPool = workerNode.SepPool + + if labels, ok := d.GetOk("labels"); ok { + labels := labels.([]interface{}) + for _, label := range labels { + if !strings.HasPrefix(label.(string), "workersGroupName") { + createReq.Labels = append(createReq.Labels, label.(string)) + } + } + } + + if taints, ok := d.GetOk("taints"); ok { + taints := taints.([]interface{}) + for _, taint := range taints { + createReq.Taints = append(createReq.Taints, taint.(string)) + } + } + + if annotations, ok := d.GetOk("annotations"); ok { + annotations := annotations.([]interface{}) + for _, annotation := range annotations { + createReq.Annotations = append(createReq.Annotations, annotation.(string)) + } + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + createReq.ZoneID = uint64(zoneID.(int)) + } + + createReq.WithLB = d.Get("with_lb").(bool) + + ///4.4.0 + createReq.HighlyAvailable = d.Get("ha_mode").(bool) + + if additionalSans, ok := d.GetOk("additional_sans"); ok { + addSans := additionalSans.([]interface{}) + resSans := make([]string, 0) + for _, san := range addSans { + resSans = append(resSans, san.(string)) + } + + createReq.AdditionalSANs = resSans + } + + if clusterConfig, ok := d.GetOk("cluster_config"); ok { + createReq.ClusterConfiguration = clusterConfig.(string) + } + + if kubeletConfig, ok := d.GetOk("kubelet_config"); ok { + createReq.KubeletConfiguration = kubeletConfig.(string) + } + + if kubeProxyConfig, ok := d.GetOk("kube_proxy_config"); ok { + createReq.KubeProxyConfiguration = kubeProxyConfig.(string) + } + + if joinConfig, ok := d.GetOk("join_config"); ok { + createReq.JoinConfiguration = joinConfig.(string) + } + + if cloudInit, ok := d.GetOk("cloud_init"); ok { + createReq.UserData = cloudInit.(string) + } + + if initConfig, ok := d.GetOk("init_config"); ok { + createReq.InitConfiguration = initConfig.(string) + } + + if lbSysctlParams, ok := d.GetOk("lb_sysctl_params"); ok { + syscrlSliceMaps := lbSysctlParams.([]interface{}) + res := make([]map[string]interface{}, 0, len(syscrlSliceMaps)) + for _, syscrlMap := range syscrlSliceMaps { + tempMap := make(map[string]interface{}) + for k, v := range syscrlMap.(map[string]interface{}) { + if intVal, err := strconv.Atoi(v.(string)); err == nil { + tempMap[k] = intVal + continue + } + tempMap[k] = v.(string) + } + res = append(res, tempMap) + } + createReq.LbSysctlParams = res + } + + if oidcCertificate, ok := d.GetOk("oidc_cert"); ok { + createReq.OidcCertificate = oidcCertificate.(string) + } + + /// + + if chipset, ok := d.GetOk("chipset"); ok { + createReq.Chipset = chipset.(string) + } + + createReq.ExtNetOnly = d.Get("extnet_only").(bool) + + if extNet, ok := d.GetOk("extnet_id"); ok { + createReq.ExtNetID = uint64(extNet.(int)) + } else { + createReq.ExtNetID = 0 + } + + if vins, ok := d.GetOk("vins_id"); ok { + createReq.VinsId = uint64(vins.(int)) + } else { + createReq.VinsId = 0 + } + + if desc, ok := d.GetOk("desc"); ok { + createReq.Description = desc.(string) + } + + resp, err := c.CloudAPI().K8S().Create(ctx, createReq) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(resp, `"`), + } + + for { + task, err := c.CloudAPI().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceK8sCreate: instance creating - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot create k8s instance: %v", task.Error)) + } + + id, err := task.Result.ID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(id)) + break + } + + time.Sleep(time.Second * 20) + } + + return resourceK8sRead(ctx, d, m) +} + +func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + + hasChanged := false + + switch cluster.Status { + case status.Modeled: + return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", cluster.Status) + case status.Creating: + case status.Created: + case status.Deleting: + case status.Deleted: + // id, _ := strconv.ParseUint(d.Id(), 10, 64) + // restoreReq := k8s.RestoreRequest{ + // K8SID: id, + // } + + // _, err := c.CloudAPI().K8S().Restore(ctx, restoreReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // enableReq := k8s.DisableEnableRequest{ + // K8SID: id, + // } + + // _, err = c.CloudAPI().K8S().Enable(ctx, enableReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // hasChanged = true + case status.Destroying: + return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status) + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceK8sCreate(ctx, d, m) + case status.Enabling: + case status.Enabled: + case status.Disabling: + case status.Disabled: + log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", cluster.Status) + case status.Restoring: + } + + if hasChanged { + cluster, err = utilityK8sCheckPresence(ctx, d, m) + if cluster == nil { + d.SetId("") + if err != nil { + return diag.FromErr(err) + } + return nil + } + } + + if d.Get("start").(bool) { + if cluster.TechStatus == "STOPPED" { + req := k8s.StartRequest{ + K8SID: cluster.ID, + } + _, err := c.CloudAPI().K8S().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + k8sList, err := utilityK8sListForResourceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + curK8s := k8s.ItemK8SCluster{} + for _, k8sCluster := range k8sList.Data { + if k8sCluster.ID == cluster.ID { + curK8s = k8sCluster + } + } + if curK8s.ID == 0 { + return diag.Errorf("Cluster with id %d not found", cluster.ID) + } + + d.Set("vins_id", curK8s.VINSID) + + masterComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Masters.DetailedInfo)) + workersComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Workers)) + for _, masterNode := range cluster.K8SGroups.Masters.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, masterNode.ID) + if err != nil { + return diag.FromErr(err) + } + masterComputeList = append(masterComputeList, *compute) + } + for _, worker := range cluster.K8SGroups.Workers { + for _, info := range worker.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) + if err != nil { + return diag.FromErr(err) + } + workersComputeList = append(workersComputeList, *compute) + } + } + + flattenResourceK8s(d, *cluster, masterComputeList, workersComputeList) + + if d.Get("with_lb").(bool) || cluster.LBID != 0 { + lbGetReq := lb.GetRequest{ + LBID: cluster.LBID, + } + + lb, err := c.CloudAPI().LB().Get(ctx, lbGetReq) + if err != nil { + return diag.FromErr(err) + } + + d.Set("extnet_id", lb.ExtNetID) + d.Set("lb_ip", lb.PrimaryNode.FrontendIP) + } + + kubeconfigReq := k8s.GetConfigRequest{ + K8SID: cluster.ID, + } + + kubeconfig, err := c.CloudAPI().K8S().GetConfig(ctx, kubeconfigReq) + if err != nil { + log.Warnf("could not get kubeconfig: %v", err) + } + + d.Set("kubeconfig", kubeconfig) + + return nil +} + +func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sUpdate: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + + haveRGID, err := existRGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveRGID { + return diag.Errorf("resourceK8sUpdate: can't update k8s cluster because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + + haveK8sciID, err := existK8sCIID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveK8sciID { + return diag.Errorf("resourceK8sUpdate: can't update k8s cluster because K8sCIID %d is not allowed or does not exist", d.Get("k8sci_id").(int)) + } + + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + hasChanged := false + + switch cluster.Status { + case status.Modeled: + return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", cluster.Status) + case status.Creating: + case status.Created: + case status.Deleting: + case status.Deleted: + id, _ := strconv.ParseUint(d.Id(), 10, 64) + restoreReq := k8s.RestoreRequest{ + K8SID: id, + } + + _, err := c.CloudAPI().K8S().Restore(ctx, restoreReq) + if err != nil { + return diag.FromErr(err) + } + + enableReq := k8s.DisableEnableRequest{ + K8SID: id, + } + + _, err = c.CloudAPI().K8S().Enable(ctx, enableReq) + if err != nil { + return diag.FromErr(err) + } + + hasChanged = true + case status.Destroying: + return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status) + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceK8sCreate(ctx, d, m) + case status.Enabling: + case status.Enabled: + case status.Disabling: + case status.Disabled: + log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", cluster.Status) + case status.Restoring: + } + + if hasChanged { + cluster, err = utilityK8sCheckPresence(ctx, d, m) + if cluster == nil { + d.SetId("") + if err != nil { + return diag.FromErr(err) + } + return nil + } + } + + updateReq := k8s.UpdateRequest{K8SID: cluster.ID} + doBasicUpdate := false + + if d.HasChange("name") { + updateReq.Name = d.Get("name").(string) + doBasicUpdate = true + } + + if d.HasChange("desc") { + updateReq.Description = d.Get("desc").(string) + doBasicUpdate = true + } + + if doBasicUpdate { + _, err := c.CloudAPI().K8S().Update(ctx, updateReq) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("workers") { + err := handleWorkersChange(ctx, d, c, cluster) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("zone_id") { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + zoneID := uint64(d.Get("zone_id").(int)) + + start := d.Get("start").(bool) + + if start { + stopReq := k8s.StopRequest{ + K8SID: id, + } + + _, err := c.CloudAPI().K8S().Stop(ctx, stopReq) + if err != nil { + return diag.FromErr(err) + } + } + + req := k8s.MigrateToZoneRequest{ + K8SID: id, + ZoneID: zoneID, + } + + _, err := c.CloudAPI().K8S().MigrateToZone(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + if start { + startReq := k8s.StartRequest{ + K8SID: id, + } + + _, err = c.CloudAPI().K8S().Start(ctx, startReq) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("start") { + if d.Get("start").(bool) { + if cluster.TechStatus == "STOPPED" { + req := k8s.StartRequest{ + K8SID: cluster.ID, + } + _, err := c.CloudAPI().K8S().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } else { + if cluster.TechStatus == "STARTED" { + req := k8s.StopRequest{ + K8SID: cluster.ID, + } + _, err := c.CloudAPI().K8S().Stop(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + if d.HasChange("lb_sysctl_params") && d.Get("with_lb").(bool) { + lbSysctlParams := d.Get("lb_sysctl_params").([]interface{}) + res := make([]map[string]interface{}, 0, len(lbSysctlParams)) + for _, syscrlMap := range lbSysctlParams { + tempMap := make(map[string]interface{}) + for k, v := range syscrlMap.(map[string]interface{}) { + if intVal, err := strconv.Atoi(v.(string)); err == nil { + tempMap[k] = intVal + continue + } + tempMap[k] = v.(string) + } + res = append(res, tempMap) + } + if len(res) > 0 { + req := lb.UpdateSysctParamsRequest{ + LBID: cluster.LBID, + SysctlParams: res, + } + _, err := c.CloudAPI().LB().UpdateSysctlParams(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + return resourceK8sRead(ctx, d, m) +} + +func resourceK8sDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("resourceK8sDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) + + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + req := k8s.DeleteRequest{K8SID: cluster.ID} + + if val, ok := d.GetOk("permanently"); ok { + req.Permanently = val.(bool) + } + + c := m.(*controller.ControllerCfg) + + _, err = c.CloudAPI().K8S().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +func resourceK8sSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the cluster.", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "Resource group ID that this instance belongs to.", + }, + "k8sci_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "ID of the k8s catalog item to base this instance on.", + }, + "wg_name": { + Type: schema.TypeString, + Required: true, + Description: "Name for first worker group created with cluster.", + }, + "network_plugin": { + Type: schema.TypeString, + Required: true, + Description: "Network plugin to be used", + ValidateFunc: validation.StringInSlice([]string{"flannel", "weavenet", "calico"}, true), + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the storage policy", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of the zone to put the cluster into.", + }, + "labels": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "taints": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "annotations": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "masters": { + Type: schema.TypeList, + Optional: true, + Computed: true, + //ForceNew: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: mastersSchemaMake(), + }, + Description: "Master node(s) configuration.", + }, + "workers": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: workersSchemaMake(), + }, + Description: "Worker node(s) configuration.", + }, + "with_lb": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Create k8s with load balancer if true.", + }, + "extnet_only": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Use only selected ExtNet for infrastructure connections", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + //ForceNew: true, + Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Determines if cluster should be destroyed", + }, + + ///4.4.0 + "cloud_init": { + Type: schema.TypeString, + Optional: true, + Description: "Meta data for working group computes, format YAML 'user_data': 1111", + }, + "join_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting.", + }, + "kube_proxy_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting.", + }, + "kubelet_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. insert a valid JSON string with all levels of nesting.", + }, + "cluster_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to define global settings and configurations for the entire cluster. It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. insert a valid JSON string with all levels of nesting.", + }, + "init_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting.", + }, + "additional_sans": { + Type: schema.TypeList, + Optional: true, + Description: "Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ha_mode": { + Type: schema.TypeBool, + Optional: true, + Description: "Use Highly Available schema for LB deploy", + }, + "lb_sysctl_params": { + Type: schema.TypeList, + Optional: true, + Description: "Custom sysctl values for Load Balancer instance. Applied on boot.", + Elem: &schema.Schema{ + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + "oidc_cert": { + Type: schema.TypeString, + Optional: true, + Description: "insert ssl certificate in x509 pem format", + }, + + "chipset": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"Q35", "i440fx"}, false), + Default: "Q35", + Description: "Type of the emulated system. Possible values: i440fx, Q35. Default: Q35", + }, + + "desc": { + Type: schema.TypeString, + Optional: true, + Description: "Text description of this instance.", + }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Start k8s cluster", + }, + + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclGroupSchemaMake(), + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "bservice_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_ci_name": { + Type: schema.TypeString, + Computed: true, + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lb_ip": { + Type: schema.TypeString, + Computed: true, + Description: "IP address of default load balancer.", + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "default_wg_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of default workers group for this instace.", + }, + "kubeconfig": { + Type: schema.TypeString, + Computed: true, + Description: "Kubeconfig for cluster access.", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of default vins for this instace.", + }, + } +} + +func ResourceK8s() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceK8sCreate, + ReadContext: resourceK8sRead, + UpdateContext: resourceK8sUpdate, + DeleteContext: resourceK8sDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout30m, + Read: &constants.Timeout600s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceK8sSchemaMake(), + } +} diff --git a/internal/service/cloudapi/k8s/resource_k8s_cp.go b/internal/service/cloudapi/k8s/resource_k8s_cp.go new file mode 100644 index 00000000..8489fc16 --- /dev/null +++ b/internal/service/cloudapi/k8s/resource_k8s_cp.go @@ -0,0 +1,966 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators" +) + +func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sControlPlaneCreate: called with name %s, rg %d", d.Get("name").(string), d.Get("rg_id").(int)) + + haveRGID, err := existRGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveRGID { + return diag.Errorf("resourceK8sCreate: can't create k8s cluster because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + + haveK8sciID, err := existK8sCIID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveK8sciID { + return diag.Errorf("resourceK8sCreate: can't create k8s cluster because K8sCIID %d is not allowed or does not exist", d.Get("k8sci_id").(int)) + } + + if _, ok := d.GetOk("extnet_id"); ok { + haveExtNetID, err := existExtNetID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveExtNetID { + return diag.Errorf("resourceK8sCreate: can't create k8s cluster because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int)) + } + } + + c := m.(*controller.ControllerCfg) + createReq := k8s.CreateRequest{} + + createReq.Name = d.Get("name").(string) + createReq.RGID = uint64(d.Get("rg_id").(int)) + createReq.K8SCIID = uint64(d.Get("k8sci_id").(int)) + createReq.WorkerGroupName = "temp" + createReq.NetworkPlugin = d.Get("network_plugin").(string) + createReq.StoragePolicyID = uint64(d.Get("storage_policy_id").(int)) + + if zoneID, ok := d.GetOk("zone_id"); ok { + createReq.ZoneID = uint64(zoneID.(int)) + } + + if num, ok := d.GetOk("num"); ok { + createReq.MasterNum = uint(num.(int)) + } else { + createReq.MasterNum = 1 + } + + if cpu, ok := d.GetOk("cpu"); ok { + createReq.MasterCPU = uint(cpu.(int)) + } else { + createReq.MasterCPU = 2 + } + + if ram, ok := d.GetOk("ram"); ok { + createReq.MasterRAM = uint64(ram.(int)) + } else { + createReq.MasterRAM = 2048 + } + + if disk, ok := d.GetOk("disk"); ok { + createReq.MasterDisk = uint(disk.(int)) + } else { + createReq.MasterDisk = 0 + } + + if sepId, ok := d.GetOk("sep_id"); ok { + createReq.MasterSEPID = uint64(sepId.(int)) + } + + if chipset, ok := d.GetOk("chipset"); ok { + createReq.Chipset = chipset.(string) + } + + if sepPool, ok := d.GetOk("sep_pool"); ok { + createReq.MasterSEPPool = sepPool.(string) + } + + createReq.WithLB = d.Get("with_lb").(bool) + + ///4.4.0 + createReq.HighlyAvailable = d.Get("ha_mode").(bool) + + if additionalSans, ok := d.GetOk("additional_sans"); ok { + addSans := additionalSans.([]interface{}) + resSans := make([]string, 0) + for _, san := range addSans { + resSans = append(resSans, san.(string)) + } + + createReq.AdditionalSANs = resSans + } + + if clusterConfig, ok := d.GetOk("cluster_config"); ok { + createReq.ClusterConfiguration = clusterConfig.(string) + } + + if kubeletConfig, ok := d.GetOk("kubelet_config"); ok { + createReq.KubeletConfiguration = kubeletConfig.(string) + } + + if kubeProxyConfig, ok := d.GetOk("kube_proxy_config"); ok { + createReq.KubeProxyConfiguration = kubeProxyConfig.(string) + } + + if joinConfig, ok := d.GetOk("join_config"); ok { + createReq.JoinConfiguration = joinConfig.(string) + } + + // if cloudInit, ok := d.GetOk("cloud_init"); ok { + // createReq.UserData = cloudInit.(string) + // } + + if initConfig, ok := d.GetOk("init_config"); ok { + createReq.InitConfiguration = initConfig.(string) + } + + if lbSysctlParams, ok := d.GetOk("lb_sysctl_params"); ok { + syscrlSliceMaps := lbSysctlParams.([]interface{}) + res := make([]map[string]interface{}, 0, len(syscrlSliceMaps)) + for _, syscrlMap := range syscrlSliceMaps { + tempMap := make(map[string]interface{}) + for k, v := range syscrlMap.(map[string]interface{}) { + if intVal, err := strconv.Atoi(v.(string)); err == nil { + tempMap[k] = intVal + continue + } + tempMap[k] = v.(string) + } + res = append(res, tempMap) + } + createReq.LbSysctlParams = res + } + + if oidcCertificate, ok := d.GetOk("oidc_cert"); ok { + createReq.OidcCertificate = oidcCertificate.(string) + log.Debug(createReq.OidcCertificate) + } + + /// + + createReq.ExtNetOnly = d.Get("extnet_only").(bool) + + if extNet, ok := d.GetOk("extnet_id"); ok { + createReq.ExtNetID = uint64(extNet.(int)) + } else { + createReq.ExtNetID = 0 + } + + if vins, ok := d.GetOk("vins_id"); ok { + createReq.VinsId = uint64(vins.(int)) + } else { + createReq.VinsId = 0 + } + + if desc, ok := d.GetOk("desc"); ok { + createReq.Description = desc.(string) + } + + resp, err := c.CloudAPI().K8S().Create(ctx, createReq) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(resp, `"`), + } + + for { + task, err := c.CloudAPI().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceK8sControlPlaneCreate: instance creating - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot create k8s instance: %v", task.Error)) + } + + id, err := task.Result.ID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(id)) + break + } + + time.Sleep(time.Second * 20) + } + + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + delWGReq := k8s.WorkersGroupDeleteRequest{ + K8SID: cluster.ID, + WorkersGroupID: cluster.K8SGroups.Workers[0].ID, + } + + _, err = c.CloudAPI().K8S().WorkersGroupDelete(ctx, delWGReq) + if err != nil { + return diag.FromErr(err) + } + + return resourceK8sCPRead(ctx, d, m) +} + +func resourceK8sCPRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + + hasChanged := false + + switch cluster.Status { + case status.Modeled: + return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", cluster.Status) + case status.Creating: + case status.Created: + case status.Deleting: + case status.Deleted: + // id, _ := strconv.ParseUint(d.Id(), 10, 64) + // restoreReq := k8s.RestoreRequest{ + // K8SID: id, + // } + + // _, err := c.CloudAPI().K8S().Restore(ctx, restoreReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // enableReq := k8s.DisableEnableRequest{ + // K8SID: id, + // } + + // _, err = c.CloudAPI().K8S().Enable(ctx, enableReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // hasChanged = true + case status.Destroying: + return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status) + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceK8sCreate(ctx, d, m) + case status.Enabling: + case status.Enabled: + case status.Disabling: + case status.Disabled: + log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", cluster.Status) + case status.Restoring: + } + + if hasChanged { + cluster, err = utilityK8sCheckPresence(ctx, d, m) + if cluster == nil { + d.SetId("") + if err != nil { + return diag.FromErr(err) + } + return nil + } + } + + if d.Get("start").(bool) { + if cluster.TechStatus == "STOPPED" { + req := k8s.StartRequest{ + K8SID: cluster.ID, + } + _, err := c.CloudAPI().K8S().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + k8sList, err := utilityK8sListForResourceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + curK8s := k8s.ItemK8SCluster{} + for _, k8sCluster := range k8sList.Data { + if k8sCluster.ID == cluster.ID { + curK8s = k8sCluster + } + } + if curK8s.ID == 0 { + return diag.Errorf("Cluster with id %d not found", cluster.ID) + } + + d.Set("vins_id", curK8s.VINSID) + + masterComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Masters.DetailedInfo)) + for _, masterNode := range cluster.K8SGroups.Masters.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, masterNode.ID) + if err != nil { + return diag.FromErr(err) + } + masterComputeList = append(masterComputeList, *compute) + } + + var warnings dc.Warnings + + if _, ok := d.GetOk("k8s_id"); !ok { + for _, worker := range cluster.K8SGroups.Workers { + err := fmt.Errorf("found worker-group with ID %d. Make sure to import it to decort_k8s_wg resource if you wish to manage it", worker.ID) + warnings.Add(err) + } + } + + flattenResourceK8sCP(d, *cluster, masterComputeList) + + lbGetReq := lb.GetRequest{ + LBID: cluster.LBID, + } + + if d.Get("with_lb").(bool) || cluster.LBID != 0 { + lb, err := c.CloudAPI().LB().Get(ctx, lbGetReq) + if err != nil { + return diag.FromErr(err) + } + + d.Set("extnet_id", lb.ExtNetID) + d.Set("lb_ip", lb.PrimaryNode.FrontendIP) + } + + kubeconfigReq := k8s.GetConfigRequest{ + K8SID: cluster.ID, + } + + kubeconfig, err := c.CloudAPI().K8S().GetConfig(ctx, kubeconfigReq) + if err != nil { + log.Warnf("could not get kubeconfig: %v", err) + } + + d.Set("kubeconfig", kubeconfig) + + return warnings.Get() +} + +func resourceK8sCPUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sControlPlaneUpdate: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + + haveRGID, err := existRGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveRGID { + return diag.Errorf("resourceK8sUpdate: can't update k8s cluster because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + + haveK8sciID, err := existK8sCIID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveK8sciID { + return diag.Errorf("resourceK8sUpdate: can't update k8s cluster because K8sCIID %d is not allowed or does not exist", d.Get("k8sci_id").(int)) + } + + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + hasChanged := false + + switch cluster.Status { + case status.Modeled: + return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", cluster.Status) + case status.Creating: + case status.Created: + case status.Deleting: + case status.Deleted: + id, _ := strconv.ParseUint(d.Id(), 10, 64) + restoreReq := k8s.RestoreRequest{ + K8SID: id, + } + + _, err := c.CloudAPI().K8S().Restore(ctx, restoreReq) + if err != nil { + return diag.FromErr(err) + } + + enableReq := k8s.DisableEnableRequest{ + K8SID: id, + } + + _, err = c.CloudAPI().K8S().Enable(ctx, enableReq) + if err != nil { + return diag.FromErr(err) + } + + hasChanged = true + case status.Destroying: + return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status) + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceK8sCreate(ctx, d, m) + case status.Enabling: + case status.Enabled: + case status.Disabling: + case status.Disabled: + log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", cluster.Status) + case status.Restoring: + } + + if hasChanged { + cluster, err = utilityK8sCheckPresence(ctx, d, m) + if cluster == nil { + d.SetId("") + if err != nil { + return diag.FromErr(err) + } + return nil + } + } + + updateReq := k8s.UpdateRequest{K8SID: cluster.ID} + doBasicUpdate := false + + if d.HasChange("name") { + updateReq.Name = d.Get("name").(string) + doBasicUpdate = true + } + + if d.HasChange("desc") { + updateReq.Description = d.Get("desc").(string) + doBasicUpdate = true + } + + if doBasicUpdate { + _, err := c.CloudAPI().K8S().Update(ctx, updateReq) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("start") { + if d.Get("start").(bool) { + if cluster.TechStatus == "STOPPED" { + req := k8s.StartRequest{ + K8SID: cluster.ID, + } + _, err := c.CloudAPI().K8S().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } else { + if cluster.TechStatus == "STARTED" { + req := k8s.StopRequest{ + K8SID: cluster.ID, + } + _, err := c.CloudAPI().K8S().Stop(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + if d.HasChange("zone_id") { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + zoneID := uint64(d.Get("zone_id").(int)) + + start := d.Get("start").(bool) + + if start { + stopReq := k8s.StopRequest{ + K8SID: id, + } + + _, err := c.CloudAPI().K8S().Stop(ctx, stopReq) + if err != nil { + return diag.FromErr(err) + } + } + + req := k8s.MigrateToZoneRequest{ + K8SID: id, + ZoneID: zoneID, + } + + _, err := c.CloudAPI().K8S().MigrateToZone(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + if start { + startReq := k8s.StartRequest{ + K8SID: id, + } + + _, err := c.CloudAPI().K8S().Start(ctx, startReq) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("num") { + oldVal, newVal := d.GetChange("num") + + if oldVal.(int) > newVal.(int) { + ids := make([]uint64, 0) + for i := oldVal.(int) - 1; i >= newVal.(int); i-- { + id := cluster.K8SGroups.Masters.DetailedInfo[i].ID + ids = append(ids, id) + } + + req := k8s.DeleteMasterFromGroupRequest{ + K8SID: cluster.ID, + MasterGroupID: cluster.K8SGroups.Masters.ID, + MasterIDs: ids, + } + + _, err := c.CloudAPI().K8S().DeleteMasterFromGroup(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("lb_sysctl_params") && d.Get("with_lb").(bool) { + lbSysctlParams := d.Get("lb_sysctl_params").([]interface{}) + res := make([]map[string]interface{}, 0, len(lbSysctlParams)) + for _, syscrlMap := range lbSysctlParams { + tempMap := make(map[string]interface{}) + for k, v := range syscrlMap.(map[string]interface{}) { + if intVal, err := strconv.Atoi(v.(string)); err == nil { + tempMap[k] = intVal + continue + } + tempMap[k] = v.(string) + } + res = append(res, tempMap) + } + if len(res) > 0 { + req := lb.UpdateSysctParamsRequest{ + LBID: cluster.LBID, + SysctlParams: res, + } + _, err := c.CloudAPI().LB().UpdateSysctlParams(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + return resourceK8sCPRead(ctx, d, m) +} + +func resourceK8sCPDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("resourceK8sControlPlaneDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) + + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + req := k8s.DeleteRequest{K8SID: cluster.ID} + + if val, ok := d.GetOk("permanently"); ok { + req.Permanently = val.(bool) + } + + c := m.(*controller.ControllerCfg) + + _, err = c.CloudAPI().K8S().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceK8sCPSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the cluster.", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "Resource group ID that this instance belongs to.", + }, + "k8sci_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "ID of the k8s catalog item to base this instance on.", + }, + "network_plugin": { + Type: schema.TypeString, + Required: true, + Description: "Network plugin to be used", + ValidateFunc: validation.StringInSlice([]string{"flannel", "weavenet", "calico"}, true), + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the storage policy", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of the zone to put the cluster into.", + }, + "num": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.IntInSlice([]int{1, 3, 5}), + Description: "Number of VMs to create. Can be either 1, 3 or 5", + }, + "cpu": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Node CPU count.", + }, + "ram": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.All( + validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + validators.DivisibleBy(constants.RAM_DIVISIBILITY), + ), + Description: "Node RAM in MB.", + }, + "chipset": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"Q35", "i440fx"}, false), + Default: "Q35", + Description: "Type of the emulated system. Possible values: i440fx, Q35. Default: Q35", + }, + "disk": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Node boot disk size in GB.", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Storage Endpoint ID", + }, + "sep_pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Storage Endpoint Pool", + }, + "with_lb": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Create k8s with load balancer if true.", + }, + "extnet_only": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Use only selected ExtNet for infrastructure connections", + }, + "join_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting.", + }, + "kube_proxy_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting.", + }, + "kubelet_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. insert a valid JSON string with all levels of nesting.", + }, + "cluster_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to define global settings and configurations for the entire cluster. It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. insert a valid JSON string with all levels of nesting.", + }, + "init_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting.", + }, + "additional_sans": { + Type: schema.TypeList, + Optional: true, + Description: "Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ha_mode": { + Type: schema.TypeBool, + Optional: true, + Description: "Use Highly Available schema for LB deploy", + }, + "lb_sysctl_params": { + Type: schema.TypeList, + Optional: true, + Description: "Custom sysctl values for Load Balancer instance. Applied on boot.", + Elem: &schema.Schema{ + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + "oidc_cert": { + Type: schema.TypeString, + Optional: true, + Description: "insert ssl certificate in x509 pem format", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + //ForceNew: true, + Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Description: "Text description of this instance.", + }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Start k8s cluster.", + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: detailedInfoSchemaMake(), + }, + }, + "master_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Master group ID.", + }, + "master_name": { + Type: schema.TypeString, + Computed: true, + Description: "Master group name.", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Determines if cluster should be destroyed", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclGroupSchemaMake(), + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "bservice_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_ci_name": { + Type: schema.TypeString, + Computed: true, + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lb_ip": { + Type: schema.TypeString, + Computed: true, + Description: "IP address of default load balancer.", + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "kubeconfig": { + Type: schema.TypeString, + Computed: true, + Description: "Kubeconfig for cluster access.", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of default vins for this instace.", + }, + } +} + +func ResourceK8sCP() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceK8sCPCreate, + ReadContext: resourceK8sCPRead, + UpdateContext: resourceK8sCPUpdate, + DeleteContext: resourceK8sCPDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout30m, + Read: &constants.Timeout600s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceK8sCPSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceK8sCPSchemaV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceK8sCPStateUpgradeV1, + Version: 1, + }, + }, + } +} diff --git a/internal/service/cloudapi/k8s/resource_k8s_wg.go b/internal/service/cloudapi/k8s/resource_k8s_wg.go new file mode 100644 index 00000000..e6d6c43d --- /dev/null +++ b/internal/service/cloudapi/k8s/resource_k8s_wg.go @@ -0,0 +1,406 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators" +) + +func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sWgCreate: called with k8s id %d", d.Get("k8s_id").(int)) + + haveK8sID, err := existK8sID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveK8sID { + return diag.Errorf("resourceK8sWgCreate: can't create k8s cluster because K8sID %d is not allowed or does not exist", d.Get("k8s_id").(int)) + } + + c := m.(*controller.ControllerCfg) + req := k8s.WorkersGroupAddRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + Name: d.Get("name").(string), + WorkerNum: uint64(d.Get("num").(int)), + WorkerCPU: uint64(d.Get("cpu").(int)), + WorkerRAM: uint64(d.Get("ram").(int)), + WorkerSEPID: uint64(d.Get("worker_sep_id").(int)), + WorkerSEPPool: d.Get("worker_sep_pool").(string), + Chipset: d.Get("chipset").(string), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + labels, _ := d.Get("labels").([]interface{}) + for _, label := range labels { + if !strings.HasPrefix(label.(string), "workersGroupName") { + req.Labels = append(req.Labels, label.(string)) + } + } + + annotations, _ := d.Get("annotations").([]interface{}) + for _, annotation := range annotations { + req.Annotations = append(req.Annotations, annotation.(string)) + } + + taints, _ := d.Get("taints").([]interface{}) + for _, taint := range taints { + req.Taints = append(req.Taints, taint.(string)) + } + + if d.Get("disk") == nil { + req.WorkerDisk = 0 + } else { + req.WorkerDisk = uint64(d.Get("disk").(int)) + } + + if cloudInit, ok := d.GetOk("cloud_init"); ok { + req.UserData = cloudInit.(string) + } + + resp, err := c.CloudAPI().K8S().WorkersGroupAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(resp, `"`), + } + + for { + task, err := c.CloudAPI().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceK8sWgCreate: instance creating - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot create k8s wg instance: %v", task.Error)) + } + + id, err := task.Result.ID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(fmt.Sprint(d.Get("k8s_id").(int), "#", strconv.Itoa(id))) + break + } + + time.Sleep(time.Second * 20) + } + + return resourceK8sWgRead(ctx, d, m) +} + +func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sWgRead: called with %v", d.Id()) + + wg, err := utilityK8sWgCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + workersComputeList := make([]compute.RecordCompute, 0) + for _, info := range wg.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) + if err != nil { + return diag.FromErr(err) + } + workersComputeList = append(workersComputeList, *compute) + } + + d.Set("wg_id", wg.ID) + if strings.Contains(d.Id(), "#") { + k8sId, err := strconv.Atoi(strings.Split(d.Id(), "#")[0]) + if err != nil { + return diag.FromErr(err) + } + + d.Set("k8s_id", k8sId) + } else { + d.Set("k8s_id", d.Get("k8s_id")) + } + d.SetId(fmt.Sprintf("%d#%d", d.Get("k8s_id").(int), wg.ID)) + + flattenWg(d, *wg, workersComputeList) + + return nil +} + +func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sWgUpdate: called with k8s id %d", d.Get("k8s_id").(int)) + + c := m.(*controller.ControllerCfg) + + haveK8sID, err := existK8sID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveK8sID { + return diag.Errorf("resourceK8sUpdate: can't update k8s cluster because K8sID %d is not allowed or does not exist", d.Get("k8s_id").(int)) + } + + wg, err := utilityK8sWgCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if newNum := d.Get("num").(int); uint64(newNum) > wg.Num { + req := k8s.WorkerAddRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + Num: uint64(newNum) - wg.Num, + Chipset: d.Get("chipset").(string), + } + + _, err := c.CloudAPI().K8S().WorkerAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + for i := int(wg.Num) - 1; i >= newNum; i-- { + req := k8s.DeleteWorkerFromGroupRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + WorkerID: wg.DetailedInfo[i].ID, + } + + _, err := c.CloudAPI().K8S().DeleteWorkerFromGroup(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("cloud_init") { + req := k8s.UpdateWorkerNodesMetaDataRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + UserData: d.Get("cloud_init").(string), + } + + _, err := c.CloudAPI().K8S().UpdateWorkerNodesMetaData(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceK8sWgRead(ctx, d, m) +} + +func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sWgDelete: called with k8s id %d", d.Get("k8s_id").(int)) + + wg, err := utilityK8sWgCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := k8s.WorkersGroupDeleteRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + } + + _, err = c.CloudAPI().K8S().WorkersGroupDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceK8sWgSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "ID of k8s instance.", + }, + + "name": { + Type: schema.TypeString, + Required: true, + //ForceNew: true, + Description: "Name of the worker group.", + }, + + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the storage policy", + }, + + "num": { + Type: schema.TypeInt, + Optional: true, + Default: 1, + Description: "Number of worker nodes to create.", + }, + + "chipset": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"Q35", "i440fx"}, false), + Default: "Q35", + Description: "Type of the emulated system. Possible values: i440fx, Q35. Default: Q35", + }, + + "cpu": { + Type: schema.TypeInt, + Optional: true, + //ForceNew: true, + Default: 1, + Description: "Worker node CPU count.", + }, + + "ram": { + Type: schema.TypeInt, + Optional: true, + //ForceNew: true, + Default: 1024, + ValidateFunc: validation.All( + validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + validators.DivisibleBy(constants.RAM_DIVISIBILITY), + ), + Description: "Worker node RAM in MB.", + }, + + "disk": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Worker node boot disk size. If unspecified or 0, size is defined by OS image size.", + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "annotations": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "worker_sep_id": { + Type: schema.TypeInt, + Optional: true, + }, + "worker_sep_pool": { + Type: schema.TypeString, + Optional: true, + }, + "cloud_init": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: cloudInitDiffSupperss, + }, + "wg_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of k8s worker Group.", + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: detailedInfoSchemaMake(), + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func ResourceK8sWg() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceK8sWgCreate, + ReadContext: resourceK8sWgRead, + UpdateContext: resourceK8sWgUpdate, + DeleteContext: resourceK8sWgDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout20m, + Read: &constants.Timeout20m, + Update: &constants.Timeout20m, + Delete: &constants.Timeout20m, + Default: &constants.Timeout20m, + }, + + Schema: resourceK8sWgSchemaMake(), + } +} diff --git a/internal/service/cloudapi/k8s/state_upgraders.go b/internal/service/cloudapi/k8s/state_upgraders.go new file mode 100644 index 00000000..dee4b02a --- /dev/null +++ b/internal/service/cloudapi/k8s/state_upgraders.go @@ -0,0 +1,15 @@ +package k8s + +import ( + "context" + + log "github.com/sirupsen/logrus" +) + +func resourceK8sCPStateUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceK8sCPStateUpgradeV1: upgrading state") + + delete(rawState, "cloud_init") + + return rawState, nil +} diff --git a/internal/service/cloudapi/k8s/utility_k8ci.go b/internal/service/cloudapi/k8s/utility_k8ci.go new file mode 100644 index 00000000..bc651b3a --- /dev/null +++ b/internal/service/cloudapi/k8s/utility_k8ci.go @@ -0,0 +1,80 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8ci" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityK8CIListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8ci.ListK8CI, error) { + c := m.(*controller.ControllerCfg) + + req := k8ci.ListRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if network_plugin, ok := d.GetOk("network_plugin"); ok { + req.NetworkPlugins = network_plugin.(string) + } + if include_disabled, ok := d.GetOk("include_disabled"); ok { + req.IncludeDisabled = include_disabled.(bool) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + resList, err := c.CloudAPI().K8CI().List(ctx, req) + if err != nil { + return nil, err + } + + return resList, nil +} diff --git a/internal/service/cloudapi/k8s/utility_k8s.go b/internal/service/cloudapi/k8s/utility_k8s.go new file mode 100644 index 00000000..a040e944 --- /dev/null +++ b/internal/service/cloudapi/k8s/utility_k8s.go @@ -0,0 +1,385 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func handleWorkersChange(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, cluster *k8s.RecordK8S) error { + o, n := d.GetChange("workers") + old_set, _ := o.([]interface{}) + new_set, _ := n.([]interface{}) + old_len := len(old_set) + new_len := len(new_set) + + if old_len > new_len { + deleted := workersDifference(old_set, new_set) + if err := deleteWGs(ctx, c, cluster, deleted); err != nil { + return err + } + + } else if old_len < new_len { + added := workersDifference(old_set, new_set) + if err := addWGs(ctx, c, cluster, added); err != nil { + return err + } + } + + if err := updateNum(ctx, c, cluster, old_set, new_set); err != nil { + return err + } + + return nil +} + +func updateNum(ctx context.Context, c *controller.ControllerCfg, cluster *k8s.RecordK8S, old_set []interface{}, new_set []interface{}) error { + for _, valOld := range old_set { + wgOld, _ := valOld.(map[string]interface{}) + for _, valNew := range new_set { + wgNew, _ := valNew.(map[string]interface{}) + if wgOld["id"] == wgNew["id"] { + oldNum := wgOld["num"].(int) + newNum := wgNew["num"].(int) + + if oldNum < newNum { + req := k8s.WorkerAddRequest{ + K8SID: cluster.ID, + WorkersGroupID: uint64(wgNew["id"].(int)), + Num: uint64(newNum - oldNum), + Chipset: wgNew["chipset"].(string), + } + + _, err := c.CloudAPI().K8S().WorkerAdd(ctx, req) + if err != nil { + return err + } + + } else if oldNum > newNum { + for i := oldNum - 1; i >= newNum; i-- { + detailedInfo := wgOld["detailed_info"].([]interface{}) + if len(detailedInfo) == 0 { + return nil + } + + req := k8s.DeleteWorkerFromGroupRequest{ + K8SID: cluster.ID, + WorkersGroupID: uint64(wgNew["id"].(int)), + WorkerID: uint64(detailedInfo[i].(map[string]interface{})["compute_id"].(int)), + } + + _, err := c.CloudAPI().K8S().DeleteWorkerFromGroup(ctx, req) + if err != nil { + return err + } + } + } + } + } + } + + return nil +} + +func deleteWGs(ctx context.Context, c *controller.ControllerCfg, cluster *k8s.RecordK8S, deleted []interface{}) error { + for _, elem := range deleted { + found_wg := elem.(map[string]interface{}) + req := k8s.WorkersGroupDeleteRequest{ + K8SID: cluster.ID, + WorkersGroupID: uint64(found_wg["id"].(int)), + } + + _, err := c.CloudAPI().K8S().WorkersGroupDelete(ctx, req) + if err != nil { + return err + } + } + return nil +} + +func addWGs(ctx context.Context, c *controller.ControllerCfg, cluster *k8s.RecordK8S, added []interface{}) error { + for _, elem := range added { + found_wg := elem.(map[string]interface{}) + req := k8s.WorkersGroupAddRequest{ + K8SID: cluster.ID, + Name: found_wg["name"].(string), + WorkerSEPID: uint64(found_wg["sep_id"].(int)), + WorkerSEPPool: found_wg["sep_pool"].(string), + WorkerNum: uint64(found_wg["num"].(int)), + WorkerCPU: uint64(found_wg["cpu"].(int)), + WorkerRAM: uint64(found_wg["ram"].(int)), + WorkerDisk: uint64(found_wg["disk"].(int)), + Chipset: found_wg["chipset"].(string), + } + + labels, _ := found_wg["labels"].([]interface{}) + for _, label := range labels { + if !strings.HasPrefix(label.(string), "workersGroupName") { + req.Labels = append(req.Labels, label.(string)) + } + } + + annotations, _ := found_wg["annotations"].([]interface{}) + for _, annotation := range annotations { + req.Annotations = append(req.Annotations, annotation.(string)) + } + + taints, _ := found_wg["taints"].([]interface{}) + for _, taint := range taints { + req.Taints = append(req.Taints, taint.(string)) + } + + _, err := c.CloudAPI().K8S().WorkersGroupAdd(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func utilityK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8S, error) { + c := m.(*controller.ControllerCfg) + + var k8sID uint64 + if d.Id() != "" { + k8sID, _ = strconv.ParseUint(d.Id(), 10, 64) + } else { + k8sID = uint64(d.Get("k8s_id").(int)) + } + req := k8s.GetRequest{ + K8SID: k8sID, + } + + k8s, err := c.CloudAPI().K8S().Get(ctx, req) + if err != nil { + return nil, err + } + + return k8s, nil +} + +func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}, computeID uint64) (*compute.RecordCompute, error) { + c := m.(*controller.ControllerCfg) + req := compute.GetRequest{ + ComputeID: computeID, + } + + compute, err := c.CloudAPI().Compute().Get(ctx, req) + if err != nil { + return nil, err + } + + return compute, nil +} + +func utilityDataK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8S, error) { + c := m.(*controller.ControllerCfg) + + req := k8s.GetRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + } + + k8s, err := c.CloudAPI().K8S().Get(ctx, req) + if err != nil { + return nil, err + } + + return k8s, nil +} + +func utilityK8sListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ListK8SClusters, error) { + c := m.(*controller.ControllerCfg) + req := k8s.ListRequest{ + IncludeDeleted: false, + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if ip_address, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ip_address.(string) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if lb_id, ok := d.GetOk("lb_id"); ok { + req.LBID = uint64(lb_id.(int)) + } + + if bservice_id, ok := d.GetOk("bservice_id"); ok { + req.BasicServiceID = uint64(bservice_id.(int)) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if includedeleted, ok := d.GetOk("includedeleted"); ok { + req.IncludeDeleted = includedeleted.(bool) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + k8sList, err := c.CloudAPI().K8S().List(ctx, req) + if err != nil { + return nil, err + } + + return k8sList, nil +} + +func utilityK8sListForResourceCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ListK8SClusters, error) { + c := m.(*controller.ControllerCfg) + req := k8s.ListRequest{ + IncludeDeleted: false, + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + k8sList, err := c.CloudAPI().K8S().List(ctx, req) + if err != nil { + return nil, err + } + + return k8sList, nil +} + +func utilityK8sListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ListK8SClusters, error) { + c := m.(*controller.ControllerCfg) + req := k8s.ListDeletedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if ip_address, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ip_address.(string) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if lb_id, ok := d.GetOk("lb_id"); ok { + req.LBID = uint64(lb_id.(int)) + } + + if bservice_id, ok := d.GetOk("bservice_id"); ok { + req.BasicServiceID = uint64(bservice_id.(int)) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + k8sList, err := c.CloudAPI().K8S().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return k8sList, nil +} + +func workersDifference(slice1 []interface{}, slice2 []interface{}) []interface{} { + var diff []interface{} + + for i := 0; i < 2; i++ { + for _, s1 := range slice1 { + found := false + for _, s2 := range slice2 { + if s1.(map[string]interface{})["id"] == s2.(map[string]interface{})["id"] { + found = true + break + } + } + + if !found { + diff = append(diff, s1) + } + } + + if i == 0 { + slice1, slice2 = slice2, slice1 + } + } + + return diff +} diff --git a/internal/service/cloudapi/k8s/utility_k8s_wg.go b/internal/service/cloudapi/k8s/utility_k8s_wg.go new file mode 100644 index 00000000..c86870dd --- /dev/null +++ b/internal/service/cloudapi/k8s/utility_k8s_wg.go @@ -0,0 +1,164 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDataK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ItemK8SGroup, []compute.RecordCompute, error) { + c := m.(*controller.ControllerCfg) + + k8sId := uint64(d.Get("k8s_id").(int)) + wgId := uint64(d.Get("wg_id").(int)) + + k8sGetReq := k8s.GetRequest{ + K8SID: k8sId, + } + + cluster, err := c.CloudAPI().K8S().Get(ctx, k8sGetReq) + if err != nil { + return nil, nil, err + } + + curWg := k8s.ItemK8SGroup{} + for _, wg := range cluster.K8SGroups.Workers { + if wg.ID == wgId { + curWg = wg + break + } + } + if curWg.ID == 0 { + return nil, nil, fmt.Errorf("WG with id %v in k8s cluster %v not found", wgId, k8sId) + } + + workersComputeList := make([]compute.RecordCompute, 0) + for _, info := range curWg.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) + if err != nil { + return nil, nil, err + } + + workersComputeList = append(workersComputeList, *compute) + } + + return &curWg, workersComputeList, nil +} + +func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ItemK8SGroup, error) { + c := m.(*controller.ControllerCfg) + var wgId int + var k8sId int + var err error + + if strings.Contains(d.Id(), "#") { + wgId, err = strconv.Atoi(strings.Split(d.Id(), "#")[1]) + if err != nil { + return nil, err + } + k8sId, err = strconv.Atoi(strings.Split(d.Id(), "#")[0]) + if err != nil { + return nil, err + } + } else { + wgId, err = strconv.Atoi(d.Id()) + if err != nil { + return nil, err + } + k8sId = d.Get("k8s_id").(int) + } + + req := k8s.GetRequest{ + K8SID: uint64(k8sId), + } + + cluster, err := c.CloudAPI().K8S().Get(ctx, req) + if err != nil { + return nil, err + } + + for _, wg := range cluster.K8SGroups.Workers { + if wg.ID == uint64(wgId) { + return &wg, nil + } + } + + return nil, fmt.Errorf("not found wg with id: %v in k8s cluster: %v", wgId, cluster.ID) +} + +func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (k8s.ListK8SGroups, error) { + c := m.(*controller.ControllerCfg) + req := k8s.GetRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + } + + cluster, err := c.CloudAPI().K8S().Get(ctx, req) + if err != nil { + return nil, err + } + + return cluster.K8SGroups.Workers, nil +} + +func utilityK8sWgCloudInitCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + req := k8s.GetWorkerNodesMetaDataRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: uint64(d.Get("wg_id").(int)), + } + + cloudInit, err := c.CloudAPI().K8S().GetWorkerNodesMetaData(ctx, req) + if err != nil { + return "", err + } + + return cloudInit, nil +} + +func cloudInitDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool { + if newVal != "" && newVal != oldVal { + log.Debugf("networkSubresIPAddreDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal) + return false + } + log.Debugf("networkSubresIPAddreDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal) + return true // suppress difference +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute.go b/internal/service/cloudapi/kvmvm/data_source_compute.go new file mode 100644 index 00000000..9ebd4e72 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute.go @@ -0,0 +1,1244 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func findInExtraDisks(DiskId uint, ExtraDisks []interface{}) bool { + for _, ExtraDisk := range ExtraDisks { + if DiskId == uint(ExtraDisk.(int)) { + return true + } + } + return false +} + +func dataSourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + compute, err := utilityDataComputeCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(int(compute.ID))) + + pciList, err := utilityComputePCIDevicesList(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + flattenDataCompute(d, compute, pciList) + return nil +} + +func computeListRulesSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "key": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + "topology": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + } + return res +} + +func computeListACLSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func computeACLSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeListACLSchemaMake(), + }, + }, + "compute_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeListACLSchemaMake(), + }, + }, + "rg_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeListACLSchemaMake(), + }, + }, + } +} + +func computeIOTuneSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func computeSnapshotsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "reference_id": { + Type: schema.TypeInt, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + } +} +func computeListDisksSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "_ckey": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeIOTuneSchemaMake(), + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "params": { + Type: schema.TypeString, + Computed: true, + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_available": { + Type: schema.TypeFloat, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeSnapshotsSchemaMake(), + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_id": { + Type: schema.TypeInt, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func computeQOSSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_brust": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func computeInterfacesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "flip_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + "listen_ssh": { + Type: schema.TypeBool, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeQOSSchemaMake(), + }, + }, + "libvirt_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeLibvirtSettingsSchemaMake(), + }, + }, + "sdn_interface_id": { + Type: schema.TypeString, + Computed: true, + }, + "security_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "target": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "trunk_tags": { + Type: schema.TypeString, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } +} + +func computeLibvirtSettingsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "txmode": { + Type: schema.TypeString, + Computed: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Computed: true, + }, + "event_idx": { + Type: schema.TypeString, + Computed: true, + }, + "queues": { + Type: schema.TypeInt, + Computed: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func computeOsUsersSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "public_key": { + Type: schema.TypeString, + Computed: true, + }, + } +} +func computeSnapSetsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + } +} +func dataSourceComputeSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeACLSchemaMake(), + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_label": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeListRulesSchemaMake(), + }, + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "anti_affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeListRulesSchemaMake(), + }, + }, + "arch": { + Type: schema.TypeString, + Computed: true, + }, + "auto_start_w_node": { + Type: schema.TypeBool, + Computed: true, + }, + "chipset": { + Type: schema.TypeString, + Computed: true, + }, + "clock": { + Type: schema.TypeString, + Computed: true, + }, + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "bootdisk_size": { + Type: schema.TypeInt, + Computed: true, + }, + "boot_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "clone_reference": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_devices": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "clones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cpu_alignment_profiles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "cpu_pin": { + Type: schema.TypeBool, + Computed: true, + }, + "cpus": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "custom_fields": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "devices": { + Type: schema.TypeString, + Computed: true, + }, + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeListDisksSchemaMake(), + }, + }, + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hp_backed": { + Type: schema.TypeBool, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeInterfacesSchemaMake(), + }, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "live_migration_job_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "migrationjob": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "need_reboot": { + Type: schema.TypeBool, + Computed: true, + }, + "numa_affinity": { + Type: schema.TypeString, + Computed: true, + }, + "numa_node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_ip": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_name": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network_name": { + Type: schema.TypeString, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeOsUsersSchemaMake(), + }, + }, + "pinned": { + Type: schema.TypeBool, + Computed: true, + }, + "preferred_cpu": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "qemu_guest": { + Type: schema.TypeList, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "enabled_agent_features": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "last_update": { + Type: schema.TypeInt, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "reserved_node_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "snap_sets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeSnapSetsSchemaMake(), + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tags": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "read_only": { + Type: schema.TypeBool, + Computed: true, + Description: "Shows if compute is in read-only mode.", + }, + "userdata": { + Type: schema.TypeString, + Computed: true, + }, + "vnc_password": { + Type: schema.TypeString, + Computed: true, + }, + "vgpus": { + Type: schema.TypeList, + Computed: true, + Description: "List of virtual GPUs", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "profile_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "last_update_time": { + Type: schema.TypeInt, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + "pgpuid": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "last_claimed_by": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "stateless_sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stateless_sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "loader_type": { + Type: schema.TypeString, + Computed: true, + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + "loader_meta_iso": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "device_name": { + Type: schema.TypeString, + Computed: true, + }, + "path": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "os_version": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func DataSourceCompute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_audits.go b/internal/service/cloudapi/kvmvm/data_source_compute_audits.go new file mode 100644 index 00000000..fd6a97f7 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_audits.go @@ -0,0 +1,148 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeAudits, err := utilityComputeAuditsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenComputeAudits(computeAudits)) + d.Set("entry_count", computeAudits.EntryCount) + return nil +} + +func dataSourceComputeAuditsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "timestamp_at": { + Type: schema.TypeInt, + Optional: true, + }, + "timestamp_to": { + Type: schema.TypeInt, + Optional: true, + }, + "user": { + Type: schema.TypeString, + Optional: true, + }, + "call": { + Type: schema.TypeString, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "min_status_code": { + Type: schema.TypeInt, + Optional: true, + }, + "max_status_code": { + Type: schema.TypeInt, + Optional: true, + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "call": { + Type: schema.TypeString, + Computed: true, + }, + "responsetime": { + Type: schema.TypeFloat, + Computed: true, + }, + "statuscode": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func DataSourceComputeAudits() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeAuditsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeAuditsSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_cpu_alignment_profile.go b/internal/service/cloudapi/kvmvm/data_source_compute_cpu_alignment_profile.go new file mode 100644 index 00000000..4d604047 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_cpu_alignment_profile.go @@ -0,0 +1,98 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeCPUAlignmentProfileRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + profile, err := utilityComputeGetCPUAlignmentProfile(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("model", profile.Model) + d.Set("name", profile.Name) + d.Set("vendor", profile.Vendor) + + return nil +} + +func dataSourceComputeCPUAlignmentProfileSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the compute instance", + }, + "model": { + Type: schema.TypeString, + Computed: true, + Description: "CPU model of the alignment profile", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the CPU alignment profile", + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + Description: "CPU vendor of the alignment profile", + }, + } +} + +func DataSourceComputeCPUAlignmentProfile() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeCPUAlignmentProfileRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeCPUAlignmentProfileSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_get_audits.go b/internal/service/cloudapi/kvmvm/data_source_compute_get_audits.go new file mode 100644 index 00000000..4bee35a3 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_get_audits.go @@ -0,0 +1,95 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeGetAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeAudits, err := utilityComputeGetAuditsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenComputeGetAudits(computeAudits)) + return nil +} + +func dataSourceComputeGetAuditsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "epoch": { + Type: schema.TypeFloat, + Computed: true, + }, + "message": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } +} + +func DataSourceComputeGetAudits() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeGetAuditsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeGetAuditsSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_get_console_url.go b/internal/service/cloudapi/kvmvm/data_source_compute_get_console_url.go new file mode 100644 index 00000000..992d11eb --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_get_console_url.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "strings" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeGetConsoleUrlRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeConsoleUrl, err := utilityComputeGetConsoleUrlCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + result := strings.ReplaceAll(computeConsoleUrl, "\"", "") + result = strings.ReplaceAll(result, "\\", "") + d.Set("console_url", result) + return nil +} + +func dataSourceComputeGetConsoleUrlSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "console_url": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func DataSourceComputeGetConsoleUrl() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeGetConsoleUrlRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeGetConsoleUrlSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_get_log.go b/internal/service/cloudapi/kvmvm/data_source_compute_get_log.go new file mode 100644 index 00000000..7235d3e8 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_get_log.go @@ -0,0 +1,86 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeGetLogRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeGetLog, err := utilityComputeGetLogCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("log", computeGetLog) + return nil +} + +func dataSourceComputeGetLogSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "path": { + Type: schema.TypeString, + Required: true, + }, + "log": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func DataSourceComputeGetLog() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeGetLogRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeGetLogSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_list.go b/internal/service/cloudapi/kvmvm/data_source_compute_list.go new file mode 100644 index 00000000..275786d6 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_list.go @@ -0,0 +1,587 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeList, err := utilityDataComputeListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + result := computeList + if d.Get("ignore_k8s").(bool) { + // matches automatically generated names like "s234-g2134-c1" etc + result = matchComputes(computeList) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenComputeList(result)) + d.Set("entry_count", computeList.EntryCount) + + return nil +} + +func computeDisksSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} +func itemComputeSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeListACLSchemaMake(), + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_label": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeListRulesSchemaMake(), + }, + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "anti_affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeListRulesSchemaMake(), + }, + }, + "arch": { + Type: schema.TypeString, + Computed: true, + }, + "auto_start_w_node": { + Type: schema.TypeBool, + Computed: true, + }, + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "bootdisk_size": { + Type: schema.TypeInt, + Computed: true, + }, + "boot_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "clone_reference": { + Type: schema.TypeInt, + Computed: true, + }, + "chipset": { + Type: schema.TypeString, + Computed: true, + }, + "clock": { + Type: schema.TypeString, + Computed: true, + }, + "clones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cpu_alignment_profiles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "cpu_pin": { + Type: schema.TypeBool, + Computed: true, + }, + "cpus": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "custom_fields": { //NEED + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "devices": { //NEED + Type: schema.TypeString, + Computed: true, + }, + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeDisksSchemaMake(), + }, + }, + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hp_backed": { + Type: schema.TypeBool, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeInterfacesSchemaMake(), + }, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "live_migration_job_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "migrationjob": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "need_reboot": { + Type: schema.TypeBool, + Computed: true, + }, + "numa_affinity": { + Type: schema.TypeString, + Computed: true, + }, + "numa_node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "os_version": { + Type: schema.TypeString, + Computed: true, + }, + "pinned": { + Type: schema.TypeBool, + Computed: true, + }, + "preferred_cpu": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "qemu_guest": { + Type: schema.TypeList, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "enabled_agent_features": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "last_update": { + Type: schema.TypeInt, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "reserved_node_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "snap_sets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeSnapSetsSchemaMake(), + }, + }, + "stateless_sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stateless_sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tags": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Computed: true, + }, + "val": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "total_disk_size": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "read_only": { + Type: schema.TypeBool, + Computed: true, + Description: "Shows if compute is in read-only mode.", + }, + "vgpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "vins_connected": { + Type: schema.TypeInt, + Computed: true, + }, + "loader_type": { + Type: schema.TypeString, + Computed: true, + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceComputeListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by AccountID", + }, + "rg_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by resgroup name", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by RGID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by tech status", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "Find by IP address", + }, + "extnet_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by Extnet name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by Extnet ID", + }, + "includedeleted": { + Type: schema.TypeBool, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "ignore_k8s": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If set to true, ignores any VMs associated with any k8s cluster", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: itemComputeSchemaMake(), + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceComputeList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_list_deleted.go b/internal/service/cloudapi/kvmvm/data_source_compute_list_deleted.go new file mode 100644 index 00000000..009e0e59 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_list_deleted.go @@ -0,0 +1,159 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeList, err := utilityDataComputeListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + result := computeList + if d.Get("ignore_k8s").(bool) { + // matches automatically generated names like "s234-g2134-c1" etc + result = matchComputes(computeList) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenComputeList(result)) + d.Set("entry_count", computeList.EntryCount) + + return nil +} + +func dataSourceComputeListDeletedSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by AccountID", + }, + "rg_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by resgroup name", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by RGID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by tech status", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "Find by IP address", + }, + "extnet_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by Extnet name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by Extnet ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "ignore_k8s": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If set to true, ignores any VMs associated with any k8s cluster", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: itemComputeSchemaMake(), + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceComputeListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_pci_device_list.go b/internal/service/cloudapi/kvmvm/data_source_compute_pci_device_list.go new file mode 100644 index 00000000..a806ed46 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_pci_device_list.go @@ -0,0 +1,166 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputePCIDeviceListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computePCIDeviceList, err := utilityComputePCIDeviceListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenPCIDevice(computePCIDeviceList.Data)) + d.Set("entry_count", computePCIDeviceList.EntryCount) + return nil +} + +func dataSourceComputePCIDeviceListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by RG id", + }, + "device_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by device id", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Find by name", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Find by status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hwpath": { + Type: schema.TypeString, + Computed: true, + }, + "device_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "system_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func DataSourceComputePCIDeviceList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputePCIDeviceListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputePCIDeviceListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_pfw_list.go b/internal/service/cloudapi/kvmvm/data_source_compute_pfw_list.go new file mode 100644 index 00000000..1b85be01 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_pfw_list.go @@ -0,0 +1,119 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputePfwListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computePfwList, err := utilityComputePfwListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenPfwList(computePfwList)) + d.Set("entry_count", computePfwList.EntryCount) + return nil +} + +func dataSourceComputePfwListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pfw_id": { + Type: schema.TypeInt, + Computed: true, + }, + "local_ip": { + Type: schema.TypeString, + Computed: true, + }, + "local_port": { + Type: schema.TypeInt, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "public_port_end": { + Type: schema.TypeInt, + Computed: true, + }, + "public_port_start": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func DataSourceComputePfwList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputePfwListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputePfwListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_snapshot_usage.go b/internal/service/cloudapi/kvmvm/data_source_compute_snapshot_usage.go new file mode 100644 index 00000000..e3a4c440 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_snapshot_usage.go @@ -0,0 +1,74 @@ +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeSnapshotUsageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeSnapshotUsage, err := utilityComputeSnapshotUsageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenSnapshotUsage(computeSnapshotUsage)) + return nil +} + +func dataSourceComputeSnapshotUsagSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "label": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "count": { + Type: schema.TypeInt, + Computed: true, + }, + "stored": { + Type: schema.TypeFloat, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } +} + +func DataSourceComputeSnapshotUsage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeSnapshotUsageRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeSnapshotUsagSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_user_list.go b/internal/service/cloudapi/kvmvm/data_source_compute_user_list.go new file mode 100644 index 00000000..c523db6a --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_user_list.go @@ -0,0 +1,78 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeUserListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeUserList, err := utilityComputeUserListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + flattenUserList(d, computeUserList) + return nil +} + +func dataSourceComputeUserListSchemaMake() map[string]*schema.Schema { + res := computeACLSchemaMake() + res["compute_id"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + } + return res +} + +func DataSourceComputeUserList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeUserListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeUserListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_vgpu_list.go b/internal/service/cloudapi/kvmvm/data_source_compute_vgpu_list.go new file mode 100644 index 00000000..03651d77 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/data_source_compute_vgpu_list.go @@ -0,0 +1,198 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeVGPUListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeVGPUList, err := utilityComputeVGPUListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVGPU(computeVGPUList.Data)) + d.Set("entry_count", computeVGPUList.EntryCount) + return nil +} + +func dataSourceComputeVGPUListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "gpu_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by GPU id", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "Find by type", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Find by status", + }, + "includedeleted": { + Type: schema.TypeBool, + Optional: true, + Description: "Include deleted computes. If using field 'status', then includedeleted will be ignored", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "vgpu_id": { + Type: schema.TypeInt, + Computed: true, + }, + "last_claimed_by": { + Type: schema.TypeInt, + Computed: true, + }, + "last_update_time": { + Type: schema.TypeInt, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "pgpuid": { + Type: schema.TypeInt, + Computed: true, + }, + "profile_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func DataSourceComputeVGPUList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeVGPUListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeVGPUListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/kvmvm/flattens.go b/internal/service/cloudapi/kvmvm/flattens.go new file mode 100644 index 00000000..ef6cb28b --- /dev/null +++ b/internal/service/cloudapi/kvmvm/flattens.go @@ -0,0 +1,991 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "encoding/json" + "sort" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func flattenDisks(disks []compute.InfoDisk) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, disk := range disks { + temp := map[string]interface{}{ + // "bus_number": disk.BusNumber, + "disk_id": disk.ID, + // "pci_slot": disk.PCISlot, + "sep_id": disk.SepID, + } + res = append(res, temp) + } + return res +} +func flattenQOS(qos compute.QOS) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "e_rate": qos.ERate, + "guid": qos.GUID, + "in_brust": qos.InBurst, + "in_rate": qos.InRate, + } + res = append(res, temp) + return res +} +func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(interfaces)) + for _, interfaceItem := range interfaces { + temp := map[string]interface{}{ + "bus_number": interfaceItem.BusNumber, + "conn_id": interfaceItem.ConnID, + "conn_type": interfaceItem.ConnType, + "def_gw": interfaceItem.DefGW, + "enabled": interfaceItem.Enabled, + "enable_secgroups": interfaceItem.EnableSecGroups, + "flip_group_id": interfaceItem.FLIPGroupID, + "guid": interfaceItem.GUID, + "ip_address": interfaceItem.IPAddress, + "listen_ssh": interfaceItem.ListenSSH, + "mac": interfaceItem.MAC, + "mtu": interfaceItem.MTU, + "name": interfaceItem.Name, + "net_id": interfaceItem.NetID, + "netmask": interfaceItem.NetMask, + "net_type": interfaceItem.NetType, + "node_id": interfaceItem.NodeID, + "pci_slot": interfaceItem.PCISlot, + "qos": flattenQOS(interfaceItem.QOS), + "security_groups": interfaceItem.SecGroups, + "sdn_interface_id": interfaceItem.SDNInterfaceID, + "target": interfaceItem.Target, + "type": interfaceItem.Type, + "trunk_tags": interfaceItem.TrunkTags, + "vnfs": interfaceItem.VNFs, + "libvirt_settings": flattenLibvirtSettings(interfaceItem.LibvirtSettings), + } + res = append(res, temp) + } + return res +} + +func flattenLibvirtSettings(libvirtSettings compute.LibvirtSettings) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "guid": libvirtSettings.GUID, + "txmode": libvirtSettings.TXMode, + "ioeventfd": libvirtSettings.IOEventFD, + "event_idx": libvirtSettings.EventIDx, + "queues": libvirtSettings.Queues, + "rx_queue_size": libvirtSettings.RXQueueSize, + "tx_queue_size": libvirtSettings.TXQueueSize, + } + res = append(res, temp) + return res +} + +func flattenSnapSets(snapSets compute.ListSnapSets) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(snapSets)) + for _, snapSet := range snapSets { + temp := map[string]interface{}{ + "disks": snapSet.Disks, + "guid": snapSet.GUID, + "label": snapSet.Label, + "timestamp": snapSet.Timestamp, + } + res = append(res, temp) + } + return res +} +func flattenTags(tags map[string]string) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(tags)) + for key, val := range tags { + temp := map[string]interface{}{ + "key": key, + "val": val, + } + res = append(res, temp) + } + return res +} + +func flattenListRules(listRules compute.ListRules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(listRules)) + for _, rule := range listRules { + temp := map[string]interface{}{ + "guid": rule.GUID, + "key": rule.Key, + "mode": rule.Mode, + "policy": rule.Policy, + "topology": rule.Topology, + "value": rule.Value, + } + res = append(res, temp) + } + return res +} +func flattenListACL(listAcl compute.ListACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(listAcl)) + for _, acl := range listAcl { + temp := map[string]interface{}{ + "explicit": acl.Explicit, + "guid": acl.GUID, + "right": acl.Right, + "status": acl.Status, + "type": acl.Type, + "user_group_id": acl.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenComputeList(computes *compute.ListComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computes.Data)) + for _, compute := range computes.Data { + customFields, _ := json.Marshal(compute.CustomFields) + devices, _ := json.Marshal(compute.Devices) + temp := map[string]interface{}{ + "acl": flattenListACL(compute.ACL), + "account_id": compute.AccountID, + "account_name": compute.AccountName, + "affinity_label": compute.AffinityLabel, + "affinity_rules": flattenListRules(compute.AffinityRules), + "affinity_weight": compute.AffinityWeight, + "anti_affinity_rules": flattenListRules(compute.AntiAffinityRules), + "arch": compute.Architecture, + "auto_start_w_node": compute.AutoStart, + "boot_order": compute.BootOrder, + "bootdisk_size": compute.BootDiskSize, + "boot_image_id": compute.BootImageID, + "chipset": compute.Chipset, + "clock": compute.Clock, + "cd_image_id": compute.CdImageId, + "clone_reference": compute.CloneReference, + "clones": compute.Clones, + "computeci_id": compute.ComputeCIID, + "cpu_alignment_profiles": flattenCPUAlignmentProfile(compute.CPUAlignmentProfile), + "cpu_pin": compute.CPUPin, + "cpus": compute.CPU, + "created_by": compute.CreatedBy, + "created_time": compute.CreatedTime, + "custom_fields": string(customFields), + "deleted_by": compute.DeletedBy, + "deleted_time": compute.DeletedTime, + "desc": compute.Description, + "devices": string(devices), + "disks": flattenDisks(compute.Disks), + "driver": compute.Driver, + "gid": compute.GID, + "guid": compute.GUID, + "hp_backed": compute.HPBacked, + "compute_id": compute.ID, + "interfaces": flattenInterfaces(compute.Interfaces), + "live_migration_job_id": compute.LiveMigrationJobID, + "lock_status": compute.LockStatus, + "manager_id": compute.ManagerID, + "manager_type": compute.ManagerType, + "migrationjob": compute.MigrationJob, + "milestones": compute.Milestones, + "name": compute.Name, + "need_reboot": compute.NeedReboot, + "numa_affinity": compute.NumaAffinity, + "numa_node_id": compute.NumaNodeId, + "os_version": compute.OSVersion, + "pinned": compute.PinnedToNode, + "preferred_cpu": compute.PreferredCPU, + "qemu_guest": flattenQemuQuest(compute.QemuQuest), + "ram": compute.RAM, + "reference_id": compute.ReferenceID, + "registered": compute.Registered, + "res_name": compute.ResName, + "reserved_node_cpus": compute.ReservedNodeCpus, + "rg_id": compute.RGID, + "rg_name": compute.RGName, + "snap_sets": flattenSnapSets(compute.SnapSets), + "stateless_sep_id": compute.StatelessSepID, + "stateless_sep_type": compute.StatelessSepType, + "status": compute.Status, + "tags": flattenTags(compute.Tags), + "tech_status": compute.TechStatus, + "total_disk_size": compute.TotalDiskSize, + "updated_by": compute.UpdatedBy, + "updated_time": compute.UpdatedTime, + "user_managed": compute.UserManaged, + "read_only": compute.ReadOnly, + "vgpus": compute.VGPUs, + "vins_connected": compute.VINSConnected, + "loader_type": compute.LoaderType, + "boot_type": compute.BootType, + "hot_resize": compute.HotResize, + "network_interface_naming": compute.NetworkInterfaceNaming, + "zone_id": compute.ZoneID, + "weight": compute.Weight, + } + res = append(res, temp) + } + + return res +} + +func flattenBootDisk(bootDisk *compute.ItemComputeDisk) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + + temp := map[string]interface{}{ + "disk_name": bootDisk.Name, + "disk_id": bootDisk.ID, + "sep_id": bootDisk.SepID, + "shareable": bootDisk.Shareable, + "size_max": bootDisk.SizeMax, + "size_used": bootDisk.SizeUsed, + "pool": bootDisk.Pool, + "desc": bootDisk.Description, + "image_id": bootDisk.ImageID, + "size": bootDisk.SizeMax, + "present_to": bootDisk.PresentTo, + "storage_policy_id": bootDisk.StoragePolicyID, + "to_clean": bootDisk.ToClean, + "cache": bootDisk.Cache, + "discard": bootDisk.Discard, + "block_size": bootDisk.BlockSize, + "bus_number": bootDisk.BusNumber, + "provision": bootDisk.Provision, + "pci_slot": bootDisk.PCISlot, + "created_time": bootDisk.CreatedTime, + "created_by": bootDisk.CreatedBy, + "deleted_by": bootDisk.DeletedBy, + "deleted_time": bootDisk.DeletedTime, + "updated_time": bootDisk.UpdatedTime, + "devicename": bootDisk.DeviceName, + } + + res = append(res, temp) + + return res +} + +func flattenComputeDisksDemo(disksList compute.ListComputeDisks, disksBlocks, extraDisks []interface{}, bootDiskId uint64) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(disksList)) + + sort.Slice(disksList, func(i, j int) bool { + return disksList[i].ID < disksList[j].ID + }) + + indexDataDisks := 0 + + for _, disk := range disksList { + if disk.ID == bootDiskId || findInExtraDisks(uint(disk.ID), extraDisks) { //skip main bootdisk and extraDisks + continue + } + + var pernamentlyValue bool + if indexDataDisks < len(disksBlocks) { + if diskBlock, ok := disksBlocks[indexDataDisks].(map[string]interface{}); ok { + if perm, exists := diskBlock["permanently"]; exists { + if permBool, ok := perm.(bool); ok { + pernamentlyValue = permBool + } + } + } + } + + temp := map[string]interface{}{ + "devicename": disk.DeviceName, + "disk_name": disk.Name, + "disk_id": disk.ID, + "independent": disk.Independent, + "pci_slot": disk.PCISlot, + "bus_number": disk.BusNumber, + "sep_id": disk.SepID, + "shareable": disk.Shareable, + "size_max": disk.SizeMax, + "size_used": disk.SizeUsed, + "pool": disk.Pool, + "desc": disk.Description, + "image_id": disk.ImageID, + "size": disk.SizeMax, + "present_to": disk.PresentTo, + "storage_policy_id": disk.StoragePolicyID, + "to_clean": disk.ToClean, + "created_by": disk.CreatedBy, + "created_time": disk.CreatedTime, + "deleted_by": disk.DeletedBy, + "deleted_time": disk.DeletedTime, + "updated_time": disk.UpdatedTime, + "permanently": pernamentlyValue, + "cache": disk.Cache, + "discard": disk.Discard, + "block_size": disk.BlockSize, + "provision": disk.Provision, + "iotune": flattenIotune(disk.IOTune), + } + res = append(res, temp) + indexDataDisks++ + } + + return res +} + +func flattenNetwork(networks []interface{}, interfaces compute.ListInterfaces) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(interfaces)) + + for _, network := range interfaces { + temp := map[string]interface{}{ + "net_id": network.NetID, + "net_type": network.NetType, + "ip_address": network.IPAddress, + "mac": network.MAC, + "mtu": network.MTU, + "net_mask": network.NetMask, + "sdn_interface_id": network.SDNInterfaceID, + "weight": flattenNetworkWeight(networks, network.NetID, network.NetType), + "enabled": network.Enabled, + } + res = append(res, temp) + } + return res +} + +func flattenNetworkWeight(networks []interface{}, netID uint64, netType string) int { + for _, network := range networks { + ns := network.(map[string]interface{}) + if ns["net_id"].(int) == int(netID) && ns["net_type"].(string) == netType { + weight := ns["weight"].(int) + return weight + } + } + return 0 +} + +func isBootDisk(diskConv map[string]interface{}, chipset string) bool { + if chipset == "i440fx" { + return diskConv["pci_slot"].(int) == 6 + } + return diskConv["bus_number"].(int) == 6 +} + +func findBootDisk(disks compute.ListComputeDisks, chipset string) *compute.ItemComputeDisk { + for _, disk := range disks { + if chipset == "i440fx" { + if disk.PCISlot == 6 { + return &disk + } + } else { + if disk.BusNumber == 6 { + return &disk + } + } + } + return &compute.ItemComputeDisk{} +} + +func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute, pciList *compute.ListPCIDevices) error { + // This function expects that compFacts string contains response from API compute/get, + // i.e. detailed information about compute instance. + // + // NOTE: this function modifies ResourceData argument - as such it should never be called + // from resourceComputeExists(...) method + log.Debugf("flattenCompute: ID %d, RG ID %d", computeRec.ID, computeRec.RGID) + + devices, _ := json.Marshal(computeRec.Devices) + bootDisk := findBootDisk(computeRec.Disks, computeRec.Chipset) + + //check extraDisks, ipa_type, is, + d.SetId(strconv.FormatUint(computeRec.ID, 10)) + // d.Set("acl", flattenACL(computeRec.ACL)) + d.Set("account_id", computeRec.AccountID) + d.Set("account_name", computeRec.AccountName) + d.Set("affinity_weight", computeRec.AffinityWeight) + d.Set("arch", computeRec.Architecture) + d.Set("auto_start_w_node", computeRec.AutoStart) + d.Set("boot_order", computeRec.BootOrder) + // we intentionally use the SizeMax field, do not change it until the BootDiskSize field is fixed on the platform + d.Set("boot_disk_size", bootDisk.SizeMax) + d.Set("boot_disk", flattenBootDisk(bootDisk)) + d.Set("boot_disk_id", bootDisk.ID) + d.Set("boot_image_id", computeRec.BootImageID) + d.Set("cd_image_id", computeRec.CdImageId) + d.Set("sep_id", bootDisk.SepID) + d.Set("pool", bootDisk.Pool) + d.Set("chipset", computeRec.Chipset) + d.Set("clock", computeRec.Clock) + d.Set("clone_reference", computeRec.CloneReference) + d.Set("clones", computeRec.Clones) + d.Set("computeci_id", computeRec.ComputeCIID) + d.Set("created_by", computeRec.CreatedBy) + d.Set("created_time", computeRec.CreatedTime) + // d.Set("custom_fields", flattenCustomFields(computeRec.CustomFields)) + d.Set("deleted_by", computeRec.DeletedBy) + d.Set("deleted_time", computeRec.DeletedTime) + d.Set("description", computeRec.Description) + d.Set("devices", string(devices)) + err := d.Set("disks", flattenComputeDisksDemo(computeRec.Disks, d.Get("disks").([]interface{}), d.Get("extra_disks").(*schema.Set).List(), bootDisk.ID)) + if err != nil { + return err + } + d.Set("driver", computeRec.Driver) + d.Set("cpu", computeRec.CPU) + d.Set("gid", computeRec.GID) + d.Set("guid", computeRec.GUID) + d.Set("compute_id", computeRec.ID) + d.Set("image_id", computeRec.ImageID) + d.Set("interfaces", flattenInterfaces(computeRec.Interfaces)) + d.Set("lock_status", computeRec.LockStatus) + d.Set("manager_id", computeRec.ManagerID) + d.Set("manager_type", computeRec.ManagerType) + d.Set("migrationjob", computeRec.MigrationJob) + d.Set("milestones", computeRec.Milestones) + d.Set("name", computeRec.Name) + d.Set("need_reboot", computeRec.NeedReboot) + d.Set("numa_node_id", computeRec.NumaNodeId) + d.Set("natable_vins_id", computeRec.NatableVINSID) + d.Set("natable_vins_ip", computeRec.NatableVINSIP) + d.Set("natable_vins_name", computeRec.NatableVINSName) + d.Set("natable_vins_network", computeRec.NatableVINSNetwork) + d.Set("natable_vins_network_name", computeRec.NatableVINSNetworkName) + if err := d.Set("os_users", parseOsUsers(computeRec.OSUsers)); err != nil { + return err + } + d.Set("pinned", computeRec.PinnedToNode) + d.Set("preferred_cpu", computeRec.PreferredCPU) + d.Set("ram", computeRec.RAM) + d.Set("reference_id", computeRec.ReferenceID) + d.Set("registered", computeRec.Registered) + d.Set("res_name", computeRec.ResName) + d.Set("reserved_node_cpus", computeRec.ReservedNodeCpus) + d.Set("rg_id", computeRec.RGID) + d.Set("rg_name", computeRec.RGName) + d.Set("snap_sets", flattenSnapSets(computeRec.SnapSets)) + d.Set("stateless_sep_id", computeRec.StatelessSepID) + d.Set("stateless_sep_type", computeRec.StatelessSepType) + d.Set("status", computeRec.Status) + // d.Set("tags", flattenTags(computeRec.Tags)) + d.Set("tech_status", computeRec.TechStatus) + d.Set("updated_by", computeRec.UpdatedBy) + d.Set("updated_time", computeRec.UpdatedTime) + d.Set("user_managed", computeRec.UserManaged) + d.Set("read_only", computeRec.ReadOnly) + d.Set("vnc_password", computeRec.VNCPassword) + d.Set("vgpus", flattenVGPUs(computeRec.VGPUs)) + d.Set("loader_type", computeRec.LoaderType) + d.Set("boot_type", computeRec.BootType) + d.Set("hot_resize", computeRec.HotResize) + d.Set("network_interface_naming", computeRec.NetworkInterfaceNaming) + d.Set("zone_id", computeRec.ZoneID) + d.Set("loader_meta_iso", flattenLoaderMetaIso(computeRec.LoaderMetaIso)) + d.Set("cpu_pin", computeRec.CPUPin) + d.Set("cpu_alignment_profile", computeRec.CPUAlignmentProfile.Name) + d.Set("numa_affinity", computeRec.NumaAffinity) + d.Set("hp_backed", computeRec.HPBacked) + d.Set("weight", computeRec.Weight) + + d.Set("enabled", false) + if computeRec.Status == status.Enabled { + d.Set("enabled", true) + } + + d.Set("started", false) + if computeRec.TechStatus == "STARTED" { + d.Set("started", true) + } + + d.Set("network", flattenNetwork(d.Get("network").(*schema.Set).List(), computeRec.Interfaces)) + d.Set("pci_devices", flattenPCI(*pciList)) + + d.Set("os_version", computeRec.OSVersion) + + return nil +} + +func flattenLoaderMetaIso(loaderMetaIso compute.LoaderMetaIso) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "device_name": loaderMetaIso.DeviceName, + "path": loaderMetaIso.Path, + } + res = append(res, temp) + return res +} + +func flattenACL(acl compute.RecordACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "account_acl": flattenListACL(acl.AccountACL), + "compute_acl": flattenListACL(acl.ComputeACL), + "rg_acl": flattenListACL(acl.RGACL), + } + res = append(res, temp) + return res +} + +func flattenAffinityRules(affinityRules compute.ListRules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(affinityRules)) + for _, affinityRule := range affinityRules { + temp := map[string]interface{}{ + "guid": affinityRule.GUID, + "key": affinityRule.Key, + "mode": affinityRule.Mode, + "policy": affinityRule.Policy, + "topology": affinityRule.Topology, + "value": affinityRule.Value, + } + res = append(res, temp) + } + + return res +} + +func flattenIotune(iotune compute.IOTune) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "read_bytes_sec": iotune.ReadBytesSec, + "read_bytes_sec_max": iotune.ReadBytesSecMax, + "read_iops_sec": iotune.ReadIOPSSec, + "read_iops_sec_max": iotune.ReadIOPSSecMax, + "size_iops_sec": iotune.SizeIOPSSec, + "total_bytes_sec": iotune.TotalBytesSec, + "total_bytes_sec_max": iotune.TotalBytesSecMax, + "total_iops_sec": iotune.TotalIOPSSec, + "total_iops_sec_max": iotune.TotalIOPSSecMax, + "write_bytes_sec": iotune.WriteBytesSec, + "write_bytes_sec_max": iotune.WriteBytesSecMax, + "write_iops_sec": iotune.WriteIOPSSec, + "write_iops_sec_max": iotune.WriteIOPSSecMax, + } + res = append(res, temp) + + return res +} + +func flattenSnapshots(snapshots compute.SnapshotExtendList) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(snapshots)) + for _, snapshot := range snapshots { + temp := map[string]interface{}{ + "guid": snapshot.GUID, + "label": snapshot.Label, + "res_id": snapshot.ResID, + "reference_id": snapshot.ReferenceID, + "snap_set_guid": snapshot.SnapSetGUID, + "snap_set_time": snapshot.SnapSetTime, + "timestamp": snapshot.TimeStamp, + } + res = append(res, temp) + } + + return res +} + +func flattenListComputeDisks(disks compute.ListComputeDisks) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(disks)) + for _, disk := range disks { + acl, _ := json.Marshal(disk.ACL) + temp := map[string]interface{}{ + "_ckey": disk.CKey, + "acl": string(acl), + "account_id": disk.AccountID, + "discard": disk.Discard, + "block_size": disk.BlockSize, + "boot_partition": disk.BootPartition, + "bus_number": disk.BusNumber, + "created_time": disk.CreatedTime, + "cache": disk.Cache, + "created_by": disk.CreatedBy, + "deleted_time": disk.DeletedTime, + "deleted_by": disk.DeletedBy, + "devicename": disk.DeviceName, + "description": disk.Description, + "destruction_time": disk.DestructionTime, + "disk_path": disk.DiskPath, + "gid": disk.GID, + "guid": disk.GUID, + "disk_id": disk.ID, + "image_id": disk.ImageID, + "images": disk.Images, + "iotune": flattenIotune(disk.IOTune), + "independent": disk.Independent, + "iqn": disk.IQN, + "login": disk.Login, + "milestones": disk.Milestones, + "name": disk.Name, + "params": disk.Params, + "parent_id": disk.ParentID, + "passwd": disk.Passwd, + "pci_slot": disk.PCISlot, + "pool": disk.Pool, + "present_to": disk.PresentTo, + "purge_time": disk.PurgeTime, + "replication": flattenDiskReplication(disk.Replication), + "reality_device_number": disk.RealityDeviceNumber, + "res_id": disk.ResID, + "role": disk.Role, + "sep_id": disk.SepID, + "shareable": disk.Shareable, + "size_available": disk.SizeAvailable, + "size_max": disk.SizeMax, + "size_used": disk.SizeUsed, + "snapshots": flattenSnapshots(disk.Snapshots), + "status": disk.Status, + "storage_policy_id": disk.StoragePolicyID, + "tech_status": disk.TechStatus, + "to_clean": disk.ToClean, + "provision": disk.Provision, + "updated_time": disk.UpdatedTime, + } + res = append(res, temp) + } + + return res +} + +func flattenDiskReplication(rep compute.ItemReplication) []map[string]interface{} { + res := []map[string]interface{}{ + { + "disk_id": rep.DiskID, + "pool_id": rep.PoolID, + "role": rep.Role, + "self_volume_id": rep.SelfVolumeID, + "storage_id": rep.StorageID, + "volume_id": rep.VolumeID, + }, + } + return res +} + +func flattenCustomFields(customFields map[string]interface{}) string { + encoded, _ := json.Marshal(customFields) + return string(encoded) +} + +func flattenOsUsers(osUsers compute.ListOSUser) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(osUsers)) + for _, user := range osUsers { + temp := map[string]interface{}{ + "guid": user.GUID, + "login": user.Login, + "password": user.Password, + "public_key": user.PubKey, + } + res = append(res, temp) + } + return res +} + +func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute, pciList *compute.ListPCIDevices) { + devices, _ := json.Marshal(computeRec.Devices) + userdata, _ := json.Marshal(computeRec.Userdata) + d.Set("acl", flattenACL(computeRec.ACL)) + d.Set("account_id", computeRec.AccountID) + d.Set("account_name", computeRec.AccountName) + d.Set("affinity_label", computeRec.AffinityLabel) + d.Set("affinity_rules", flattenAffinityRules(computeRec.AffinityRules)) + d.Set("affinity_weight", computeRec.AffinityWeight) + d.Set("anti_affinity_rules", flattenListRules(computeRec.AntiAffinityRules)) + d.Set("auto_start_w_node", computeRec.AutoStart) + d.Set("arch", computeRec.Architecture) + d.Set("chipset", computeRec.Chipset) + d.Set("clock", computeRec.Clock) + d.Set("boot_order", computeRec.BootOrder) + d.Set("bootdisk_size", computeRec.BootDiskSize) + d.Set("boot_image_id", computeRec.BootImageID) + d.Set("cd_image_id", computeRec.CdImageId) + d.Set("clone_reference", computeRec.CloneReference) + d.Set("clones", computeRec.Clones) + d.Set("computeci_id", computeRec.ComputeCIID) + d.Set("cpu_pin", computeRec.CPUPin) + d.Set("cpus", computeRec.CPU) + d.Set("created_by", computeRec.CreatedBy) + d.Set("created_time", computeRec.CreatedTime) + d.Set("custom_fields", flattenCustomFields(computeRec.CustomFields)) + d.Set("deleted_by", computeRec.DeletedBy) + d.Set("deleted_time", computeRec.DeletedTime) + d.Set("desc", computeRec.Description) + d.Set("devices", string(devices)) + d.Set("disks", flattenListComputeDisks(computeRec.Disks)) + d.Set("driver", computeRec.Driver) + d.Set("gid", computeRec.GID) + d.Set("guid", computeRec.GUID) + d.Set("hp_backed", computeRec.HPBacked) + d.Set("compute_id", computeRec.ID) + d.Set("image_id", computeRec.ImageID) + d.Set("image_name", computeRec.ImageName) + d.Set("interfaces", flattenInterfaces(computeRec.Interfaces)) + d.Set("live_migration_job_id", computeRec.LiveMigrationJobID) + d.Set("lock_status", computeRec.LockStatus) + d.Set("manager_id", computeRec.ManagerID) + d.Set("manager_type", computeRec.ManagerType) + d.Set("migrationjob", computeRec.MigrationJob) + d.Set("milestones", computeRec.Milestones) + d.Set("name", computeRec.Name) + d.Set("need_reboot", computeRec.NeedReboot) + d.Set("numa_affinity", computeRec.NumaAffinity) + d.Set("numa_node_id", computeRec.NumaNodeId) + d.Set("natable_vins_id", computeRec.NatableVINSID) + d.Set("natable_vins_ip", computeRec.NatableVINSIP) + d.Set("natable_vins_name", computeRec.NatableVINSName) + d.Set("natable_vins_network", computeRec.NatableVINSNetwork) + d.Set("natable_vins_network_name", computeRec.NatableVINSNetworkName) + d.Set("os_users", flattenOsUsers(computeRec.OSUsers)) + d.Set("pinned", computeRec.PinnedToNode) + d.Set("preferred_CPU", computeRec.PreferredCPU) + d.Set("qemu_guest", flattenQemuQuest(computeRec.QemuQuest)) + d.Set("ram", computeRec.RAM) + d.Set("reference_id", computeRec.ReferenceID) + d.Set("registered", computeRec.Registered) + d.Set("res_name", computeRec.ResName) + d.Set("reserved_node_cpus", computeRec.ReservedNodeCpus) + d.Set("rg_id", computeRec.RGID) + d.Set("rg_name", computeRec.RGName) + d.Set("snap_sets", flattenSnapSets(computeRec.SnapSets)) + d.Set("stateless_sep_id", computeRec.StatelessSepID) + d.Set("stateless_sep_type", computeRec.StatelessSepType) + d.Set("status", computeRec.Status) + d.Set("tags", computeRec.Tags) + d.Set("tech_status", computeRec.TechStatus) + d.Set("updated_by", computeRec.UpdatedBy) + d.Set("updated_time", computeRec.UpdatedTime) + d.Set("user_managed", computeRec.UserManaged) + d.Set("read_only", computeRec.ReadOnly) + d.Set("userdata", string(userdata)) + d.Set("vnc_password", computeRec.VNCPassword) + d.Set("vgpus", flattenVGPUs(computeRec.VGPUs)) + d.Set("pci_devices", flattenPCI(*pciList)) + d.Set("loader_type", computeRec.LoaderType) + d.Set("boot_type", computeRec.BootType) + d.Set("hot_resize", computeRec.HotResize) + d.Set("network_interface_naming", computeRec.NetworkInterfaceNaming) + d.Set("zone_id", computeRec.ZoneID) + d.Set("loader_meta_iso", flattenLoaderMetaIso(computeRec.LoaderMetaIso)) + d.Set("os_version", computeRec.OSVersion) + d.Set("cpu_alignment_profiles", flattenCPUAlignmentProfile(computeRec.CPUAlignmentProfile)) + d.Set("weight", computeRec.Weight) +} + +func flattenCPUAlignmentProfile(profile compute.CPUAlignmentProfile) []map[string]interface{} { + if profile.Name == "" && profile.Model == "" && profile.Vendor == "" { + return nil + } + return []map[string]interface{}{ + { + "name": profile.Name, + "model": profile.Model, + "vendor": profile.Vendor, + }, + } +} + +func flattenPCI(pciList compute.ListPCIDevices) []uint64 { + res := make([]uint64, 0, len(pciList.Data)) + + for _, v := range pciList.Data { + res = append(res, v.ID) + } + + return res +} + +func flattenComputeAudits(computeAudits compute.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computeAudits.Data)) + for _, computeAudit := range computeAudits.Data { + temp := map[string]interface{}{ + "call": computeAudit.Call, + "responsetime": computeAudit.ResponseTime, + "statuscode": computeAudit.StatusCode, + "timestamp": computeAudit.Timestamp, + "user": computeAudit.User, + } + res = append(res, temp) + } + return res +} + +func flattenPfwList(computePfws *compute.ListPFWs) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computePfws.Data)) + for _, computePfw := range computePfws.Data { + temp := map[string]interface{}{ + "pfw_id": computePfw.ID, + "local_ip": computePfw.LocalIP, + "local_port": computePfw.LocalPort, + "protocol": computePfw.Protocol, + "public_port_end": computePfw.PublicPortEnd, + "public_port_start": computePfw.PublicPortStart, + "vm_id": computePfw.VMID, + } + res = append(res, temp) + } + return res +} + +func flattenUserList(d *schema.ResourceData, userList *compute.ListUsers) { + d.Set("account_acl", flattenListACL(userList.Data.AccountACL)) + d.Set("compute_acl", flattenListACL(userList.Data.ComputeACL)) + d.Set("rg_acl", flattenListACL(userList.Data.RGACL)) +} + +func flattenComputeGetAudits(computeAudits compute.ListShortAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computeAudits)) + for _, computeAudit := range computeAudits { + temp := map[string]interface{}{ + "epoch": computeAudit.Epoch, + "message": computeAudit.Message, + } + res = append(res, temp) + } + return res +} + +func flattenSnapshotUsage(computeSnapshotUsages compute.ListUsageSnapshots) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computeSnapshotUsages)) + for _, computeUsage := range computeSnapshotUsages { + temp := map[string]interface{}{ + "count": computeUsage.Count, + "stored": computeUsage.Stored, + "label": computeUsage.Label, + "timestamp": computeUsage.Timestamp, + } + res = append(res, temp) + } + return res +} + +// func flattenSnapshotList(computeSnapshotUsages *compute.ListSnapShots) []map[string]interface{} { +// res := make([]map[string]interface{}, 0, len(computeSnapshotUsages.Data)) +// for _, computeUsage := range computeSnapshotUsages.Data { +// temp := map[string]interface{}{ +// "disks": computeUsage.Disks, +// "guid": computeUsage.GUID, +// "label": computeUsage.Label, +// "timestamp": computeUsage.Timestamp, +// } +// res = append(res, temp) +// } +// return res +// } + +func flattenVGPU(vgpuList []compute.ItemVGPU) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vgpuList)) + for _, dev := range vgpuList { + temp := map[string]interface{}{ + "account_id": dev.AccountID, + "created_time": dev.CreatedTime, + "deleted_time": dev.DeletedTime, + "gid": dev.GID, + "guid": dev.GUID, + "vgpu_id": dev.ID, + "last_claimed_by": dev.LastClaimedBy, + "last_update_time": dev.LastUpdateTime, + "mode": dev.Mode, + "pci_slot": dev.PCISlot, + "pgpuid": dev.PGPUID, + "profile_id": dev.ProfileID, + "ram": dev.RAM, + "reference_id": dev.ReferenceID, + "rg_id": dev.RGID, + "status": dev.Status, + "type": dev.Type, + "vm_id": dev.VMID, + } + res = append(res, temp) + } + return res +} + +func flattenPCIDevice(deviceList []compute.ItemPCIDevice) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(deviceList)) + for _, dev := range deviceList { + temp := map[string]interface{}{ + "compute_id": dev.ComputeID, + "description": dev.Description, + "guid": dev.GUID, + "hwpath": dev.HwPath, + "device_id": dev.ID, + "name": dev.Name, + "rg_id": dev.RGID, + "node_id": dev.NodeID, + "status": dev.Status, + "system_name": dev.SystemName, + } + res = append(res, temp) + } + return res +} + +func flattenVGPUs(vgpus []compute.VGPUItem) []map[string]interface{} { + res := make([]map[string]interface{}, len(vgpus)) + + for i, vgpu := range vgpus { + + res[i] = map[string]interface{}{ + "id": int(vgpu.ID), + "gid": int(vgpu.GID), + "type": vgpu.Type, + "mode": vgpu.Mode, + "status": vgpu.Status, + "profile_id": vgpu.ProfileID, + "ram": int(vgpu.RAM), + "last_update_time": int(vgpu.LastUpdateTime), + "created_time": int(vgpu.CreatedTime), + "deleted_time": int(vgpu.DeletedTime), + "vmid": int(vgpu.VMID), + "pgpuid": int(vgpu.PGPuid), + "reference_id": vgpu.ReferenceID, + "account_id": int(vgpu.AccountID), + "rg_id": int(vgpu.RgID), + "last_claimed_by": int(vgpu.LastClaimedBy), + "pci_slot": int(vgpu.PCISlot), + "bus_number": int(vgpu.BusNumber), + "guid": int(vgpu.GUID), + } + } + + return res +} + +func flattenQemuQuest(qemuQuest compute.QemuQuest) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + + temp := map[string]interface{}{ + "enabled": qemuQuest.Enabled, + "enabled_agent_features": qemuQuest.EnabledAgentFeatures, + "guid": qemuQuest.GUID, + "last_update": uint64(qemuQuest.LastUpdate), + "user": qemuQuest.User, + } + + res = append(res, temp) + + return res +} diff --git a/internal/service/cloudapi/kvmvm/models.go b/internal/service/cloudapi/kvmvm/models.go new file mode 100644 index 00000000..2a63815f --- /dev/null +++ b/internal/service/cloudapi/kvmvm/models.go @@ -0,0 +1,10 @@ +package kvmvm + +type updatedNetwork struct { + DetachMap []map[string]interface{} + ChangeIPMap []map[string]interface{} + ChangeMacMap []map[string]interface{} + ChangeMTUMap []map[string]interface{} + AttachMap []map[string]interface{} + EnableMap []map[string]interface{} +} diff --git a/internal/service/cloudapi/kvmvm/network_subresource.go b/internal/service/cloudapi/kvmvm/network_subresource.go new file mode 100644 index 00000000..75d6d900 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/network_subresource.go @@ -0,0 +1,196 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "bytes" + "hash/fnv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" + + "sort" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +// This is subresource of compute resource used when creating/managing compute network connections + +func networkSubresIPAddreDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool { + if newVal != "" && newVal != oldVal { + log.Debugf("networkSubresIPAddreDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal) + return false + } + log.Debugf("networkSubresIPAddreDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal) + return true // suppress difference +} + +// This function is based on the original Terraform SerializeResourceForHash found +// in helper/schema/serialize.go +// It skips network subresource attributes, which are irrelevant for identification +// of unique network blocks +func networkSubresourceSerialize(output *bytes.Buffer, val interface{}, resource *schema.Resource) { + if val == nil { + return + } + + rs := resource.Schema + m := val.(map[string]interface{}) + + keys := make([]string, 0, len(rs)) + allComputed := true + + for k, val := range rs { + if val.Optional || val.Required { + allComputed = false + } + + keys = append(keys, k) + } + + sort.Strings(keys) + for _, k := range keys { + // explicitly ignore "ip_address" when hashing + if k == "ip_address" { + continue + } + + subSchema := rs[k] + // Skip attributes that are not user-provided. Computed attributes + // do not contribute to the hash since their ultimate value cannot + // be known at plan/diff time. + if !allComputed && !(subSchema.Required || subSchema.Optional) { + continue + } + + output.WriteString(k) + output.WriteRune(':') + value := m[k] + schema.SerializeValueForHash(output, value, subSchema) + } +} + +// HashNetworkSubresource hashes network subresource of compute resource. It uses +// specially designed networkSubresourceSerialize (see above) to make sure hashing +// does not involve attributes that we deem irrelevant to the uniqueness of network +// subresource definitions. +// It is this function that should be specified as SchemaSetFunc when creating Set +// from network subresource (e.g. in flattenCompute) +// +// This function is based on the original Terraform function HashResource from +// helper/schema/set.go +func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc { + return func(v interface{}) int { + var serialized bytes.Buffer + networkSubresourceSerialize(&serialized, v, resource) + + hs := fnv.New32a() + hs.Write(serialized.Bytes()) + return int(hs.Sum32()) + } +} + +func networkSubresourceSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS", "VFNIC", "DPDK", "SDN", "TRUNK"}, false), // observe case while validating + Description: "Type of the network for this connection", + }, + + "net_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the network for this connection.", + }, + + "ip_address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: networkSubresIPAddreDiffSupperss, + Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.", + }, + + "mac": { + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: networkSubresIPAddreDiffSupperss, + Description: "MAC address associated with this connection. MAC address is assigned automatically.", + }, + + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "weight the network if you need to sort network list, the smallest attach first. zero or null weight attach last", + }, + + "mtu": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + //Default: 1500, + ValidateFunc: validation.IntBetween(1500, 9216), + Description: "Maximum transmission unit, used only for DPDK type, must be 1500-9216", + }, + + "sdn_interface_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: networkSubresIPAddreDiffSupperss, + Description: "unique_identifier of LogicalPort on SDN side", + }, + + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "network enable flag", + }, + + "net_mask": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Subnet mask, used only for DPDK and VFNIC network types", + }, + } + return rets +} diff --git a/internal/service/cloudapi/kvmvm/old_schemas.go b/internal/service/cloudapi/kvmvm/old_schemas.go new file mode 100644 index 00000000..0c09ce1a --- /dev/null +++ b/internal/service/cloudapi/kvmvm/old_schemas.go @@ -0,0 +1,1445 @@ +package kvmvm + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" +) + +func resourceComputeResourceV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "ID of the resource group where this compute should be deployed.", + }, + "driver": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86"}, false), // observe case while validating + Description: "Hardware architecture of this compute instance.", + }, + "cpu": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, constants.MAX_CPUS_PER_COMPUTE), + Description: "Number of CPUs to allocate to this compute instance.", + }, + "ram": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + Description: "Amount of RAM in MB to allocate to this compute instance.", + }, + "image_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, //REDEPLOY + Description: "ID of the OS image to base this compute instance on.", + }, + "boot_disk_size": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.", + }, + "affinity_label": { + Type: schema.TypeString, + Optional: true, + Description: "Set affinity label for compute", + }, + "affinity_rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topology": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false), + Description: "compute or node, for whom rule applies", + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false), + Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule", + }, + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false), + Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'", + }, + "key": { + Type: schema.TypeString, + Required: true, + Description: "key that are taken into account when analyzing this rule will be identified", + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: "value that must match the key to be taken into account when analyzing this rule", + }, + }, + }, + }, + "anti_affinity_rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topology": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false), + Description: "compute or node, for whom rule applies", + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false), + Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule", + }, + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false), + Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'", + }, + "key": { + Type: schema.TypeString, + Required: true, + Description: "key that are taken into account when analyzing this rule will be identified", + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: "value that must match the key to be taken into account when analyzing this rule", + }, + }, + }, + }, + "disks": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: disksSubresourceSchemaMake(), + }, + }, + "custom_fields": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Computed: true, + }, + "val": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "stateless": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Compute will be stateless (SVA_KVM_X86) if set to True", + }, + "with_default_vins": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Create compute with default resgroup ViNS (true) or without any interfaces (false). This parameter is ignored if network block is specified", + }, + "boot_disk": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: disksSubresourceSchemaMake(), + }, + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ForceNew: true, + Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.", + }, + + "extra_disks": { + Type: schema.TypeSet, + Optional: true, + MaxItems: constants.MAX_EXTRA_DISKS_PER_COMPUTE, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.", + }, + + "network": { + Type: schema.TypeSet, + Optional: true, + MinItems: 1, + MaxItems: constants.MAX_NETWORKS_PER_COMPUTE, + Elem: &schema.Resource{ + Schema: networkSubresourceSchemaMake(), + }, + Description: "Optional network connection(s) for this compute. You may specify several network blocks, one for each connection.", + }, + + "tags": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: tagsSubresourceSchemaMake(), + }, + }, + + "port_forwarding": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: portForwardingSubresourceSchemaMake(), + }, + }, + + "user_access": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: userAccessSubresourceSchemaMake(), + }, + }, + + "snapshot": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: snapshotSubresourceSchemaMake(), + }, + }, + + "rollback": { + Type: schema.TypeSet, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: snapshotRollbackSubresourceSchemaMake(), + }, + }, + + "cd": { + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: cdSubresourceSchemaMake(), + }, + }, + + "pin_to_stack": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Optional text description of this compute instance.", + }, + + "cloud_init": { + Type: schema.TypeString, + Optional: true, + Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.", + }, + + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "If true - enable compute, else - disable", + }, + + "pause": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "reset": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "auto_start": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Flag for redeploy compute", + }, + "force_stop": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Flag for redeploy compute", + }, + "data_disks": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"KEEP", "DETACH", "DESTROY"}, false), + Default: "DETACH", + Description: "Flag for redeploy compute", + }, + "started": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Is compute started.", + }, + "detach_disks": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "is": { + Type: schema.TypeString, + Optional: true, + Description: "system name", + }, + "ipa_type": { + Type: schema.TypeString, + Optional: true, + Description: "compute purpose", + }, + // The rest are Compute properties, which are "computed" once it is created + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the account this compute instance belongs to.", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account this compute instance belongs to.", + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "arch": { + Type: schema.TypeString, + Computed: true, + }, + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "boot_disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "This compute instance boot disk ID.", + }, + "clone_reference": { + Type: schema.TypeInt, + Computed: true, + }, + "clones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devices": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeInterfacesSchemaMake(), + }, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "migrationjob": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_ip": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_name": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network_name": { + Type: schema.TypeString, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: osUsersSubresourceSchemaMake(), + }, + Description: "Guest OS users provisioned on this compute instance.", + }, + "pinned": { + Type: schema.TypeBool, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource group where this compute instance is located.", + }, + "snap_sets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeSnapSetsSchemaMake(), + }, + }, + "stateless_sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stateless_sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vgpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "virtual_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "virtual_image_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceComputeResourceV2() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "ID of the resource group where this compute should be deployed.", + }, + "driver": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86"}, false), // observe case while validating + Description: "Hardware architecture of this compute instance.", + }, + "cpu": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, constants.MAX_CPUS_PER_COMPUTE), + Description: "Number of CPUs to allocate to this compute instance.", + }, + "ram": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + Description: "Amount of RAM in MB to allocate to this compute instance.", + }, + "image_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, //REDEPLOY + Description: "ID of the OS image to base this compute instance on.", + }, + "boot_disk_size": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.", + }, + "affinity_label": { + Type: schema.TypeString, + Optional: true, + Description: "Set affinity label for compute", + }, + "affinity_rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topology": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false), + Description: "compute or node, for whom rule applies", + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false), + Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule", + }, + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false), + Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'", + }, + "key": { + Type: schema.TypeString, + Required: true, + Description: "key that are taken into account when analyzing this rule will be identified", + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: "value that must match the key to be taken into account when analyzing this rule", + }, + }, + }, + }, + "anti_affinity_rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topology": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false), + Description: "compute or node, for whom rule applies", + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false), + Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule", + }, + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false), + Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'", + }, + "key": { + Type: schema.TypeString, + Required: true, + Description: "key that are taken into account when analyzing this rule will be identified", + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: "value that must match the key to be taken into account when analyzing this rule", + }, + }, + }, + }, + "disks": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_name": { + Type: schema.TypeString, + Required: true, + Description: "Name for disk", + }, + "size": { + Type: schema.TypeInt, + Required: true, + Description: "Disk size in GiB", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Storage endpoint provider ID; by default the same with boot disk", + }, + "disk_type": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false), + Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Pool name; by default will be chosen automatically", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Optional description", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Specify image id for create disk from template", + }, + "permanently": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: "Disk deletion status", + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk ID", + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "custom_fields": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "stateless": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Compute will be stateless (SVA_KVM_X86) if set to True", + }, + "with_default_vins": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Create compute with default resgroup ViNS (true) or without any interfaces (false). This parameter is ignored if network block is specified", + }, + "boot_disk": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_name": { + Type: schema.TypeString, + Required: true, + Description: "Name for disk", + }, + "size": { + Type: schema.TypeInt, + Required: true, + Description: "Disk size in GiB", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Storage endpoint provider ID; by default the same with boot disk", + }, + "disk_type": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false), + Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Pool name; by default will be chosen automatically", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Optional description", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Specify image id for create disk from template", + }, + "permanently": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: "Disk deletion status", + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk ID", + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ForceNew: true, + Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.", + }, + + "extra_disks": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + MaxItems: constants.MAX_EXTRA_DISKS_PER_COMPUTE, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.", + }, + + "network": { + Type: schema.TypeSet, + Optional: true, + MinItems: 1, + MaxItems: constants.MAX_NETWORKS_PER_COMPUTE, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS"}, false), // observe case while validating + Description: "Type of the network for this connection, either EXTNET or VINS.", + }, + + "net_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the network for this connection.", + }, + + "ip_address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: networkSubresIPAddreDiffSupperss, + Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.", + }, + + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address associated with this connection. MAC address is assigned automatically.", + }, + }, + }, + Description: "Optional network connection(s) for this compute. You may specify several network blocks, one for each connection.", + }, + + "tags": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Required: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + + "port_forwarding": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "public_port_start": { + Type: schema.TypeInt, + Required: true, + }, + "public_port_end": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + }, + "local_port": { + Type: schema.TypeInt, + Required: true, + }, + "proto": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false), + }, + }, + }, + }, + + "user_access": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + }, + "access_type": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + + "snapshot": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + + "rollback": { + Type: schema.TypeSet, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + + "cd": { + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cdrom_id": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + + "pin_to_stack": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Optional text description of this compute instance.", + }, + + "cloud_init": { + Type: schema.TypeString, + Optional: true, + Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.", + }, + + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "If true - enable compute, else - disable", + }, + + "pause": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "reset": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "auto_start": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Flag for redeploy compute", + }, + "force_stop": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Flag for redeploy compute", + }, + "data_disks": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"KEEP", "DETACH", "DESTROY"}, false), + Default: "DETACH", + Description: "Flag for redeploy compute", + }, + "started": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Is compute started.", + }, + "detach_disks": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "is": { + Type: schema.TypeString, + Optional: true, + Description: "system name", + }, + "ipa_type": { + Type: schema.TypeString, + Optional: true, + Description: "compute purpose", + }, + // The rest are Compute properties, which are "computed" once it is created + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the account this compute instance belongs to.", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account this compute instance belongs to.", + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "arch": { + Type: schema.TypeString, + Computed: true, + }, + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "boot_disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "This compute instance boot disk ID.", + }, + "clone_reference": { + Type: schema.TypeInt, + Computed: true, + }, + "clones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devices": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "flip_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + "listen_ssh": { + Type: schema.TypeBool, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_brust": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "target": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "migrationjob": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_ip": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_name": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network_name": { + Type: schema.TypeString, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "GUID of this guest OS user.", + }, + + "login": { + Type: schema.TypeString, + Computed: true, + Description: "Login name of this guest OS user.", + }, + + "password": { + Type: schema.TypeString, + Computed: true, + //Sensitive: true, + Description: "Password of this guest OS user.", + }, + + "public_key": { + Type: schema.TypeString, + Computed: true, + Description: "SSH public key of this guest OS user.", + }, + }, + }, + Description: "Guest OS users provisioned on this compute instance.", + }, + "pinned": { + Type: schema.TypeBool, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource group where this compute instance is located.", + }, + "snap_sets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "stateless_sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stateless_sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vgpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "virtual_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "virtual_image_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceComputeResourceV3() *schema.Resource { + s := ResourceComputeSchemaMake() + + for _, blockKey := range []string{"disks", "boot_disk"} { + if block, ok := s[blockKey]; ok { + if res, ok := block.Elem.(*schema.Resource); ok { + res.Schema["blk_discard"] = &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + } + } + } + } + return &schema.Resource{Schema: s} +} diff --git a/internal/service/cloudapi/kvmvm/osusers_subresource.go b/internal/service/cloudapi/kvmvm/osusers_subresource.go new file mode 100644 index 00000000..49e3f67e --- /dev/null +++ b/internal/service/cloudapi/kvmvm/osusers_subresource.go @@ -0,0 +1,88 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func parseOsUsers(logins compute.ListOSUser) []interface{} { + var result = make([]interface{}, len(logins)) + + for index, value := range logins { + elem := make(map[string]interface{}) + + elem["guid"] = value.GUID + elem["login"] = value.Login + elem["password"] = value.Password + elem["public_key"] = value.PubKey + result[index] = elem + log.Debugf("parseOsUsers: parsed element %d - login %q", index, value.Login) + } + + return result +} + +func osUsersSubresourceSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "GUID of this guest OS user.", + }, + + "login": { + Type: schema.TypeString, + Computed: true, + Description: "Login name of this guest OS user.", + }, + + "password": { + Type: schema.TypeString, + Computed: true, + //Sensitive: true, + Description: "Password of this guest OS user.", + }, + + "public_key": { + Type: schema.TypeString, + Computed: true, + Description: "SSH public key of this guest OS user.", + }, + } + + return rets +} diff --git a/internal/service/cloudapi/kvmvm/resource_check_input_values.go b/internal/service/cloudapi/kvmvm/resource_check_input_values.go new file mode 100644 index 00000000..a14aea2e --- /dev/null +++ b/internal/service/cloudapi/kvmvm/resource_check_input_values.go @@ -0,0 +1,184 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/dpdknet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/trunk" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vfpool" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func existRgID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + rgId := uint64(d.Get("rg_id").(int)) + req := rg.ListRequest{ + IncludeDeleted: false, + } + + rgList, err := c.CloudAPI().RG().List(ctx, req) + if err != nil { + return false, err + } + + return len(rgList.FilterByID(rgId).Data) != 0, nil +} + +func existImageId(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + imageId := uint64(d.Get("image_id").(int)) + req := image.ListRequest{ + ByID: imageId, + } + + imageList, err := c.CloudAPI().Image().List(ctx, req) + if err != nil { + return false, err + } + + return len(imageList.Data) != 0, nil +} + +func existVinsIdInList(vinsId uint64, vinsList *vins.ListVINS) bool { + for _, vins := range vinsList.Data { + if vinsId == vins.ID { + return true + } + } + + return false +} + +func existExtNetIdInList(extId uint64, extList *extnet.ListExtNets) bool { + for _, ext := range extList.Data { + if extId == ext.ID { + return true + } + } + + return false +} + +func existVinsId(ctx context.Context, m interface{}, id int) (int, bool) { + c := m.(*controller.ControllerCfg) + req := vins.ListRequest{IncludeDeleted: false} + + vinsList, err := c.CloudAPI().VINS().List(ctx, req) + if err != nil { + log.Debugf("Unable to retrieve ViNS list, %s", err) + return 0, false + } + + if !existVinsIdInList(uint64(id), vinsList) { + return id, false + } + + return 0, true +} + +func existExtNetId(ctx context.Context, m interface{}, id int) (int, bool) { + c := m.(*controller.ControllerCfg) + req := extnet.ListRequest{} + + extNetList, err := c.CloudAPI().ExtNet().List(ctx, req) + if err != nil { + log.Debugf("Unable to retrieve extnet list, %s", err) + return 0, false + } + + if !existExtNetIdInList(uint64(id), extNetList) { + return id, false + } + + return 0, true +} + +func existVFPoolId(ctx context.Context, m interface{}, id int) (int, bool) { + c := m.(*controller.ControllerCfg) + req := vfpool.ListRequest{ByID: uint64(id)} + + vfpoolList, err := c.CloudAPI().VFPool().List(ctx, req) + if err != nil { + log.Debugf("Unable to retrieve vfpool list, %s", err) + return id, false + } + + if len(vfpoolList.Data) == 1 { + return 0, true + } + + return id, false +} + +func existDPDKNetId(ctx context.Context, m interface{}, id int) (int, bool) { + c := m.(*controller.ControllerCfg) + req := dpdknet.ListRequest{ByID: uint64(id)} + + dpdkList, err := c.CloudAPI().DPDKNet().List(ctx, req) + if err != nil { + log.Debugf("Unable to retrieve dpdk list, %s", err) + return id, false + } + + if len(dpdkList.Data) == 1 { + return 0, true + } + + return id, false +} + +func existTRUNKId(ctx context.Context, m interface{}, id int) (int, bool) { + c := m.(*controller.ControllerCfg) + req := trunk.ListRequest{IDs: []uint64{uint64(id)}} + + trunkList, err := c.CloudAPI().Trunk().List(ctx, req) + if err != nil { + log.Debugf("Unable to retrieve trunk list, %s", err) + return id, false + } + + if len(trunkList.Data) == 1 { + return 0, true + } + + return id, false +} diff --git a/internal/service/cloudapi/kvmvm/resource_compute.go b/internal/service/cloudapi/kvmvm/resource_compute.go new file mode 100644 index 00000000..19066d71 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/resource_compute.go @@ -0,0 +1,3186 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "errors" + "fmt" + "sort" + "strconv" + "strings" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmx86" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int)) + c := m.(*controller.ControllerCfg) + createReqX86 := kvmx86.CreateRequest{} + + hasRG, err := existRgID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !hasRG { + return diag.Errorf("resourceComputeCreate: can't create Compute because rgID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + + if !d.Get("create_blank").(bool) { + hasImage, err := existImageId(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !hasImage { + return diag.Errorf("resourceComputeCreate: can't create Compute because imageID %d is not allowed or does not exist", d.Get("image_id").(int)) + } + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + createReqX86.ZoneID = uint64(zoneID.(int)) + } + + if network, ok := d.GetOk("network"); ok { + networkList := network.(*schema.Set).List() + for _, elem := range networkList { + networkData := elem.(map[string]interface{}) + + switch networkData["net_type"].(string) { + case "VINS": + if vinsId, ok := existVinsId(ctx, m, networkData["net_id"].(int)); !ok { + return diag.Errorf("resourceComputeCreate: can't create compute because vins ID %d is not allowed or does not exist", vinsId) + } + case "EXTNET": + if extNetId, ok := existExtNetId(ctx, m, networkData["net_id"].(int)); !ok { + return diag.Errorf("resourceComputeCreate: can't create compute because extnet ID %d is not allowed or does not exist", extNetId) + } + case "VFNIC": + if vfpoolId, ok := existVFPoolId(ctx, m, networkData["net_id"].(int)); !ok { + return diag.Errorf("resourceComputeCreate: can't create compute because vfpool ID %d is not allowed or does not exist", vfpoolId) + } + case "DPDK": + if dpdkId, ok := existDPDKNetId(ctx, m, networkData["net_id"].(int)); !ok { + return diag.Errorf("resourceComputeCreate: can't create compute because DPDK ID %d is not allowed or does not exist", dpdkId) + } + case "TRUNK": + if trunkId, ok := existTRUNKId(ctx, m, networkData["net_id"].(int)); !ok { + return diag.Errorf("resourceComputeCreate: can't create compute because TRUNK ID %d is not allowed or does not exist", trunkId) + } + default: + continue + } + } + } + + argVal, ok := d.GetOk("description") + if ok { + createReqX86.Description = argVal.(string) + } + + if sepID, ok := d.GetOk("sep_id"); ok { + createReqX86.SepID = uint64(sepID.(int)) + } + + if pool, ok := d.GetOk("pool"); ok { + createReqX86.Pool = pool.(string) + } + + if bootSize, ok := d.GetOk("boot_disk_size"); ok { + createReqX86.BootDisk = uint64(bootSize.(int)) + } + + if networks, ok := d.GetOk("network"); ok { + if networks.(*schema.Set).Len() > 0 { + ns := networks.(*schema.Set).List() + + sort.Slice(ns, func(i, j int) bool { + weightI := ns[i].(map[string]interface{})["weight"].(int) + weightJ := ns[j].(map[string]interface{})["weight"].(int) + if weightI == 0 { + return false + } + if weightJ == 0 { + return true + } + return weightI < weightJ + }) + interfaces := make([]kvmx86.Interface, 0) + for _, elem := range ns { + netInterfaceVal := elem.(map[string]interface{}) + reqInterface := kvmx86.Interface{ + NetType: netInterfaceVal["net_type"].(string), + NetID: uint64(netInterfaceVal["net_id"].(int)), + } + + if enabledNetwork(d.GetRawConfig().GetAttr("network"), reqInterface.NetID, reqInterface.NetType) { + reqInterface.Enabled = netInterfaceVal["enabled"].(bool) + } + + if reqInterface.NetType == "DPDK" || reqInterface.NetType == "EXTNET" || reqInterface.NetType == "TRUNK" { + reqInterface.MTU = uint64(netInterfaceVal["mtu"].(int)) + } + + if reqInterface.NetType == "DPDK" || reqInterface.NetType == "VFNIC" { + if netMask, netMaskSet := netInterfaceVal["net_mask"]; netMaskSet { + reqInterface.NetMask = uint64(netMask.(int)) + } + } + + ipaddr, ipSet := netInterfaceVal["ip_address"] + if ipSet { + reqInterface.IPAddr = ipaddr.(string) + } + + macaddr, macSet := netInterfaceVal["mac"] + if macSet { + reqInterface.MAC = macaddr.(string) + } + + sdnID, sdnSet := netInterfaceVal["sdn_interface_id"] + if sdnSet { + reqInterface.SDNInterfaceID = sdnID.(string) + } + + interfaces = append(interfaces, reqInterface) + } + + createReqX86.Interfaces = interfaces + } + } + + if disks, ok := d.GetOk("disks"); ok { + disksX86 := make([]kvmx86.DataDisk, 0) + + for _, elem := range disks.([]interface{}) { + diskVal := elem.(map[string]interface{}) + reqDataDisk := kvmx86.DataDisk{ + DiskName: diskVal["disk_name"].(string), + Size: uint64(diskVal["size"].(int)), + StoragePolicyID: uint64(diskVal["storage_policy_id"].(int)), + } + if sepId, ok := diskVal["sep_id"]; ok { + reqDataDisk.SepID = uint64(sepId.(int)) + } + if pool, ok := diskVal["pool"]; ok { + reqDataDisk.Pool = pool.(string) + } + if desc, ok := diskVal["desc"]; ok { + reqDataDisk.Description = desc.(string) + } + if imageID, ok := diskVal["image_id"]; ok { + reqDataDisk.ImageID = uint64(imageID.(int)) + } + disksX86 = append(disksX86, reqDataDisk) + } + + createReqX86.DataDisks = disksX86 + + } + + argVal, ok = d.GetOk("cloud_init") + if ok { + userdata := argVal.(string) + if userdata != "" && userdata != "applied" { + createReqX86.Userdata = strings.TrimSpace(userdata) + } + } + + var computeId uint64 + + createReqX86.RGID = uint64(d.Get("rg_id").(int)) + createReqX86.Name = d.Get("name").(string) + createReqX86.CPU = uint64(d.Get("cpu").(int)) + createReqX86.RAM = uint64(d.Get("ram").(int)) + createReqX86.StoragePolicyID = uint64(d.Get("storage_policy_id").(int)) + + if image, ok := d.GetOk("image_id"); ok { + createReqX86.ImageID = uint64(image.(int)) + } + if withoutBootDisk, ok := d.GetOk("without_boot_disk"); ok { + createReqX86.WithoutBootDisk = withoutBootDisk.(bool) + } + + if custom_fields, ok := d.GetOk("custom_fields"); ok { + val := custom_fields.(string) + val = strings.ReplaceAll(val, "\\", "") + val = strings.ReplaceAll(val, "\n", "") + val = strings.ReplaceAll(val, "\t", "") + val = strings.TrimSpace(val) + + createReqX86.CustomFields = val + } + + if numaAffinity, ok := d.GetOk("numa_affinity"); ok { + createReqX86.NumaAffinity = numaAffinity.(string) + } + createReqX86.CPUPin = d.Get("cpu_pin").(bool) + createReqX86.HPBacked = d.Get("hp_backed").(bool) + createReqX86.Chipset = d.Get("chipset").(string) + if clock, ok := d.GetOk("clock"); ok { + createReqX86.Clock = clock.(string) + } + + if preferredCPU, ok := d.GetOk("preferred_cpu"); ok { + preferredList := preferredCPU.([]interface{}) + if len(preferredList) > 0 { + for _, v := range preferredList { + cpuNum := v.(int) + createReqX86.PreferredCPU = append(createReqX86.PreferredCPU, int64(cpuNum)) + } + } + } + + if osVersion, ok := d.GetOk("os_version"); ok { + createReqX86.OSVersion = osVersion.(string) + } + + log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86") + var apiResp uint64 + if d.Get("create_blank").(bool) { + log.Debugf("resourceComputeCreate: using createBlank endpoint") + createBlankReq := kvmx86.CreateBlankRequest{ + RGID: createReqX86.RGID, + Name: createReqX86.Name, + CPU: createReqX86.CPU, + RAM: createReqX86.RAM, + StoragePolicyID: createReqX86.StoragePolicyID, + WithoutBootDisk: createReqX86.WithoutBootDisk, + BootDisk: createReqX86.BootDisk, + SEPID: createReqX86.SepID, + Pool: createReqX86.Pool, + DataDisks: createReqX86.DataDisks, + Interfaces: createReqX86.Interfaces, + Description: createReqX86.Description, + Chipset: createReqX86.Chipset, + PreferredCPU: createReqX86.PreferredCPU, + ZoneID: createReqX86.ZoneID, + OSVersion: createReqX86.OSVersion, + } + apiResp, err = c.CloudAPI().KVMX86().CreateBlank(ctx, createBlankReq) + } else { + apiResp, err = c.CloudAPI().KVMX86().Create(ctx, createReqX86) + } + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(apiResp, 10)) + computeId = apiResp + + warnings := dc.Warnings{} + + simpleCompRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + warnings.Add(err) + } + + cleanup := false + defer func() { + if cleanup { + req := compute.DeleteRequest{ + ComputeID: computeId, + Permanently: true, + DetachDisks: true, + } + + if _, err := c.CloudAPI().Compute().Delete(ctx, req); err != nil { + log.Errorf("resourceComputeCreate: could not delete compute after failed creation: %v", err) + } + + d.SetId("") + } + }() + + log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", computeId, d.Get("name").(string)) + + updateReq := compute.UpdateRequest{} + + loaderType, loaderTypeOk := d.GetOk("loader_type") + bootType, bootTypeOk := d.GetOk("boot_type") + hotResize, hotResizeOk := d.GetOkExists("hot_resize") + networkInterfaceNaming, networkInterfaceNamingOk := d.GetOk("network_interface_naming") + + if loaderTypeOk { + updateReq.LoaderType = loaderType.(string) + } + + if bootTypeOk { + updateReq.BootType = bootType.(string) + } + + if hotResizeOk { + updateReq.HotResize = hotResize.(bool) + } + + if networkInterfaceNamingOk { + updateReq.NetworkInterfaceNaming = networkInterfaceNaming.(string) + } + + if loaderTypeOk || bootTypeOk || hotResizeOk || networkInterfaceNamingOk { + log.Debugf("resourceComputeCreate: change loaderType or bootType or hotResize or networkInterfaceNaming on ComputeID: %d", computeId) + updateReq.ComputeID = computeId + _, err := c.CloudAPI().Compute().Update(ctx, updateReq) + if err != nil { + warnings.Add(err) + } + } + + if ars, ok := d.GetOk("pci_devices"); ok { + log.Debugf("resourceComputeCreate: add pci devices on ComputeID: %d", computeId) + addedPciDevices := ars.(*schema.Set).List() + if len(addedPciDevices) > 0 { + for _, v := range addedPciDevices { + devicesConv := v.(int) + req := compute.AttachPCIDeviceRequest{ + ComputeID: computeId, + DeviceID: uint64(devicesConv), + } + + _, err := c.CloudAPI().Compute().AttachPCIDevice(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + argVal, ok = d.GetOk("extra_disks") + if ok && argVal.(*schema.Set).Len() > 0 { + log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len()) + err = utilityComputeExtraDisksConfigure(ctx, d, m, false, nil) + if err != nil { + log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", computeId, err) + cleanup = true + return diag.FromErr(err) + } + } + + if _, ok := d.GetOk("disks"); ok { + if err := utilityComputeCreateIOTune(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + if !cleanup { + + if enabled, ok := d.GetOk("enabled"); ok { + if enabled.(bool) { + req := compute.EnableRequest{ComputeID: computeId} + log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId) + if _, err := c.CloudAPI().Compute().Enable(ctx, req); err != nil { + warnings.Add(err) + } + } else { + req := compute.DisableRequest{ComputeID: computeId} + log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId) + if _, err := c.CloudAPI().Compute().Disable(ctx, req); err != nil { + warnings.Add(err) + } + } + } + + if secGroups, ok := d.GetOk("security_groups"); ok { + if secGroups.(*schema.Set).Len() > 0 { + sgl := secGroups.(*schema.Set).List() + for _, elem := range sgl { + secGroupsMap := elem.(map[string]interface{}) + + netType := secGroupsMap["net_type"].(string) + netId := uint64(secGroupsMap["net_id"].(int)) + var mac string + for _, iface := range simpleCompRec.Interfaces { + if iface.NetID == netId && iface.NetType == netType { + mac = iface.MAC + break + } + } + if mac == "" { + warnings.Add(fmt.Errorf("add security groups: Network with type %s and id %d is not connected to the compute %d", netType, netId, computeId)) + continue + } + secGroupsIDs := make([]uint64, 0) + for _, id := range secGroupsMap["security_groups"].(*schema.Set).List() { + secGroupsIDs = append(secGroupsIDs, uint64(id.(int))) + } + log.Debugf("resourceComputeCreate: Configure security groups interface parameters on Network with type %s and id %d", netType, netId) + req := compute.ChangeSecGroupsRequest{ + ComputeID: computeId, + Interface: mac, + SecGroups: secGroupsIDs, + EnableSecGroups: secGroupsMap["enable_secgroups"].(bool), + } + + _, err := c.CloudAPI().Compute().ChangeSecGroups(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + // Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface), + // now we need to start it before we report the sequence complete + if start, ok := d.GetOk("started"); ok { + if start.(bool) { + req := compute.StartRequest{ComputeID: computeId} + if altBootID, ok := d.Get("alt_boot_id").(int); ok { + req.AltBootID = uint64(altBootID) + } + log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", computeId) + if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil { + warnings.Add(err) + } + } + if !start.(bool) { + req := compute.StopRequest{ComputeID: computeId} + log.Debugf("resourceComputeCreate: stoping Compute ID %d after completing its resource configuration", computeId) + if _, err := c.CloudAPI().Compute().Stop(ctx, req); err != nil { + warnings.Add(err) + } + } + } + + if d.Get("pin_to_node").(bool) { + if !d.Get("started").(bool) { + warnings.Add(errors.New("cannot pin to node a VM, VM should be started")) + } + if d.Get("started").(bool) { + req := compute.PinToNodeRequest{ + ComputeID: computeId, + } + req.AutoStart = d.Get("auto_start_w_node").(bool) + _, err = c.CloudAPI().Compute().PinToNode(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + + if affinityLabel, ok := d.GetOk("affinity_label"); ok { + req := compute.AffinityLabelSetRequest{ + ComputeID: computeId, + AffinityLabel: affinityLabel.(string), + } + + _, err := c.CloudAPI().Compute().AffinityLabelSet(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + if profileName, ok := d.GetOk("cpu_alignment_profile"); ok { + req := compute.SetCPUAlignmentProfileRequest{ + ComputeIDs: []int64{int64(computeId)}, + CPUAlignmentProfile: profileName.(string), + } + _, err := c.CloudAPI().Compute().SetCPUAlignmentProfile(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + if ars, ok := d.GetOk("affinity_rules"); ok { + log.Debugf("resourceComputeCreate: Create affinity rules on ComputeID: %d", computeId) + addedAR := ars.([]interface{}) + if len(addedAR) > 0 { + for _, ar := range addedAR { + arConv := ar.(map[string]interface{}) + req := compute.AffinityRuleAddRequest{ + ComputeID: computeId, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudAPI().Compute().AffinityRuleAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if ars, ok := d.GetOk("anti_affinity_rules"); ok { + log.Debugf("resourceComputeCreate: Create anti affinity rules on ComputeID: %d", computeId) + addedAR := ars.([]interface{}) + if len(addedAR) > 0 { + for _, ar := range addedAR { + arConv := ar.(map[string]interface{}) + req := compute.AntiAffinityRuleAddRequest{ + ComputeID: computeId, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudAPI().Compute().AntiAffinityRuleAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if tags, ok := d.GetOk("tags"); ok { + log.Debugf("resourceComputeCreate: Create tags on ComputeID: %d", computeId) + addedTags := tags.(*schema.Set).List() + if len(addedTags) > 0 { + for _, tagInterface := range addedTags { + tagItem := tagInterface.(map[string]interface{}) + req := compute.TagAddRequest{ + ComputeID: computeId, + Key: tagItem["key"].(string), + Value: tagItem["value"].(string), + } + + _, err := c.CloudAPI().Compute().TagAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if pfws, ok := d.GetOk("port_forwarding"); ok { + log.Debugf("resourceComputeCreate: Create port farwarding on ComputeID: %d", computeId) + addedPfws := pfws.(*schema.Set).List() + if len(addedPfws) > 0 { + for _, pfwInterface := range addedPfws { + pfwItem := pfwInterface.(map[string]interface{}) + req := compute.PFWAddRequest{ + ComputeID: computeId, + PublicPortStart: uint64(pfwItem["public_port_start"].(int)), + Proto: pfwItem["proto"].(string), + } + + if pfwItem["local_port"].(int) != 0 { + req.LocalBasePort = uint64(pfwItem["local_port"].(int)) + } + if pfwItem["public_port_end"].(int) != 0 { + req.PublicPortEnd = int64(pfwItem["public_port_end"].(int)) + } + + _, err := c.CloudAPI().Compute().PFWAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if userAcess, ok := d.GetOk("user_access"); ok { + log.Debugf("resourceComputeCreate: Create user access on ComputeID: %d", computeId) + usersAcess := userAcess.(*schema.Set).List() + if len(usersAcess) > 0 { + for _, userAcessInterface := range usersAcess { + userAccessItem := userAcessInterface.(map[string]interface{}) + req := compute.UserGrantRequest{ + ComputeID: computeId, + Username: userAccessItem["username"].(string), + AccessType: userAccessItem["access_type"].(string), + } + + _, err := c.CloudAPI().Compute().UserGrant(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if snapshotList, ok := d.GetOk("snapshot"); ok { + log.Debugf("resourceComputeCreate: Create snapshot on ComputeID: %d", computeId) + snapshots := snapshotList.(*schema.Set).List() + if len(snapshots) > 0 { + for _, snapshotInterface := range snapshots { + snapshotItem := snapshotInterface.(map[string]interface{}) + req := compute.SnapshotCreateRequest{ + ComputeID: computeId, + Label: snapshotItem["label"].(string), + } + + _, err := c.CloudAPI().Compute().SnapshotCreate(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if cdtList, ok := d.GetOk("cd"); ok { + log.Debugf("resourceComputeCreate: Create cd on ComputeID: %d", computeId) + cds := cdtList.(*schema.Set).List() + if len(cds) > 0 { + snapshotItem := cds[0].(map[string]interface{}) + req := compute.CDInsertRequest{ + ComputeID: computeId, + CDROMID: uint64(snapshotItem["cdrom_id"].(int)), + } + + _, err := c.CloudAPI().Compute().CDInsert(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + + if !d.Get("pin_to_node").(bool) && d.Get("auto_start_w_node").(bool) { + req := compute.UpdateRequest{ + ComputeID: computeId, + AutoStart: d.Get("auto_start_w_node").(bool), + CPUPin: d.Get("cpu_pin").(bool), + HPBacked: d.Get("hp_backed").(bool), + } + _, err := c.CloudAPI().Compute().Update(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + if d.Get("pause").(bool) { + req := compute.PauseRequest{ + ComputeID: computeId, + } + _, err := c.CloudAPI().Compute().Pause(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + } + + log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", computeId, d.Get("name").(string)) + + // We may reuse dataSourceComputeRead here as we maintain similarity + // between Compute resource and Compute data source schemas + // Compute read function will also update resource ID on success, so that Terraform + // will know the resource exists + return append(warnings.Get(), resourceComputeRead(ctx, d, m)...) +} + +func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceComputeRead: called for Compute name %s, RG ID %d", + d.Get("name").(string), d.Get("rg_id").(int)) + + // c := m.(*controller.ControllerCfg) + + computeRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + pciList, err := utilityComputePCIDevicesList(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + hasChanged := false + + switch computeRec.Status { + case status.Deleted: + // restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID} + // enableReq := compute.EnableRequest{ComputeID: computeRec.ID} + + // _, err := c.CloudAPI().Compute().Restore(ctx, restoreReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // _, err = c.CloudAPI().Compute().Enable(ctx, enableReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // hasChanged = true + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceComputeCreate(ctx, d, m) + case status.Disabled: + log.Debugf("The compute is in status: %s, troubles may occur with update. Please, enable compute first.", computeRec.Status) + case status.Redeploying: + case status.Deleting: + case status.Destroying: + return diag.Errorf("The compute is in progress with status: %s", computeRec.Status) + case status.Modeled: + return diag.Errorf("The compute is in status: %s, please, contact support for more information", computeRec.Status) + } + + if hasChanged { + computeRec, err = utilityComputeCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + pciList, err = utilityComputePCIDevicesList(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if err = flattenCompute(d, computeRec, pciList); err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceComputeRead: after flattenCompute: Compute ID %s, name %q, RG ID %d", + d.Id(), d.Get("name").(string), d.Get("rg_id").(int)) + + return nil +} + +func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceComputeUpdate: called for Compute ID %s / name %s, RGID %d", + d.Id(), d.Get("name").(string), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + + hasRG, err := existRgID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !hasRG { + return diag.Errorf("resourceComputeUpdate: can't update Compute because rgID %d not allowed or does not exist", d.Get("rg_id").(int)) + } + + if !d.Get("create_blank").(bool) { + hasImage, err := existImageId(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !hasImage { + return diag.Errorf("resourceComputeUpdate: can't update Compute because imageID %d not allowed or does not exist", d.Get("image_id").(int)) + } + } + + if d.HasChange("zone_id") { + if err := utilityComputeUpdateZoneID(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if network, ok := d.GetOk("network"); ok { + networkList := network.(*schema.Set).List() + for _, elem := range networkList { + networkData := elem.(map[string]interface{}) + + switch networkData["net_type"].(string) { + case "VINS": + if vinsId, ok := existVinsId(ctx, m, networkData["net_id"].(int)); !ok { + return diag.Errorf("resourceComputeUpdate: can't update compute because vins ID %d is not allowed or does not exist", vinsId) + } + case "EXTNET": + if extNetId, ok := existExtNetId(ctx, m, networkData["net_id"].(int)); !ok { + return diag.Errorf("resourceComputeUpdate: can't update compute because extnet ID %d is not allowed or does not exist", extNetId) + } + case "VFNIC": + if vfpoolId, ok := existVFPoolId(ctx, m, networkData["net_id"].(int)); !ok { + return diag.Errorf("resourceComputeUpdate: can't create compute because vfpool ID %d is not allowed or does not exist", vfpoolId) + } + case "DPDK": + if dpdkId, ok := existDPDKNetId(ctx, m, networkData["net_id"].(int)); !ok { + return diag.Errorf("resourceComputeCreate: can't create compute because DPDK ID %d is not allowed or does not exist", dpdkId) + } + case "TRUNK": + if trunkId, ok := existTRUNKId(ctx, m, networkData["net_id"].(int)); !ok { + return diag.Errorf("resourceComputeCreate: can't create compute because TRUNK ID %d is not allowed or does not exist", trunkId) + } + default: + continue + } + } + } + + computeRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + hasChanged := false + + // check compute statuses + switch computeRec.Status { + case status.Deleted: + if restore, ok := d.GetOk("restore"); ok && restore.(bool) { + restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID} + _, err := c.CloudAPI().Compute().Restore(ctx, restoreReq) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if enabled, ok := d.GetOk("enabled"); ok { + if enabled.(bool) { + enableReq := compute.EnableRequest{ComputeID: computeRec.ID} + _, err = c.CloudAPI().Compute().Enable(ctx, enableReq) + if err != nil { + return diag.FromErr(err) + } + } + if !enabled.(bool) { + enableReq := compute.DisableRequest{ComputeID: computeRec.ID} + _, err = c.CloudAPI().Compute().Disable(ctx, enableReq) + if err != nil { + return diag.FromErr(err) + } + } + } + + if start, ok := d.GetOk("started"); ok { + if start.(bool) { + req := compute.StartRequest{ComputeID: computeRec.ID} + + if altBootID, ok := d.Get("alt_boot_id").(int); ok { + req.AltBootID = uint64(altBootID) + } + + if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil { + return diag.FromErr(err) + } + } + if !start.(bool) { + req := compute.StopRequest{ComputeID: computeRec.ID} + + if _, err := c.CloudAPI().Compute().Stop(ctx, req); err != nil { + return diag.FromErr(err) + } + } + } + + hasChanged = true + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceComputeCreate(ctx, d, m) + case status.Disabled: + log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", computeRec.Status) + case status.Redeploying: + case status.Deleting: + case status.Destroying: + return diag.Errorf("The compute is in progress with status: %s", computeRec.Status) + case status.Modeled: + return diag.Errorf("The compute is in status: %s, please, contant the support for more information", computeRec.Status) + } + + if hasChanged { + computeRec, err = utilityComputeCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("enabled") { + enabled := d.Get("enabled").(bool) + if enabled { + req := compute.EnableRequest{ + ComputeID: computeRec.ID, + } + + if _, err := c.CloudAPI().Compute().Enable(ctx, req); err != nil { + return diag.FromErr(err) + } + } else { + req := compute.DisableRequest{ + ComputeID: computeRec.ID, + } + + if _, err := c.CloudAPI().Compute().Disable(ctx, req); err != nil { + return diag.FromErr(err) + } + } + log.Debugf("resourceComputeUpdate: enable=%s Compute ID %v after completing its resource configuration", d.Id(), enabled) + } + + oldSize, newSize := d.GetChange("boot_disk_size") + if oldSize.(int) < newSize.(int) { + req := compute.DiskResizeRequest{ComputeID: computeRec.ID} + if diskId, ok := d.GetOk("boot_disk_id"); ok { + req.DiskID = uint64(diskId.(int)) + + } else { + bootDisk, err := utilityComputeBootDiskCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + req.DiskID = bootDisk.ID + } + req.Size = uint64(newSize.(int)) + + log.Debugf("resourceComputeUpdate: compute ID %s, boot disk ID %d resize %d -> %d", + d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int)) + + _, err := c.CloudAPI().Compute().DiskResize(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + } else if oldSize.(int) > newSize.(int) { + log.Warnf("resourceComputeUpdate: compute ID %s - shrinking boot disk is not allowed", d.Id()) + } + + if d.HasChange("extra_disks") { + err := utilityComputeExtraDisksConfigure(ctx, d, m, true, computeRec.Disks) // pass do_delta = true to apply changes, if any + if err != nil { + return diag.FromErr(err) + } + } + + // Note bene: numa_affinity, cpu_pin and hp_backed are not allowed to be changed for compute in STARTED tech status. + var isStopRequired bool + if d.HasChanges("numa_affinity", "cpu_pin", "hp_backed", "chipset", "preferred_cpu", "hot_resize") && d.Get("started").(bool) { + isStopRequired = true + } + + old, new := d.GetChange("cpu") + if old.(int) > new.(int) && d.Get("started").(bool) && d.Get("force_resize").(bool) { + isStopRequired = true + } + if isStopRequired { + if _, err := c.CloudAPI().Compute().Stop(ctx, compute.StopRequest{ComputeID: computeRec.ID}); err != nil { + return diag.FromErr(err) + } + } + + doUpdate := false + resizeReq := compute.ResizeRequest{ + ComputeID: computeRec.ID, + } + forceResize, ok := d.GetOk("force_resize") + if ok { + resizeReq.Force = forceResize.(bool) + } + + warnings := dc.Warnings{} + + oldCpu, newCpu := d.GetChange("cpu") + if oldCpu.(int) > newCpu.(int) && !forceResize.(bool) { + return diag.Errorf("Cannot resize compute ID %d: enable 'force_resize' to reduce compute vCPUs", computeRec.ID) + } + if oldCpu.(int) != newCpu.(int) { + resizeReq.CPU = uint64(newCpu.(int)) + doUpdate = true + } else { + resizeReq.CPU = 0 + } + + if resizeReq.CPU != 0 { + if preferredCPU, ok := d.GetOk("preferred_cpu"); ok { + preferredList := preferredCPU.([]interface{}) + if len(preferredList) > 0 { + for _, v := range preferredList { + cpuNum := v.(int) + resizeReq.PreferredCPU = append(resizeReq.PreferredCPU, int64(cpuNum)) + } + } + } + oldPCPU, newPCPU := d.GetChange("preferred_cpu") + if len(oldPCPU.([]interface{})) != 0 && len(newPCPU.([]interface{})) == 0 { + resizeReq.PreferredCPU = []int64{-1} + } + } + + oldRam, newRam := d.GetChange("ram") + if oldRam.(int) != newRam.(int) { + resizeReq.RAM = uint64(newRam.(int)) + doUpdate = true + } else { + resizeReq.RAM = 0 + } + + if doUpdate { + log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d", + oldCpu.(int), newCpu.(int), + oldRam.(int), newRam.(int)) + _, err := c.CloudAPI().Compute().Resize(ctx, resizeReq) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("description", + "name", + "clock", + "numa_affinity", + "cpu_pin", + "hp_backed", + "chipset", + "auto_start_w_node", + "preferred_cpu", + "loader_type", + "boot_type", + "hot_resize", + "network_interface_naming", + "os_version") { + req := compute.UpdateRequest{ + ComputeID: computeRec.ID, + } + + if d.HasChange("name") { + req.Name = d.Get("name").(string) + } + if d.HasChange("description") { + req.Description = d.Get("description").(string) + } + if d.HasChange("numa_affinity") { + req.NumaAffinity = d.Get("numa_affinity").(string) + } + if d.HasChange("chipset") { + req.Chipset = d.Get("chipset").(string) + } + if d.HasChange("clock") { + req.Clock = d.Get("clock").(string) + } + if d.HasChange("preferred_cpu") { + if preferredCPU, ok := d.GetOk("preferred_cpu"); ok { + preferredList := preferredCPU.([]interface{}) + if len(preferredList) > 0 { + for _, v := range preferredList { + cpuNum := v.(int) + req.PreferredCPU = append(req.PreferredCPU, int64(cpuNum)) + } + } + } + oldPCPU, newPCPU := d.GetChange("preferred_cpu") + if len(oldPCPU.([]interface{})) != 0 && len(newPCPU.([]interface{})) == 0 { + req.PreferredCPU = []int64{-1} + } + } + req.CPUPin = d.Get("cpu_pin").(bool) + req.HPBacked = d.Get("hp_backed").(bool) + req.AutoStart = d.Get("auto_start_w_node").(bool) + + if d.HasChange("loader_type") { + req.LoaderType = d.Get("loader_type").(string) + } + + if d.HasChange("boot_type") { + req.BootType = d.Get("boot_type").(string) + } + + if d.HasChange("hot_resize") { + req.HotResize = d.Get("hot_resize").(bool) + } + + if d.HasChange("network_interface_naming") { + req.NetworkInterfaceNaming = d.Get("network_interface_naming").(string) + } + + if d.HasChange("os_version") { + req.OSVersion = d.Get("os_version").(string) + } + + // perform update + if _, err := c.CloudAPI().Compute().Update(ctx, req); err != nil { + return diag.FromErr(err) + } + + } + + // If used to be STARTED, we need to start it after update + if isStopRequired { + + req := compute.StartRequest{ComputeID: computeRec.ID} + if altBootID, ok := d.Get("alt_boot_id").(int); ok { + req.AltBootID = uint64(altBootID) + } + if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("network") { + err = utilityComputeNetworksConfigure(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("security_groups") { + err = utilityComputeSecGroupsConfigure(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("disks") { + deletedDisks := make([]interface{}, 0) + addedDisks := make([]interface{}, 0) + resizedDisks := make([]interface{}, 0) + renamedDisks := make([]interface{}, 0) + changeStoragePolicyDisks := make([]interface{}, 0) + iotuneUpdatedDisks := make([]interface{}, 0) + + oldDisks, newDisks := d.GetChange("disks") + oldConv := oldDisks.([]interface{}) + newConv := newDisks.([]interface{}) + + for _, el := range oldConv { + if !isContainsDisk(newConv, el) && !isRenameDisk(newConv, el) && !isResizeDisk(newConv, el) && !isChangeStoragePolicy(newConv, el) { + flag := false + extraDisks := d.Get("extra_disks").(*schema.Set).List() + delDisk := el.(map[string]interface{}) + delDiskId := delDisk["disk_id"].(int) + + for _, extraDiskId := range extraDisks { + if extraDiskId.(int) == delDiskId { + flag = true + break + } + } + + if !flag { + deletedDisks = append(deletedDisks, el) + } else { + log.Debugf("disk %d will not be deleted because it is present in the extra_disks block", delDiskId) + } + } + } + + for _, el := range newConv { + if !isContainsDisk(oldConv, el) { + addedDisks = append(addedDisks, el) + } + if isResizeDisk(oldConv, el) { + resizedDisks = append(resizedDisks, el) + } + if isRenameDisk(oldConv, el) { + renamedDisks = append(renamedDisks, el) + } + if isChangeStoragePolicy(oldConv, el) { + changeStoragePolicyDisks = append(changeStoragePolicyDisks, el) + } + if isChangeIOTuneDisk(oldConv, el) { + iotuneUpdatedDisks = append(iotuneUpdatedDisks, el) + } + } + + chipset := d.Get("chipset").(string) + + if len(deletedDisks) > 0 { + for _, disk := range deletedDisks { + diskConv := disk.(map[string]interface{}) + if isBootDisk(diskConv, chipset) { + continue + } + + req := compute.DiskDelRequest{ + ComputeID: computeRec.ID, + DiskID: uint64(diskConv["disk_id"].(int)), + Permanently: diskConv["permanently"].(bool), + } + + log.Debugf("trying to delete disk %d", req.DiskID) + + _, err := c.CloudAPI().Compute().DiskDel(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if len(addedDisks) > 0 { + for _, disk := range addedDisks { + diskConv := disk.(map[string]interface{}) + if isBootDisk(diskConv, chipset) { + continue + } + req := compute.DiskAddRequest{ + ComputeID: computeRec.ID, + DiskName: diskConv["disk_name"].(string), + Size: uint64(diskConv["size"].(int)), + StoragePolicyID: uint64(diskConv["storage_policy_id"].(int)), + } + + if diskConv["sep_id"].(int) != 0 { + req.SepID = uint64(diskConv["sep_id"].(int)) + } + if diskConv["pool"].(string) != "" { + req.Pool = diskConv["pool"].(string) + } + if diskConv["desc"].(string) != "" { + req.Description = diskConv["desc"].(string) + } + if diskConv["image_id"].(int) != 0 { + req.ImageID = uint64(diskConv["image_id"].(int)) + } + diskID, err := c.CloudAPI().Compute().DiskAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + if iotuneRaw, ok := diskConv["iotune"].([]interface{}); ok && len(iotuneRaw) > 0 { + iotuneMap := iotuneRaw[0].(map[string]interface{}) + limitReq := disks.LimitIORequest{ + DiskID: diskID, + ReadBytesSec: uint64(iotuneMap["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotuneMap["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotuneMap["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotuneMap["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotuneMap["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotuneMap["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotuneMap["total_bytes_sec_max"].(int)), + TotalIOPSSec: uint64(iotuneMap["total_iops_sec"].(int)), + TotalIOPSSecMax: uint64(iotuneMap["total_iops_sec_max"].(int)), + WriteBytesSec: uint64(iotuneMap["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotuneMap["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotuneMap["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotuneMap["write_iops_sec_max"].(int)), + } + _, err = c.CloudAPI().Disks().LimitIO(ctx, limitReq) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + if len(resizedDisks) > 0 { + for _, disk := range resizedDisks { + diskConv := disk.(map[string]interface{}) + if isBootDisk(diskConv, chipset) { + continue + } + req := compute.DiskResizeRequest{ + ComputeID: computeRec.ID, + DiskID: uint64(diskConv["disk_id"].(int)), + Size: uint64(diskConv["size"].(int)), + } + + _, err := c.CloudAPI().Compute().DiskResize(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if len(renamedDisks) > 0 { + for _, disk := range renamedDisks { + diskConv := disk.(map[string]interface{}) + + req := disks.RenameRequest{ + DiskID: uint64(diskConv["disk_id"].(int)), + Name: diskConv["disk_name"].(string), + } + + _, err := c.CloudAPI().Disks().Rename(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if len(changeStoragePolicyDisks) > 0 { + for _, disk := range changeStoragePolicyDisks { + diskConv := disk.(map[string]interface{}) + + req := disks.ChangeDiskStoragePolicyRequest{ + DiskID: uint64(diskConv["disk_id"].(int)), + StoragePolicyID: uint64(diskConv["storage_policy_id"].(int)), + } + + _, err := c.CloudAPI().Disks().ChangeDiskStoragePolicy(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if len(iotuneUpdatedDisks) > 0 { + for _, disk := range iotuneUpdatedDisks { + diskConv := disk.(map[string]interface{}) + if isBootDisk(diskConv, chipset) { + continue + } + diskID := uint64(diskConv["disk_id"].(int)) + if diskID == 0 { + continue + } + iotuneRaw, ok := diskConv["iotune"].([]interface{}) + if !ok || len(iotuneRaw) == 0 { + continue + } + iotuneMap := iotuneRaw[0].(map[string]interface{}) + req := disks.LimitIORequest{ + DiskID: diskID, + ReadBytesSec: uint64(iotuneMap["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotuneMap["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotuneMap["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotuneMap["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotuneMap["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotuneMap["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotuneMap["total_bytes_sec_max"].(int)), + TotalIOPSSec: uint64(iotuneMap["total_iops_sec"].(int)), + TotalIOPSSecMax: uint64(iotuneMap["total_iops_sec_max"].(int)), + WriteBytesSec: uint64(iotuneMap["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotuneMap["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotuneMap["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotuneMap["write_iops_sec_max"].(int)), + } + _, err := c.CloudAPI().Disks().LimitIO(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + if d.HasChange("affinity_label") { + affinityLabel := d.Get("affinity_label").(string) + if affinityLabel == "" { + req := compute.AffinityLabelRemoveRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().AffinityLabelRemove(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + req := compute.AffinityLabelSetRequest{ + ComputeID: computeRec.ID, + AffinityLabel: affinityLabel, + } + + _, err := c.CloudAPI().Compute().AffinityLabelSet(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("affinity_rules") { + deletedAR := make([]interface{}, 0) + addedAR := make([]interface{}, 0) + + oldAR, newAR := d.GetChange("affinity_rules") + oldConv := oldAR.([]interface{}) + newConv := newAR.([]interface{}) + + if len(newConv) == 0 { + req := compute.AffinityRulesClearRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().AffinityRulesClear(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + for _, el := range oldConv { + if !isContainsAR(newConv, el) { + deletedAR = append(deletedAR, el) + } + } + for _, el := range newConv { + if !isContainsAR(oldConv, el) { + addedAR = append(addedAR, el) + } + } + + if len(deletedAR) > 0 { + for _, ar := range deletedAR { + arConv := ar.(map[string]interface{}) + req := compute.AffinityRuleRemoveRequest{ + ComputeID: computeRec.ID, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudAPI().Compute().AffinityRuleRemove(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + if len(addedAR) > 0 { + for _, ar := range addedAR { + arConv := ar.(map[string]interface{}) + req := compute.AffinityRuleAddRequest{ + ComputeID: computeRec.ID, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudAPI().Compute().AffinityRuleAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + } + + if d.HasChange("anti_affinity_rules") { + deletedAR := make([]interface{}, 0) + addedAR := make([]interface{}, 0) + + oldAR, newAR := d.GetChange("anti_affinity_rules") + oldConv := oldAR.([]interface{}) + newConv := newAR.([]interface{}) + + if len(newConv) == 0 { + req := compute.AntiAffinityRulesClearRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().AntiAffinityRulesClear(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + for _, el := range oldConv { + if !isContainsAR(newConv, el) { + deletedAR = append(deletedAR, el) + } + } + for _, el := range newConv { + if !isContainsAR(oldConv, el) { + addedAR = append(addedAR, el) + } + } + + if len(deletedAR) > 0 { + for _, ar := range deletedAR { + arConv := ar.(map[string]interface{}) + req := compute.AntiAffinityRuleRemoveRequest{ + ComputeID: computeRec.ID, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudAPI().Compute().AntiAffinityRuleRemove(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + if len(addedAR) > 0 { + for _, ar := range addedAR { + arConv := ar.(map[string]interface{}) + req := compute.AntiAffinityRuleAddRequest{ + ComputeID: computeRec.ID, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudAPI().Compute().AntiAffinityRuleAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + } + + if d.HasChange("tags") { + oldSet, newSet := d.GetChange("tags") + deletedTags := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedTags) > 0 { + for _, tagInterface := range deletedTags { + tagItem := tagInterface.(map[string]interface{}) + req := compute.TagRemoveRequest{ + ComputeID: computeRec.ID, + Key: tagItem["key"].(string), + } + + _, err := c.CloudAPI().Compute().TagRemove(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + addedTags := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedTags) > 0 { + for _, tagInterface := range addedTags { + tagItem := tagInterface.(map[string]interface{}) + req := compute.TagAddRequest{ + ComputeID: computeRec.ID, + Key: tagItem["key"].(string), + Value: tagItem["value"].(string), + } + + _, err := c.CloudAPI().Compute().TagAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + if d.HasChange("port_forwarding") { + oldSet, newSet := d.GetChange("port_forwarding") + deletedPfws := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedPfws) > 0 { + for _, pfwInterface := range deletedPfws { + pfwItem := pfwInterface.(map[string]interface{}) + req := compute.PFWDelRequest{ + ComputeID: computeRec.ID, + PublicPortStart: uint64(pfwItem["public_port_start"].(int)), + Proto: pfwItem["proto"].(string), + } + if pfwItem["local_port"].(int) != 0 { + req.LocalBasePort = uint64(pfwItem["local_port"].(int)) + } + if pfwItem["public_port_end"].(int) == -1 { + req.PublicPortEnd = req.PublicPortStart + } else { + req.PublicPortEnd = uint64(pfwItem["public_port_end"].(int)) + } + + _, err := c.CloudAPI().Compute().PFWDel(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + + addedPfws := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedPfws) > 0 { + for _, pfwInterface := range addedPfws { + pfwItem := pfwInterface.(map[string]interface{}) + req := compute.PFWAddRequest{ + ComputeID: computeRec.ID, + PublicPortStart: uint64(pfwItem["public_port_start"].(int)), + PublicPortEnd: int64(pfwItem["public_port_end"].(int)), + Proto: pfwItem["proto"].(string), + } + if pfwItem["local_port"].(int) != 0 { + req.LocalBasePort = uint64(pfwItem["local_port"].(int)) + } + _, err := c.CloudAPI().Compute().PFWAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + if d.HasChange("user_access") { + oldSet, newSet := d.GetChange("user_access") + deletedUserAcess := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedUserAcess) > 0 { + for _, userAcessInterface := range deletedUserAcess { + userAccessItem := userAcessInterface.(map[string]interface{}) + req := compute.UserRevokeRequest{ + ComputeID: computeRec.ID, + Username: userAccessItem["username"].(string), + } + + _, err := c.CloudAPI().Compute().UserRevoke(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + addedUserAccess := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedUserAccess) > 0 { + for _, userAccessInterface := range addedUserAccess { + userAccessItem := userAccessInterface.(map[string]interface{}) + req := compute.UserGrantRequest{ + ComputeID: computeRec.ID, + Username: userAccessItem["username"].(string), + AccessType: userAccessItem["access_type"].(string), + } + + _, err := c.CloudAPI().Compute().UserGrant(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + if d.HasChange("snapshot") { + oldSet, newSet := d.GetChange("snapshot") + deletedSnapshots := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedSnapshots) > 0 { + for _, snapshotInterface := range deletedSnapshots { + snapshotItem := snapshotInterface.(map[string]interface{}) + req := compute.SnapshotDeleteRequest{ + ComputeID: computeRec.ID, + Label: snapshotItem["label"].(string), + } + + asyncMode, ok := d.GetOk("snapshot_delete_async") + if ok && asyncMode.(bool) { + _, err := c.CloudAPI().Compute().SnapshotDeleteAsync(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + _, err := c.CloudAPI().Compute().SnapshotDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + } + } + + addedSnapshots := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedSnapshots) > 0 { + for _, snapshotInterface := range addedSnapshots { + snapshotItem := snapshotInterface.(map[string]interface{}) + req := compute.SnapshotCreateRequest{ + ComputeID: computeRec.ID, + Label: snapshotItem["label"].(string), + } + + _, err := c.CloudAPI().Compute().SnapshotCreate(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + if d.HasChange("rollback") { + if rollback, ok := d.GetOk("rollback"); ok { + req := compute.StopRequest{ + ComputeID: computeRec.ID, + Force: false, + } + + _, err := c.CloudAPI().Compute().Stop(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + rollbackInterface := rollback.(*schema.Set).List()[0] + rollbackItem := rollbackInterface.(map[string]interface{}) + + rollbackReq := compute.SnapshotRollbackRequest{ + ComputeID: computeRec.ID, + Label: rollbackItem["label"].(string), + } + + _, err = c.CloudAPI().Compute().SnapshotRollback(ctx, rollbackReq) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("cd") { + oldSet, newSet := d.GetChange("cd") + deletedCd := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedCd) > 0 { + req := compute.CDEjectRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().CDEject(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + addedCd := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedCd) > 0 { + cdItem := addedCd[0].(map[string]interface{}) + req := compute.CDInsertRequest{ + ComputeID: computeRec.ID, + CDROMID: uint64(cdItem["cdrom_id"].(int)), + } + + _, err := c.CloudAPI().Compute().CDInsert(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("pause") { + oldPause, newPause := d.GetChange("pause") + if !newPause.(bool) { + req := compute.ResumeRequest{ + ComputeID: computeRec.ID, + } + _, err := c.CloudAPI().Compute().Resume(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + if !oldPause.(bool) { + req := compute.PauseRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().Pause(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("reset") { + _, newReset := d.GetChange("reset") + if newReset.(bool) { + req := compute.ResetRequest{ + ComputeID: computeRec.ID, + } + _, err := c.CloudAPI().Compute().Reset(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("image_id") { + oldImage, newImage := d.GetChange("image_id") + stopReq := compute.StopRequest{ + ComputeID: computeRec.ID, + Force: false, + } + if forceStop, ok := d.GetOk("force_stop"); ok { + stopReq.Force = forceStop.(bool) + } + + _, err := c.CloudAPI().Compute().Stop(ctx, stopReq) + if err != nil { + return diag.FromErr(err) + } + + if oldImage.(int) != newImage.(int) { + req := compute.RedeployRequest{ + ComputeID: computeRec.ID, + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + ImageID: uint64(newImage.(int)), + DataDisks: "KEEP", + } + + if diskSize, ok := d.GetOk("boot_disk_size"); ok { + req.DiskSize = uint64(diskSize.(int)) + } + if autoStart, ok := d.GetOk("started"); ok { + req.AutoStart = autoStart.(bool) + } + if forceStop, ok := d.GetOk("force_stop"); ok { + req.ForceStop = forceStop.(bool) + } + + if osVersion, ok := d.GetOk("os_version"); ok { + req.OSVersion = osVersion.(string) + } + + _, err := c.CloudAPI().Compute().Redeploy(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("custom_fields") { + val := d.Get("custom_fields").(string) + val = strings.ReplaceAll(val, "\\", "") + val = strings.ReplaceAll(val, "\n", "") + val = strings.ReplaceAll(val, "\t", "") + val = strings.TrimSpace(val) + + if len(val) > 0 { + req := compute.SetCustomFieldsRequest{ + ComputeID: computeRec.ID, + CustomFields: val, + } + + _, err := c.CloudAPI().Compute().SetCustomFields(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := compute.DeleteCustomFieldsRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().DeleteCustomFields(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("pci_devices") { + if err := utilityComputeUpdatePciDevices(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("started") { + if d.Get("started").(bool) { + req := compute.StartRequest{ + ComputeID: computeRec.ID, + } + if altBootID, ok := d.Get("alt_boot_id").(int); ok { + req.AltBootID = uint64(altBootID) + } + if !isStopRequired { + if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil { + return diag.FromErr(err) + } + } + + } else { + req := compute.StopRequest{ + ComputeID: computeRec.ID, + } + if _, err := c.CloudAPI().Compute().Stop(ctx, req); err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("pin_to_node") || d.HasChange("started") { + newPin := d.Get("pin_to_node") + if !newPin.(bool) && d.HasChange("pin_to_node") { + req := compute.UnpinFromNodeRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().UnpinFromNode(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + if newPin.(bool) { + if !d.Get("started").(bool) { + return diag.Errorf("Cannot pin to node a VM, that is not started") + } + + req := compute.PinToNodeRequest{ + ComputeID: computeRec.ID, + } + req.AutoStart = d.Get("auto_start_w_node").(bool) + _, err = c.CloudAPI().Compute().PinToNode(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("cpu_alignment_profile") { + if err := utilityComputeUpdateCPUAlignmentProfile(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + // we may reuse dataSourceComputeRead here as we maintain similarity + // between Compute resource and Compute data source schemas + + return append(warnings.Get(), resourceComputeRead(ctx, d, m)...) +} + +func isResizeDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) && + elOldConv["size"].(int) != elConv["size"].(int) { + return true + } + } + return false +} + +func isRenameDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) && + elOldConv["disk_name"].(string) != elConv["disk_name"].(string) { + return true + } + } + return false +} + +func isChangeStoragePolicy(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) && + elOldConv["storage_policy_id"].(int) != elConv["storage_policy_id"].(int) { + return true + } + } + return false +} + +func isChangeIOTuneDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) != elConv["disk_id"].(int) { + continue + } + oldIOTune := elOldConv["iotune"].([]interface{}) + newIOTune := elConv["iotune"].([]interface{}) + if len(oldIOTune) == 0 && len(newIOTune) == 0 { + return false + } + if len(oldIOTune) == 0 || len(newIOTune) == 0 { + return true + } + oldMap := oldIOTune[0].(map[string]interface{}) + newMap := newIOTune[0].(map[string]interface{}) + return oldMap["read_bytes_sec"].(int) != newMap["read_bytes_sec"].(int) || + oldMap["read_bytes_sec_max"].(int) != newMap["read_bytes_sec_max"].(int) || + oldMap["read_iops_sec"].(int) != newMap["read_iops_sec"].(int) || + oldMap["read_iops_sec_max"].(int) != newMap["read_iops_sec_max"].(int) || + oldMap["size_iops_sec"].(int) != newMap["size_iops_sec"].(int) || + oldMap["total_bytes_sec"].(int) != newMap["total_bytes_sec"].(int) || + oldMap["total_bytes_sec_max"].(int) != newMap["total_bytes_sec_max"].(int) || + oldMap["total_iops_sec"].(int) != newMap["total_iops_sec"].(int) || + oldMap["total_iops_sec_max"].(int) != newMap["total_iops_sec_max"].(int) || + oldMap["write_bytes_sec"].(int) != newMap["write_bytes_sec"].(int) || + oldMap["write_bytes_sec_max"].(int) != newMap["write_bytes_sec_max"].(int) || + oldMap["write_iops_sec"].(int) != newMap["write_iops_sec"].(int) || + oldMap["write_iops_sec_max"].(int) != newMap["write_iops_sec_max"].(int) + } + return false +} + +func isContainsDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) { + return true + } + } + return false +} + +func isContainsAR(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["key"].(string) == elConv["key"].(string) && + elOldConv["value"].(string) == elConv["value"].(string) && + elOldConv["mode"].(string) == elConv["mode"].(string) && + elOldConv["topology"].(string) == elConv["topology"].(string) && + elOldConv["policy"].(string) == elConv["policy"].(string) { + return true + } + } + return false +} + +func resourceComputeDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + // NOTE: this function destroys target Compute instance "permanently", so + // there is no way to restore it. + // If compute being destroyed has some extra disks attached, they are + // detached from the compute + log.Debugf("resourceComputeDelete: called for Compute name %s, RG ID %d", + d.Get("name").(string), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + req := compute.DeleteRequest{ + ComputeID: computeId, + Permanently: d.Get("permanently").(bool), + DetachDisks: d.Get("detach_disks").(bool), + } + + if _, err := c.CloudAPI().Compute().Delete(ctx, req); err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func disksSubresourceSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_name": { + Type: schema.TypeString, + Required: true, + Description: "Name for disk", + }, + "size": { + Type: schema.TypeInt, + Required: true, + Description: "Disk size in GiB", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "Storage policy id of disk. The rules of the specified storage policy will be used.", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Storage endpoint provider ID; by default the same with boot disk", + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "PCI slot number of the disk", + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + Description: "Bus number of the disk on virtual bus (6 = boot disk)", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Pool name; by default will be chosen automatically", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Optional description", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Specify image id for create disk from template", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Description: "Disk deletion status", + }, + "iotune": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk ID", + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + } + return rets +} + +func tagsSubresourceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Required: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + }, + } +} + +func portForwardingSubresourceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "public_port_start": { + Type: schema.TypeInt, + Required: true, + }, + "public_port_end": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + }, + "local_port": { + Type: schema.TypeInt, + Optional: true, + }, + "proto": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false), + }, + } +} + +func userAccessSubresourceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + }, + "access_type": { + Type: schema.TypeString, + Required: true, + }, + } +} + +func snapshotSubresourceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Required: true, + }, + } +} + +func snapshotRollbackSubresourceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Required: true, + }, + } +} + +func cdSubresourceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "cdrom_id": { + Type: schema.TypeInt, + Required: true, + }, + } +} + +func ResourceComputeSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + // ForceNew: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "ID of the resource group where this compute should be deployed.", + }, + "cpu": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, constants.MAX_CPUS_PER_COMPUTE), + Description: "Number of CPUs to allocate to this compute instance.", + }, + "ram": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.All( + validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + validators.DivisibleBy(constants.RAM_DIVISIBILITY), + ), + Description: "Amount of RAM in MB to allocate to this compute instance.", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "Storage policy id of compute. The rules of the specified storage policy will be used.", + }, + "boot_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, false), + Description: "Type of image upload.", + }, + "image_id": { + Type: schema.TypeInt, + Optional: true, + //ForceNew: true, //REDEPLOY + Description: "ID of the OS image to base this compute instance on.", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + + "chipset": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"Q35", "i440fx"}, false), // observe case while validating + Description: "Type of the emulated system.", + }, + "clock": { + Type: schema.TypeString, + Optional: true, + Default: "default", + ValidateFunc: validation.StringInSlice([]string{"default", "linux", "windows", "none"}, false), + Description: "Clock synchronization mode.", + }, + "without_boot_disk": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state.", + }, + "create_blank": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If True, the compute is created via kvmx86/createBlank endpoint (without OS image). The image_id field is not required in this case.", + }, + "boot_disk_size": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.", + }, + "affinity_label": { + Type: schema.TypeString, + Optional: true, + Description: "Set affinity label for compute", + }, + "cpu_alignment_profile": { + Type: schema.TypeString, + Optional: true, + Description: "CPU alignment profile name", + }, + "affinity_rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topology": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false), + Description: "compute or node, for whom rule applies", + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false), + Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule", + }, + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false), + Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'", + }, + "key": { + Type: schema.TypeString, + Required: true, + Description: "key that are taken into account when analyzing this rule will be identified", + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: "value that must match the key to be taken into account when analyzing this rule", + }, + }, + }, + }, + "anti_affinity_rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topology": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false), + Description: "compute or node, for whom rule applies", + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false), + Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule", + }, + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false), + Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'", + }, + "key": { + Type: schema.TypeString, + Required: true, + Description: "key that are taken into account when analyzing this rule will be identified", + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: "value that must match the key to be taken into account when analyzing this rule", + }, + }, + }, + }, + "disks": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: disksSubresourceSchemaMake(), + }, + }, + "custom_fields": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "boot_disk": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: disksSubresourceSchemaMake(), + }, + }, + "boot_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + // ForceNew: true, + Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + // ForceNew: true, + Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.", + }, + "extra_disks": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + MaxItems: constants.MAX_EXTRA_DISKS_PER_COMPUTE, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.", + }, + "network": { + Type: schema.TypeSet, + Optional: true, + MinItems: 1, + Elem: &schema.Resource{ + Schema: networkSubresourceSchemaMake(), + }, + Description: "Optional network connection(s) for this compute. You may specify several network blocks, one for each connection.", + }, + "tags": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: tagsSubresourceSchemaMake(), + }, + }, + "port_forwarding": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: portForwardingSubresourceSchemaMake(), + }, + }, + "user_access": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: userAccessSubresourceSchemaMake(), + }, + }, + "snapshot": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: snapshotSubresourceSchemaMake(), + }, + }, + "snapshot_delete_async": { + Type: schema.TypeBool, + Optional: true, + }, + "rollback": { + Type: schema.TypeSet, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: snapshotRollbackSubresourceSchemaMake(), + }, + }, + "cd": { + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: cdSubresourceSchemaMake(), + }, + }, + "pin_to_node": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Optional text description of this compute instance.", + }, + "cloud_init": { + Type: schema.TypeString, + Optional: true, + Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "If true - enable compute, else - disable", + }, + "loader_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "unknown"}, false), + Description: "Type of image vm.", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Type of image vm.", + }, + "pause": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "reset": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "auto_start_w_node": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Flag for start compute after node exits from MAINTENANCE state", + }, + "force_stop": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Flag for redeploy compute", + }, + "force_resize": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Flag for resize compute", + }, + "alt_boot_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of CD-ROM live image to boot", + }, + "started": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Is compute started.", + }, + "detach_disks": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, false), + Description: "Name of netfowrk interface.", + }, + "numa_affinity": { + Type: schema.TypeString, + Optional: true, + Default: "none", + ValidateFunc: validation.StringInSlice([]string{"none", "strict", "loose"}, false), // observe case while validating + Description: "Rule for VM placement with NUMA affinity.", + }, + "cpu_pin": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node.", + }, + "hp_backed": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Use Huge Pages to allocate RAM of the virtual machine. The system must be pre-configured by allocating Huge Pages on the physical node.", + }, + "preferred_cpu": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Recommended isolated CPUs. Field is ignored if compute.cpupin=False or compute.pinned=False", + }, + "pci_devices": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "ID of the connected pci devices", + }, + + "security_groups": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"VINS", "EXTNET", "DPDK"}, false), // observe case while validating + Description: "Type of the network", + }, + "net_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the network", + }, + "security_groups": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + }, + }, + Description: "list of security group IDs to apply to this interface", + }, + "os_version": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "the OS version installed on the VM", + }, + + // The rest are Compute properties, which are "computed" once it is created + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the account this compute instance belongs to.", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account this compute instance belongs to.", + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + Description: "Priority weight of the compute. Higher value means higher priority and later migration.", + }, + "arch": { + Type: schema.TypeString, + Computed: true, + }, + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "boot_disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "This compute instance boot disk ID.", + }, + "cd_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "clone_reference": { + Type: schema.TypeInt, + Computed: true, + }, + "clones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devices": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeInterfacesSchemaMake(), + }, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "migrationjob": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "need_reboot": { + Type: schema.TypeBool, + Computed: true, + }, + "numa_node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_ip": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_name": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network_name": { + Type: schema.TypeString, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: osUsersSubresourceSchemaMake(), + }, + Description: "Guest OS users provisioned on this compute instance.", + }, + "pinned": { + Type: schema.TypeBool, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "reserved_node_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource group where this compute instance is located.", + }, + "snap_sets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: computeSnapSetsSchemaMake(), + }, + }, + "stateless_sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stateless_sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "read_only": { + Type: schema.TypeBool, + Computed: true, + Description: "Shows if compute is in read-only mode.", + }, + "vnc_password": { + Type: schema.TypeString, + Computed: true, + }, + "vgpus": { + Type: schema.TypeList, + Computed: true, + Description: "List of virtual GPUs", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "profile_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "last_update_time": { + Type: schema.TypeInt, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + "pgpuid": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "last_claimed_by": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "virtual_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "virtual_image_name": { + Type: schema.TypeString, + Computed: true, + }, + "loader_meta_iso": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "device_name": { + Type: schema.TypeString, + Computed: true, + }, + "path": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } + return rets +} + +func ResourceCompute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 4, + + CreateContext: resourceComputeCreate, + ReadContext: resourceComputeRead, + UpdateContext: resourceComputeUpdate, + DeleteContext: resourceComputeDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error { + if diff.HasChanges() || diff.HasChanges("chipset", "pin_to_node", "auto_start_w_node", "network", "affinity_rules", "anti_affinity_rules", + "extra_disks", "tags", "port_forwarding", "user_access", "snapshot", "pci_devices", "preferred_cpu", "security_groups") { + diff.SetNewComputed("updated_time") + diff.SetNewComputed("updated_by") + } + if diff.HasChanges("pin_to_node") { + diff.SetNewComputed("pinned") + } + if diff.HasChanges("image_id") { + diff.SetNewComputed("boot_disk") + diff.SetNewComputed("boot_image_id") + } + return nil + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: ResourceComputeSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceComputeResourceV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceCompueteStateUpgradeV1, + Version: 1, + }, + { + Type: resourceComputeResourceV2().CoreConfigSchema().ImpliedType(), + Upgrade: resourceComputeStateUpgradeV2, + Version: 2, + }, + { + Type: resourceComputeResourceV3().CoreConfigSchema().ImpliedType(), + Upgrade: resourceComputeStateUpgradeV3, + Version: 3, + }, + }, + } +} diff --git a/internal/service/cloudapi/kvmvm/state_upgraders.go b/internal/service/cloudapi/kvmvm/state_upgraders.go new file mode 100644 index 00000000..320956d1 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/state_upgraders.go @@ -0,0 +1,64 @@ +package kvmvm + +import ( + "context" + "fmt" + "strings" + + log "github.com/sirupsen/logrus" +) + +func resourceCompueteStateUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceCompueteStateUpgradeV1: upgrading state") + customFields, ok := rawState["custom_fields"] + if !ok || customFields == nil { + rawState["custom_fields"] = "{}" + return rawState, nil + } + + b := &strings.Builder{} + b.WriteString("{") + oldCustomFieldsSlice := customFields.([]interface{}) + for i := range oldCustomFieldsSlice { + oldCustomFields := oldCustomFieldsSlice[i].(map[string]interface{}) + b.WriteString(fmt.Sprintf(`"%s":"%s"`, oldCustomFields["key"], oldCustomFields["val"])) + if i < len(oldCustomFieldsSlice)-1 { + b.WriteString(",") + } + } + b.WriteString("}") + rawState["custom_fields"] = b.String() + + return rawState, nil +} + +func resourceComputeStateUpgradeV2(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceComputeStateUpgradeV2: upgrading state") + + delete(rawState, "with_default_vins") + + return rawState, nil +} + +func resourceComputeStateUpgradeV3(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceComputeStateUpgradeV3: upgrading state") + + for _, blockKey := range []string{"disks", "boot_disk"} { + if items, ok := rawState[blockKey].([]interface{}); ok { + for _, item := range items { + if disk, ok := item.(map[string]interface{}); ok { + if v, ok := disk["blk_discard"].(bool); ok { + if v { + disk["discard"] = "unmap" + } else { + disk["discard"] = "ignore" + } + } + delete(disk, "blk_discard") + } + } + } + } + + return rawState, nil +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute.go b/internal/service/cloudapi/kvmvm/utility_compute.go new file mode 100644 index 00000000..fd44dd56 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute.go @@ -0,0 +1,722 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "errors" + "fmt" + "regexp" + "sort" + "strconv" + + "github.com/hashicorp/go-cty/cty" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func matchComputes(computeList *compute.ListComputes) *compute.ListComputes { + matched, _ := regexp.Compile(`[a-zA-Z]+\\d+-[a-zA-Z]+\\d+-[a-zA-Z]+\\d+`) + result := computeList.FilterFunc(func(ic compute.ItemCompute) bool { + res := matched.Match([]byte(ic.Name)) + return !res + }) + + return &result +} + +func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool, disks compute.ListComputeDisks) error { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %t", d.Id(), do_delta) + + old_set, new_set := d.GetChange("extra_disks") + + apiErrCount := 0 + var lastSavedError error + + if !do_delta { + if new_set.(*schema.Set).Len() < 1 { + return nil + } + + for _, disk := range new_set.(*schema.Set).List() { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.DiskAttachRequest{ + ComputeID: computeId, + DiskID: uint64(disk.(int)), + } + + _, err := c.CloudAPI().Compute().DiskAttach(ctx, req) + if err != nil { + apiErrCount++ + lastSavedError = err + } + } + + if apiErrCount > 0 { + log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when attaching disks to Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) + return lastSavedError + } + + return nil + } + + detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set)) + log.Debugf("utilityComputeExtraDisksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id()) + + if detach_set.Len() > 0 { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + for _, diskId := range detach_set.List() { + req := compute.DiskDetachRequest{ + ComputeID: computeId, + DiskID: uint64(diskId.(int)), + } + _, err := c.CloudAPI().Compute().DiskDetach(ctx, req) + if err != nil { + log.Errorf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + } + + attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set)) + log.Debugf("utilityComputeExtraDisksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id()) + for _, diskId := range attach_set.List() { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.DiskAttachRequest{ + ComputeID: computeId, + DiskID: uint64(diskId.(int)), + } + + log.Debug("before attach HERE0") + + flag := false + + // check if there is an extra disk in the disks from the platform, so as not to attach it if it is already attached + for _, elem := range disks { + if elem.ID == uint64(diskId.(int)) { + flag = true + break + } + } + + if flag { + continue + } + + _, err := c.CloudAPI().Compute().DiskAttach(ctx, req) + if err != nil { + log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + if apiErrCount > 0 { + log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when managing disks of Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) + return lastSavedError + } + + return nil +} + +func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + oldSet, newSet := d.GetChange("network") + + oldList := oldSet.(*schema.Set).List() + newList := newSet.(*schema.Set).List() + + updateNetwork := differenceNetwork(oldList, newList) + + apiErrCount := 0 + var lastSavedError error + + log.Debugf("utilityComputeNetworksConfigure: detach set has %d items for Compute ID %s", len(updateNetwork.DetachMap), d.Id()) + for _, netData := range updateNetwork.DetachMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.NetDetachRequest{ + ComputeID: computeId, + IPAddr: netData["ip_address"].(string), + MAC: netData["mac"].(string), + } + + _, err := c.CloudAPI().Compute().NetDetach(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s", + netData["net_id"].(int), netData["net_type"].(string), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + log.Debugf("utilityComputeNetworksConfigure: changeIp set has %d items for Compute ID %s", len(updateNetwork.ChangeIPMap), d.Id()) + for _, netData := range updateNetwork.ChangeIPMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.ChangeIPRequest{ + ComputeID: computeId, + NetType: netData["net_type"].(string), + NetID: uint64(netData["net_id"].(int)), + IPAddr: netData["ip_address"].(string), + } + + _, err := c.CloudAPI().Compute().ChangeIP(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to change net ID %d of type %s from Compute ID %s: %s", + netData["net_id"].(int), netData["net_type"].(string), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + needStart := false + + if oldSet.(*schema.Set).Len() == len(updateNetwork.DetachMap) || oldSet.(*schema.Set).Len() == 0 || hasDPDKnetwork(updateNetwork.AttachMap) || len(updateNetwork.ChangeMacMap) != 0 { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + if err := utilityComputeStop(ctx, computeId, m); err != nil { + apiErrCount++ + lastSavedError = err + } + if start := d.Get("started"); start.(bool) { + needStart = true + } + } + + log.Debugf("utilityComputeNetworksConfigure: changeMac set has %d items for Compute ID %s", len(updateNetwork.ChangeMacMap), d.Id()) + for _, netData := range updateNetwork.ChangeMacMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.ChangeMACRequest{ + ComputeID: computeId, + NewMAC: netData["mac"].(string), + СurrentMAC: netData["old_mac"].(string), + } + + _, err := c.CloudAPI().Compute().ChangeMAC(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to change mac %s to %s from Compute ID %s: %s", + req.СurrentMAC, req.NewMAC, d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + sort.Slice(updateNetwork.AttachMap, func(i, j int) bool { + weightI := updateNetwork.AttachMap[i]["weight"].(int) + weightJ := updateNetwork.AttachMap[j]["weight"].(int) + if weightI == 0 { + return false + } + if weightJ == 0 { + return true + } + return weightI < weightJ + }) + + log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", len(updateNetwork.AttachMap), d.Id()) + for _, netData := range updateNetwork.AttachMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.NetAttachRequest{ + ComputeID: computeId, + NetType: netData["net_type"].(string), + NetID: uint64(netData["net_id"].(int)), + } + + if netData["ip_address"].(string) != "" { + req.IPAddr = netData["ip_address"].(string) + } + + if netData["mac"].(string) != "" { + req.MACAddr = netData["mac"].(string) + } + + if netData["sdn_interface_id"].(string) != "" { + req.SDNInterfaceID = netData["sdn_interface_id"].(string) + } + + if enabledNetwork(d.GetRawConfig().GetAttr("network"), req.NetID, req.NetType) { + req.Enabled = netData["enabled"].(bool) + } + + if req.NetType == "DPDK" || req.NetType == "EXTNET" { + req.MTU = uint64(netData["mtu"].(int)) + } + + if req.NetType == "DPDK" || req.NetType == "VFNIC" { + if netMask, ok := netData["net_mask"].(int); ok && netMask > 0 { + req.NetMask = uint64(netMask) + } + } + + _, err := c.CloudAPI().Compute().NetAttach(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s", + netData["net_id"].(int), netData["net_type"].(string), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + if needStart { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + var altBootID uint64 + if altBootIDRaw, ok := d.Get("alt_boot_id").(int); ok { + altBootID = uint64(altBootIDRaw) + } else { + altBootID = 0 + } + if numErr, err := utilityComputeStart(ctx, computeId, altBootID, m); err != nil { + apiErrCount += numErr + lastSavedError = err + } + } + + log.Debugf("utilityComputeNetworksConfigure: changeMTU set has %d items for Compute ID %s", len(updateNetwork.ChangeMTUMap), d.Id()) + for _, netData := range updateNetwork.ChangeMTUMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.ChangeMTURequest{ + ComputeID: computeId, + Interface: netData["mac"].(string), + MTU: uint64(netData["mtu"].(int)), + } + + _, err := c.CloudAPI().Compute().ChangeMTU(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to change MTU ID %d of type %s from Compute ID %s: %s", + netData["net_id"].(int), netData["net_type"].(string), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + log.Debugf("utilityComputeNetworksConfigure: enableMap set has %d items for Compute ID %s", len(updateNetwork.EnableMap), d.Id()) + for _, netData := range updateNetwork.EnableMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.ChangeLinkStateRequest{ + ComputeID: computeId, + Interface: netData["mac"].(string), + State: "off", + } + + if netData["enabled"].(bool) { + req.State = "on" + } + + _, err := c.CloudAPI().Compute().ChangeLinkState(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to change link state network ID %d of type %s from Compute ID %s: %s", + netData["net_id"].(int), netData["net_type"].(string), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + if apiErrCount > 0 { + log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) + return lastSavedError + } + + return nil +} + +func utilityComputeSecGroupsConfigure(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + simpleCompRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + return err + } + + apiErrCount := 0 + var lastSavedError error + + oldSecGroups, newSecGroups := d.GetChange("security_groups") + updateSecGroups := (newSecGroups.(*schema.Set).Difference(oldSecGroups.(*schema.Set))).List() + + log.Debugf("utilityComputeSecGroupsConfigure: update security groups has %d items for Compute ID %s", len(updateSecGroups), d.Id()) + if len(updateSecGroups) > 0 { + for _, elem := range updateSecGroups { + secGroupsMap := elem.(map[string]interface{}) + + netType := secGroupsMap["net_type"].(string) + netId := uint64(secGroupsMap["net_id"].(int)) + var mac string + for _, iface := range simpleCompRec.Interfaces { + if iface.NetID == netId && iface.NetType == netType { + mac = iface.MAC + break + } + } + if mac == "" { + log.Errorf("utilityComputeSecGroupsConfigure: Network with type %s and id %d is not connected to the compute %s", + netType, netId, d.Id()) + apiErrCount++ + lastSavedError = errors.New(fmt.Sprintf("utilityComputeSecGroupsConfigure: Network with type %s and id %d is not connected to the compute %s", + netType, netId, d.Id())) + continue + } + secGroupsIDs := make([]uint64, 0) + for _, id := range secGroupsMap["security_groups"].(*schema.Set).List() { + secGroupsIDs = append(secGroupsIDs, uint64(id.(int))) + } + log.Debugf("utilityComputeSecGroupsConfigure: Configure security groups interface parameters on Network with type %s and id %d", netType, netId) + req := compute.ChangeSecGroupsRequest{ + ComputeID: computeId, + Interface: mac, + SecGroups: secGroupsIDs, + } + + if secGroupsMap["enable_secgroups"] != nil { + req.EnableSecGroups = secGroupsMap["enable_secgroups"].(bool) + } + + _, err := c.CloudAPI().Compute().ChangeSecGroups(ctx, req) + if err != nil { + apiErrCount++ + lastSavedError = err + } + } + } + + if apiErrCount > 0 { + log.Errorf("utilityComputeSecGroupsConfigure: there were %d error(s) when managing security groups of Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) + return lastSavedError + } + + return nil +} + +func hasDPDKnetwork(networkAttachMap []map[string]interface{}) bool { + for _, elem := range networkAttachMap { + if elem["net_type"].(string) == "DPDK" { + return true + } + } + return false +} + +func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.RecordCompute, error) { + c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.GetRequest{ + ComputeID: computeId, + } + + computeRecord, err := c.CloudAPI().Compute().Get(ctx, req) + if err != nil { + return compute.RecordCompute{}, err + } + + return *computeRecord, nil +} + +func utilityComputeStop(ctx context.Context, computeID uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + req := compute.StopRequest{ + ComputeID: computeID, + Force: true, + } + + log.Debugf("utilityComputeNetworksConfigure: stopping compute %d", computeID) + _, err := c.CloudAPI().Compute().Stop(ctx, req) + if err != nil { + return err + } + return nil +} + +func utilityComputeStart(ctx context.Context, computeID uint64, altBootID uint64, m interface{}) (int, error) { + c := m.(*controller.ControllerCfg) + startReq := compute.StartRequest{ComputeID: computeID} + + if altBootID > 0 { + startReq.AltBootID = altBootID + } + + log.Debugf("utilityComputeNetworksConfigure: starting compute %d", computeID) + _, err := c.CloudAPI().Compute().Start(ctx, startReq) + if err != nil { + return 1, err + } + return 0, nil +} + +func utilityComputeUpdatePciDevices(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + oldSet, newSet := d.GetChange("pci_devices") + deletedDevices := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedDevices) > 0 { + for _, ar := range deletedDevices { + arConv := ar.(int) + req := compute.DetachPCIDeviceRequest{ + ComputeID: computeId, + DeviceID: uint64(arConv), + } + _, err := c.CloudAPI().Compute().DetachPCIDevice(ctx, req) + if err != nil { + return err + } + } + } + + added := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(added) > 0 { + for _, ar := range added { + arConv := ar.(int) + req := compute.AttachPCIDeviceRequest{ + ComputeID: computeId, + DeviceID: uint64(arConv), + } + + _, err := c.CloudAPI().Compute().AttachPCIDevice(ctx, req) + if err != nil { + return err + } + } + } + + return nil +} + +func differenceNetwork(oldList, newList []interface{}) *updatedNetwork { + attachMap := make([]map[string]interface{}, 0) + changeIpMap := make([]map[string]interface{}, 0) + changeMacMap := make([]map[string]interface{}, 0) + changeMTUMap := make([]map[string]interface{}, 0) + detachMap := make([]map[string]interface{}, 0) + enableMap := make([]map[string]interface{}, 0) + for _, oldNetwork := range oldList { + oldMap := oldNetwork.(map[string]interface{}) + found := false + for _, newNetwork := range newList { + newMap := newNetwork.(map[string]interface{}) + if compareNetwork(newMap, oldMap) { + found = true + if (newMap["net_type"].(string) == "EXTNET" || newMap["net_type"].(string) == "VINS") && (newMap["ip_address"] != oldMap["ip_address"] && newMap["ip_address"].(string) != "") { + changeIpMap = append(changeIpMap, newMap) + } + if newMap["mac"] != oldMap["mac"] && newMap["mac"].(string) != "" { + newMap["old_mac"] = oldMap["mac"] + changeMacMap = append(changeMacMap, newMap) + } + if (newMap["net_type"].(string) == "EXTNET" || newMap["net_type"].(string) == "DPDK") && (newMap["mtu"] != oldMap["mtu"] && newMap["mtu"].(int) != 0) { + changeMTUMap = append(changeMTUMap, newMap) + } + if newMap["enabled"].(bool) != oldMap["enabled"].(bool) { + mac, _ := newMap["mac"].(string) + if mac == "" { + newMap["mac"] = oldMap["mac"] + } + enableMap = append(enableMap, newMap) + } + } + if found { + break + } + } + if found { + continue + } + detachMap = append(detachMap, oldMap) + } + + for _, newNetwork := range newList { + newMap := newNetwork.(map[string]interface{}) + found := false + for _, oldNetwork := range oldList { + oldMap := oldNetwork.(map[string]interface{}) + if compareNetwork(newMap, oldMap) { + found = true + break + } + } + if found { + continue + } + attachMap = append(attachMap, newMap) + } + + res := updatedNetwork{ + DetachMap: detachMap, + ChangeIPMap: changeIpMap, + ChangeMacMap: changeMacMap, + ChangeMTUMap: changeMTUMap, + AttachMap: attachMap, + EnableMap: enableMap, + } + + return &res +} + +func compareNetwork(newMap, oldMap map[string]interface{}) bool { + return newMap["net_type"] == oldMap["net_type"] && newMap["net_id"] == oldMap["net_id"] && newMap["sdn_interface_id"] == oldMap["sdn_interface_id"] && newMap["weight"] == oldMap["weight"] +} + +func utilityComputeUpdateZoneID(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + req := compute.MigrateToZoneRequest{ + ComputeID: computeId, + } + + zoneID, ok := d.GetOk("zone_id") + if ok { + req.ZoneID = uint64(zoneID.(int)) + } + + _, err := c.CloudAPI().Compute().MigrateToZone(ctx, req) + if err != nil { + return err + } + + return nil +} + +func enabledNetwork(rawNetworkConfig cty.Value, netID uint64, netType string) bool { + for _, netConfigVal := range rawNetworkConfig.AsValueSlice() { + if netConfigVal.IsNull() { + continue + } + + netConfig := netConfigVal.AsValueMap() + + tempID, _ := netConfig["net_id"].AsBigFloat().Int64() + configNetID := uint64(tempID) + + configNetType := netConfig["net_type"].AsString() + + if configNetID == netID && configNetType == netType { + enabledVal := netConfig["enabled"] + return !enabledVal.IsNull() + } + } + + return false +} + +func getComputeDiskIDsAPI(disksList compute.ListComputeDisks, disksBlocks, extraDisks []interface{}, bootDiskId uint64) []interface{} { + res := make([]interface{}, 0) + + if len(disksBlocks) == 0 { + return res + } + + sort.Slice(disksList, func(i, j int) bool { + return disksList[i].ID < disksList[j].ID + }) + + for _, disk := range disksList { + if disk.ID == bootDiskId || findInExtraDisks(uint(disk.ID), extraDisks) { + continue + } + res = append(res, disk.ID) + } + + return res +} + +func utilityComputeCreateIOTune(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + diskList := d.Get("disks").([]interface{}) + + iotuneArr := make([]interface{}, 0, len(diskList)) + hasAny := false + for _, elem := range diskList { + diskVal := elem.(map[string]interface{}) + iotune := diskVal["iotune"].([]interface{}) + iotuneArr = append(iotuneArr, iotune) + if len(iotune) > 0 { + hasAny = true + } + } + + if !hasAny { + return nil + } + + computeRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + return err + } + bootDisk := findBootDisk(computeRec.Disks, computeRec.Chipset) + computeDisksIDs := getComputeDiskIDsAPI(computeRec.Disks, diskList, d.Get("extra_disks").(*schema.Set).List(), bootDisk.ID) + + for i, diskID := range computeDisksIDs { + if i >= len(iotuneArr) { + continue + } + iotune, ok := iotuneArr[i].([]interface{}) + if !ok || len(iotune) == 0 { + continue + } + iotuneMap := iotune[0].(map[string]interface{}) + req := disks.LimitIORequest{ + DiskID: diskID.(uint64), + ReadBytesSec: uint64(iotuneMap["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotuneMap["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotuneMap["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotuneMap["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotuneMap["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotuneMap["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotuneMap["total_bytes_sec_max"].(int)), + TotalIOPSSec: uint64(iotuneMap["total_iops_sec"].(int)), + TotalIOPSSecMax: uint64(iotuneMap["total_iops_sec_max"].(int)), + WriteBytesSec: uint64(iotuneMap["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotuneMap["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotuneMap["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotuneMap["write_iops_sec_max"].(int)), + } + _, err := c.CloudAPI().Disks().LimitIO(ctx, req) + if err != nil { + return err + } + } + + return nil +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_audits.go b/internal/service/cloudapi/kvmvm/utility_compute_audits.go new file mode 100644 index 00000000..0ee19293 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_audits.go @@ -0,0 +1,81 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListAudits, error) { + c := m.(*controller.ControllerCfg) + req := compute.AuditsRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + if timestampAt, ok := d.GetOk("timestamp_at"); ok { + req.TimestampAT = uint64(timestampAt.(int)) + } + if timestampTo, ok := d.GetOk("timestamp_to"); ok { + req.TimestampTO = uint64(timestampTo.(int)) + } + if user, ok := d.GetOk("user"); ok { + req.User = user.(string) + } + if call, ok := d.GetOk("call"); ok { + req.Call = call.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if minStatusCode, ok := d.GetOk("min_status_code"); ok { + req.MinStatusCode = uint64(minStatusCode.(int)) + } + if maxStatusCode, ok := d.GetOk("max_status_code"); ok { + req.MaxStatusCode = uint64(maxStatusCode.(int)) + } + + computeAudits, err := c.CloudAPI().Compute().Audits(ctx, req) + if err != nil { + return compute.ListAudits{}, err + } + return *computeAudits, nil +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_boot_disk.go b/internal/service/cloudapi/kvmvm/utility_compute_boot_disk.go new file mode 100644 index 00000000..ed9a9a0d --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_boot_disk.go @@ -0,0 +1,56 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" +) + +func utilityComputeBootDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemComputeDisk, error) { + computeRecord, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + return nil, err + } + + bootDisk := &compute.ItemComputeDisk{} + for _, disk := range computeRecord.Disks { + if disk.Name == "bootdisk" { + *bootDisk = disk + break + } + } + return bootDisk, nil +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_cpu_alignment_profile.go b/internal/service/cloudapi/kvmvm/utility_compute_cpu_alignment_profile.go new file mode 100644 index 00000000..1ea915bd --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_cpu_alignment_profile.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeUpdateCPUAlignmentProfile(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + profileName := d.Get("cpu_alignment_profile").(string) + if profileName == "" { + req := compute.DeleteCPUAlignmentProfileRequest{ + ComputeIDs: []uint64{computeId}, + } + _, err := c.CloudAPI().Compute().DeleteCPUAlignmentProfile(ctx, req) + return err + } + + req := compute.SetCPUAlignmentProfileRequest{ + ComputeIDs: []int64{int64(computeId)}, + CPUAlignmentProfile: profileName, + } + _, err := c.CloudAPI().Compute().SetCPUAlignmentProfile(ctx, req) + return err +} + +func utilityComputeGetCPUAlignmentProfile(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.CPUAlignmentProfile, error) { + c := m.(*controller.ControllerCfg) + req := compute.GetCPUAlignmentProfileRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + return c.CloudAPI().Compute().GetCPUAlignmentProfile(ctx, req) +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_get_audits.go b/internal/service/cloudapi/kvmvm/utility_compute_get_audits.go new file mode 100644 index 00000000..92a9fdbb --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_get_audits.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeGetAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListShortAudits, error) { + c := m.(*controller.ControllerCfg) + req := compute.GetAuditsRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + computeAudits, err := c.CloudAPI().Compute().GetAudits(ctx, req) + if err != nil { + return nil, err + } + + return computeAudits, nil +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_get_console_url.go b/internal/service/cloudapi/kvmvm/utility_compute_get_console_url.go new file mode 100644 index 00000000..856ef6e7 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_get_console_url.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeGetConsoleUrlCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + + req := compute.GetConsoleURLRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + computeConsoleUrl, err := c.CloudAPI().Compute().GetConsoleURL(ctx, req) + if err != nil { + return "", err + } + + return computeConsoleUrl, nil +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_get_log.go b/internal/service/cloudapi/kvmvm/utility_compute_get_log.go new file mode 100644 index 00000000..d80ae416 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_get_log.go @@ -0,0 +1,56 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeGetLogCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + req := compute.GetLogRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + Path: d.Get("path").(string), + } + + computeGetLog, err := c.CloudAPI().Compute().GetLog(ctx, req) + if err != nil { + return "", err + } + + return computeGetLog, nil +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_list.go b/internal/service/cloudapi/kvmvm/utility_compute_list.go new file mode 100644 index 00000000..2bc96b57 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_list.go @@ -0,0 +1,99 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDataComputeListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListComputes, error) { + c := m.(*controller.ControllerCfg) + req := compute.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if rgName, ok := d.GetOk("rg_name"); ok { + req.RGName = rgName.(string) + } + if rgId, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgId.(int)) + } + if techStatus, ok := d.GetOk("tech_status"); ok { + req.TechStatus = techStatus.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if ipAddress, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ipAddress.(string) + } + if extNetName, ok := d.GetOk("extnet_name"); ok { + req.ExtNetName = extNetName.(string) + } + if extnetId, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnetId.(int)) + } + if includeDeleted, ok := d.GetOk("includedeleted"); ok { + req.IncludeDeleted = includeDeleted.(bool) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + listComputes, err := c.CloudAPI().Compute().List(ctx, req) + if err != nil { + return nil, err + } + + return listComputes, nil +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_list_deleted.go b/internal/service/cloudapi/kvmvm/utility_compute_list_deleted.go new file mode 100644 index 00000000..08f56092 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_list_deleted.go @@ -0,0 +1,90 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDataComputeListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListComputes, error) { + c := m.(*controller.ControllerCfg) + req := compute.ListDeletedRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if rgName, ok := d.GetOk("rg_name"); ok { + req.RGName = rgName.(string) + } + if rgId, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgId.(int)) + } + if techStatus, ok := d.GetOk("tech_status"); ok { + req.TechStatus = techStatus.(string) + } + if ipAddress, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ipAddress.(string) + } + if extNetName, ok := d.GetOk("extnet_name"); ok { + req.ExtNetName = extNetName.(string) + } + if extnetId, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnetId.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listComputes, err := c.CloudAPI().Compute().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return listComputes, nil +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_pci_device_list.go b/internal/service/cloudapi/kvmvm/utility_compute_pci_device_list.go new file mode 100644 index 00000000..0ca7b5ea --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_pci_device_list.go @@ -0,0 +1,77 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputePCIDeviceListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListPCIDevices, error) { + c := m.(*controller.ControllerCfg) + req := compute.ListPCIDeviceRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + if rgId, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgId.(int)) + } + if devId, ok := d.GetOk("device_id"); ok { + req.DevID = uint64(devId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listPCIDevice, err := c.CloudAPI().Compute().ListPCIDevice(ctx, req) + if err != nil { + return nil, err + } + + return listPCIDevice, err + +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_pfw_list.go b/internal/service/cloudapi/kvmvm/utility_compute_pfw_list.go new file mode 100644 index 00000000..7b116307 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_pfw_list.go @@ -0,0 +1,56 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputePfwListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListPFWs, error) { + c := m.(*controller.ControllerCfg) + req := compute.PFWListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + listPFWs, err := c.CloudAPI().Compute().PFWList(ctx, req) + if err != nil { + return nil, err + } + + return listPFWs, err + +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_snapshot_usage.go b/internal/service/cloudapi/kvmvm/utility_compute_snapshot_usage.go new file mode 100644 index 00000000..f2458a15 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_snapshot_usage.go @@ -0,0 +1,28 @@ +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeSnapshotUsageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListUsageSnapshots, error) { + c := m.(*controller.ControllerCfg) + req := compute.SnapshotUsageRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + if label, ok := d.GetOk("label"); ok { + req.Label = label.(string) + } + + computeSnapshotUsage, err := c.CloudAPI().Compute().SnapshotUsage(ctx, req) + if err != nil { + return nil, err + } + + return computeSnapshotUsage, err + +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_user_list.go b/internal/service/cloudapi/kvmvm/utility_compute_user_list.go new file mode 100644 index 00000000..71c9d4f1 --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_user_list.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeUserListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListUsers, error) { + c := m.(*controller.ControllerCfg) + req := compute.UserListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + computeUserList, err := c.CloudAPI().Compute().UserList(ctx, req) + if err != nil { + return computeUserList, err + } + + return computeUserList, err +} diff --git a/internal/service/cloudapi/kvmvm/utility_compute_vgpu_list.go b/internal/service/cloudapi/kvmvm/utility_compute_vgpu_list.go new file mode 100644 index 00000000..d1c4817a --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_compute_vgpu_list.go @@ -0,0 +1,77 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeVGPUListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListVGPUs, error) { + c := m.(*controller.ControllerCfg) + req := compute.ListVGPURequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + if GPUID, ok := d.GetOk("gpu_id"); ok { + req.GPUID = uint64(GPUID.(int)) + } + if typeVGPU, ok := d.GetOk("type"); ok { + req.Type = typeVGPU.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if includeDeleted, ok := d.GetOk("includedeleted"); ok { + req.IncludeDeleted = includeDeleted.(bool) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listVGPU, err := c.CloudAPI().Compute().ListVGPU(ctx, req) + if err != nil { + return nil, err + } + + return listVGPU, err + +} diff --git a/internal/service/cloudapi/kvmvm/utility_data_source_compute.go b/internal/service/cloudapi/kvmvm/utility_data_source_compute.go new file mode 100644 index 00000000..8620940b --- /dev/null +++ b/internal/service/cloudapi/kvmvm/utility_data_source_compute.go @@ -0,0 +1,79 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDataComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.RecordCompute, error) { + c := m.(*controller.ControllerCfg) + req := compute.GetRequest{} + if d.Id() != "" { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.ComputeID = computeId + } else { + req.ComputeID = uint64(d.Get("compute_id").(int)) + } + + computeRecord, err := c.CloudAPI().Compute().Get(ctx, req) + if err != nil { + return compute.RecordCompute{}, err + } + + return *computeRecord, nil +} + +func utilityComputePCIDevicesList(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListPCIDevices, error) { + c := m.(*controller.ControllerCfg) + req := compute.ListPCIDeviceRequest{} + + if d.Id() != "" { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.ComputeID = computeId + } else { + req.ComputeID = uint64(d.Get("compute_id").(int)) + } + + res, err := c.CloudAPI().Compute().ListPCIDevice(ctx, req) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/internal/service/cloudapi/lb/data_source_lb.go b/internal/service/cloudapi/lb/data_source_lb.go new file mode 100644 index 00000000..6d1a2077 --- /dev/null +++ b/internal/service/cloudapi/lb/data_source_lb.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + lb, err := utilityLBCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(lb.ID, 10)) + + flattenLB(d, lb) + + return nil +} + +func DataSourceLB() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLBRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dsLBSchemaMake(), + } +} diff --git a/internal/service/cloudapi/lb/data_source_lb_list.go b/internal/service/cloudapi/lb/data_source_lb_list.go new file mode 100644 index 00000000..00aa6fdd --- /dev/null +++ b/internal/service/cloudapi/lb/data_source_lb_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceLBListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + lbList, err := utilityLBListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenLBList(lbList)) + d.Set("entry_count", lbList.EntryCount) + + return nil +} + +func DataSourceLBList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLBListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dsLBListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/lb/data_source_lb_list_deleted.go b/internal/service/cloudapi/lb/data_source_lb_list_deleted.go new file mode 100644 index 00000000..3965590a --- /dev/null +++ b/internal/service/cloudapi/lb/data_source_lb_list_deleted.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceLBListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + lbList, err := utilityLBListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenLBList(lbList)) + d.Set("entry_count", lbList.EntryCount) + + return nil +} + +func DataSourceLBListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLBListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dsLBListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudapi/lb/flattens.go b/internal/service/cloudapi/lb/flattens.go new file mode 100644 index 00000000..fc064dd5 --- /dev/null +++ b/internal/service/cloudapi/lb/flattens.go @@ -0,0 +1,300 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" +) + +func flattenLBFrontendBind(d *schema.ResourceData, b *lb.ItemBinding, lbId int64, frontendName string) { + d.Set("lb_id", lbId) + d.Set("frontend_name", frontendName) + d.Set("name", b.Name) + d.Set("address", b.Address) + d.Set("guid", b.GUID) + d.Set("port", b.Port) +} + +func flattenLBFrontend(d *schema.ResourceData, f *lb.ItemFrontend, lbId int64) { + d.Set("lb_id", lbId) + d.Set("backend_name", f.Backend) + d.Set("name", f.Name) + d.Set("guid", f.GUID) + d.Set("bindings", flattendBindings(f.Bindings)) +} + +func flattenResourceLBBackendServer(d *schema.ResourceData, s *lb.ItemServer, lbId int64, backendName string) { + d.Set("lb_id", lbId) + d.Set("backend_name", backendName) + d.Set("name", s.Name) + d.Set("port", s.Port) + d.Set("address", s.Address) + d.Set("check", s.Check) + d.Set("guid", s.GUID) + d.Set("downinter", s.ServerSettings.DownInter) + d.Set("fall", s.ServerSettings.Fall) + d.Set("inter", s.ServerSettings.Inter) + d.Set("maxconn", s.ServerSettings.MaxConn) + d.Set("maxqueue", s.ServerSettings.MaxQueue) + d.Set("rise", s.ServerSettings.Rise) + d.Set("slowstart", s.ServerSettings.SlowStart) + d.Set("weight", s.ServerSettings.Weight) + +} + +func flattenResourceLBBackend(d *schema.ResourceData, b *lb.ItemBackend, lbId int64) { + d.Set("lb_id", lbId) + d.Set("name", b.Name) + d.Set("algorithm", b.Algorithm) + d.Set("guid", b.GUID) + d.Set("downinter", b.ServerDefaultSettings.DownInter) + d.Set("fall", b.ServerDefaultSettings.Fall) + d.Set("inter", b.ServerDefaultSettings.Inter) + d.Set("maxconn", b.ServerDefaultSettings.MaxConn) + d.Set("maxqueue", b.ServerDefaultSettings.MaxQueue) + d.Set("rise", b.ServerDefaultSettings.Rise) + d.Set("slowstart", b.ServerDefaultSettings.SlowStart) + d.Set("weight", b.ServerDefaultSettings.Weight) + d.Set("servers", flattenServers(b.Servers)) +} + +func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) { + d.Set("ha_mode", lb.HAMode) + d.Set("backend_haip", lb.BackendHAIP) + d.Set("backends", flattenLBBackends(lb.Backends)) + d.Set("created_by", lb.CreatedBy) + d.Set("created_time", lb.CreatedTime) + d.Set("deleted_by", lb.DeletedBy) + d.Set("deleted_time", lb.DeletedTime) + d.Set("desc", lb.Description) + d.Set("dp_api_user", lb.DPAPIUser) + d.Set("extnet_id", lb.ExtNetID) + d.Set("frontend_haip", lb.FrontendHAIP) + d.Set("frontends", flattenFrontends(lb.Frontends)) + d.Set("gid", lb.GID) + d.Set("guid", lb.GUID) + d.Set("manager_id", lb.ManagerId) + d.Set("manager_type", lb.ManagerType) + d.Set("lb_id", lb.ID) + d.Set("image_id", lb.ImageID) + d.Set("milestones", lb.Milestones) + d.Set("name", lb.Name) + d.Set("part_k8s", lb.PartK8s) + d.Set("primary_node", flattenNode(lb.PrimaryNode)) + d.Set("rg_id", lb.RGID) + d.Set("rg_name", lb.RGName) + d.Set("secondary_node", flattenNode(lb.SecondaryNode)) + d.Set("status", lb.Status) + d.Set("tech_status", lb.TechStatus) + d.Set("updated_by", lb.UpdatedBy) + d.Set("updated_time", lb.UpdatedTime) + d.Set("user_managed", lb.UserManaged) + d.Set("vins_id", lb.VINSID) + d.Set("zone_id", lb.ZoneID) + +} + +func flattenLB(d *schema.ResourceData, lb *lb.RecordLB) { + d.Set("account_id", lb.AccountID) + d.Set("ha_mode", lb.HAMode) + d.Set("backend_haip", lb.BackendHAIP) + d.Set("backends", flattenLBBackends(lb.Backends)) + d.Set("created_by", lb.CreatedBy) + d.Set("created_time", lb.CreatedTime) + d.Set("deleted_by", lb.DeletedBy) + d.Set("deleted_time", lb.DeletedTime) + d.Set("desc", lb.Description) + d.Set("dp_api_user", lb.DPAPIUser) + d.Set("extnet_id", lb.ExtNetID) + d.Set("frontend_haip", lb.FrontendHAIP) + d.Set("frontends", flattenFrontends(lb.Frontends)) + d.Set("gid", lb.GID) + d.Set("guid", lb.GUID) + d.Set("manager_id", lb.ManagerId) + d.Set("manager_type", lb.ManagerType) + d.Set("image_id", lb.ImageID) + d.Set("milestones", lb.Milestones) + d.Set("name", lb.Name) + d.Set("part_k8s", lb.PartK8s) + d.Set("primary_node", flattenNode(lb.PrimaryNode)) + d.Set("rg_id", lb.RGID) + d.Set("rg_name", lb.RGName) + d.Set("secondary_node", flattenNode(lb.SecondaryNode)) + d.Set("status", lb.Status) + d.Set("tech_status", lb.TechStatus) + d.Set("updated_by", lb.UpdatedBy) + d.Set("updated_time", lb.UpdatedTime) + d.Set("user_managed", lb.UserManaged) + d.Set("vins_id", lb.VINSID) + d.Set("zone_id", lb.ZoneID) +} + +func flattenNode(node lb.RecordNode) []map[string]interface{} { + temp := make([]map[string]interface{}, 0) + n := map[string]interface{}{ + "backend_ip": node.BackendIP, + "compute_id": node.ComputeID, + "frontend_ip": node.FrontendIP, + "guid": node.GUID, + "mgmt_ip": node.MGMTIP, + "network_id": node.NetworkID, + } + + temp = append(temp, n) + + return temp +} + +func flattendBindings(bs []lb.ItemBinding) []map[string]interface{} { + temp := make([]map[string]interface{}, 0, len(bs)) + for _, b := range bs { + t := map[string]interface{}{ + "address": b.Address, + "guid": b.GUID, + "name": b.Name, + "port": b.Port, + } + temp = append(temp, t) + } + return temp +} + +func flattenFrontends(fs []lb.ItemFrontend) []map[string]interface{} { + temp := make([]map[string]interface{}, 0, len(fs)) + for _, f := range fs { + t := map[string]interface{}{ + "backend": f.Backend, + "bindings": flattendBindings(f.Bindings), + "guid": f.GUID, + "name": f.Name, + } + temp = append(temp, t) + } + + return temp +} + +func flattenServers(servers []lb.ItemServer) []map[string]interface{} { + temp := make([]map[string]interface{}, 0, len(servers)) + for _, server := range servers { + t := map[string]interface{}{ + "address": server.Address, + "check": server.Check, + "guid": server.GUID, + "name": server.Name, + "port": server.Port, + "server_settings": flattenServerSettings(server.ServerSettings), + } + + temp = append(temp, t) + } + return temp +} + +func flattenServerSettings(defSet lb.RecordServerSettings) []map[string]interface{} { + temp := map[string]interface{}{ + "downinter": defSet.DownInter, + "fall": defSet.Fall, + "guid": defSet.GUID, + "inter": defSet.Inter, + "maxconn": defSet.MaxConn, + "maxqueue": defSet.MaxQueue, + "rise": defSet.Rise, + "slowstart": defSet.SlowStart, + "weight": defSet.Weight, + } + + res := make([]map[string]interface{}, 0) + res = append(res, temp) + return res +} + +func flattenLBBackends(backends []lb.ItemBackend) []map[string]interface{} { + temp := make([]map[string]interface{}, 0, len(backends)) + for _, item := range backends { + t := map[string]interface{}{ + "algorithm": item.Algorithm, + "guid": item.GUID, + "name": item.Name, + "server_default_settings": flattenServerSettings(item.ServerDefaultSettings), + "servers": flattenServers(item.Servers), + } + + temp = append(temp, t) + } + return temp +} + +func flattenLBList(lbl *lb.ListLB) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(lbl.Data)) + for _, lb := range lbl.Data { + temp := map[string]interface{}{ + "ha_mode": lb.HAMode, + "backend_haip": lb.BackendHAIP, + "backends": flattenLBBackends(lb.Backends), + "created_by": lb.CreatedBy, + "created_time": lb.CreatedTime, + "deleted_by": lb.DeletedBy, + "deleted_time": lb.DeletedTime, + "desc": lb.Description, + "dp_api_user": lb.DPAPIUser, + "dp_api_password": lb.DPAPIPassword, + "extnet_id": lb.ExtNetID, + "frontend_haip": lb.FrontendHAIP, + "frontends": flattenFrontends(lb.Frontends), + "gid": lb.GID, + "guid": lb.GUID, + "manager_id": lb.ManagerId, + "manager_type": lb.ManagerType, + "image_id": lb.ImageID, + "milestones": lb.Milestones, + "name": lb.Name, + "part_k8s": lb.PartK8s, + "primary_node": flattenNode(lb.PrimaryNode), + "rg_id": lb.RGID, + "rg_name": lb.RGName, + "secondary_node": flattenNode(lb.SecondaryNode), + "status": lb.Status, + "tech_status": lb.TechStatus, + "updated_by": lb.UpdatedBy, + "updated_time": lb.UpdatedTime, + "user_managed": lb.UserManaged, + "vins_id": lb.VINSID, + "lb_id": lb.ID, + "zone_id": lb.ZoneID, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/lb/lb_data_subresource.go b/internal/service/cloudapi/lb/lb_data_subresource.go new file mode 100644 index 00000000..5682275f --- /dev/null +++ b/internal/service/cloudapi/lb/lb_data_subresource.go @@ -0,0 +1,208 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func dsLBSchemaMake() map[string]*schema.Schema { + sch := createLBSchema() + sch["lb_id"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + } + sch["zone_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + } + return sch +} + +func dsLBListDeletedSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by Account ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by TechStatus", + }, + "front_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by FrontIP", + }, + "back_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by BackIP", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dsLBItemSchemaMake(), + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dsLBListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by Account ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by TechStatus", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by Status", + }, + "front_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by FrontIP", + }, + "back_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by BackIP", + }, + "includedeleted": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dsLBItemSchemaMake(), + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dsLBItemSchemaMake() map[string]*schema.Schema { + sch := createLBSchema() + sch["dp_api_password"] = &schema.Schema{ + Type: schema.TypeString, + Computed: true, + } + sch["zone_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + } + return sch +} diff --git a/internal/service/cloudapi/lb/lb_resource_subresource.go b/internal/service/cloudapi/lb/lb_resource_subresource.go new file mode 100644 index 00000000..ae3d42dc --- /dev/null +++ b/internal/service/cloudapi/lb/lb_resource_subresource.go @@ -0,0 +1,119 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func lbResourceSchemaMake() map[string]*schema.Schema { + sch := createLBSchema() + sch["rg_id"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + } + sch["name"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + } + sch["zone_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Computed: true, + } + sch["extnet_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + } + + sch["vins_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + } + sch["start"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + } + sch["desc"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + } + + sch["enable"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + } + + sch["restart"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + } + + sch["restore"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + } + + sch["safe"] = &schema.Schema{ + Type: schema.TypeBool, + Default: true, + Optional: true, + } + + sch["config_reset"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + } + ///4.4.0 + sch["ha_mode"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + } + sch["sysctl_params"] = &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + } + + /// + sch["permanently"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + } + return sch +} diff --git a/internal/service/cloudapi/lb/lb_schema.go b/internal/service/cloudapi/lb/lb_schema.go new file mode 100644 index 00000000..841c5f72 --- /dev/null +++ b/internal/service/cloudapi/lb/lb_schema.go @@ -0,0 +1,396 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func createLBSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ha_mode": { + Type: schema.TypeBool, + Computed: true, + }, + "backend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "backends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "algorithm": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "server_default_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "servers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "check": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + "server_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dp_api_user": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "frontends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend": { + Type: schema.TypeString, + Computed: true, + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "part_k8s": { + Type: schema.TypeBool, + Computed: true, + }, + "primary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} diff --git a/internal/service/cloudapi/lb/models.go b/internal/service/cloudapi/lb/models.go new file mode 100644 index 00000000..9c495ec8 --- /dev/null +++ b/internal/service/cloudapi/lb/models.go @@ -0,0 +1,121 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +type LoadBalancer struct { + HAMode bool `json:"HAmode"` + ACL interface{} `json:"acl"` + Backends []Backend `json:"backends"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + Description string `json:"desc"` + DPAPIUser string `json:"dpApiUser"` + ExtnetId uint64 `json:"extnetId"` + Frontends []Frontend `json:"frontends"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + ImageId uint64 `json:"imageId"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + PrimaryNode Node `json:"primaryNode"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + SecondaryNode Node `json:"secondaryNode"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + VinsId uint64 `json:"vinsId"` +} + +type LoadBalancerDetailed struct { + DPAPIPassword string `json:"dpApiPassword"` + LoadBalancer +} + +type Backend struct { + Algorithm string `json:"algorithm"` + GUID string `json:"guid"` + Name string `json:"name"` + ServerDefaultSettings ServerSettings `json:"serverDefaultSettings"` + Servers []Server `json:"servers"` +} + +type LBList []LoadBalancerDetailed + +type ServerSettings struct { + Inter uint64 `json:"inter"` + GUID string `json:"guid"` + DownInter uint64 `json:"downinter"` + Rise uint `json:"rise"` + Fall uint `json:"fall"` + SlowStart uint64 `json:"slowstart"` + MaxConn uint `json:"maxconn"` + MaxQueue uint `json:"maxqueue"` + Weight uint `json:"weight"` +} + +type Server struct { + Address string `json:"address"` + Check string `json:"check"` + GUID string `json:"guid"` + Name string `json:"name"` + Port uint `json:"port"` + ServerSettings ServerSettings `json:"serverSettings"` +} + +type Node struct { + BackendIp string `json:"backendIp"` + ComputeId uint64 `json:"computeId"` + FrontendIp string `json:"frontendIp"` + GUID string `json:"guid"` + MGMTIp string `json:"mgmtIp"` + NetworkId uint64 `json:"networkId"` +} + +type Frontend struct { + Backend string `json:"backend"` + Bindings []Binding `json:"bindings"` + GUID string `json:"guid"` + Name string `json:"name"` +} + +type Binding struct { + Address string `json:"address"` + GUID string `json:"guid"` + Name string `json:"name"` + Port uint `json:"port"` +} diff --git a/internal/service/cloudapi/lb/resource_check_input_values.go b/internal/service/cloudapi/lb/resource_check_input_values.go new file mode 100644 index 00000000..ff711727 --- /dev/null +++ b/internal/service/cloudapi/lb/resource_check_input_values.go @@ -0,0 +1,78 @@ +package lb + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func existLBID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + lbId := uint64(d.Get("lb_id").(int)) + + req := lb.ListRequest{} + + lbList, err := c.CloudAPI().LB().List(ctx, req) + if err != nil { + return false, err + } + + return len(lbList.FilterByID(lbId).Data) != 0, nil +} + +func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + rgId := uint64(d.Get("rg_id").(int)) + + req := rg.ListRequest{} + + rgList, err := c.CloudAPI().RG().List(ctx, req) + if err != nil { + return false, err + } + + return len(rgList.FilterByID(rgId).Data) != 0, nil +} + +func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + extNetID := uint64(d.Get("extnet_id").(int)) + + // this code is needed in order to be able to pass 0 + if extNetID == 0 { + return true, nil + } + + req := extnet.ListRequest{} + + extNetList, err := c.CloudAPI().ExtNet().List(ctx, req) + if err != nil { + return false, err + } + + return len(extNetList.FilterByID(extNetID).Data) != 0, nil +} + +func existViNSID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + vinsID := uint64(d.Get("vins_id").(int)) + + // this code is needed in order to be able to pass 0 + if vinsID == 0 { + return true, nil + } + + req := vins.ListRequest{} + + vinsList, err := c.CloudAPI().VINS().List(ctx, req) + if err != nil { + return false, err + } + + return len(vinsList.FilterByID(vinsID).Data) != 0, nil +} diff --git a/internal/service/cloudapi/lb/resource_lb.go b/internal/service/cloudapi/lb/resource_lb.go new file mode 100644 index 00000000..d673b329 --- /dev/null +++ b/internal/service/cloudapi/lb/resource_lb.go @@ -0,0 +1,555 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBCreate") + + haveRGID, err := existRGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveRGID { + return diag.Errorf("resourceLBCreate: can't create LB because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + + haveExtNetID, err := existExtNetID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveExtNetID { + return diag.Errorf("resourceLBCreate: can't create LB because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int)) + } + + haveVins, err := existViNSID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveVins { + return diag.Errorf("resourceLBCreate: can't create LB because ViNSID %d is not allowed or does not exist", d.Get("vins_id").(int)) + } + + c := m.(*controller.ControllerCfg) + req := lb.CreateRequest{ + Name: d.Get("name").(string), + RGID: uint64(d.Get("rg_id").(int)), + ExtNetID: uint64(d.Get("extnet_id").(int)), + VINSID: uint64(d.Get("vins_id").(int)), + } + + if start, ok := d.GetOk("start"); ok { + req.Start = start.(bool) + } + + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + if haMode, ok := d.GetOk("ha_mode"); ok { + req.HighlyAvailable = haMode.(bool) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + if sysctlParams, ok := d.GetOk("sysctl_params"); ok { + syscrlSliceMaps := sysctlParams.([]interface{}) + res := make([]map[string]interface{}, 0, len(syscrlSliceMaps)) + for _, syscrlMap := range syscrlSliceMaps { + tempMap := make(map[string]interface{}) + for k, v := range syscrlMap.(map[string]interface{}) { + if intVal, err := strconv.Atoi(v.(string)); err == nil { + tempMap[k] = intVal + continue + } + tempMap[k] = v.(string) + } + res = append(res, tempMap) + } + req.SysctlParams = res + } + + lbId, err := c.CloudAPI().LB().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(lbId, 10)) + d.Set("lb_id", lbId) + + w := dc.Warnings{} + + if enable, ok := d.GetOk("enable"); ok { + req := lb.DisableEnableRequest{ + LBID: lbId, + } + + if enable.(bool) { + _, err := c.CloudAPI().LB().Enable(ctx, req) + if err != nil { + w.Add(err) + } + } else { + _, err := c.CloudAPI().LB().Disable(ctx, req) + if err != nil { + w.Add(err) + } + } + + if start, ok := d.GetOk("start"); ok && enable.(bool) { + if start.(bool) { + req := lb.StartRequest{LBID: lbId} + _, err := c.CloudAPI().LB().Start(ctx, req) + if err != nil { + w.Add(err) + } + } else { + req := lb.StopRequest{LBID: lbId} + _, err := c.CloudAPI().LB().Stop(ctx, req) + if err != nil { + w.Add(err) + } + } + } + } + + return append(w.Get(), resourceLBRead(ctx, d, m)...) +} + +func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBRead") + + // c := m.(*controller.ControllerCfg) + + lbRec, err := utilityLBCheckPresence(ctx, d, m) + if lbRec == nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch lbRec.Status { + case status.Modeled: + return diag.Errorf("The LB is in status: %s, please, contact support for more information", lbRec.Status) + case status.Creating: + case status.Created: + case status.Deleting: + case status.Deleted: + // lbId, _ := strconv.ParseUint(d.Id(), 10, 64) + // restoreReq := lb.RestoreRequest{LBID: lbId} + // enableReq := lb.DisableEnableRequest{LBID: lbId} + + // _, err := c.CloudAPI().LB().Restore(ctx, restoreReq) + // if err != nil { + // return diag.FromErr(err) + // } + // _, err = c.CloudAPI().LB().Enable(ctx, enableReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // hasChanged = true + case status.Destroying: + return diag.Errorf("The LB is in progress with status: %s", lbRec.Status) + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceLBCreate(ctx, d, m) + case status.Enabled: + case status.Enabling: + case status.Disabling: + case status.Disabled: + log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lbRec.Status) + case status.Restoring: + } + + if hasChanged { + lbRec, err = utilityLBCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + flattenResourceLB(d, lbRec) + + return nil +} + +func resourceLBDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBDelete") + + c := m.(*controller.ControllerCfg) + lbId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := lb.DeleteRequest{ + LBID: lbId, + } + + if permanently, ok := d.GetOk("permanently"); ok { + req.Permanently = permanently.(bool) + } + + _, err := c.CloudAPI().LB().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBUpdate") + c := m.(*controller.ControllerCfg) + + haveRGID, err := existRGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveRGID { + return diag.Errorf("resourceLBUpdate: can't update LB because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + + haveExtNetID, err := existExtNetID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveExtNetID { + return diag.Errorf("resourceLBUpdate: can't update LB because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int)) + } + + haveVins, err := existViNSID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveVins { + return diag.Errorf("resourceLBUpdate: can't update LB because ViNSID %d is not allowed or does not exist", d.Get("vins_id").(int)) + } + + lbRec, err := utilityLBCheckPresence(ctx, d, m) + if lbRec == nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch lbRec.Status { + case status.Modeled: + return diag.Errorf("The LB is in status: %s, please, contact support for more information", lbRec.Status) + case status.Creating: + case status.Created: + case status.Deleting: + case status.Deleted: + if restore, ok := d.GetOk("restore"); ok && restore.(bool) { + restoreReq := lb.RestoreRequest{LBID: lbRec.ID} + + _, err := c.CloudAPI().LB().Restore(ctx, restoreReq) + if err != nil { + return diag.FromErr(err) + } + } + if enable, ok := d.GetOk("enable"); ok { + req := lb.DisableEnableRequest{ + LBID: lbRec.ID, + } + + if enable.(bool) { + _, err := c.CloudAPI().LB().Enable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + _, err := c.CloudAPI().LB().Disable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if start, ok := d.GetOk("start"); ok && enable.(bool) { + if start.(bool) { + req := lb.StartRequest{LBID: lbRec.ID} + _, err := c.CloudAPI().LB().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := lb.StopRequest{LBID: lbRec.ID} + _, err := c.CloudAPI().LB().Stop(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + hasChanged = true + case status.Destroying: + return diag.Errorf("The LB is in progress with status: %s", lbRec.Status) + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceLBCreate(ctx, d, m) + case status.Enabled: + case status.Enabling: + case status.Disabling: + case status.Disabled: + log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lbRec.Status) + case status.Restoring: + } + + if hasChanged { + _, err = utilityLBCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChange("ha_mode") { + hamode := d.Get("ha_mode").(bool) + if hamode { + req := lb.HighlyAvailableRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + _, err := c.CloudAPI().LB().HighlyAvailable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("sysctl_params") { + syscrlSliceMaps := d.Get("sysctl_params").([]interface{}) + res := make([]map[string]interface{}, 0, len(syscrlSliceMaps)) + for _, syscrlMap := range syscrlSliceMaps { + tempMap := make(map[string]interface{}) + for k, v := range syscrlMap.(map[string]interface{}) { + if intVal, err := strconv.Atoi(v.(string)); err == nil { + tempMap[k] = intVal + continue + } + tempMap[k] = v.(string) + } + res = append(res, tempMap) + } + if len(res) > 0 { + req := lb.UpdateSysctParamsRequest{ + LBID: uint64(d.Get("lb_id").(int)), + SysctlParams: res, + } + _, err := c.CloudAPI().LB().UpdateSysctlParams(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("enable") { + enable := d.Get("enable").(bool) + req := lb.DisableEnableRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + if enable { + _, err := c.CloudAPI().LB().Enable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + _, err := c.CloudAPI().LB().Disable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("start") { + start := d.Get("start").(bool) + lbId := uint64(d.Get("lb_id").(int)) + if start { + req := lb.StartRequest{LBID: lbId} + _, err := c.CloudAPI().LB().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := lb.StopRequest{LBID: lbId} + _, err := c.CloudAPI().LB().Stop(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("desc") { + req := lb.UpdateRequest{ + LBID: uint64(d.Get("lb_id").(int)), + Description: d.Get("desc").(string), + } + + _, err := c.CloudAPI().LB().Update(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("zone_id") { + start := d.Get("start").(bool) + + if start { + reqStop := lb.StopRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + + _, err := c.CloudAPI().LB().Stop(ctx, reqStop) + if err != nil { + return diag.FromErr(err) + } + + start = false + } + + req := lb.MigrateToZoneRequest{ + LBID: uint64(d.Get("lb_id").(int)), + ZoneID: uint64(d.Get("zone_id").(int)), + } + + _, err := c.CloudAPI().LB().MigrateToZone(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + if start { + reqStart := lb.StartRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + + _, err := c.CloudAPI().LB().Start(ctx, reqStart) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("restart") { + restart := d.Get("restart").(bool) + if restart { + req := lb.RestartRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + if safe, ok := d.GetOk("safe"); ok { + req.Safe = safe.(bool) + } + + _, err := c.CloudAPI().LB().Restart(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("restore") { + restore := d.Get("restore").(bool) + if restore { + req := lb.RestoreRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + + _, err := c.CloudAPI().LB().Restore(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("config_reset") { + cfgReset := d.Get("config_reset").(bool) + if cfgReset { + req := lb.ConfigResetRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + + _, err := c.CloudAPI().LB().ConfigReset(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + return resourceLBRead(ctx, d, m) +} + +func ResourceLB() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLBCreate, + ReadContext: resourceLBRead, + UpdateContext: resourceLBUpdate, + DeleteContext: resourceLBDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: lbResourceSchemaMake(), + } +} diff --git a/internal/service/cloudapi/lb/resource_lb_backend.go b/internal/service/cloudapi/lb/resource_lb_backend.go new file mode 100644 index 00000000..bc93c9cf --- /dev/null +++ b/internal/service/cloudapi/lb/resource_lb_backend.go @@ -0,0 +1,379 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceLBBackendCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendCreate") + + haveLBID, err := existLBID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveLBID { + return diag.Errorf("resourceLBBackendCreate: can't create LB backend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) + } + + c := m.(*controller.ControllerCfg) + req := lb.BackendCreateRequest{} + + req.BackendName = d.Get("name").(string) + req.LBID = uint64(d.Get("lb_id").(int)) + + if algorithm, ok := d.GetOk("algorithm"); ok { + req.Algorithm = algorithm.(string) + } + if inter, ok := d.GetOk("inter"); ok { + req.Inter = uint64(inter.(int)) + } + if downinter, ok := d.GetOk("downinter"); ok { + req.DownInter = uint64(downinter.(int)) + } + if rise, ok := d.GetOk("rise"); ok { + req.Rise = uint64(rise.(int)) + } + if fall, ok := d.GetOk("fall"); ok { + req.Fall = uint64(fall.(int)) + } + if slowstart, ok := d.GetOk("slowstart"); ok { + req.SlowStart = uint64(slowstart.(int)) + } + if maxconn, ok := d.GetOk("maxconn"); ok { + req.MaxConn = uint64(maxconn.(int)) + } + if maxqueue, ok := d.GetOk("maxqueue"); ok { + req.MaxQueue = uint64(maxqueue.(int)) + } + if weight, ok := d.GetOk("weight"); ok { + req.Weight = uint64(weight.(int)) + } + + _, err = c.CloudAPI().LB().BackendCreate(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("name").(string)) + + _, err = utilityLBBackendCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + return resourceLBBackendRead(ctx, d, m) +} + +func resourceLBBackendRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendRead") + + b, err := utilityLBBackendCheckPresence(ctx, d, m) + if b == nil { + d.SetId("") + return diag.FromErr(err) + } + + lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) + + flattenResourceLBBackend(d, b, lbId) + + return nil +} + +func resourceLBBackendDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendDelete") + + _, err := utilityLBBackendCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := lb.BackendDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + BackendName: d.Get("name").(string), + } + + _, err = c.CloudAPI().LB().BackendDelete(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceLBBackendUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendEdit") + c := m.(*controller.ControllerCfg) + + haveLBID, err := existLBID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveLBID { + return diag.Errorf("resourceLBBackendUpdate: can't update LB backend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) + } + + req := lb.BackendUpdateRequest{ + LBID: uint64(d.Get("lb_id").(int)), + BackendName: d.Get("name").(string), + } + + if algorithm, ok := d.GetOk("algorithm"); ok { + req.Algorithm = algorithm.(string) + } + if inter, ok := d.GetOk("inter"); ok { + req.Inter = uint64(inter.(int)) + } + if downinter, ok := d.GetOk("downinter"); ok { + req.DownInter = uint64(downinter.(int)) + } + if rise, ok := d.GetOk("rise"); ok { + req.Rise = uint64(rise.(int)) + } + if fall, ok := d.GetOk("fall"); ok { + req.Fall = uint64(fall.(int)) + } + if slowstart, ok := d.GetOk("slowstart"); ok { + req.SlowStart = uint64(slowstart.(int)) + } + if maxconn, ok := d.GetOk("maxconn"); ok { + req.MaxConn = uint64(maxconn.(int)) + } + if maxqueue, ok := d.GetOk("maxqueue"); ok { + req.MaxQueue = uint64(maxqueue.(int)) + } + if weight, ok := d.GetOk("weight"); ok { + req.Weight = uint64(weight.(int)) + } + + _, err = c.CloudAPI().LB().BackendUpdate(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + return resourceLBBackendRead(ctx, d, m) +} + +func ResourceLBBackend() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLBBackendCreate, + ReadContext: resourceLBBackendRead, + UpdateContext: resourceLBBackendUpdate, + DeleteContext: resourceLBBackendDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: map[string]*schema.Schema{ + "lb_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the LB instance to backendCreate", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Must be unique among all backends of this LB - name of the new backend to create", + }, + "algorithm": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"roundrobin", "static-rr", "leastconn"}, false), + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "downinter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "servers": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "check": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "server_settings": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + } +} diff --git a/internal/service/cloudapi/lb/resource_lb_backend_server.go b/internal/service/cloudapi/lb/resource_lb_backend_server.go new file mode 100644 index 00000000..3b70c54c --- /dev/null +++ b/internal/service/cloudapi/lb/resource_lb_backend_server.go @@ -0,0 +1,318 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceLBBackendServerCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendServerCreate") + + haveLBID, err := existLBID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveLBID { + return diag.Errorf("resourceLBBackendServerCreate: can't create LB backend server because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) + } + + c := m.(*controller.ControllerCfg) + req := lb.BackendServerAddRequest{ + BackendName: d.Get("backend_name").(string), + ServerName: d.Get("name").(string), + Address: d.Get("address").(string), + LBID: uint64(d.Get("lb_id").(int)), + Port: uint64(d.Get("port").(int)), + } + + if check, ok := d.GetOk("check"); ok { + req.Check = check.(string) + } + + if inter, ok := d.GetOk("inter"); ok { + req.Inter = uint64(inter.(int)) + } + if downinter, ok := d.GetOk("downinter"); ok { + req.DownInter = uint64(downinter.(int)) + } + if rise, ok := d.GetOk("rise"); ok { + req.Rise = uint64(rise.(int)) + } + if fall, ok := d.GetOk("fall"); ok { + req.Fall = uint64(fall.(int)) + } + if slowstart, ok := d.GetOk("slowstart"); ok { + req.SlowStart = uint64(slowstart.(int)) + } + if maxconn, ok := d.GetOk("maxconn"); ok { + req.MaxConn = uint64(maxconn.(int)) + } + if maxqueue, ok := d.GetOk("maxqueue"); ok { + req.MaxQueue = uint64(maxqueue.(int)) + } + if weight, ok := d.GetOk("weight"); ok { + req.Weight = uint64(weight.(int)) + } + + _, err = c.CloudAPI().LB().BackendServerAdd(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("backend_name").(string) + "#" + d.Get("name").(string)) + + _, err = utilityLBBackendServerCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + return resourceLBBackendServerRead(ctx, d, m) +} + +func resourceLBBackendServerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendServerRead") + + s, err := utilityLBBackendServerCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) + backendName := strings.Split(d.Id(), "#")[1] + + flattenResourceLBBackendServer(d, s, lbId, backendName) + + return nil +} + +func resourceLBBackendServerDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendServerDelete") + + _, err := utilityLBBackendServerCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := lb.BackendServerDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + BackendName: d.Get("backend_name").(string), + ServerName: d.Get("name").(string), + } + + _, err = c.CloudAPI().LB().BackendServerDelete(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId("") + + return nil +} + +func resourceLBBackendServerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendServerEdit") + c := m.(*controller.ControllerCfg) + + haveLBID, err := existLBID(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + if !haveLBID { + return diag.Errorf("resourceLBBackendServerUpdate: can't update LB backend server because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) + } + + req := lb.BackendServerUpdateRequest{ + BackendName: d.Get("backend_name").(string), + LBID: uint64(d.Get("lb_id").(int)), + ServerName: d.Get("name").(string), + Address: d.Get("address").(string), + Port: uint64(d.Get("port").(int)), + } + + if check, ok := d.GetOk("check"); ok { + req.Check = check.(string) + } + if inter, ok := d.GetOk("inter"); ok { + req.Inter = uint64(inter.(int)) + } + if downinter, ok := d.GetOk("downinter"); ok { + req.DownInter = uint64(downinter.(int)) + } + if rise, ok := d.GetOk("rise"); ok { + req.Rise = uint64(rise.(int)) + } + if fall, ok := d.GetOk("fall"); ok { + req.Fall = uint64(fall.(int)) + } + if slowstart, ok := d.GetOk("slowstart"); ok { + req.SlowStart = uint64(slowstart.(int)) + } + if maxconn, ok := d.GetOk("maxconn"); ok { + req.MaxConn = uint64(maxconn.(int)) + } + if maxqueue, ok := d.GetOk("maxqueue"); ok { + req.MaxQueue = uint64(maxqueue.(int)) + } + if weight, ok := d.GetOk("weight"); ok { + req.Weight = uint64(weight.(int)) + } + + _, err = c.CloudAPI().LB().BackendServerUpdate(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + return resourceLBBackendServerRead(ctx, d, m) +} + +func ResourceLBBackendServer() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLBBackendServerCreate, + ReadContext: resourceLBBackendServerRead, + UpdateContext: resourceLBBackendServerUpdate, + DeleteContext: resourceLBBackendServerDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: map[string]*schema.Schema{ + "lb_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the LB instance to backendCreate", + }, + "backend_name": { + Type: schema.TypeString, + Required: true, + Description: "Must be unique among all backends of this LB - name of the new backend to create", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Must be unique among all servers defined for this backend - name of the server definition to add.", + }, + "address": { + Type: schema.TypeString, + Required: true, + Description: "IP address of the server.", + }, + "port": { + Type: schema.TypeInt, + Required: true, + Description: "Port number on the server", + }, + "check": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"disabled", "enabled"}, false), + Description: "set to disabled if this server should be used regardless of its state.", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "downinter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + } +} diff --git a/internal/service/cloudapi/lb/resource_lb_frontend.go b/internal/service/cloudapi/lb/resource_lb_frontend.go new file mode 100644 index 00000000..95fd90e1 --- /dev/null +++ b/internal/service/cloudapi/lb/resource_lb_frontend.go @@ -0,0 +1,195 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceLBFrontendCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendCreate") + + haveLBID, err := existLBID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveLBID { + return diag.Errorf("resourceLBFrontendCreate: can't create LB frontend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) + } + + c := m.(*controller.ControllerCfg) + req := lb.FrontendCreateRequest{ + BackendName: d.Get("backend_name").(string), + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("name").(string), + } + + _, err = c.CloudAPI().LB().FrontendCreate(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("name").(string)) + + _, err = utilityLBFrontendCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + return resourceLBFrontendRead(ctx, d, m) +} + +func resourceLBFrontendRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendRead") + + f, err := utilityLBFrontendCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) + + flattenLBFrontend(d, f, lbId) + + return nil +} + +func resourceLBFrontendDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendDelete") + + _, err := utilityLBFrontendCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := lb.FrontendDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("name").(string), + } + + _, err = c.CloudAPI().LB().FrontendDelete(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceLBFrontendEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + return nil +} + +func ResourceLBFrontend() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLBFrontendCreate, + ReadContext: resourceLBFrontendRead, + UpdateContext: resourceLBFrontendEdit, + DeleteContext: resourceLBFrontendDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: map[string]*schema.Schema{ + "lb_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the LB instance to backendCreate", + }, + "backend_name": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} diff --git a/internal/service/cloudapi/lb/resource_lb_frontend_bind.go b/internal/service/cloudapi/lb/resource_lb_frontend_bind.go new file mode 100644 index 00000000..7513542d --- /dev/null +++ b/internal/service/cloudapi/lb/resource_lb_frontend_bind.go @@ -0,0 +1,216 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceLBFrontendBindCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendBindCreate") + + haveLBID, err := existLBID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveLBID { + return diag.Errorf("resourceLBFrontendBindCreate: can't create LB frontend bind because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) + } + + c := m.(*controller.ControllerCfg) + req := lb.FrontendBindRequest{ + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("frontend_name").(string), + BindingName: d.Get("name").(string), + BindingAddress: d.Get("address").(string), + BindingPort: uint64(d.Get("port").(int)), + } + + _, err = c.CloudAPI().LB().FrontendBind(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("frontend_name").(string) + "#" + d.Get("name").(string)) + + _, err = utilityLBFrontendBindCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + return resourceLBFrontendBindRead(ctx, d, m) +} + +func resourceLBFrontendBindRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendBindRead") + + b, err := utilityLBFrontendBindCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) + frontendName := strings.Split(d.Id(), "#")[1] + + flattenLBFrontendBind(d, b, lbId, frontendName) + + return nil +} + +func resourceLBFrontendBindDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendBindDelete") + + _, err := utilityLBFrontendBindCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := lb.FrontendBindDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("frontend_name").(string), + BindingName: d.Get("name").(string), + } + + _, err = c.CloudAPI().LB().FrontendBindDelete(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceLBFrontendBindUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendBindEdit") + c := m.(*controller.ControllerCfg) + + haveLBID, err := existLBID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveLBID { + return diag.Errorf("resourceLBFrontendBindUpdate: can't update LB frontend bind because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) + } + + req := lb.FrontendBindUpdateRequest{ + FrontendName: d.Get("frontend_name").(string), + BindingName: d.Get("name").(string), + LBID: uint64(d.Get("lb_id").(int)), + } + + if d.HasChange("address") { + req.BindingAddress = d.Get("address").(string) + } + + if d.HasChange("port") { + req.BindingPort = uint64(d.Get("port").(int)) + } + + _, err = c.CloudAPI().LB().FrontendBindUpdate(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + return resourceLBFrontendBindRead(ctx, d, m) +} + +func ResourceLBFrontendBind() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLBFrontendBindCreate, + ReadContext: resourceLBFrontendBindRead, + UpdateContext: resourceLBFrontendBindUpdate, + DeleteContext: resourceLBFrontendBindDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: map[string]*schema.Schema{ + "lb_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the LB instance to backendCreate", + }, + "frontend_name": { + Type: schema.TypeString, + Required: true, + Description: "Must be unique among all backends of this LB - name of the new backend to create", + }, + "address": { + Type: schema.TypeString, + Required: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "port": { + Type: schema.TypeInt, + Required: true, + }, + }, + } +} diff --git a/internal/service/cloudapi/lb/utility_lb.go b/internal/service/cloudapi/lb/utility_lb.go new file mode 100644 index 00000000..d1d00ca1 --- /dev/null +++ b/internal/service/cloudapi/lb/utility_lb.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLBCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.RecordLB, error) { + c := m.(*controller.ControllerCfg) + req := lb.GetRequest{} + + if (d.Get("lb_id").(int)) != 0 { + req.LBID = uint64(d.Get("lb_id").(int)) + } else { + lbId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.LBID = lbId + } + + lb, err := c.CloudAPI().LB().Get(ctx, req) + if err != nil { + return nil, err + } + + return lb, nil +} diff --git a/internal/service/cloudapi/lb/utility_lb_backend.go b/internal/service/cloudapi/lb/utility_lb_backend.go new file mode 100644 index 00000000..c935e504 --- /dev/null +++ b/internal/service/cloudapi/lb/utility_lb_backend.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLBBackendCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemBackend, error) { + c := m.(*controller.ControllerCfg) + req := lb.GetRequest{} + bName := d.Get("name").(string) + + if (d.Get("lb_id").(int)) != 0 { + req.LBID = uint64(d.Get("lb_id").(int)) + } else { + parameters := strings.Split(d.Id(), "#") + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + req.LBID = lbId + bName = parameters[1] + } + + lb, err := c.CloudAPI().LB().Get(ctx, req) + if err != nil { + return nil, err + } + + backends := lb.Backends + for _, b := range backends { + if b.Name == bName { + return &b, nil + } + } + + return nil, fmt.Errorf("can not find backend with name: %s for lb: %d", bName, lb.ID) +} diff --git a/internal/service/cloudapi/lb/utility_lb_backend_server.go b/internal/service/cloudapi/lb/utility_lb_backend_server.go new file mode 100644 index 00000000..227d955b --- /dev/null +++ b/internal/service/cloudapi/lb/utility_lb_backend_server.go @@ -0,0 +1,89 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLBBackendServerCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemServer, error) { + c := m.(*controller.ControllerCfg) + req := lb.GetRequest{} + + bName := d.Get("backend_name").(string) + sName := d.Get("name").(string) + + if (d.Get("lb_id").(int)) != 0 { + req.LBID = uint64(d.Get("lb_id").(int)) + } else { + parameters := strings.Split(d.Id(), "#") + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + req.LBID = lbId + + bName = parameters[1] + sName = parameters[2] + } + + foundLB, err := c.CloudAPI().LB().Get(ctx, req) + if err != nil { + return nil, err + } + + backend := &lb.ItemBackend{} + backends := foundLB.Backends + for i, b := range backends { + if b.Name == bName { + backend = &backends[i] + break + } + } + + if backend.Name == "" { + return nil, fmt.Errorf("can not find backend with name: %s for lb: %d", bName, foundLB.ID) + } + + for _, s := range backend.Servers { + if s.Name == sName { + return &s, nil + } + } + + return nil, fmt.Errorf("can not find server with name: %s for backend: %s for lb: %d", sName, bName, foundLB.ID) +} diff --git a/internal/service/cloudapi/lb/utility_lb_frontend.go b/internal/service/cloudapi/lb/utility_lb_frontend.go new file mode 100644 index 00000000..e060ca72 --- /dev/null +++ b/internal/service/cloudapi/lb/utility_lb_frontend.go @@ -0,0 +1,75 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLBFrontendCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemFrontend, error) { + c := m.(*controller.ControllerCfg) + req := lb.GetRequest{} + + fName := d.Get("name").(string) + + if (d.Get("lb_id").(int)) != 0 { + req.LBID = uint64(d.Get("lb_id").(int)) + } else { + parameters := strings.Split(d.Id(), "#") + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + + req.LBID = lbId + fName = parameters[1] + } + + foundLB, err := c.CloudAPI().LB().Get(ctx, req) + if err != nil { + return nil, err + } + + frontends := foundLB.Frontends + for _, f := range frontends { + if f.Name == fName { + return &f, nil + } + } + + return nil, fmt.Errorf("can not find frontend with name: %s for lb: %d", fName, foundLB.ID) +} diff --git a/internal/service/cloudapi/lb/utility_lb_frontend_bind.go b/internal/service/cloudapi/lb/utility_lb_frontend_bind.go new file mode 100644 index 00000000..3af1cd86 --- /dev/null +++ b/internal/service/cloudapi/lb/utility_lb_frontend_bind.go @@ -0,0 +1,88 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLBFrontendBindCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemBinding, error) { + c := m.(*controller.ControllerCfg) + req := lb.GetRequest{} + + fName := d.Get("frontend_name").(string) + bName := d.Get("name").(string) + + if (d.Get("lb_id").(int)) != 0 { + req.LBID = uint64(d.Get("lb_id").(int)) + } else { + parameters := strings.Split(d.Id(), "#") + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + + req.LBID = lbId + fName = parameters[1] + bName = parameters[2] + } + + foundLB, err := c.CloudAPI().LB().Get(ctx, req) + if err != nil { + return nil, err + } + + frontend := &lb.ItemFrontend{} + frontends := foundLB.Frontends + for i, f := range frontends { + if f.Name == fName { + frontend = &frontends[i] + break + } + } + if frontend.Name == "" { + return nil, fmt.Errorf("can not find frontend with name: %s for lb: %d", fName, foundLB.ID) + } + + for _, b := range frontend.Bindings { + if b.Name == bName { + return &b, nil + } + } + + return nil, fmt.Errorf("can not find bind with name: %s for frontend: %s for lb: %d", bName, fName, foundLB.ID) +} diff --git a/internal/service/cloudapi/lb/utility_lb_list.go b/internal/service/cloudapi/lb/utility_lb_list.go new file mode 100644 index 00000000..2433aa58 --- /dev/null +++ b/internal/service/cloudapi/lb/utility_lb_list.go @@ -0,0 +1,106 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityLBListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ListLB, error) { + c := m.(*controller.ControllerCfg) + req := lb.ListRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if front_ip, ok := d.GetOk("front_ip"); ok { + req.FrontIP = front_ip.(string) + } + + if back_ip, ok := d.GetOk("back_ip"); ok { + req.BackIP = back_ip.(string) + } + + if includedeleted, ok := d.GetOk("includedeleted"); ok { + req.IncludeDeleted = includedeleted.(bool) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + log.Debugf("utilityLBListCheckPresence: load lb list") + lbList, err := c.CloudAPI().LB().List(ctx, req) + if err != nil { + return nil, err + } + + return lbList, nil +} diff --git a/internal/service/cloudapi/lb/utility_lb_list_deleted.go b/internal/service/cloudapi/lb/utility_lb_list_deleted.go new file mode 100644 index 00000000..a5be51b9 --- /dev/null +++ b/internal/service/cloudapi/lb/utility_lb_list_deleted.go @@ -0,0 +1,95 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityLBListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ListLB, error) { + c := m.(*controller.ControllerCfg) + req := lb.ListDeletedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if front_ip, ok := d.GetOk("front_ip"); ok { + req.FrontIP = front_ip.(string) + } + + if back_ip, ok := d.GetOk("back_ip"); ok { + req.BackIP = back_ip.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityLBListDeletedCheckPresence: load lb list") + lbList, err := c.CloudAPI().LB().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return lbList, nil +} diff --git a/internal/service/cloudapi/locations/data_source_locations_list.go b/internal/service/cloudapi/locations/data_source_locations_list.go new file mode 100644 index 00000000..30f0b711 --- /dev/null +++ b/internal/service/cloudapi/locations/data_source_locations_list.go @@ -0,0 +1,219 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package locations + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenLocationsList(ll *locations.ListLocations) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ll.Data)) + for _, l := range ll.Data { + temp := map[string]interface{}{ + "ckey": l.CKey, + "meta": flattens.FlattenMeta(l.Meta), + "auth_broker": l.AuthBroker, + "flag": l.Flag, + "gid": l.GID, + "guid": l.GUID, + "id": l.ID, + "location_code": l.LocationCode, + "name": l.Name, + "network_modes": l.NetworkModes, + "sdn_support": l.SDNSupport, + "zero_access_enabled": l.ZeroAccessEnabled, + "bro_enabled": l.BROEnabled, + } + res = append(res, temp) + } + return res + +} + +func dataSourceLocationsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + locations, err := utilityLocationsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + d.Set("items", flattenLocationsList(locations)) + d.Set("entry_count", locations.EntryCount) + + return nil +} + +func dataSourceLocationsListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "flag": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by flag", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "location_code": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by location code", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Locations list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "auth_broker": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "flag": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "Grid id", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "location id", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "location id", + }, + "location_code": { + Type: schema.TypeString, + Computed: true, + Description: "Location code", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Location name", + }, + "network_modes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sdn_support": { + Type: schema.TypeBool, + Computed: true, + Description: "support of SDN", + }, + "zero_access_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "bro_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func DataSourceLocationsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLocationsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceLocationsListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/locations/data_source_locations_url.go b/internal/service/cloudapi/locations/data_source_locations_url.go new file mode 100644 index 00000000..3a35681f --- /dev/null +++ b/internal/service/cloudapi/locations/data_source_locations_url.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package locations + +import ( + "context" + "strings" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceLocationUrlRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + url, err := utilityLocationUrlCheckPresence(ctx, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + url = strings.ReplaceAll(url, "\\", "") + url = strings.ReplaceAll(url, "\"", "") + d.Set("url", url) + + return nil +} + +func dataSourceLocationUrlSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "url": { + Type: schema.TypeString, + Computed: true, + Description: "Location url", + }, + } +} + +func DataSourceLocationUrl() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLocationUrlRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceLocationUrlSchemaMake(), + } +} diff --git a/internal/service/cloudapi/locations/models.go b/internal/service/cloudapi/locations/models.go new file mode 100644 index 00000000..7c4d76ad --- /dev/null +++ b/internal/service/cloudapi/locations/models.go @@ -0,0 +1,36 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package locations + +type Location struct { + GridID int `json:"gid"` + Id int `json:"id"` + Guid int `json:"guid"` + LocationCode string `json:"locationCode"` + Name string `json:"name"` + NetworkModes []string `json:"network_modes"` + SDNSupport bool `json:"sdn_support"` + Flag string `json:"flag"` + Meta []interface{} `json:"_meta"` + CKey string `json:"_ckey"` +} + +type LocationsList []Location diff --git a/internal/service/cloudapi/locations/utility_location_url.go b/internal/service/cloudapi/locations/utility_location_url.go new file mode 100644 index 00000000..bec3226f --- /dev/null +++ b/internal/service/cloudapi/locations/utility_location_url.go @@ -0,0 +1,52 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package locations + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLocationUrlCheckPresence(ctx context.Context, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityLocationUrlCheckPresence: load locations list") + locationUrl, err := c.CloudAPI().Locations().GetURL(ctx) + if err != nil { + return "", err + } + + return locationUrl, nil +} diff --git a/internal/service/cloudapi/locations/utility_locations_list.go b/internal/service/cloudapi/locations/utility_locations_list.go new file mode 100644 index 00000000..dc01539c --- /dev/null +++ b/internal/service/cloudapi/locations/utility_locations_list.go @@ -0,0 +1,84 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package locations + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityLocationsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*locations.ListLocations, error) { + c := m.(*controller.ControllerCfg) + req := locations.ListRequest{} + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if flag, ok := d.GetOk("flag"); ok { + req.Flag = flag.(string) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if location_code, ok := d.GetOk("location_code"); ok { + req.LocationCode = location_code.(string) + } + + log.Debugf("utilityLocationsListCheckPresence: load locations list") + locationsList, err := c.CloudAPI().Locations().List(ctx, req) + if err != nil { + return nil, err + } + + return locationsList, nil +} diff --git a/internal/service/cloudapi/pfw/flattens.go b/internal/service/cloudapi/pfw/flattens.go new file mode 100644 index 00000000..55e2b65e --- /dev/null +++ b/internal/service/cloudapi/pfw/flattens.go @@ -0,0 +1,15 @@ +package pfw + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" +) + +func flattenPFW(d *schema.ResourceData, pfw *compute.ItemPFW) { + d.Set("compute_id", pfw.VMID) + d.Set("public_port_start", pfw.PublicPortStart) + d.Set("public_port_end", pfw.PublicPortEnd) + d.Set("local_ip", pfw.LocalIP) + d.Set("local_base_port", pfw.LocalPort) + d.Set("proto", pfw.Protocol) +} diff --git a/internal/service/cloudapi/pfw/resource_pfw.go b/internal/service/cloudapi/pfw/resource_pfw.go new file mode 100644 index 00000000..8aceeb27 --- /dev/null +++ b/internal/service/cloudapi/pfw/resource_pfw.go @@ -0,0 +1,193 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package pfw + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourcePfwCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourcePfwCreate: called for compute %d", d.Get("compute_id").(int)) + + c := m.(*controller.ControllerCfg) + req := compute.PFWAddRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + PublicPortStart: uint64(d.Get("public_port_start").(int)), + LocalBasePort: uint64(d.Get("local_base_port").(int)), + Proto: d.Get("proto").(string), + } + + if portEnd, ok := d.GetOk("public_port_end"); ok { + req.PublicPortEnd = int64(portEnd.(int)) + } + + pfwId, err := c.CloudAPI().Compute().PFWAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(fmt.Sprintf("%d-%d", d.Get("compute_id").(int), pfwId)) + + pfw, err := utilityPfwCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + d.Set("local_ip", pfw.LocalIP) + if _, ok := d.GetOk("public_port_end"); !ok { + d.Set("public_port_end", pfw.PublicPortEnd) + } + + return resourcePfwRead(ctx, d, m) +} + +func resourcePfwRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourcePfwRead: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id()) + + pfw, err := utilityPfwCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenPFW(d, pfw) + + return nil +} + +func resourcePfwDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourcePfwDelete: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id()) + + pfw, err := utilityPfwCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := compute.PFWDelRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + PFWID: pfw.ID, + } + + _, err = c.CloudAPI().Compute().PFWDel(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourcePfwSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: "ID of compute instance.", + }, + + "public_port_start": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validation.IntBetween(1, 65535), + Description: "External start port number for the rule.", + }, + + "public_port_end": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.IntBetween(1, 65535), + Description: "End port number (inclusive) for the ranged rule.", + }, + + "local_ip": { + Type: schema.TypeString, + Computed: true, + Description: "IP address of compute instance.", + }, + + "local_base_port": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validation.IntBetween(1, 65535), + Description: "Internal base port number.", + }, + + "proto": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false), + Description: "Network protocol, either 'tcp' or 'udp'.", + }, + } +} + +func ResourcePfw() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourcePfwCreate, + ReadContext: resourcePfwRead, + DeleteContext: resourcePfwDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourcePfwSchemaMake(), + } +} diff --git a/internal/service/cloudapi/pfw/utility_pfw.go b/internal/service/cloudapi/pfw/utility_pfw.go new file mode 100644 index 00000000..30c53ab3 --- /dev/null +++ b/internal/service/cloudapi/pfw/utility_pfw.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package pfw + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemPFW, error) { + c := m.(*controller.ControllerCfg) + req := compute.PFWListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + pfws, err := c.CloudAPI().Compute().PFWList(ctx, req) + if err != nil { + return nil, err + } + + idS := strings.Split(d.Id(), "-")[1] + id, err := strconv.Atoi(idS) + if err != nil { + return nil, err + } + + for _, pfw := range pfws.Data { + if pfw.ID == uint64(id) { + return &pfw, nil + } + } + + return nil, fmt.Errorf("PFW not found") +} diff --git a/internal/service/cloudapi/rg/data_source_rg.go b/internal/service/cloudapi/rg/data_source_rg.go new file mode 100644 index 00000000..56f132fc --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg.go @@ -0,0 +1,439 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rg, err := utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + flattenRg(d, *rg) + return nil +} + +func DataSourceResgroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceResgroupRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgSchemaMake(), + } +} + +// func sepsSchemaMake() map[string]*schema.Schema { +// res := map[string]*schema.Schema{ +// "sep_id": { +// Type: schema.TypeString, +// Computed: true, +// }, +// "data_name": { +// Type: schema.TypeString, +// Computed: true, +// }, +// "disk_size": { +// Type: schema.TypeFloat, +// Computed: true, +// }, +// "disk_size_max": { +// Type: schema.TypeInt, +// Computed: true, +// }, +// } + +// return res +// } + +// func resourcesSchemaMake() map[string]*schema.Schema { +// res := map[string]*schema.Schema{ +// "current": { +// Type: schema.TypeList, +// Computed: true, +// Elem: &schema.Resource{ +// Schema: map[string]*schema.Schema{ +// "cpu": { +// Type: schema.TypeInt, +// Computed: true, +// }, +// "disk_size": { +// Type: schema.TypeFloat, +// Computed: true, +// }, +// "disk_size_max": { +// Type: schema.TypeFloat, +// Computed: true, +// }, +// "extips": { +// Type: schema.TypeInt, +// Computed: true, +// }, +// "gpu": { +// Type: schema.TypeInt, +// Computed: true, +// }, +// "ram": { +// Type: schema.TypeInt, +// Computed: true, +// }, +// "seps": { +// Type: schema.TypeSet, +// Computed: true, +// Elem: &schema.Resource{ +// Schema: map[string]*schema.Schema{ +// "sep_id": { +// Type: schema.TypeString, +// Computed: true, +// }, +// "map": { +// Type: schema.TypeMap, +// Computed: true, +// Elem: &schema.Schema{ +// Type: schema.TypeString, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// "reserved": { +// Type: schema.TypeList, +// Computed: true, +// Elem: &schema.Resource{ +// Schema: map[string]*schema.Schema{ +// "cpu": { +// Type: schema.TypeInt, +// Computed: true, +// }, +// "disk_size": { +// Type: schema.TypeFloat, +// Computed: true, +// }, +// "disk_size_max": { +// Type: schema.TypeInt, +// Computed: true, +// }, +// "extips": { +// Type: schema.TypeInt, +// Computed: true, +// }, +// "gpu": { +// Type: schema.TypeInt, +// Computed: true, +// }, +// "ram": { +// Type: schema.TypeInt, +// Computed: true, +// }, +// "seps": { +// Type: schema.TypeSet, +// Computed: true, +// Elem: &schema.Resource{ +// Schema: map[string]*schema.Schema{ +// "sep_id": { +// Type: schema.TypeString, +// Computed: true, +// }, +// "map": { +// Type: schema.TypeMap, +// Computed: true, +// Elem: &schema.Schema{ +// Type: schema.TypeString, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// } + +// return res +// } + +func aclSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "email": { + Type: schema.TypeString, + Computed: true, + }, + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + } + + return res +} + +func resourceLimitsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Required: true, + }, + "limit": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + }, + } + + return res +} + +func dataSourceRgSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + }, + + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclSchemaMake(), + }, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_type": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dirty": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: resourceLimitsSchemaMake(), + }, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "res_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "sdn_access_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } + return res +} diff --git a/internal/service/cloudapi/rg/data_source_rg_affinity_group_computes.go b/internal/service/cloudapi/rg/data_source_rg_affinity_group_computes.go new file mode 100644 index 00000000..e0e80f8d --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_affinity_group_computes.go @@ -0,0 +1,140 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgAffinityGroupComputesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgComputes, err := utilityRgAffinityGroupComputesCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("items", flattenRgAffinityGroupComputes(rgComputes)) + return nil +} + +func dataSourceRgAffinityGroupComputesSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "affinity_group": { + Type: schema.TypeString, + Required: true, + Description: "Affinity group label", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "other_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "other_node_indirect": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "other_node_indirect_soft": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "other_node_soft": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "same_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "same_node_soft": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + } + + return res +} + +func DataSourceRgAffinityGroupComputes() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgAffinityGroupComputesRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgAffinityGroupComputesSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_affinity_groups_get.go b/internal/service/cloudapi/rg/data_source_rg_affinity_groups_get.go new file mode 100644 index 00000000..bd4e719f --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_affinity_groups_get.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgAffinityGroupsGetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computes, err := utilityRgAffinityGroupsGetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("ids", computes) + return nil +} + +func dataSourceRgAffinityGroupsGetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "affinity_group": { + Type: schema.TypeString, + Required: true, + Description: "Affinity group label", + }, + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } + + return res +} + +func DataSourceRgAffinityGroupsGet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgAffinityGroupsGetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgAffinityGroupsGetSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_affinity_groups_list.go b/internal/service/cloudapi/rg/data_source_rg_affinity_groups_list.go new file mode 100644 index 00000000..5bf5947c --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_affinity_groups_list.go @@ -0,0 +1,124 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgAffinityGroupsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + list, err := utilityRgAffinityGroupsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("affinity_groups", flattenRgListGroups(list)) + d.Set("entry_count", list.EntryCount) + return nil +} + +func dataSourceRgAffinityGroupsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "affinity_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Computed: true, + }, + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func DataSourceRgAffinityGroupsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgAffinityGroupsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgAffinityGroupsListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_audits.go b/internal/service/cloudapi/rg/data_source_rg_audits.go new file mode 100644 index 00000000..1acf4135 --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_audits.go @@ -0,0 +1,109 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgAudits, err := utilityRgAuditsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("items", flattenRgAudits(rgAudits)) + + return nil +} + +func dataSourceRgAuditsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "call": { + Type: schema.TypeString, + Computed: true, + }, + "responsetime": { + Type: schema.TypeFloat, + Computed: true, + }, + "statuscode": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } + + return res +} + +func DataSourceRgAudits() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgAuditsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgAuditsSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_get_resource_consumption.go b/internal/service/cloudapi/rg/data_source_rg_get_resource_consumption.go new file mode 100644 index 00000000..033bc37c --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_get_resource_consumption.go @@ -0,0 +1,102 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRGResourceConsumptionGetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + RGResourceConsumptionRec, err := utilityRGResourceConsumptionGetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenRGResourceConsumption(d, RGResourceConsumptionRec) + return nil +} + +func dataSourceRGResourceConsumptionGetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + }, + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceRGResourceSchemaMake(), + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceRGResourceSchemaMake(), + }, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceResourceLimitsSchemaMake(), + }, + }, + } + + return res +} + +func DataSourceRGResourceConsumptionGet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRGResourceConsumptionGetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRGResourceConsumptionGetSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_list.go b/internal/service/cloudapi/rg/data_source_rg_list.go new file mode 100644 index 00000000..24e988ab --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_list.go @@ -0,0 +1,299 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgList, err := utilityRgListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenRgList(rgList)) + d.Set("entry_count", rgList.EntryCount) + + return nil +} + +func dataSourceRgListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by account ID", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by account name", + }, + "created_after": { + Type: schema.TypeInt, + Optional: true, + Description: "Find RGs created after specific time (unix timestamp)", + }, + "created_before": { + Type: schema.TypeInt, + Optional: true, + Description: "Find RGs created before specific time (unix timestamp)", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "lock_status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by lock status", + }, + "includedeleted": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "included deleted resource groups", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclSchemaMake(), + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_type": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dirty": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: resourceLimitsSchemaMake(), + }, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "vms": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "resource_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sdn_access_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceRgList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_list_computes.go b/internal/service/cloudapi/rg/data_source_rg_list_computes.go new file mode 100644 index 00000000..37d68895 --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_list_computes.go @@ -0,0 +1,281 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListComputesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + listComputes, err := utilityRgListComputesCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenRgListComputes(listComputes)) + d.Set("entry_count", listComputes.EntryCount) + + return nil +} + +func rulesSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "key": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + "topology": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + } + + return res + +} + +func dataSourceRgListComputesSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by compute ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by account ID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by tech. status", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "FIlter by IP address", + }, + "extnet_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by extnet name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by extnet ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_label": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: rulesSchemaMake(), + }, + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "antiaffinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: rulesSchemaMake(), + }, + }, + "cpus": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "total_disks_size": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vins_connected": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func DataSourceRgListComputes() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListComputesRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListComputesSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_list_deleted.go b/internal/service/cloudapi/rg/data_source_rg_list_deleted.go new file mode 100644 index 00000000..e93578a1 --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_list_deleted.go @@ -0,0 +1,288 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgList, err := utilityRgListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenRgList(rgList)) + d.Set("entry_count", rgList.EntryCount) + + return nil +} + +func dataSourceRgListDeletedSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by account ID", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by account name", + }, + "created_after": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter RGs created after certain point in time (unix timestamp)", + }, + "created_before": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter RGs created before certain point in time (unix timestamp)", + }, + "lock_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by lock status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclSchemaMake(), + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_type": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dirty": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: resourceLimitsSchemaMake(), + }, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "vms": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "resource_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sdn_access_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceRgListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_list_lb.go b/internal/service/cloudapi/rg/data_source_rg_list_lb.go new file mode 100644 index 00000000..2a917766 --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_list_lb.go @@ -0,0 +1,448 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListLbRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + listLb, err := utilityRgListLbCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("items", flattenRgListLb(listLb)) + d.Set("entry_count", listLb.EntryCount) + + return nil +} + +func serversSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "check": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + "server_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: serverSettingsSchemaMake(), + }, + }, + } + return res +} + +func serverSettingsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "down_inter": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "slow_start": { + Type: schema.TypeInt, + Computed: true, + }, + "max_conn": { + Type: schema.TypeInt, + Computed: true, + }, + "max_queue": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func backendsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "algorithm": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "server_default_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: serverSettingsSchemaMake(), + }, + }, + "servers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: serversSchemaMake(), + }, + }, + } + return res +} + +func bindingsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func frontendsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "backend": { + Type: schema.TypeString, + Computed: true, + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: bindingsSchemaMake(), + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + } + + return res +} + +func nodeSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceRgListLbSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by tech. status", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "front_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by frontend IP", + }, + "back_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by backend IP", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ha_mode": { + Type: schema.TypeBool, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclSchemaMake(), + }, + }, + "backend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "backends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: backendsSchemaMake(), + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dp_api_user": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "frontends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: frontendsSchemaMake(), + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "primary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: nodeSchemaMake(), + }, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: nodeSchemaMake(), + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func DataSourceRgListLb() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListLbRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListLbSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_list_pfw.go b/internal/service/cloudapi/rg/data_source_rg_list_pfw.go new file mode 100644 index 00000000..ea97a1dc --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_list_pfw.go @@ -0,0 +1,127 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListPfwRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + listPfw, err := utilityRgListPfwCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("items", flattenRgListPfw(listPfw)) + d.Set("entry_count", listPfw.EntryCount) + + return nil +} + +func dataSourceRgListPfwSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "public_port_end": { + Type: schema.TypeInt, + Computed: true, + }, + "public_port_start": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_ip": { + Type: schema.TypeString, + Computed: true, + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + }, + "vm_port": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func DataSourceRgListPfw() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListPfwRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListPfwSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_list_vins.go b/internal/service/cloudapi/rg/data_source_rg_list_vins.go new file mode 100644 index 00000000..28e7c77a --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_list_vins.go @@ -0,0 +1,202 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + listVins, err := utilityRgListVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("items", flattenRgListVins(listVins)) + d.Set("entry_count", listVins.EntryCount) + + return nil +} + +func dataSourceRgListVinsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by account ID", + }, + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by external IP", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ViNS ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "computes": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "pri_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func DataSourceRgListVins() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListVinsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListVinsSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_resource_consumption_list.go b/internal/service/cloudapi/rg/data_source_rg_resource_consumption_list.go new file mode 100644 index 00000000..a954fc0b --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_resource_consumption_list.go @@ -0,0 +1,204 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRGResourceConsumptionListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgResourceConsumptionList, err := utilityRGResourceConsumptionListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenRGResourceConsumptionList(rgResourceConsumptionList)) + d.Set("entry_count", rgResourceConsumptionList.EntryCount) + return nil +} + +func dataSourceRGResourceConsumptionListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceRGResourceSchemaMake(), + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceRGResourceSchemaMake(), + }, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceResourceLimitsSchemaMake(), + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceSepsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + } + return res +} + +func dataSourceRGResourceSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceSepsSchemaMake(), + }, + }, + } + return res +} + +func dataSourceResourceLimitsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + } + + return res +} + +func DataSourceRGResourceConsumptionList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRGResourceConsumptionListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRGResourceConsumptionListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/data_source_rg_usage.go b/internal/service/cloudapi/rg/data_source_rg_usage.go new file mode 100644 index 00000000..cf68b4b8 --- /dev/null +++ b/internal/service/cloudapi/rg/data_source_rg_usage.go @@ -0,0 +1,124 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgUsageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + usage, err := utilityDataRgUsageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + flattenRgUsageResource(d, *usage) + return nil +} + +func dataSourceRgUsageSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + }, + + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "map": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + } + + return res +} + +func DataSourceRgUsage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgUsageRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgUsageSchemaMake(), + } +} diff --git a/internal/service/cloudapi/rg/flattens.go b/internal/service/cloudapi/rg/flattens.go new file mode 100644 index 00000000..c07cf6db --- /dev/null +++ b/internal/service/cloudapi/rg/flattens.go @@ -0,0 +1,633 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "encoding/json" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" +) + +func flattenRGSeps(seps map[string]map[string]rg.DiskUsage) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for sepKey, sepVal := range seps { + for dataKey, dataVal := range sepVal { + temp := map[string]interface{}{ + "sep_id": sepKey, + "data_name": dataKey, + "disk_size": dataVal.DiskSize, + "disk_size_max": dataVal.DiskSizeMax, + } + res = append(res, temp) + } + } + + return res +} + +// func flattenAccResource(r Resource) []map[string]interface{} { +// res := make([]map[string]interface{}, 0) +// temp := map[string]interface{}{ +// "cpu": r.CPU, +// "disksize": r.DiskSize, +// "extips": r.ExtIPs, +// "gpu": r.GPU, +// "ram": r.RAM, +// "seps": flattenRgSeps(r.SEPs), +// } +// res = append(res, temp) + +// return res +// } + +// func flattenRgResources(r Resources) []map[string]interface{} { +// res := make([]map[string]interface{}, 0) +// temp := map[string]interface{}{ +// "current": flattenAccResource(r.Current), +// "reserved": flattenAccResource(r.Reserved), +// } +// res = append(res, temp) +// return res +// } + +func flattenResgroup(d *schema.ResourceData, details rg.RecordResourceGroup) error { + log.Debugf("flattenResgroup: decoded RG name %q / ID %d, account ID %d", + details.Name, details.ID, details.AccountID) + + d.Set("account_id", details.AccountID) + d.Set("gid", details.GID) + d.Set("name", details.Name) + d.Set("quota", flattenQuota(details.ResourceLimits)) + d.Set("account_name", details.AccountName) + d.Set("acl", flattenRgAcl(details.ACL)) + d.Set("compute_features", details.ComputeFeatures) + d.Set("storage_policy", flattenRgStoragePolicy(details.ResourceLimits.StoragePolicies)) + d.Set("vms", details.Computes) + d.Set("created_by", details.CreatedBy) + d.Set("created_time", details.CreatedTime) + d.Set("def_net_id", details.DefNetID) + d.Set("deleted_by", details.DeletedBy) + d.Set("deleted_time", details.DeletedTime) + d.Set("description", details.Description) + d.Set("dirty", details.Dirty) + d.Set("guid", details.GUID) + d.Set("rg_id", details.ID) + d.Set("lock_status", details.LockStatus) + d.Set("milestones", details.Milestones) + d.Set("res_types", details.ResTypes) + d.Set("secret", details.Secret) + d.Set("status", details.Status) + d.Set("updated_by", details.UpdatedBy) + d.Set("updated_time", details.UpdatedTime) + d.Set("uniq_pools", details.UniqPools) + d.Set("vins", details.VINS) + d.Set("cpu_allocation_parameter", details.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", details.CPUAllocationRatio) + d.Set("sdn_access_group_id", details.SDNAccessGroupID) + d.Set("resource_limits", flattenRgResourceLimits(details.ResourceLimits)) + d.Set("storage_policy_ids", details.StoragePolicyIDs) + + return nil +} + +func flattenRgSeps(seps map[string]map[string]rg.DiskUsage) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(seps)) + for sepKey, sepVal := range seps { + SepMap := map[string]interface{}{} + for dataKey, dataVal := range sepVal { + val, _ := json.Marshal(dataVal) + SepMap[dataKey] = string(val) + } + temp := map[string]interface{}{ + "sep_id": sepKey, + "map": SepMap, + } + res = append(res, temp) + } + return res +} + +func flattenQuota(resource rg.ResourceLimits) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": resource.CUC, + "ram": resource.CUM, + "disk": resource.CUDM, + "ext_ips": resource.CUI, + "gpu_units": resource.GPUUnits, + "cu_d": resource.CUD, + } + + res = append(res, temp) + + return res +} + +func flattenResource(resource rg.Resource) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": resource.CPU, + "disk_size": resource.DiskSize, + "disk_size_max": resource.DiskSizeMax, + "extips": resource.ExtIPs, + "gpu": resource.GPU, + "ram": resource.RAM, + "seps": flattenRGSeps(resource.SEPs), + } + + res = append(res, temp) + + return res +} + +func flattenRg(d *schema.ResourceData, itemRg rg.RecordResourceGroup) { + // d.Set("resources", flattenRgResource(itemRg.Resources)) + d.Set("account_id", itemRg.AccountID) + d.Set("account_name", itemRg.AccountName) + d.Set("acl", flattenRgAcl(itemRg.ACL)) + d.Set("computes", itemRg.Computes) + d.Set("compute_features", itemRg.ComputeFeatures) + d.Set("created_by", itemRg.CreatedBy) + d.Set("created_time", itemRg.CreatedTime) + d.Set("def_net_id", itemRg.DefNetID) + d.Set("def_net_type", itemRg.DefNetType) + d.Set("deleted_by", itemRg.DeletedBy) + d.Set("deleted_time", itemRg.DeletedTime) + d.Set("desc", itemRg.Description) + d.Set("dirty", itemRg.Dirty) + d.Set("gid", itemRg.GID) + d.Set("guid", itemRg.GUID) + d.Set("rg_id", itemRg.ID) + d.Set("lock_status", itemRg.LockStatus) + d.Set("milestones", itemRg.Milestones) + d.Set("name", itemRg.Name) + d.Set("res_types", itemRg.ResTypes) + d.Set("resource_limits", flattenRgResourceLimits(itemRg.ResourceLimits)) + d.Set("secret", itemRg.Secret) + d.Set("status", itemRg.Status) + d.Set("updated_by", itemRg.UpdatedBy) + d.Set("updated_time", itemRg.UpdatedTime) + d.Set("uniq_pools", itemRg.UniqPools) + d.Set("vins", itemRg.VINS) + d.Set("cpu_allocation_parameter", itemRg.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", itemRg.CPUAllocationRatio) + d.Set("sdn_access_group_id", itemRg.SDNAccessGroupID) + d.Set("storage_policy_ids", itemRg.StoragePolicyIDs) +} + +func flattenRgAudits(rgAudits rg.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rgAudits)) + for _, rgAudit := range rgAudits { + temp := map[string]interface{}{ + "call": rgAudit.Call, + "responsetime": rgAudit.ResponseTime, + "statuscode": rgAudit.StatusCode, + "timestamp": rgAudit.Timestamp, + "user": rgAudit.User, + } + + res = append(res, temp) + } + + return res +} + +func flattenRgList(rgl *rg.ListResourceGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rgl.Data)) + for _, rg := range rgl.Data { + temp := map[string]interface{}{ + "account_acl": flattenRgAcl(rg.ACL), + "account_id": rg.AccountID, + "account_name": rg.AccountName, + "compute_features": rg.ComputeFeatures, + "created_by": rg.CreatedBy, + "created_time": rg.CreatedTime, + "def_net_id": rg.DefNetID, + "def_net_type": rg.DefNetType, + "deleted_by": rg.DeletedBy, + "deleted_time": rg.DeletedTime, + "desc": rg.Description, + "dirty": rg.Dirty, + "gid": rg.GID, + "guid": rg.GUID, + "rg_id": rg.ID, + "lock_status": rg.LockStatus, + "milestones": rg.Milestones, + "name": rg.Name, + "resource_limits": flattenRgResourceLimits(rg.ResourceLimits), + "secret": rg.Secret, + "status": rg.Status, + "updated_by": rg.UpdatedBy, + "updated_time": rg.UpdatedTime, + "vins": rg.VINS, + "vms": rg.Computes, + "resource_types": rg.ResTypes, + "uniq_pools": rg.UniqPools, + "cpu_allocation_parameter": rg.CPUAllocationParameter, + "cpu_allocation_ratio": rg.CPUAllocationRatio, + "sdn_access_group_id": rg.SDNAccessGroupID, + "storage_policy_ids": rg.StoragePolicyIDs, + } + res = append(res, temp) + } + return res +} + +func flattenRgAcl(rgAcls rg.ListACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rgAcls)) + for _, rgAcl := range rgAcls { + temp := map[string]interface{}{ + "email": rgAcl.Email, + "explicit": rgAcl.Explicit, + "guid": rgAcl.GUID, + "right": rgAcl.Right, + "status": rgAcl.Status, + "type": rgAcl.Type, + "user_group_id": rgAcl.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenRgResourceLimits(rl rg.ResourceLimits) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cu_c": rl.CUC, + "cu_d": rl.CUD, + "cu_i": rl.CUI, + "cu_m": rl.CUM, + "cu_dm": rl.CUDM, + "gpu_units": rl.GPUUnits, + "storage_policy": flattenRgStoragePolicy(rl.StoragePolicies), + } + res = append(res, temp) + + return res +} + +func flattenRgStoragePolicy(spList []rg.StoragePolicy) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(spList)) + for _, sp := range spList { + temp := map[string]interface{}{ + "id": sp.ID, + "limit": sp.Limit, + } + + res = append(res, temp) + } + + return res +} + +func flattenRules(list rg.ListRules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + for _, rule := range list { + temp := map[string]interface{}{ + "guid": rule.GUID, + "key": rule.Key, + "mode": rule.Mode, + "policy": rule.Policy, + "topology": rule.Topology, + "value": rule.Value, + } + + res = append(res, temp) + } + + return res +} + +func flattenRgListComputes(lc *rg.ListComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(lc.Data)) + for _, compute := range lc.Data { + temp := map[string]interface{}{ + "account_id": compute.AccountID, + "account_name": compute.AccountName, + "affinity_label": compute.AffinityLabel, + "affinity_rules": flattenRules(compute.AffinityRules), + "affinity_weight": compute.AffinityWeight, + "antiaffinity_rules": flattenRules(compute.AntiAffinityRules), + "cpus": compute.CPUs, + "created_by": compute.CreatedBy, + "created_time": compute.CreatedTime, + "deleted_by": compute.DeletedBy, + "deleted_time": compute.DeletedTime, + "id": compute.ID, + "name": compute.Name, + "ram": compute.RAM, + "registered": compute.Registered, + "rg_name": compute.RGName, + "status": compute.Status, + "tech_status": compute.TechStatus, + "total_disks_size": compute.TotalDisksSize, + "updated_by": compute.UpdatedBy, + "updated_time": compute.UpdatedTime, + "user_managed": compute.UserManaged, + "vins_connected": compute.VINSConnected, + } + + res = append(res, temp) + } + + return res +} + +func flattenServerSettings(settings rg.RecordServerSettings) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "inter": settings.Inter, + "guid": settings.GUID, + "down_inter": settings.DownInter, + "rise": settings.Rise, + "fall": settings.Fall, + "slow_start": settings.SlowStart, + "max_conn": settings.MaxConn, + "max_queue": settings.MaxQueue, + "weight": settings.Weight, + } + res = append(res, temp) + return res +} + +func flattenListServers(list rg.ListServers) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + for _, serv := range list { + temp := map[string]interface{}{ + "address": serv.Address, + "check": serv.Check, + "guid": serv.GUID, + "name": serv.Name, + "port": serv.Port, + "server_settings": flattenServerSettings(serv.ServerSettings), + } + res = append(res, temp) + } + + return res +} + +func flattenBackends(b rg.ListBackends) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(b)) + for _, item := range b { + temp := map[string]interface{}{ + "algorithm": item.Algorithm, + "guid": item.GUID, + "name": item.Name, + "server_default_settings": flattenServerSettings(item.ServerDefaultSettings), + "servers": flattenListServers(item.Servers), + } + res = append(res, temp) + } + return res +} + +func flattenBindings(list rg.ListBindings) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + for _, bind := range list { + temp := map[string]interface{}{ + "address": bind.Address, + "guid": bind.GUID, + "name": bind.Name, + "port": bind.Port, + } + res = append(res, temp) + } + + return res +} + +func flattenFrontends(list rg.ListFrontends) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + for _, front := range list { + temp := map[string]interface{}{ + "backend": front.Backend, + "bindings": flattenBindings(front.Bindings), + "guid": front.GUID, + "name": front.Name, + } + res = append(res, temp) + } + + return res +} + +func flattenNode(node rg.RecordNode) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "backend_ip": node.BackendIP, + "compute_id": node.ComputeID, + "frontend_ip": node.FrontendIP, + "guid": node.GUID, + "mgmt_ip": node.MGMTIP, + "network_id": node.NetworkID, + } + res = append(res, temp) + return res +} + +func flattenRgListLb(listLb *rg.ListLB) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(listLb.Data)) + for _, lb := range listLb.Data { + temp := map[string]interface{}{ + "ha_mode": lb.HAMode, + "acl": lb.ACL, + "backend_haip": lb.BackendHAIP, + "backends": flattenBackends(lb.Backends), + "created_by": lb.CreatedBy, + "created_time": lb.CreatedTime, + "deleted_by": lb.DeletedBy, + "deleted_time": lb.DeletedTime, + "desc": lb.Description, + "dp_api_user": lb.DPAPIUser, + "extnet_id": lb.ExtNetID, + "frontend_haip": lb.FrontendHAIP, + "frontends": flattenFrontends(lb.Frontends), + "gid": lb.GID, + "guid": lb.GUID, + "id": lb.ID, + "image_id": lb.ImageID, + "milestones": lb.Milestones, + "name": lb.Name, + "primary_node": flattenNode(lb.PrimaryNode), + "rg_name": lb.RGName, + "secondary_node": flattenNode(lb.SecondaryNode), + "status": lb.Status, + "tech_status": lb.TechStatus, + "updated_by": lb.UpdatedBy, + "updated_time": lb.UpdatedTime, + "vins_id": lb.VINSID, + } + res = append(res, temp) + } + return res +} + +func flattenRgListPfw(listPfw *rg.ListPortForwards) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(listPfw.Data)) + for _, pfw := range listPfw.Data { + temp := map[string]interface{}{ + "public_port_end": pfw.PublicPortEnd, + "public_port_start": pfw.PublicPortStart, + "vm_id": pfw.VMID, + "vm_ip": pfw.VMIP, + "vm_name": pfw.VMName, + "vm_port": pfw.VMPort, + "vins_id": pfw.VINSID, + "vins_name": pfw.VINSName, + } + res = append(res, temp) + } + + return res +} + +func flattenRgListVins(lv *rg.ListVINS) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(lv.Data)) + for _, vins := range lv.Data { + temp := map[string]interface{}{ + "account_id": vins.AccountID, + "account_name": vins.AccountName, + "computes": vins.Computes, + "created_by": vins.CreatedBy, + "created_time": vins.CreatedTime, + "deleted_by": vins.DeletedBy, + "deleted_time": vins.DeletedTime, + "external_ip": vins.ExternalIP, + "extnet_id": vins.ExtnetId, + "free_ips": vins.FreeIPs, + "id": vins.ID, + "name": vins.Name, + "network": vins.Network, + "pri_vnf_dev_id": vins.PriVNFDevID, + "rg_name": vins.RGName, + "status": vins.Status, + "updated_by": vins.UpdatedBy, + "updated_time": vins.UpdatedTime, + } + + res = append(res, temp) + } + + return res +} + +func flattenRgAffinityGroupComputes(list rg.ListAffinityGroupsComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + + for _, item := range list { + temp := map[string]interface{}{ + "compute_id": item.ComputeID, + "other_node": item.OtherNode, + "other_node_indirect": item.OtherNodeIndirect, + "other_node_indirect_soft": item.OtherNodeIndirectSoft, + "other_node_soft": item.OtherNodeSoft, + "same_node": item.SameNode, + "same_node_soft": item.SameNodeSoft, + } + res = append(res, temp) + } + + return res +} + +// func flattenRgAffinityGroupsGet(list []uint64) []map[string]interface{} { +// res := make([]map[string]interface{}, 0) +// temp := map[string]interface{}{ +// "items": list, +// } +// res = append(res, temp) + +// return res +// } + +func flattenRgListGroups(list *rg.ListAffinityGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list.Data)) + for _, groupVal := range list.Data { + for label, ag := range groupVal { + temp := map[string]interface{}{ + "label": label, + "ids": flattenRgAffinityListGroup(ag), + } + res = append(res, temp) + } + } + + return res +} + +func flattenRgAffinityListGroup(list rg.ListAffinityGroup) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + for _, ag := range list { + temp := map[string]interface{}{ + "id": ag.ID, + "node_id": ag.NodeID, + } + res = append(res, temp) + } + + return res +} + +func flattenRgUsageResource(d *schema.ResourceData, usage rg.RecordResourceUsage) { + d.Set("cpu", usage.CPU) + d.Set("disk_size", usage.DiskSize) + d.Set("disk_size_max", usage.DiskSizeMax) + d.Set("extips", usage.ExtIPs) + d.Set("gpu", usage.GPU) + d.Set("ram", usage.RAM) + d.Set("seps", flattenRgSeps(usage.SEPs)) +} + +func flattenRGResourceConsumptionList(rg *rg.ListResourceConsumption) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rg.Data)) + for _, rc := range rg.Data { + temp := map[string]interface{}{ + "consumed": flattenResource(rc.Consumed), + "reserved": flattenResource(rc.Reserved), + "resource_limits": flattenRgResourceLimits(rc.ResourceLimits), + "rg_id": rc.RGID, + } + res = append(res, temp) + } + return res +} + +func flattenRGResourceConsumption(d *schema.ResourceData, rg *rg.ItemResourceConsumption) { + d.Set("consumed", flattenResource(rg.Consumed)) + d.Set("reserved", flattenResource(rg.Reserved)) + d.Set("resource_limits", flattenRgResourceLimits(rg.ResourceLimits)) + d.Set("rg_id", rg.RGID) +} diff --git a/internal/service/cloudapi/rg/models.go b/internal/service/cloudapi/rg/models.go new file mode 100644 index 00000000..81f58066 --- /dev/null +++ b/internal/service/cloudapi/rg/models.go @@ -0,0 +1,738 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +type ResourceLimits struct { + CUC float64 `json:"CU_C"` + CUD float64 `json:"CU_D"` + CUI float64 `json:"CU_I"` + CUM float64 `json:"CU_M"` + GpuUnits float64 `json:"gpu_units"` +} + +type QuotaRecord struct { // this is how quota is reported by /api/.../rg/get + Cpu int `json:"CU_C"` // CPU count in pcs + Ram int `json:"CU_M"` // RAM volume in MB + Disk int `json:"CU_D"` // Disk capacity in GB + ExtIPs int `json:"CU_I"` // Ext IPs count + GpuUnits int `json:"gpu_units"` // GPU count +} + +// Main information about audit +type ItemAudit struct { + // Call + Call string `json:"call"` + + // Response time + ResponseTime float64 `json:"responsetime"` + + // Status code + StatusCode uint64 `json:"statuscode"` + + // Timestamp + Timestamp float64 `json:"timestamp"` + + // User + User string `json:"user"` +} + +// List of audits +type ListAudits []ItemAudit + +// Resources used +type Resource struct { + // Number of cores + CPU int64 `json:"cpu"` + + // Disk size + DiskSize float64 `json:"disksize"` + + // Max disk size + DiskSizeMax uint64 `json:"disksizemax"` + + // Number of External IPs + ExtIPs int64 `json:"extips"` + + // Number of grafic cores + GPU int64 `json:"gpu"` + + // Number of RAM + RAM int64 `json:"ram"` + + // SEPs + SEPs map[string]map[string]DiskUsage `json:"seps"` +} + +// Disk usage +type DiskUsage struct { + // Disk size + DiskSize float64 `json:"disksize"` + + // Disk size max + DiskSizeMax float64 `json:"disksizemax"` +} + +// Information about resources +type Resources struct { + // Current information about resources + Current Resource `json:"Current"` + + // Reserved information about resources + Reserved Resource `json:"Reserved"` +} + +// Detailed information about resource group +type RecordResourceGroup struct { + // Resources + Resources Resources `json:"Resources"` + + // Account ID + AccountID uint64 `json:"accountId"` + + // Account name + AccountName string `json:"accountName"` + + // Access Control List + ACL ListACL `json:"acl"` + + // Created by + CreatedBy string `json:"createdBy"` + + // Created time + CreatedTime uint64 `json:"createdTime"` + + // DefNetID + DefNetID int64 `json:"def_net_id"` + + // DefNetType + DefNetType string `json:"def_net_type"` + + // Deleted by + DeletedBy string `json:"deletedBy"` + + // Deleted time + DeletedTime uint64 `json:"deletedTime"` + + // Description + Description string `json:"desc"` + + // Dirty + Dirty bool `json:"dirty"` + + // Grid ID + GID uint64 `json:"gid"` + + // GUID + GUID uint64 `json:"guid"` + + // ID + ID uint64 `json:"id"` + + // Lock status + LockStatus string `json:"lockStatus"` + + // Milestones + Milestones uint64 `json:"milestones"` + + // Name + Name string `json:"name"` + + // Resource limits + ResourceLimits ResourceLimits `json:"resourceLimits"` + + // Secret + Secret string `json:"secret"` + + // Status + Status string `json:"status"` + + // Updated by + UpdatedBy string `json:"updatedBy"` + + // Updated time + UpdatedTime uint64 `json:"updatedTime"` + + // List of VINS IDs + VINS []uint64 `json:"vins"` + + // List of compute IDs + Computes []uint64 `json:"vms"` + + // List of resource types + ResTypes []string `json:"resourceTypes"` + + // UniqPools + UniqPools []string `json:"uniqPools"` +} + +// Main information about Access Control List +type ItemACL struct { + // Explicit + Explicit bool `json:"explicit"` + + // GUID + GUID string `json:"guid"` + + // Right + Right string `json:"right"` + + // Status + Status string `json:"status"` + + // Type + Type string `json:"type"` + + // User group ID + UserGroupID string `json:"userGroupId"` +} + +// List ACL +type ListACL []ItemACL + +type ItemResourceGroup struct { + // + AccountACL ItemACL `json:"accountAcl"` + + // Account ID + AccountID uint64 `json:"accountId"` + + // Account name + AccountName string `json:"accountName"` + + // Access Control List + ACL ListACL `json:"acl"` + + // Created by + CreatedBy string `json:"createdBy"` + + // Created time + CreatedTime uint64 `json:"createdTime"` + + // DefNetID + DefNetID int64 `json:"def_net_id"` + + // DefNetType + DefNetType string `json:"def_net_type"` + + // Deleted by + DeletedBy string `json:"deletedBy"` + + // Deleted time + DeletedTime uint64 `json:"deletedTime"` + + // Description + Description string `json:"desc"` + + // Dirty + Dirty bool `json:"dirty"` + + // Grid ID + GID uint64 `json:"gid"` + + // GUID + GUID uint64 `json:"guid"` + + // ID + ID uint64 `json:"id"` + + // Lock status + LockStatus string `json:"lockStatus"` + + // Milestones + Milestones uint64 `json:"milestones"` + + // Name + Name string `json:"name"` + + // Resource limits + ResourceLimits ResourceLimits `json:"resourceLimits"` + + // Secret + Secret string `json:"secret"` + + // Status + Status string `json:"status"` + + // Updated by + UpdatedBy string `json:"updatedBy"` + + // Updated time + UpdatedTime uint64 `json:"updatedTime"` + + // List of VINS IDs + VINS []uint64 `json:"vins"` + + // List of compute IDs + Computes []uint64 `json:"vms"` + + // List of resource types + ResTypes []string `json:"resourceTypes"` + + // UniqPools + UniqPools []string `json:"uniqPools"` +} + +// List of resource groups +type ListResourceGroups []ItemResourceGroup + +// Main information about affinity rule +type ItemRule struct { + // GUID + GUID string `json:"guid"` + + // Key + Key string `json:"key"` + + // Mode + Mode string `json:"mode"` + + // Policy + Policy string `json:"policy"` + + // Topology + Topology string `json:"topology"` + + // Value + Value string `json:"value"` +} + +// List rules +type ListRules []ItemRule + +// Main information about compute +type ItemCompute struct { + // Account ID + AccountID uint64 `json:"accountId"` + + // Account name + AccountName string `json:"accountName"` + + // Affinity label + AffinityLabel string `json:"affinityLabel"` + + // List affinity rules + AffinityRules ListRules `json:"affinityRules"` + + // Affinity weight + AffinityWeight uint64 `json:"affinityWeight"` + + // Anti affinity rules + AntiAffinityRules ListRules `json:"antiAffinityRules"` + + // Number of CPU + CPUs uint64 `json:"cpus"` + + // Created by + CreatedBy string `json:"createdBy"` + + // Created time + CreatedTime uint64 `json:"createdTime"` + + // Deleted by + DeletedBy string `json:"deletedBy"` + + // Deleted time + DeletedTime uint64 `json:"deletedTime"` + + // ID + ID uint64 `json:"id"` + + // Name + Name string `json:"name"` + + // Number of RAM + RAM uint64 `json:"ram"` + + // Registered + Registered bool `json:"registered"` + + // Resource group ID + RGID uint64 `json:"rgId"` + + // Resource group name + RGName string `json:"rgName"` + + // Status + Status string `json:"status"` + + // Tech status + TechStatus string `json:"techStatus"` + + // Total disks size + TotalDisksSize uint64 `json:"totalDisksSize"` + + // Updated by + UpdatedBy string `json:"updatedBy"` + + // Updated time + UpdatedTime uint64 `json:"updatedTime"` + + // User managed + UserManaged bool `json:"userManaged"` + + // VINS connected + VINSConnected uint64 `json:"vinsConnected"` +} + +// List computes +type ListComputes []ItemCompute + +// Main information about port forward +type ItemPFW struct { + // Public port end + PublicPortEnd uint64 `json:"Public Port End"` + + // Public port start + PublicPortStart uint64 `json:"Public Port Start"` + + // Virtual machine ID + VMID uint64 `json:"VM ID"` + + // Virtual machine IP + VMIP string `json:"VM IP"` + + // Virtual machine name + VMName string `json:"VM Name"` + + // Virtual machine port + VMPort uint64 `json:"VM Port"` + + // VINS ID + VINSID uint64 `json:"ViNS ID"` + + // VINS name + VINSName string `json:"ViNS Name"` +} + +// List PFWs +type ListPFW []ItemPFW + +// Main information about VINS +type ItemVINS struct { + // Account ID + AccountID uint64 `json:"accountId"` + + // Account name + AccountName string `json:"accountName"` + + // Computes + Computes uint64 `json:"computes"` + + // Created by + CreatedBy string `json:"createdBy"` + + // Created time + CreatedTime uint64 `json:"createdTime"` + + // Deleted by + DeletedBy string `json:"deletedBy"` + + // Deleted time + DeletedTime uint64 `json:"deletedTime"` + + // External IP + ExternalIP string `json:"externalIP"` + + // ID + ID uint64 `json:"id"` + + // Name + Name string `json:"name"` + + // Network + Network string `json:"network"` + + // PriVNFDev ID + PriVNFDevID uint64 `json:"priVnfDevId"` + + // Resource group ID + RGID uint64 `json:"rgId"` + + // Resource group name + RGName string `json:"rgName"` + + // Status + Status string `json:"status"` + + // Updated by + UpdatedBy string `json:"updatedBy"` + + // Updated time + UpdatedTime uint64 `json:"updatedTime"` +} + +// List VINSes +type ListVINS []ItemVINS + +// Server settings +type ServerSettings struct { + // Inter + Inter uint64 `json:"inter"` + + // GUID + GUID string `json:"guid"` + + // Down inter + DownInter uint64 `json:"downinter"` + + // Rise + Rise uint64 `json:"rise"` + + // Fall + Fall uint64 `json:"fall"` + + // Slow start + SlowStart uint64 `json:"slowstart"` + + // Max connections + MaxConn uint64 `json:"maxconn"` + + // Max queue + MaxQueue uint64 `json:"maxqueue"` + + // Weight + Weight uint64 `json:"weight"` +} + +// Main information about server +type ItemServer struct { + // Address + Address string `json:"address"` + + // Check + Check string `json:"check"` + + // GUID + GUID string `json:"guid"` + + // Name + Name string `json:"name"` + + // Port + Port uint64 `json:"port"` + + // Server settings + ServerSettings ServerSettings `json:"serverSettings"` +} + +// List of servers +type ListServers []ItemServer + +// Main information about backend +type ItemBackend struct { + // Algorithm + Algorithm string `json:"algorithm"` + + // GUID + GUID string `json:"guid"` + + // Name + Name string `json:"name"` + + // Server settings + ServerDefaultSettings ServerSettings `json:"serverDefaultSettings"` + + // List of servers + Servers ListServers `json:"servers"` +} + +// List of backends +type ListBackends []ItemBackend + +// Main information of binding +type ItemBinding struct { + // Address + Address string `json:"address"` + + // GUID + GUID string `json:"guid"` + + // Name + Name string `json:"name"` + + // Port + Port uint64 `json:"port"` +} + +// List of bindings +type ListBindings []ItemBinding + +// Main information about frontend +type ItemFrontend struct { + // Backend + Backend string `json:"backend"` + + // List of bindings + Bindings ListBindings `json:"bindings"` + + // GUID + GUID string `json:"guid"` + + // Name + Name string `json:"name"` +} + +// List of frontends +type ListFrontends []ItemFrontend + +// Main information about node +type RecordNode struct { + // Backend IP + BackendIP string `json:"backendIp"` + + // Compute ID + ComputeID uint64 `json:"computeId"` + + // Frontend IP + FrontendIP string `json:"frontendIp"` + + // GUID + GUID string `json:"guid"` + + // MGMT IP + MGMTIP string `json:"mgmtIp"` + + // Network ID + NetworkID uint64 `json:"networkId"` +} + +// Main information about load balancer +type ItemLB struct { + // HAMode + HAMode bool `json:"HAmode"` + + // List ACL + ACL ListACL `json:"acl"` + + // List backends + Backends ListBackends `json:"backends"` + + // Created by + CreatedBy string `json:"createdBy"` + + // Created time + CreatedTime uint64 `json:"createdTime"` + + // Deleted by + DeletedBy string `json:"deletedBy"` + + // Deleted time + DeletedTime uint64 `json:"deletedTime"` + + // Description + Description string `json:"desc"` + + // DPAPI user + DPAPIUser string `json:"dpApiUser"` + + // External network ID + ExtNetID uint64 `json:"extnetId"` + + // List of frontends + Frontends ListFrontends `json:"frontends"` + + // Grid ID + GID uint64 `json:"gid"` + + // GUID + GUID uint64 `json:"guid"` + + // ID + ID uint64 `json:"id"` + + // Image ID + ImageID uint64 `json:"imageId"` + + // Milestones + Milestones uint64 `json:"milestones"` + + // Name + Name string `json:"name"` + + // Primary node + PrimaryNode RecordNode `json:"primaryNode"` + + // Resource group ID + RGID uint64 `json:"rgId"` + + // Resource group name + RGName string `json:"rgName"` + + // Secondary node + SecondaryNode RecordNode `json:"secondaryNode"` + + // Status + Status string `json:"status"` + + // Tech status + TechStatus string `json:"techStatus"` + + // Updated by + UpdatedBy string `json:"updatedBy"` + + // Updated time + UpdatedTime uint64 `json:"updatedTime"` + + // VINS ID + VINSID uint64 `json:"vinsId"` +} + +// List load balancers +type ListLB []ItemLB + +// Main information about affinity group +type ItemAffinityGroupCompute struct { + // Compute ID + ComputeID uint64 `json:"computeId"` + + // Other node + OtherNode []uint64 `json:"otherNode"` + + // Other node indirect + OtherNodeIndirect []uint64 `json:"otherNodeIndirect"` + + // Other node indirect soft + OtherNodeIndirectSoft []uint64 `json:"otherNodeIndirectSoft"` + + // Other node soft + OtherNodeSoft []uint64 `json:"otherNodeSoft"` + + // Same node + SameNode []uint64 `json:"sameNode"` + + // Same node soft + SameNodeSoft []uint64 `json:"sameNodeSoft"` +} + +// List of affinity groups +type ListAffinityGroupCompute []ItemAffinityGroupCompute diff --git a/internal/service/cloudapi/rg/old_schemas.go b/internal/service/cloudapi/rg/old_schemas.go new file mode 100644 index 00000000..a6a44284 --- /dev/null +++ b/internal/service/cloudapi/rg/old_schemas.go @@ -0,0 +1,292 @@ +package rg + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceRGResourceV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "Unique ID of the account, which this resource group belongs to.", + }, + "gid": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: "Unique ID of the grid, where this resource group is deployed.", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of this resource group. Names are case sensitive and unique within the context of a account.", + }, + "def_net_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC", "NONE"}, false), + Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.", + }, + "def_net_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the default network for this resource group (if any).", + }, + "ipcidr": { + Type: schema.TypeString, + Optional: true, + Description: "Address of the netowrk inside the private network segment (aka ViNS) if def_net_type=PRIVATE", + }, + "ext_net_id": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: "ID of the external network for default ViNS. Pass 0 if def_net_type=PUBLIC or no external connection required for the defult ViNS when def_net_type=PRIVATE", + }, + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "IP address on the external netowrk to request when def_net_type=PRIVATE and ext_net_id is not 0", + }, + "quota": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + Description: "Limit on the total number of CPUs in this resource group.", + }, + "ram": { + Type: schema.TypeFloat, // NB: API expects and returns this as float in units of MB! This may be changed in the future. + Optional: true, + Default: -1, + Description: "Limit on the total amount of RAM in this resource group, specified in MB.", + }, + "disk": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + Description: "Limit on the total volume of storage resources in this resource group, specified in GB.", + }, + "ext_traffic": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + Description: "Limit on the total ingress network traffic for this resource group, specified in GB.", + }, + "ext_ips": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + Description: "Limit on the total number of external IP addresses this resource group can use.", + }, + "gpu_units": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + Description: "Limit on the total number of virtual GPUs this resource group can use.", + }, + }, + }, + Description: "Quota settings for this resource group.", + }, + "access": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "user": { + Type: schema.TypeString, + Required: true, + Description: "User or group name to grant access", + }, + "right": { + Type: schema.TypeString, + Required: true, + Description: "Access rights to set, one of 'R', 'RCX' or 'ARCXDU'", + }, + "reason": { + Type: schema.TypeString, + Optional: true, + Description: "Reason for action", + }, + }, + }, + }, + "def_net": { + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC"}, false), + Description: "Network type to set. Must be on of 'PRIVATE' or 'PUBLIC'.", + }, + "net_id": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: "Network segment ID. If netType is PUBLIC and netId is 0 then default external network segment will be selected. If netType is PRIVATE and netId=0, the first ViNS defined for this RG will be selected. Otherwise, netId identifies either existing external network segment or ViNS.", + }, + "reason": { + Type: schema.TypeString, + Optional: true, + Description: "Reason for action", + }, + }, + }, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "User-defined text description of this resource group.", + }, + "force": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Set to True if you want force delete non-empty RG", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Set to True if you want force delete non-empty RG", + }, + "reason": { + Type: schema.TypeString, + Optional: true, + Description: "Set to True if you want force delete non-empty RG", + }, + "register_computes": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Register computes in registration system", + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "flag for enable/disable RG", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account, which this resource group belongs to.", + }, + // "resources": { + // Type: schema.TypeList, + // Computed: true, + // Elem: &schema.Resource{ + // Schema: resourcesSchemaMake(), + // }, + // }, + + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclSchemaMake(), + }, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "dirty": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Current status of this resource group.", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of VINs deployed in this resource group.", + }, + + "vms": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of computes deployed in this resource group.", + }, + "res_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + } +} diff --git a/internal/service/cloudapi/rg/quota_subresource.go b/internal/service/cloudapi/rg/quota_subresource.go new file mode 100644 index 00000000..a50562af --- /dev/null +++ b/internal/service/cloudapi/rg/quota_subresource.go @@ -0,0 +1,82 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +func makeQuotaRecord(arg_list []interface{}) QuotaRecord { + quota := QuotaRecord{ + Cpu: -1, + Ram: -1, + Disk: -1, + ExtIPs: -1, + GpuUnits: -1, + } + if len(arg_list) != 0 { + subres_data := arg_list[0].(map[string]interface{}) + + if subres_data["cpu"].(int) > 0 { + quota.Cpu = subres_data["cpu"].(int) + } + + if subres_data["disk"].(int) > 0 { + quota.Disk = subres_data["disk"].(int) // Disk capacity ib GB + } + + if subres_data["ram"].(int) > 0 { + quota.Ram = subres_data["ram"].(int) // RAM volume in MB + } + + if subres_data["ext_ips"].(int) > 0 { + quota.ExtIPs = subres_data["ext_ips"].(int) + } + + if subres_data["gpu_units"].(int) > 0 { + quota.GpuUnits = subres_data["gpu_units"].(int) + } + } + return quota +} + +// func parseQuota(quota QuotaRecord) []interface{} { +// quota_map := make(map[string]interface{}) + +// quota_map["cpu"] = quota.Cpu +// quota_map["ram"] = quota.Ram // NB: this is float64, unlike the rest of values +// quota_map["disk"] = quota.Disk +// quota_map["ext_ips"] = quota.ExtIPs +// quota_map["gpu_units"] = quota.GpuUnits + +// result := make([]interface{}, 1) +// result[0] = quota_map + +// return result // this result will be used to d.Set("quota,") of dataSourceResgroup schema +// } diff --git a/internal/service/cloudapi/rg/resource_check_input_values.go b/internal/service/cloudapi/rg/resource_check_input_values.go new file mode 100644 index 00000000..a18484a1 --- /dev/null +++ b/internal/service/cloudapi/rg/resource_check_input_values.go @@ -0,0 +1,87 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + accountId := uint64(d.Get("account_id").(int)) + + req := account.ListRequest{} + + accountList, err := c.CloudAPI().Account().List(ctx, req) + if err != nil { + return false, err + } + + return len(accountList.FilterByID(accountId).Data) != 0, nil +} + +func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + gid := uint64(d.Get("gid").(int)) + + req := locations.ListRequest{} + + locationList, err := c.CloudAPI().Locations().List(ctx, req) + if err != nil { + return false, err + } + + return len(locationList.FilterByGID(gid).Data) != 0, nil +} + +func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + extNetId := uint64(d.Get("ext_net_id").(int)) + + req := extnet.ListRequest{ + AccountID: uint64(d.Get("account_id").(int)), + } + + listExtNet, err := c.CloudAPI().ExtNet().List(ctx, req) + if err != nil { + return false, err + } + + return len(listExtNet.FilterByID(extNetId).Data) != 0, nil +} diff --git a/internal/service/cloudapi/rg/resource_rg.go b/internal/service/cloudapi/rg/resource_rg.go new file mode 100644 index 00000000..2d3f1cfb --- /dev/null +++ b/internal/service/cloudapi/rg/resource_rg.go @@ -0,0 +1,1001 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "fmt" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgName, ok := d.GetOk("name") + if !ok { + return diag.FromErr(fmt.Errorf("cannot create new RG: missing name")) + } + + log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d", + rgName.(string), d.Get("account_id").(int)) + + haveAccount, err := existAccountID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + if !haveAccount { + return diag.Errorf("resourceResgroupCreate: can't create RG because AccountID %d is not allowed or does not exist", d.Get("account_id").(int)) + } + + haveGID, err := existGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + if !haveGID { + return diag.Errorf("resourceResgroupCreate: can't create RG because GID %d is not allowed or does not exist", d.Get("gid").(int)) + } + + if _, ok := d.GetOk("ext_net_id"); ok { + haveExtNet, err := existExtNetID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + if !haveExtNet { + return diag.Errorf("resourceResgroupCreate: can't create RG because ExtNetID %d is not allowed or does not exist", d.Get("ext_net_id").(int)) + } + } + c := m.(*controller.ControllerCfg) + req := rg.CreateRequest{ + Name: rgName.(string), + AccountID: uint64(d.Get("account_id").(int)), + GID: uint64(d.Get("gid").(int)), + // Owner: c.GetDecortUsername(), + } + + if quota, ok := d.GetOk("quota"); ok { + quotaBlocks := quota.([]interface{})[0] + quotaMap := quotaBlocks.(map[string]interface{}) + + if quotaMap["ram"] != nil { + maxMemCap := int64(quotaMap["ram"].(int)) + if maxMemCap == 0 { + req.MaxMemoryCapacity = -1 + } else { + req.MaxMemoryCapacity = maxMemCap + } + } + if quotaMap["disk"] != nil { + maxDiskCap := int64(quotaMap["disk"].(int)) + if maxDiskCap == 0 { + req.MaxVDiskCapacity = -1 + } else { + req.MaxVDiskCapacity = maxDiskCap + } + } + if quotaMap["cpu"] != nil { + maxCPUCap := int64(quotaMap["cpu"].(int)) + if maxCPUCap == 0 { + req.MaxCPUCapacity = -1 + } else { + req.MaxCPUCapacity = maxCPUCap + } + } + if quotaMap["ext_ips"] != nil { + maxNumPublicIP := int64(quotaMap["ext_ips"].(int)) + if maxNumPublicIP == 0 { + req.MaxNumPublicIP = -1 + } else { + req.MaxNumPublicIP = maxNumPublicIP + } + } + } + if _, ok := d.GetOk("def_net"); !ok { + if defNetType, ok := d.GetOk("def_net_type"); ok { + if defNetType.(string) == "PRIVATE" { + return diag.Errorf("resourceResgroupCreate: cannot create RG with def_net_type=\"PRIVATE\": no ViNSes exist in a newly created RG. Use def_net_type=\"PRIVATE\" only when updating an existing RG that already contains a ViNS") + } + req.DefNet = defNetType.(string) // NOTE: in API default network type is set by "def_net" parameter + } + } else { + req.DefNet = "NONE" + } + + if owner, ok := d.GetOk("owner"); ok { + req.Owner = owner.(string) + } + + if ipcidr, ok := d.GetOk("ipcidr"); ok { + req.IPCIDR = ipcidr.(string) + } + + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + + if extNetId, ok := d.GetOk("ext_net_id"); ok { + req.ExtNetID = uint64(extNetId.(int)) + } + + if extIp, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = extIp.(string) + } + + if sdnAccessGroupID, ok := d.GetOk("sdn_access_group_id"); ok { + req.SDNAccessGroupID = sdnAccessGroupID.(string) + } + + if storagePolicies, ok := d.GetOk("storage_policy"); ok { + var id uint64 + var limit int + + if storagePolicies.(*schema.Set).Len() > 0 { + spList := storagePolicies.(*schema.Set).List() + for _, spInterface := range spList { + sps := spInterface.(map[string]interface{}) + id = uint64(sps["id"].(int)) + limit = sps["limit"].(int) + + spModel := rg.StoragePolicy{ + ID: id, + Limit: limit, + } + + req.StoragePolicies = append(req.StoragePolicies, spModel) + } + } + } + + apiResp, err := c.CloudAPI().RG().Create(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(apiResp, 10)) + + w := dc.Warnings{} + if access, ok := d.GetOk("access"); ok { + var user, right string + + if access.(*schema.Set).Len() > 0 { + accessList := access.(*schema.Set).List() + for _, accessInterface := range accessList { + access := accessInterface.(map[string]interface{}) + user = access["user"].(string) + right = access["right"].(string) + + req := rg.AccessGrantRequest{ + RGID: apiResp, + User: user, + Right: right, + } + + _, err := c.CloudAPI().RG().AccessGrant(ctx, req) + if err != nil { + w.Add(err) + } + } + } + } + + if defNet, ok := d.GetOk("def_net"); ok { + if defNet.(*schema.Set).Len() > 0 { + defNetList := defNet.(*schema.Set).List() + defNetItem := defNetList[0].(map[string]interface{}) + + netType := defNetItem["net_type"].(string) + + if netType == "PRIVATE" { + return diag.Errorf("resourceResgroupCreate: cannot create RG with def_net net_type=\"PRIVATE\": no ViNSes exist in a newly created RG. Use net_type=\"PRIVATE\" in def_net block only when updating an existing RG that already contains a ViNS") + } + + req := rg.SetDefNetRequest{ + RGID: apiResp, + NetType: netType, + } + + if netID, ok := defNetItem["net_id"]; ok { + req.NetID = uint64(netID.(int)) + } + + _, err := c.CloudAPI().RG().SetDefNet(ctx, req) + if err != nil { + w.Add(err) + } + + } + + } + + if enable, ok := d.GetOk("enable"); ok { + if enable.(bool) { + req := rg.EnableRequest{ + RGID: apiResp, + } + + _, err := c.CloudAPI().RG().Enable(ctx, req) + if err != nil { + w.Add(err) + } + } else { + req := rg.DisableRequest{ + RGID: apiResp, + } + + _, err := c.CloudAPI().RG().Disable(ctx, req) + if err != nil { + w.Add(err) + } + } + } + + return append(w.Get(), resourceResgroupRead(ctx, d, m)...) +} + +func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceResgroupRead: called for RG name %s, account ID %d", + d.Get("name").(string), d.Get("account_id").(int)) + + // c := m.(*controller.ControllerCfg) + + rgData, err := utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch rgData.Status { + case status.Modeled: + return diag.Errorf("The resource group is in status: %s, please, contact support for more information", rgData.Status) + case status.Created: + case status.Deleted: + // restoreReq := rg.RestoreRequest{RGID: rgData.ID} + // enableReq := rg.EnableRequest{RGID: rgData.ID} + + // _, err := c.CloudAPI().RG().Restore(ctx, restoreReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // _, err = c.CloudAPI().RG().Enable(ctx, enableReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // hasChanged = true + case status.Deleting: + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceResgroupCreate(ctx, d, m) + case status.Destroying: + case status.Disabled: + case status.Disabling: + case status.Enabled: + case status.Enabling: + } + + if hasChanged { + rgData, err = utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + return diag.FromErr(flattenResgroup(d, *rgData)) +} + +func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceResgroupUpdate: called for RG name %s, account ID %d", + d.Get("name").(string), d.Get("account_id").(int)) + + c := m.(*controller.ControllerCfg) + + haveAccount, err := existAccountID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + if !haveAccount { + return diag.Errorf("resourceResgroupUpdate: can't create RG bacause AccountID %d not allowed or does not exist", d.Get("account_id").(int)) + } + + haveGID, err := existGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + if !haveGID { + return diag.Errorf("resourceResgroupUpdate: can't create RG because GID %d not allowed or does not exist", d.Get("gid").(int)) + } + + if _, ok := d.GetOk("ext_net_id"); ok { + haveExtNet, err := existExtNetID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + if !haveExtNet { + return diag.Errorf("resourceResgroupUpdate: can't create RG bacause ExtNetID %d not allowed or does not exist", d.Get("ext_net_id").(int)) + } + } + + rgData, err := utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch rgData.Status { + case status.Modeled: + case status.Created: + case status.Enabled: + case status.Deleted: + if restore, ok := d.GetOk("restore"); ok && restore.(bool) { + restoreReq := rg.RestoreRequest{RGID: rgData.ID} + + _, err := c.CloudAPI().RG().Restore(ctx, restoreReq) + if err != nil { + return diag.FromErr(err) + } + + if enable, ok := d.GetOk("enable"); ok && enable.(bool) { + enableReq := rg.EnableRequest{RGID: rgData.ID} + + _, err = c.CloudAPI().RG().Enable(ctx, enableReq) + if err != nil { + return diag.FromErr(err) + } + } + } + hasChanged = true + case status.Deleting: + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceResgroupCreate(ctx, d, m) + case status.Destroying: + case status.Disabled: + case status.Disabling: + case status.Enabled: + case status.Enabling: + } + + if hasChanged { + rgData, err = utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + /* NOTE: we do not allow changing the following attributes of an existing RG via terraform: + - def_net_type + - ipcidr + - ext_net_id + - ext_ip + + The following code fragment checks if any of these have been changed and generates error. + */ + + for _, attr := range []string{"def_net_type", "ipcidr", "ext_ip"} { + attrNew, attrOld := d.GetChange(attr) + if attrNew.(string) != attrOld.(string) { + return diag.FromErr(fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing %s for existing RG is not allowed", d.Id(), attr)) + } + } + + if d.HasChange("ext_net_id") { + return diag.FromErr(fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing ext_net_id for existing RG is not allowed", d.Id())) + } + + needUpdateSP := false + if d.HasChange("storage_policy") { + needUpdate, err := utilityRGUpdateStPolicy(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + needUpdateSP = needUpdate + } + + if d.HasChanges("name", "quota", "description", "uniq_pools") || needUpdateSP { + if err := utilityUpdateRG(ctx, d, m, rgData.ID); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("enable") { + enableOld, enableNew := d.GetChange("enable") + if enableOld.(bool) && !enableNew.(bool) { + req := rg.DisableRequest{RGID: rgData.ID} + + _, err := c.CloudAPI().RG().Disable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else if !enableOld.(bool) && enableNew.(bool) { + req := rg.EnableRequest{RGID: rgData.ID} + + _, err := c.CloudAPI().RG().Enable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("access") { + oldSet, newSet := d.GetChange("access") + deletedAccess := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + for _, deletedInterface := range deletedAccess { + deletedItem := deletedInterface.(map[string]interface{}) + user := deletedItem["user"].(string) + req := rg.AccessRevokeRequest{ + RGID: rgData.ID, + User: user, + } + + _, err := c.CloudAPI().RG().AccessRevoke(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + addedAccess := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + for _, addedInterface := range addedAccess { + addedItem := addedInterface.(map[string]interface{}) + user := addedItem["user"].(string) + right := addedItem["right"].(string) + + req := rg.AccessGrantRequest{ + RGID: rgData.ID, + User: user, + Right: right, + } + + _, err := c.CloudAPI().RG().AccessGrant(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + if d.HasChange("def_net") { + oldDefNet, newDefNet := d.GetChange("def_net") + if oldDefNet.(*schema.Set).Len() > 0 { + _, err := c.CloudAPI().RG().RemoveDefNet(ctx, rg.RemoveDefNetRequest{RGID: rgData.ID}) + if err != nil { + return diag.FromErr(err) + } + } + if newDefNet.(*schema.Set).Len() > 0 { + changedDefNet := (newDefNet.(*schema.Set).Difference(oldDefNet.(*schema.Set))).List() + for _, changedDefNetInterface := range changedDefNet { + defNetItem := changedDefNetInterface.(map[string]interface{}) + netType := defNetItem["net_type"].(string) + netID := uint64(defNetItem["net_id"].(int)) + + if netType == "PRIVATE" { + if netID == 0 { + if len(rgData.VINS) == 0 { + return diag.Errorf("resourceResgroupUpdate: cannot set def_net net_type=\"PRIVATE\" for RG ID %d: no ViNSes exist in this RG.", rgData.ID) + } + } else { + found := false + for _, vinsID := range rgData.VINS { + if vinsID == netID { + found = true + break + } + } + if !found { + return diag.Errorf("resourceResgroupUpdate: cannot set def_net net_type=\"PRIVATE\" for RG ID %d: ViNS ID %d is not found in this RG.", rgData.ID, netID) + } + } + } + + req := rg.SetDefNetRequest{ + RGID: rgData.ID, + NetType: netType, + NetID: netID, + } + + _, err := c.CloudAPI().RG().SetDefNet(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + return resourceResgroupRead(ctx, d, m) +} + +func resourceResgroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %d", + d.Get("name").(string), d.Get("account_id").(int)) + + c := m.(*controller.ControllerCfg) + rgId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := rg.DeleteRequest{ + RGID: rgId, + } + + if force, ok := d.GetOk("force"); ok { + req.Force = force.(bool) + } + if permanently, ok := d.GetOk("permanently"); ok { + req.Permanently = permanently.(bool) + } + + _, err := c.CloudAPI().RG().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceRgSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "Unique ID of the account, which this resource group belongs to.", + }, + + "gid": { + Type: schema.TypeInt, + Required: true, + // ForceNew: true, + Description: "Unique ID of the grid, where this resource group is deployed.", + }, + + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of this resource group. Names are case sensitive and unique within the context of a account.", + }, + + "def_net_type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC", "NONE"}, false), + Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.", + }, + + "def_net_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the default network for this resource group (if any).", + }, + + "ipcidr": { + Type: schema.TypeString, + Optional: true, + Description: "Address of the netowrk inside the private network segment (aka ViNS) if def_net_type=PRIVATE", + }, + + "ext_net_id": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: "ID of the external network for default ViNS. Pass 0 if def_net_type=PUBLIC or no external connection required for the defult ViNS when def_net_type=PRIVATE", + }, + + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "IP address on the external netowrk to request when def_net_type=PRIVATE and ext_net_id is not 0", + }, + + "owner": { + Type: schema.TypeString, + Optional: true, + }, + + "quota": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Limit on the total number of CPUs in this resource group.", + }, + "ram": { + Type: schema.TypeInt, // NB: API expects and returns this as float in units of MB! This may be changed in the future. + Optional: true, + Computed: true, + Description: "Limit on the total amount of RAM in this resource group, specified in MB.", + }, + "disk": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Limit on the total volume of virtual storage resources in this resource group, specified in GB.", + }, + "ext_ips": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Limit on the total number of external IP addresses this resource group can use.", + }, + "gpu_units": { + Type: schema.TypeInt, + Computed: true, + Description: "Limit on the total number of virtual GPUs this resource group can use.", + }, + "cu_d": { + Type: schema.TypeInt, + Computed: true, + Description: "Limit on the total volume of storage resources in this resource group, specified in GB.", + }, + }, + }, + Description: "Quota settings for this resource group.", + }, + + "access": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "user": { + Type: schema.TypeString, + Required: true, + Description: "User or group name to grant access", + }, + "right": { + Type: schema.TypeString, + Required: true, + Description: "Access rights to set, one of 'R', 'RCX' or 'ARCXDU'", + }, + }, + }, + }, + "def_net": { + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC"}, false), + Description: "Network type to set. Must be on of 'PRIVATE' or 'PUBLIC'.", + }, + "net_id": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: "Network segment ID. If netType is PUBLIC and netId is 0 then default external network segment will be selected. If netType is PRIVATE and netId=0, the first ViNS defined for this RG will be selected. Otherwise, netId identifies either existing external network segment or ViNS.", + }, + }, + }, + }, + "storage_policy": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Required: true, + }, + "limit": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + }, + }, + }, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "User-defined text description of this resource group.", + }, + "force": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Set to True if you want force delete non-empty RG", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Set to True if you want force delete non-empty RG", + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "flag for enable/disable RG", + }, + "sdn_access_group_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "ID of the SDN access group", + }, + + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account, which this resource group belongs to.", + }, + // "resources": { + // Type: schema.TypeList, + // Computed: true, + // Elem: &schema.Resource{ + // Schema: resourcesSchemaMake(), + // }, + // }, + + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: aclSchemaMake(), + }, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "dirty": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Current status of this resource group.", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of VINs deployed in this resource group.", + }, + + "vms": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of computes deployed in this resource group.", + }, + + "res_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "uniq_pools": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + } +} + +func ResourceResgroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceResgroupCreate, + ReadContext: resourceResgroupRead, + UpdateContext: resourceResgroupUpdate, + DeleteContext: resourceResgroupDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error { + if diff.HasChange("def_net") { + diff.SetNewComputed("def_net_id") + } + if diff.HasChange("storage_policy") { + diff.SetNewComputed("storage_policy_ids") + diff.SetNewComputed("resource_limits") + } + if diff.HasChanges() { + diff.SetNewComputed("updated_by") + diff.SetNewComputed("updated_time") + } + return nil + }, + + Schema: ResourceRgSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceRGResourceV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceRGStateUpgradeV1, + Version: 1, + }, + }, + } +} diff --git a/internal/service/cloudapi/rg/state_upgraders.go b/internal/service/cloudapi/rg/state_upgraders.go new file mode 100644 index 00000000..887b615d --- /dev/null +++ b/internal/service/cloudapi/rg/state_upgraders.go @@ -0,0 +1,27 @@ +package rg + +import ( + "context" + + log "github.com/sirupsen/logrus" +) + +func resourceRGStateUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceRGStateUpgradeV1: upgrading state") + quota, ok := rawState["quota"] + if !ok || quota == nil { + rawState["quota"] = QuotaRecord{ + Cpu: -1, + Ram: -1, + Disk: -1, + ExtIPs: -1, + GpuUnits: -1, + } + return rawState, nil + } + + oldQuotaList := quota.([]interface{}) + oldQuota := oldQuotaList[0].(map[string]interface{}) + oldQuota["ram"] = int64(oldQuota["ram"].(float64)) + return rawState, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg.go b/internal/service/cloudapi/rg/utility_rg.go new file mode 100644 index 00000000..54bdc819 --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg.go @@ -0,0 +1,267 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.RecordResourceGroup, error) { + c := m.(*controller.ControllerCfg) + req := rg.GetRequest{} + + if d.Id() != "" { + rgId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.RGID = rgId + } else { + req.RGID = uint64(d.Get("rg_id").(int)) + } + + rgData, err := c.CloudAPI().RG().Get(ctx, req) + if err != nil { + return nil, err + } + + return rgData, nil +} + +func utilityUpdateRG(ctx context.Context, d *schema.ResourceData, m interface{}, rgId uint64) error { + c := m.(*controller.ControllerCfg) + + req := rg.UpdateRequest{ + RGID: rgId, + } + + if d.HasChange("name") { + log.Debugf("resourceResgroupUpdate: name specified - looking for deltas from the old settings") + req.Name = d.Get("name").(string) + } + + if d.HasChange("quota") { + log.Debugf("resourceResgroupUpdate: quota specified - looking for deltas from the old quota.") + + if quota, ok := d.GetOk("quota"); ok { + resLimits := quota.([]interface{})[0] + resLimitsConv := resLimits.(map[string]interface{}) + + if resLimitsConv["ram"] != nil { + maxMemCap := int64(resLimitsConv["ram"].(int)) + if maxMemCap == 0 { + req.MaxMemoryCapacity = -1 + } else { + req.MaxMemoryCapacity = maxMemCap + } + } + + if resLimitsConv["disk"] != nil { + maxDiskCap := int64(resLimitsConv["disk"].(int)) + if maxDiskCap == 0 { + req.MaxVDiskCapacity = -1 + } else { + req.MaxVDiskCapacity = maxDiskCap + } + } + if resLimitsConv["cpu"] != nil { + maxCPUCap := int64(resLimitsConv["cpu"].(int)) + if maxCPUCap == 0 { + req.MaxCPUCapacity = -1 + } else { + req.MaxCPUCapacity = maxCPUCap + } + } + if resLimitsConv["ext_ips"] != nil { + maxNumPublicIP := int64(resLimitsConv["ext_ips"].(int)) + if maxNumPublicIP == 0 { + req.MaxNumPublicIP = -1 + } else { + req.MaxNumPublicIP = maxNumPublicIP + } + } + } + } + + if d.HasChange("storage_policy") { + log.Debugf("resourceResgroupUpdate: storage policies specified.") + + if storagePolicies, ok := d.GetOk("storage_policy"); ok { + var id uint64 + var limit int + + if storagePolicies.(*schema.Set).Len() > 0 { + spList := storagePolicies.(*schema.Set).List() + for _, spInterface := range spList { + sps := spInterface.(map[string]interface{}) + id = uint64(sps["id"].(int)) + limit = sps["limit"].(int) + + spModel := rg.StoragePolicy{ + ID: id, + Limit: limit, + } + + req.StoragePolicies = append(req.StoragePolicies, spModel) + } + } + } + } + + if d.HasChange("description") { + log.Debugf("resourceResgroupUpdate: description specified - looking for deltas from the old settings.") + req.Description = d.Get("description").(string) + } + + if d.HasChange("uniq_pools") { + uniqPools := d.Get("uniq_pools").([]interface{}) + if len(uniqPools) == 0 { + req.ClearUniqPools = true + } + for _, pool := range uniqPools { + req.UniqPools = append(req.UniqPools, pool.(string)) + } + } + + _, _, updateStPolicy := utilityGetStoragePolicyUpdate(ctx, d, m) + if len(updateStPolicy) != 0 { + storagePolicies := make([]rg.StoragePolicy, 0, len(updateStPolicy)) + for _, stPolicyVal := range updateStPolicy { + reqStPolicy := rg.StoragePolicy{ + ID: uint64(stPolicyVal["id"].(int)), + Limit: stPolicyVal["limit"].(int), + } + + storagePolicies = append(storagePolicies, reqStPolicy) + } + req.StoragePolicies = storagePolicies + } + + _, err := c.CloudAPI().RG().Update(ctx, req) + if err != nil { + return err + } + return nil +} + +func utilityRGUpdateStPolicy(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + + rgID, _ := strconv.ParseUint(d.Id(), 10, 64) + + addSP, delSP, updateSP := utilityGetStoragePolicyUpdate(ctx, d, m) + needUpdate := len(updateSP) > 0 + + if len(addSP) > 0 { + for _, spMap := range addSP { + req := rg.AddStoragePolicyRequest{ + RGID: rgID, + StoragePolicyID: uint64(spMap["id"].(int)), + Limit: spMap["limit"].(int), + } + log.Debugf("utilityRGUpdateStPolicy: starting to add storage policy ID:%d for resource group %d", req.StoragePolicyID, req.RGID) + _, err := c.CloudAPI().RG().AddStoragePolicy(ctx, req) + if err != nil { + return needUpdate, err + } + } + } + + if len(delSP) > 0 { + for _, spMap := range delSP { + req := rg.DelStoragePolicyRequest{ + RGID: rgID, + StoragePolicyID: uint64(spMap["id"].(int)), + } + log.Debugf("utilityRGUpdateStPolicy: starting to delete storage policy ID:%d from resource group %d", req.StoragePolicyID, req.RGID) + _, err := c.CloudAPI().RG().DelStoragePolicy(ctx, req) + if err != nil { + return needUpdate, err + } + } + } + + return needUpdate, nil +} + +func utilityGetStoragePolicyUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) (added, deleted, updated []map[string]interface{}) { + added = make([]map[string]interface{}, 0) + deleted = make([]map[string]interface{}, 0) + updated = make([]map[string]interface{}, 0) + oldSet, newSet := d.GetChange("storage_policy") + oldList := oldSet.(*schema.Set).List() + newList := newSet.(*schema.Set).List() + + for _, oldSP := range oldList { + oldMap := oldSP.(map[string]interface{}) + found := false + for _, newSP := range newList { + newMap := newSP.(map[string]interface{}) + if oldMap["id"] == newMap["id"] { + found = true + if oldMap["limit"] != newMap["limit"] { + updated = append(added, newMap) + } + break + } + if found { + break + } + } + if found { + continue + } + deleted = append(deleted, oldMap) + } + + for _, newSP := range newList { + newMap := newSP.(map[string]interface{}) + found := false + for _, oldSP := range oldList { + oldMap := oldSP.(map[string]interface{}) + if oldMap["id"] == newMap["id"] { + found = true + break + } + } + if found { + continue + } + added = append(added, newMap) + } + + return +} diff --git a/internal/service/cloudapi/rg/utility_rg_affinity_group_computes.go b/internal/service/cloudapi/rg/utility_rg_affinity_group_computes.go new file mode 100644 index 00000000..68c12c5c --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_affinity_group_computes.go @@ -0,0 +1,56 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgAffinityGroupComputesCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListAffinityGroupsComputes, error) { + c := m.(*controller.ControllerCfg) + req := rg.AffinityGroupComputesRequest{ + RGID: uint64(d.Get("rg_id").(int)), + AffinityGroup: d.Get("affinity_group").(string), + } + + listGroupComputes, err := c.CloudAPI().RG().AffinityGroupComputes(ctx, req) + if err != nil { + return nil, err + } + + return listGroupComputes, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_affinity_groups_get.go b/internal/service/cloudapi/rg/utility_rg_affinity_groups_get.go new file mode 100644 index 00000000..e2106c5d --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_affinity_groups_get.go @@ -0,0 +1,56 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgAffinityGroupsGetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]uint64, error) { + c := m.(*controller.ControllerCfg) + req := rg.AffinityGroupsGetRequest{ + RGID: uint64(d.Get("rg_id").(int)), + AffinityGroup: d.Get("affinity_group").(string), + } + + computes, err := c.CloudAPI().RG().AffinityGroupsGet(ctx, req) + if err != nil { + return nil, err + } + + return computes, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_affinity_groups_list.go b/internal/service/cloudapi/rg/utility_rg_affinity_groups_list.go new file mode 100644 index 00000000..c497ec86 --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_affinity_groups_list.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgAffinityGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListAffinityGroups, error) { + c := m.(*controller.ControllerCfg) + req := rg.AffinityGroupsListRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + groups, err := c.CloudAPI().RG().AffinityGroupsList(ctx, req) + if err != nil { + return nil, err + } + + return groups, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_audits.go b/internal/service/cloudapi/rg/utility_rg_audits.go new file mode 100644 index 00000000..cf965800 --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_audits.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListAudits, error) { + c := m.(*controller.ControllerCfg) + req := rg.AuditsRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + rgAudits, err := c.CloudAPI().RG().Audits(ctx, req) + if err != nil { + return nil, err + } + + return rgAudits, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_get_resource_consumption.go b/internal/service/cloudapi/rg/utility_rg_get_resource_consumption.go new file mode 100644 index 00000000..529a6af1 --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_get_resource_consumption.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityRGResourceConsumptionGetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ItemResourceConsumption, error) { + c := m.(*controller.ControllerCfg) + + id := uint64(d.Get("rg_id").(int)) + + req := rg.GetResourceConsumptionRequest{ + RGID: id, + } + + log.Debugf("utilityRGResourceConsumptionGetCheckPresence: load") + accountResourceConsumptionRec, err := c.CloudAPI().RG().GetResourceConsumption(ctx, req) + if err != nil { + return nil, err + } + + return accountResourceConsumptionRec, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_list.go b/internal/service/cloudapi/rg/utility_rg_list.go new file mode 100644 index 00000000..c13cfc6c --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_list.go @@ -0,0 +1,93 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityRgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListResourceGroups, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if accountName, ok := d.GetOk("account_name"); ok { + req.AccountName = accountName.(string) + } + if createdAfter, ok := d.GetOk("created_after"); ok { + req.CreatedAfter = uint64(createdAfter.(int)) + } + if createdBefore, ok := d.GetOk("created_before"); ok { + req.CreatedBefore = uint64(createdBefore.(int)) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if lockStatus, ok := d.GetOk("lock_status"); ok { + req.LockStatus = lockStatus.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if includedeleted, ok := d.GetOk("includedeleted"); ok { + req.IncludeDeleted = includedeleted.(bool) + } + + log.Debugf("utilityRgListCheckPresence: load rg list") + rgList, err := c.CloudAPI().RG().List(ctx, req) + if err != nil { + return nil, err + } + + return rgList, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_list_computes.go b/internal/service/cloudapi/rg/utility_rg_list_computes.go new file mode 100644 index 00000000..b1565b45 --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_list_computes.go @@ -0,0 +1,99 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgListComputesCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListComputes, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListComputesRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + if compute_id, ok := d.GetOk("compute_id"); ok { + req.ComputeID = uint64(compute_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if ip_address, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ip_address.(string) + } + + if extnet_name, ok := d.GetOk("extnet_name"); ok { + req.ExtNetName = extnet_name.(string) + } + + if extnet_id, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnet_id.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listComputes, err := c.CloudAPI().RG().ListComputes(ctx, req) + if err != nil { + return nil, err + } + + return listComputes, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_list_deleted.go b/internal/service/cloudapi/rg/utility_rg_list_deleted.go new file mode 100644 index 00000000..b801ce5a --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_list_deleted.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListResourceGroups, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListDeletedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if account_name, ok := d.GetOk("account_name"); ok { + req.AccountName = account_name.(string) + } + + if created_after, ok := d.GetOk("created_after"); ok { + req.CreatedAfter = uint64(created_after.(int)) + } + + if created_before, ok := d.GetOk("created_before"); ok { + req.CreatedBefore = uint64(created_before.(int)) + } + + if lock_status, ok := d.GetOk("lock_status"); ok { + req.LockStatus = lock_status.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + rgList, err := c.CloudAPI().RG().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return rgList, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_list_lb.go b/internal/service/cloudapi/rg/utility_rg_list_lb.go new file mode 100644 index 00000000..161b1a78 --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_list_lb.go @@ -0,0 +1,91 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgListLbCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListLB, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListLBRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if front_ip, ok := d.GetOk("front_ip"); ok { + req.FrontIP = front_ip.(string) + } + + if back_ip, ok := d.GetOk("back_ip"); ok { + req.BackIP = back_ip.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listLb, err := c.CloudAPI().RG().ListLB(ctx, req) + if err != nil { + return nil, err + } + + return listLb, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_list_pfw.go b/internal/service/cloudapi/rg/utility_rg_list_pfw.go new file mode 100644 index 00000000..4f14deb4 --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_list_pfw.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgListPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListPortForwards, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListPFWRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + listPfw, err := c.CloudAPI().RG().ListPFW(ctx, req) + if err != nil { + return nil, err + } + + return listPfw, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_list_vins.go b/internal/service/cloudapi/rg/utility_rg_list_vins.go new file mode 100644 index 00000000..ee78c790 --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_list_vins.go @@ -0,0 +1,83 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgListVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListVINS, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListVINSRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if ext_ip, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = ext_ip.(string) + } + + if vins_id, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vins_id.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listVins, err := c.CloudAPI().RG().ListVINS(ctx, req) + if err != nil { + return nil, err + } + + return listVins, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_resource_consumption_list.go b/internal/service/cloudapi/rg/utility_rg_resource_consumption_list.go new file mode 100644 index 00000000..9f3c68ad --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_resource_consumption_list.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityRGResourceConsumptionListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListResourceConsumption, error) { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityRGResourceConsumptionListCheckPresence: load") + rgResourceConsumptionList, err := c.CloudAPI().RG().ListResourceConsumption(ctx) + if err != nil { + return nil, err + } + + return rgResourceConsumptionList, nil +} diff --git a/internal/service/cloudapi/rg/utility_rg_usage.go b/internal/service/cloudapi/rg/utility_rg_usage.go new file mode 100644 index 00000000..6b664b98 --- /dev/null +++ b/internal/service/cloudapi/rg/utility_rg_usage.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDataRgUsageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.RecordResourceUsage, error) { + c := m.(*controller.ControllerCfg) + req := rg.UsageRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + usage, err := c.CloudAPI().RG().Usage(ctx, req) + if err != nil { + return nil, err + } + + return usage, nil +} diff --git a/internal/service/cloudapi/secgroup/data_source_security_group.go b/internal/service/cloudapi/secgroup/data_source_security_group.go new file mode 100644 index 00000000..d5ba7ebd --- /dev/null +++ b/internal/service/cloudapi/secgroup/data_source_security_group.go @@ -0,0 +1,38 @@ +package secgroup + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSecurityGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + securityGroup, err := utilitySecurityGroupCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenSecurityGroup(d, securityGroup) + + return nil +} + +func DataSourceSecurityGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSecurityGroupRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSecurityGroupSchemaMake(), + } +} diff --git a/internal/service/cloudapi/secgroup/data_source_security_group_list.go b/internal/service/cloudapi/secgroup/data_source_security_group_list.go new file mode 100644 index 00000000..a2bf3e1a --- /dev/null +++ b/internal/service/cloudapi/secgroup/data_source_security_group_list.go @@ -0,0 +1,40 @@ +package secgroup + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSecurityGroupListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + storagePolicyList, err := utilitySecurityGroupListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenSecurityGroupList(storagePolicyList)) + d.Set("entry_count", storagePolicyList.EntryCount) + + return nil +} + +func DataSourceSecurityGroupList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSecurityGroupListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSecurityGroupListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/secgroup/flattens.go b/internal/service/cloudapi/secgroup/flattens.go new file mode 100644 index 00000000..208341db --- /dev/null +++ b/internal/service/cloudapi/secgroup/flattens.go @@ -0,0 +1,68 @@ +package secgroup + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/secgroup" +) + +func flattenSecurityGroupResource(d *schema.ResourceData, securityGroup *secgroup.RecordSecurityGroup) { + d.Set("security_group_id", securityGroup.ID) + d.Set("account_id", securityGroup.AccountID) + d.Set("name", securityGroup.Name) + d.Set("description", securityGroup.Description) + d.Set("rules", flattenRules(securityGroup.Rules)) + d.Set("created_at", securityGroup.CreatedAt) + d.Set("created_by", securityGroup.CreatedBy) + d.Set("updated_at", securityGroup.UpdatedAt) + d.Set("updated_by", securityGroup.UpdatedBy) +} + +func flattenSecurityGroupList(securityGroupList *secgroup.ListSecurityGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(securityGroupList.Data)) + for _, v := range securityGroupList.Data { + temp := map[string]interface{}{ + "account_id": v.AccountID, + "name": v.Name, + "description": v.Description, + "rules": flattenRules(v.Rules), + "created_at": v.CreatedAt, + "created_by": v.CreatedBy, + "security_group_id": v.ID, + "updated_at": v.UpdatedAt, + "updated_by": v.UpdatedBy, + } + + res = append(res, temp) + } + + return res +} + +func flattenSecurityGroup(d *schema.ResourceData, securityGroup *secgroup.RecordSecurityGroup) { + d.Set("security_group_id", securityGroup.ID) + d.Set("account_id", securityGroup.AccountID) + d.Set("name", securityGroup.Name) + d.Set("description", securityGroup.Description) + d.Set("rules", flattenRules(securityGroup.Rules)) + d.Set("created_at", securityGroup.CreatedAt) + d.Set("created_by", securityGroup.CreatedBy) + d.Set("updated_at", securityGroup.UpdatedAt) + d.Set("updated_by", securityGroup.UpdatedBy) +} + +func flattenRules(rules secgroup.Rules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rules)) + for _, rule := range rules { + temp := map[string]interface{}{ + "id": rule.ID, + "direction": rule.Direction, + "ethertype": rule.Ethertype, + "protocol": rule.Protocol, + "port_range_min": rule.PortRangeMin, + "port_range_max": rule.PortRangeMax, + "remote_ip_prefix": rule.RemoteIPPrefix, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/secgroup/resource_security_group.go b/internal/service/cloudapi/secgroup/resource_security_group.go new file mode 100644 index 00000000..2ec81109 --- /dev/null +++ b/internal/service/cloudapi/secgroup/resource_security_group.go @@ -0,0 +1,146 @@ +package secgroup + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/secgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func resourceSecurityGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSecurityGroupCreate: called with account ID %d, name %s", uint64(d.Get("account_id").(int)), d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + warnings := dc.Warnings{} + + accountID := uint64(d.Get("account_id").(int)) + name := d.Get("name").(string) + + req := secgroup.CreateRequest{ + AccountID: accountID, + Name: name, + } + + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + + securityGroupID, err := c.CloudAPI().SecurityGroup().Create(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(securityGroupID, 10)) + d.Set("security_group_id", securityGroupID) + + return append(warnings.Get(), resourceSecurityGroupRead(ctx, d, m)...) +} + +func resourceSecurityGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSecurityGroupRead: called with with account ID %d", uint64(d.Get("account_id").(int))) + + w := dc.Warnings{} + + securityGroupItem, err := utilitySecurityGroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenSecurityGroupResource(d, securityGroupItem) + + return w.Get() +} + +func resourceSecurityGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + securityGroupID, _ := strconv.ParseUint(d.Id(), 10, 64) + + log.Debugf("resourceSecurityGroupUpdate: called security group with id %d", securityGroupID) + + c := m.(*controller.ControllerCfg) + + _, err := utilitySecurityGroupCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + + return diag.FromErr(err) + } + + _, err = strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + + d.SetId("") + + return diag.FromErr(err) + } + + if d.HasChanges("name", "description") { + + if err := utilitySecurityGroupHandleHasChanges(ctx, d, c, securityGroupID); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("rules") { + if err := utilitySecurityGroupUpdateRules(ctx, d, c, securityGroupID); err != nil { + return diag.FromErr(err) + } + } + + return resourceSecurityGroupRead(ctx, d, m) +} + +func resourceSecurityGroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSecurityGroupDelete: called with id %s", d.Id()) + + securityGroupItem, err := utilitySecurityGroupCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := secgroup.DeleteRequest{ + SecurityGroupID: securityGroupItem.ID, + } + if _, err := c.CloudAPI().SecurityGroup().Delete(ctx, req); err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceSecurityGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceSecurityGroupCreate, + ReadContext: resourceSecurityGroupRead, + UpdateContext: resourceSecurityGroupUpdate, + DeleteContext: resourceSecurityGroupDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout600s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceSecurityGroupSchemaMake(), + } +} diff --git a/internal/service/cloudapi/secgroup/schema.go b/internal/service/cloudapi/secgroup/schema.go new file mode 100644 index 00000000..9e1a49fd --- /dev/null +++ b/internal/service/cloudapi/secgroup/schema.go @@ -0,0 +1,288 @@ +package secgroup + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceSecurityGroupSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "rules": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "direction": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"inbound", "outbound"}, true), + }, + "ethertype": { + Type: schema.TypeString, + Optional: true, + Default: "IPv4", + ValidateFunc: validation.StringInSlice([]string{"IPv4", "IPv6"}, true), + }, + "protocol": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"icmp", "tcp", "udp"}, true), + }, + "port_range_min": { + Type: schema.TypeInt, + Optional: true, + }, + "port_range_max": { + Type: schema.TypeInt, + Optional: true, + }, + "remote_ip_prefix": { + Type: schema.TypeString, + Optional: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "security_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + } + return res +} + +func dataSourceSecurityGroupSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "security_group_id": { + Type: schema.TypeInt, + Required: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "direction": { + Type: schema.TypeString, + Computed: true, + }, + "ethertype": { + Type: schema.TypeString, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "port_range_min": { + Type: schema.TypeInt, + Computed: true, + }, + "port_range_max": { + Type: schema.TypeInt, + Computed: true, + }, + "remote_ip_prefix": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + } + return res +} + +func dataSourceSecurityGroupListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + }, + "desc": { + Type: schema.TypeString, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + }, + "created_min": { + Type: schema.TypeInt, + Optional: true, + }, + "created_max": { + Type: schema.TypeInt, + Optional: true, + }, + "updated_min": { + Type: schema.TypeInt, + Optional: true, + }, + "updated_max": { + Type: schema.TypeInt, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "security_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "direction": { + Type: schema.TypeString, + Computed: true, + }, + "ethertype": { + Type: schema.TypeString, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "port_range_min": { + Type: schema.TypeInt, + Computed: true, + }, + "port_range_max": { + Type: schema.TypeInt, + Computed: true, + }, + "remote_ip_prefix": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} diff --git a/internal/service/cloudapi/secgroup/utility_security_group.go b/internal/service/cloudapi/secgroup/utility_security_group.go new file mode 100644 index 00000000..bc148814 --- /dev/null +++ b/internal/service/cloudapi/secgroup/utility_security_group.go @@ -0,0 +1,95 @@ +package secgroup + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/secgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilitySecurityGroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*secgroup.RecordSecurityGroup, error) { + c := m.(*controller.ControllerCfg) + req := secgroup.GetRequest{} + if d.Id() != "" { + securityGroupID, _ := strconv.ParseUint(d.Id(), 10, 64) + req.SecurityGroupID = securityGroupID + } else { + req.SecurityGroupID = uint64(d.Get("security_group_id").(int)) + } + + log.Debugf("utilitySecurityGroupCheckPresence: load security group") + securityGroup, err := c.CloudAPI().SecurityGroup().Get(ctx, req) + if err != nil { + return nil, err + } + + return securityGroup, nil +} + +func utilitySecurityGroupHandleHasChanges(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, securityGroupID uint64) error { + req := secgroup.UpdateRequest{ + SecurityGroupID: securityGroupID, + } + + if d.HasChange("name") { + name := d.Get("name").(string) + req.Name = name + } + + if d.HasChange("description") { + description := d.Get("description").(string) + req.Description = description + } + + if _, err := c.CloudAPI().SecurityGroup().Update(ctx, req); err != nil { + return err + } + + return nil +} + +func utilitySecurityGroupUpdateRules(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, securityGroupID uint64) error { + oldSet, newSet := d.GetChange("rules") + deletedRules := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + for _, deletedInterface := range deletedRules { + deletedItem := deletedInterface.(map[string]interface{}) + ruleID := uint64(deletedItem["id"].(int)) + req := secgroup.DeleteRuleRequest{ + SecurityGroupID: securityGroupID, + RuleID: ruleID, + } + if _, err := c.CloudAPI().SecurityGroup().DeleteRule(ctx, req); err != nil { + return err + } + + } + + addedRules := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + for _, addedInterface := range addedRules { + addedItem := addedInterface.(map[string]interface{}) + direction := addedItem["direction"].(string) + ethertype := addedItem["ethertype"].(string) + protocol := addedItem["protocol"].(string) + portRangeMin := uint64(addedItem["port_range_min"].(int)) + portRangeMax := uint64(addedItem["port_range_max"].(int)) + remoteIPPrefix := addedItem["remote_ip_prefix"].(string) + req := secgroup.CreateRuleRequest{ + SecurityGroupID: securityGroupID, + Direction: direction, + Ethertype: ethertype, + Protocol: protocol, + PortRangeMin: portRangeMin, + PortRangeMax: portRangeMax, + RemoteIPPrefix: remoteIPPrefix, + } + + if _, err := c.CloudAPI().SecurityGroup().CreateRule(ctx, req); err != nil { + return err + } + } + + return nil +} diff --git a/internal/service/cloudapi/secgroup/utility_security_group_list.go b/internal/service/cloudapi/secgroup/utility_security_group_list.go new file mode 100644 index 00000000..a45345d9 --- /dev/null +++ b/internal/service/cloudapi/secgroup/utility_security_group_list.go @@ -0,0 +1,60 @@ +package secgroup + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/secgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilitySecurityGroupListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*secgroup.ListSecurityGroups, error) { + c := m.(*controller.ControllerCfg) + + req := secgroup.ListRequest{} + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if byID, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byID.(int)) + } + if accountID, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountID.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if createdMin, ok := d.GetOk("created_min"); ok { + req.CreatedMin = uint64(createdMin.(int)) + } + if createdMax, ok := d.GetOk("created_max"); ok { + req.CreatedMax = uint64(createdMax.(int)) + } + if updatedMin, ok := d.GetOk("updated_min"); ok { + req.UpdatedMin = uint64(updatedMin.(int)) + } + if updatedMax, ok := d.GetOk("updated_max"); ok { + req.UpdatedMax = uint64(updatedMax.(int)) + } + + log.Debugf("utilitySecurityGroupListCheckPresence: load storage policy list") + + securityGroupList, err := c.CloudAPI().SecurityGroup().List(ctx, req) + if err != nil { + return nil, err + } + + return securityGroupList, nil + +} diff --git a/internal/service/cloudapi/sep/available_sep_and_pools_list.go b/internal/service/cloudapi/sep/available_sep_and_pools_list.go new file mode 100644 index 00000000..82038163 --- /dev/null +++ b/internal/service/cloudapi/sep/available_sep_and_pools_list.go @@ -0,0 +1,143 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func DataSourceAvailableSEPAndPoolsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + sepList, err := utilityAvailableSEPAndPoolsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + flattenAvailableSEPList(d, sepList) + + return nil +} + +func dataSourceAvailableSEPListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "Account ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Resource group ID", + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of available SEP entries", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "List of available SEPs", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "SEP ID", + }, + "sep_name": { + Type: schema.TypeString, + Computed: true, + Description: "SEP name", + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + Description: "SEP type", + }, + "pools": { + Type: schema.TypeList, + Computed: true, + Description: "List of pools in the SEP", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Pool name", + }, + "types": { + Type: schema.TypeList, + Computed: true, + Description: "List of pool types", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "system": { + Type: schema.TypeBool, + Computed: true, + Description: "Is system pool", + }, + }, + }, + }, + }, + }, + }, + } +} + +func DataSourceAvailableSEPAndPoolsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: DataSourceAvailableSEPAndPoolsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAvailableSEPListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/sep/flattens.go b/internal/service/cloudapi/sep/flattens.go new file mode 100644 index 00000000..60ff19fd --- /dev/null +++ b/internal/service/cloudapi/sep/flattens.go @@ -0,0 +1,74 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/sep" +) + +func flattenAvailableSEPList(d *schema.ResourceData, sepList *sep.ListAvailableSEP) { + d.Set("items", flattenSEPDataList(sepList.Data)) + d.Set("entry_count", sepList.EntryCount) +} + +func flattenSEPDataList(sepDataList []sep.SEPData) []map[string]interface{} { + sh := make([]map[string]interface{}, 0) + + for _, sepData := range sepDataList { + temp := map[string]interface{}{ + "sep_id": sepData.SEPID, + "sep_name": sepData.SEPName, + "sep_type": sepData.SEPType, + "pools": flattenPoolList(sepData.Pools), + } + sh = append(sh, temp) + } + + return sh +} + +func flattenPoolList(pools []sep.Pool) []map[string]interface{} { + sh := make([]map[string]interface{}, 0) + + for _, pool := range pools { + temp := map[string]interface{}{ + "name": pool.Name, + "types": pool.Types, + "system": pool.System, + } + sh = append(sh, temp) + } + + return sh +} diff --git a/internal/service/cloudapi/sep/utility_available_sep_and_pools_list.go b/internal/service/cloudapi/sep/utility_available_sep_and_pools_list.go new file mode 100644 index 00000000..a05c7b07 --- /dev/null +++ b/internal/service/cloudapi/sep/utility_available_sep_and_pools_list.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAvailableSEPAndPoolsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.ListAvailableSEP, error) { + c := m.(*controller.ControllerCfg) + req := sep.ListAvailableSEPAndPoolsRequest{} + + if AccountID, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(AccountID.(int)) + } + if RGID, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(RGID.(int)) + } + + log.Debugf("utilityAvailableSEPAndPoolsListCheckPresence: load sep and pools list") + sepList, err := c.CloudAPI().SEP().ListAvailableSEPAndPools(ctx, req) + if err != nil { + return nil, err + } + + return sepList, nil +} diff --git a/internal/service/cloudapi/snapshot/data_source_snapshot_list.go b/internal/service/cloudapi/snapshot/data_source_snapshot_list.go new file mode 100644 index 00000000..5f43d7af --- /dev/null +++ b/internal/service/cloudapi/snapshot/data_source_snapshot_list.go @@ -0,0 +1,121 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package snapshot + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + snapshotList, err := utilitySnapshotListCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenSnapshotList(snapshotList)) + d.Set("entry_count", snapshotList.EntryCount) + return nil +} + +func dataSourceSnapshotListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: "ID of the compute instance to create snapshot for.", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "snapshot list", + Elem: &schema.Resource{ + Schema: dataSourceSnapshotSchemaMake(), + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return rets +} + +func dataSourceSnapshotSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Computed: true, + Description: "text label for snapshot. Must be unique among this compute snapshots.", + }, + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "timestamp", + }, + } +} + +func DataSourceSnapshotList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSnapshotListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSnapshotListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/snapshot/flattens.go b/internal/service/cloudapi/snapshot/flattens.go new file mode 100644 index 00000000..d85bc50f --- /dev/null +++ b/internal/service/cloudapi/snapshot/flattens.go @@ -0,0 +1,28 @@ +package snapshot + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" +) + +func flattenSnapshotList(gl *compute.ListSnapShots) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(gl.Data)) + for _, item := range gl.Data { + temp := map[string]interface{}{ + "label": item.Label, + "guid": item.GUID, + "disks": item.Disks, + "timestamp": item.Timestamp, + } + + res = append(res, temp) + } + return res +} + +func flattenSnapshot(d *schema.ResourceData, snapshot *compute.ItemSnapshot) { + d.Set("timestamp", snapshot.Timestamp) + d.Set("guid", snapshot.GUID) + d.Set("disks", snapshot.Disks) + d.Set("label", snapshot.Label) +} diff --git a/internal/service/cloudapi/snapshot/resource_snapshot.go b/internal/service/cloudapi/snapshot/resource_snapshot.go new file mode 100644 index 00000000..0b14f6af --- /dev/null +++ b/internal/service/cloudapi/snapshot/resource_snapshot.go @@ -0,0 +1,202 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package snapshot + +import ( + "context" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceSnapshotCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSnapshotCreate: called for snapshot %s", d.Get("label").(string)) + + c := m.(*controller.ControllerCfg) + req := compute.SnapshotCreateRequest{ + Label: d.Get("label").(string), + ComputeID: uint64(d.Get("compute_id").(int)), + } + + snapshotId, err := c.CloudAPI().Compute().SnapshotCreate(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + snapshotId = strings.ReplaceAll(snapshotId, "\"", "") + + d.SetId(snapshotId) + d.Set("guid", snapshotId) + + return resourceSnapshotRead(ctx, d, m) +} + +func resourceSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + snapshot, err := utilitySnapshotCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + flattenSnapshot(d, snapshot) + + return nil +} + +func resourceSnapshotDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSnapshotDelete: called for %s, id: %s", d.Get("label").(string), d.Id()) + + c := m.(*controller.ControllerCfg) + req := compute.SnapshotDeleteRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + Label: d.Get("label").(string), + } + + asyncMode, ok := d.GetOk("delete_async_mode") + if ok && asyncMode.(bool) { + _, err := c.CloudAPI().Compute().SnapshotDeleteAsync(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + _, err := c.CloudAPI().Compute().SnapshotDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + d.SetId("") + + return nil +} + +func resourceSnapshotUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + if d.HasChange("rollback") { + if d.Get("rollback").(bool) { + err := resourceSnapshotRollback(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + } + + return nil +} + +func resourceSnapshotRollback(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + req := compute.SnapshotRollbackRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + Label: d.Get("label").(string), + } + + _, err := c.CloudAPI().Compute().SnapshotRollback(ctx, req) + if err != nil { + return err + } + return nil +} + +func resourceSnapshotSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: "ID of the compute instance to create snapshot for.", + }, + "label": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "text label for snapshot. Must be unique among this compute snapshots.", + }, + "rollback": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "is rollback the snapshot", + }, + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "timestamp", + }, + "delete_async_mode": { + Type: schema.TypeBool, + Computed: true, + Description: "async mode", + }, + } +} + +func ResourceSnapshot() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceSnapshotCreate, + ReadContext: resourceSnapshotRead, + UpdateContext: resourceSnapshotUpdate, + DeleteContext: resourceSnapshotDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceSnapshotSchemaMake(), + } +} diff --git a/internal/service/cloudapi/snapshot/utility_snapshot.go b/internal/service/cloudapi/snapshot/utility_snapshot.go new file mode 100644 index 00000000..fde4cf4a --- /dev/null +++ b/internal/service/cloudapi/snapshot/utility_snapshot.go @@ -0,0 +1,65 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package snapshot + +import ( + "context" + "errors" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" +) + +func utilitySnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemSnapshot, error) { + snapShotList, err := utilitySnapshotListCheckPresence(ctx, d, m) + if err != nil { + return nil, err + } + + findId := "" + + if (d.Get("guid").(string)) != "" { + findId = d.Get("guid").(string) + } else { + findId = d.Id() + } + + for _, s := range snapShotList.Data { + if s.GUID == findId { + return &s, nil + } + } + + return nil, errors.New("snapshot not found") + +} diff --git a/internal/service/cloudapi/snapshot/utility_snapshot_list.go b/internal/service/cloudapi/snapshot/utility_snapshot_list.go new file mode 100644 index 00000000..301b56a5 --- /dev/null +++ b/internal/service/cloudapi/snapshot/utility_snapshot_list.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package snapshot + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilitySnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListSnapShots, error) { + c := m.(*controller.ControllerCfg) + req := compute.SnapshotListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + snapshotList, err := c.CloudAPI().Compute().SnapshotList(ctx, req) + if err != nil { + return nil, err + } + + return snapshotList, nil +} diff --git a/internal/service/cloudapi/stpolicy/data_source_storage_policy.go b/internal/service/cloudapi/stpolicy/data_source_storage_policy.go new file mode 100644 index 00000000..90ba6b94 --- /dev/null +++ b/internal/service/cloudapi/stpolicy/data_source_storage_policy.go @@ -0,0 +1,37 @@ +package stpolicy + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceStoragePolicyRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + storagePolicy, err := utilityStoragePolicyCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenStoragePolicyData(d, storagePolicy) + return nil +} + +func DataSourceStoragePolicy() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceStoragePolicyRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceStoragePolicySchemaMake(), + } +} diff --git a/internal/service/cloudapi/stpolicy/data_source_storage_policy_list.go b/internal/service/cloudapi/stpolicy/data_source_storage_policy_list.go new file mode 100644 index 00000000..73565f97 --- /dev/null +++ b/internal/service/cloudapi/stpolicy/data_source_storage_policy_list.go @@ -0,0 +1,40 @@ +package stpolicy + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceStoragePolicyListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + storagePolicyList, err := utilityStoragePolicyListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenStoragePolicyList(storagePolicyList)) + d.Set("entry_count", storagePolicyList.EntryCount) + + return nil +} + +func DataSourceStoragePolicyList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceStoragePolicyListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceStoragePolicyListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/stpolicy/flattens.go b/internal/service/cloudapi/stpolicy/flattens.go new file mode 100644 index 00000000..6d5cda74 --- /dev/null +++ b/internal/service/cloudapi/stpolicy/flattens.go @@ -0,0 +1,62 @@ +package stpolicy + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stpolicy" +) + +func flattenStoragePolicyData(d *schema.ResourceData, storagePolicy *stpolicy.InfoStoragePolicy) { + d.Set("description", storagePolicy.Description) + d.Set("guid", storagePolicy.GUID) + d.Set("limit_iops", storagePolicy.LimitIOPS) + d.Set("name", storagePolicy.Name) + d.Set("status", storagePolicy.Status) + d.Set("access_seps_pools", flattenAccessSEPPools(storagePolicy.AccessSEPPools)) + d.Set("usage", flattenUsage(storagePolicy.Usage)) +} + +func flattenAccessSEPPools(accessSEPPools stpolicy.ListAccessSEPPools) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(accessSEPPools)) + for _, asp := range accessSEPPools { + temp := map[string]interface{}{ + "sep_id": asp.SEPID, + "sep_name": asp.Name, + "pool_names": asp.PoolNames, + "sep_tech_status": asp.SepTechStatus, + } + + res = append(res, temp) + } + + return res +} + +func flattenUsage(usage stpolicy.Usage) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + + temp := map[string]interface{}{ + "accounts": usage.Accounts, + "resgroups": usage.Resgroups, + } + + res = append(res, temp) + return res +} + +func flattenStoragePolicyList(storagePolicyList *stpolicy.ListStoragePolicies) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(storagePolicyList.Data)) + for _, v := range storagePolicyList.Data { + temp := map[string]interface{}{ + "storage_policy_id": v.ID, + "description": v.Description, + "guid": v.GUID, + "limit_iops": v.LimitIOPS, + "name": v.Name, + "status": v.Status, + "access_seps_pools": flattenAccessSEPPools(v.AccessSEPPools), + "usage": flattenUsage(v.Usage), + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/stpolicy/schema.go b/internal/service/cloudapi/stpolicy/schema.go new file mode 100644 index 00000000..db938f7c --- /dev/null +++ b/internal/service/cloudapi/stpolicy/schema.go @@ -0,0 +1,231 @@ +package stpolicy + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceStoragePolicySchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "limit_iops": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "access_seps_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pool_names": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_name": { + Type: schema.TypeString, + Computed: true, + }, + "sep_tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "usage": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "accounts": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "resgroups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + } + + return res +} + +func dataSourceStoragePolicyListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Optional: true, + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + }, + "status": { + Type: schema.TypeString, + Optional: true, + }, + "desc": { + Type: schema.TypeString, + Optional: true, + }, + "limit_iops": { + Type: schema.TypeInt, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + }, + "resgroup_id": { + Type: schema.TypeInt, + Optional: true, + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + }, + "sep_tech_status": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"ENABLED", "DISABLED"}, true), + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "limit_iops": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "access_seps_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pool_names": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_name": { + Type: schema.TypeString, + Computed: true, + }, + "sep_tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "usage": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "accounts": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "resgroups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} diff --git a/internal/service/cloudapi/stpolicy/utility_storage_policy.go b/internal/service/cloudapi/stpolicy/utility_storage_policy.go new file mode 100644 index 00000000..1dea8ee4 --- /dev/null +++ b/internal/service/cloudapi/stpolicy/utility_storage_policy.go @@ -0,0 +1,29 @@ +package stpolicy + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stpolicy" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityStoragePolicyCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*stpolicy.InfoStoragePolicy, error) { + c := m.(*controller.ControllerCfg) + req := stpolicy.GetRequest{} + + if d.Id() != "" { + storagePolicyID, _ := strconv.ParseUint(d.Id(), 10, 64) + req.StoragePolicyID = storagePolicyID + } else { + req.StoragePolicyID = uint64(d.Get("storage_policy_id").(int)) + } + + storagePolicyData, err := c.CloudAPI().StPolicy().Get(ctx, req) + if err != nil { + return nil, err + } + + return storagePolicyData, nil +} diff --git a/internal/service/cloudapi/stpolicy/utility_storage_policy_list.go b/internal/service/cloudapi/stpolicy/utility_storage_policy_list.go new file mode 100644 index 00000000..77588b48 --- /dev/null +++ b/internal/service/cloudapi/stpolicy/utility_storage_policy_list.go @@ -0,0 +1,75 @@ +package stpolicy + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stpolicy" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityStoragePolicyListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*stpolicy.ListStoragePolicies, error) { + c := m.(*controller.ControllerCfg) + req := stpolicy.ListRequest{} + + if accountID, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountID.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if byID, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byID.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if desc, ok := d.GetOk("desc"); ok { + req.Desc = desc.(string) + } + + if limitIOPS, ok := d.GetOk("limit_iops"); ok { + req.LimitIOPS = uint64(limitIOPS.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if resgroupID, ok := d.GetOk("resgroup_id"); ok { + req.ResgroupID = uint64(resgroupID.(int)) + } + + if SEPID, ok := d.GetOk("sep_id"); ok { + req.SepID = uint64(SEPID.(int)) + } + + if SEPtechstatus, ok := d.GetOk("sep_tech_status"); ok { + req.SepTechStatus = SEPtechstatus.(string) + } + + if poolName, ok := d.GetOk("pool_name"); ok { + req.PoolName = poolName.(string) + } + + log.Debugf("utilityStoragePolicyListCheckPresence: load storage policy list") + + storagePolicyList, err := c.CloudAPI().StPolicy().List(ctx, req) + if err != nil { + return nil, err + } + + return storagePolicyList, nil +} diff --git a/internal/service/cloudapi/trunk/data_source_trunk.go b/internal/service/cloudapi/trunk/data_source_trunk.go new file mode 100644 index 00000000..3fc924ad --- /dev/null +++ b/internal/service/cloudapi/trunk/data_source_trunk.go @@ -0,0 +1,45 @@ +package trunk + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func dataSourceTrunkRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("dataSourceTrunkRead: called with name %s", d.Get("name").(string)) + + w := dc.Warnings{} + trunkItem, err := utilityTrunkCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenTrunk(d, trunkItem) + + return w.Get() +} + +func DataSourceTrunk() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceTrunkRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceTrunkSchemaMake(), + } +} diff --git a/internal/service/cloudapi/trunk/data_source_trunk_list.go b/internal/service/cloudapi/trunk/data_source_trunk_list.go new file mode 100644 index 00000000..76ea5eeb --- /dev/null +++ b/internal/service/cloudapi/trunk/data_source_trunk_list.go @@ -0,0 +1,43 @@ +package trunk + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func dataSourceTrunkListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + w := dc.Warnings{} + trunkList, err := utilityTrunkListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + d.Set("items", flattenTrunkList(trunkList)) + d.Set("entry_count", trunkList.EntryCount) + + return w.Get() +} + +func DataSourceTrunkList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceTrunkListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceTrunkListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/trunk/flattens.go b/internal/service/cloudapi/trunk/flattens.go new file mode 100644 index 00000000..9a0efc16 --- /dev/null +++ b/internal/service/cloudapi/trunk/flattens.go @@ -0,0 +1,58 @@ +package trunk + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/trunk" +) + +func flattenTrunk(d *schema.ResourceData, trunkItem *trunk.ItemTrunk) { + log.Debugf("flattenTrunk: decoded Trunk ID %d", + trunkItem.ID) + + d.Set("trunk_id", trunkItem.ID) + d.Set("guid", trunkItem.GUID) + d.Set("name", trunkItem.Name) + d.Set("mac", trunkItem.MAC) + d.Set("description", trunkItem.Description) + d.Set("account_ids", trunkItem.AccountIDs) + d.Set("ovs_bridge", trunkItem.OVSBridge) + d.Set("native_vlan_id", trunkItem.NativeVLANID) + d.Set("mtu", trunkItem.MTU) + d.Set("status", trunkItem.Status) + d.Set("trunk_tags", trunkItem.TrunkTags) + d.Set("created_at", trunkItem.CreatedAt) + d.Set("created_by", trunkItem.CreatedBy) + d.Set("updated_at", trunkItem.UpdatedAt) + d.Set("updated_by", trunkItem.UpdatedBy) + d.Set("deleted_at", trunkItem.DeletedAt) + d.Set("deleted_by", trunkItem.DeletedBy) +} + +func flattenTrunkList(trunkList *trunk.ListTrunks) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(trunkList.Data)) + for _, trunkItem := range trunkList.Data { + temp := map[string]interface{}{ + "account_ids": trunkItem.AccountIDs, + "created_at": trunkItem.CreatedAt, + "created_by": trunkItem.CreatedBy, + "deleted_at": trunkItem.DeletedAt, + "deleted_by": trunkItem.DeletedBy, + "description": trunkItem.Description, + "guid": trunkItem.GUID, + "id": trunkItem.ID, + "mac": trunkItem.MAC, + "name": trunkItem.Name, + "native_vlan_id": trunkItem.NativeVLANID, + "ovs_bridge": trunkItem.OVSBridge, + "mtu": trunkItem.MTU, + "status": trunkItem.Status, + "trunk_tags": trunkItem.TrunkTags, + "updated_at": trunkItem.UpdatedAt, + "updated_by": trunkItem.UpdatedBy, + } + res = append(res, temp) + } + + return res +} diff --git a/internal/service/cloudapi/trunk/schema.go b/internal/service/cloudapi/trunk/schema.go new file mode 100644 index 00000000..566e6a7f --- /dev/null +++ b/internal/service/cloudapi/trunk/schema.go @@ -0,0 +1,251 @@ +package trunk + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" +) + +func dataSourceTrunkSchemaMake() map[string]*schema.Schema { + log.Debugf("dataSourceTrunkSchemaMake: invoked") + + res := map[string]*schema.Schema{ + "trunk_id": { + Type: schema.TypeInt, + Required: true, + Description: "trunk id", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "GUID", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the trunk", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of the trunk", + }, + "account_ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of account IDs with access to this trunk", + }, + "ovs_bridge": { + Type: schema.TypeString, + Computed: true, + Description: "OVS bridge name", + }, + "native_vlan_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Native VLAN ID", + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum Transmission Unit", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "if the trunk is enabled", + }, + "trunk_tags": { + Type: schema.TypeString, + Computed: true, + Description: "List of trunk tags (values between 1-4095)", + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was created", + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + Description: "who created the trunk", + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was updated", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + Description: "who updated the trunk", + }, + "deleted_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was updated", + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + Description: "who updated the trunk", + }, + } + + return res +} + +func dataSourceTrunkListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "trunk_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "ID of the trunk(s) to filter by", + }, + "account_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Account access ID(s) to filter by", + }, + "trunk_tags": { + Type: schema.TypeString, + Optional: true, + Description: "Trunk tags to filter by (value between 1-4095)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number.", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size.", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "find by status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "Sort by one of supported fields, format ±", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of account IDs with access to this trunk", + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was created", + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + Description: "who created the trunk", + }, + "deleted_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was updated", + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + Description: "who updated the trunk", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of the trunk", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "GUID", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "Trunk ID", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the trunk", + }, + "native_vlan_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Native VLAN ID", + }, + "ovs_bridge": { + Type: schema.TypeString, + Computed: true, + Description: "OVS bridge name", + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum Transmission Unit", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "if the trunk is enabled", + }, + "trunk_tags": { + Type: schema.TypeString, + Computed: true, + Description: "List of trunk tags (values between 1-4095)", + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was updated", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + Description: "who updated the trunk", + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} diff --git a/internal/service/cloudapi/trunk/utility_trunk.go b/internal/service/cloudapi/trunk/utility_trunk.go new file mode 100644 index 00000000..6e1c227c --- /dev/null +++ b/internal/service/cloudapi/trunk/utility_trunk.go @@ -0,0 +1,45 @@ +package trunk + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/trunk" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityTrunkCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*trunk.ItemTrunk, error) { + c := m.(*controller.ControllerCfg) + req := trunk.GetRequest{} + + if d.Get("trunk_id") != nil { + if d.Get("trunk_id").(int) == 0 { + id, err := strconv.ParseUint(d.Id(), 10, 64) + if err != nil { + return nil, err + } + + req.TrunkID = id + } else { + req.TrunkID = uint64(d.Get("trunk_id").(int)) + } + } else { + id, err := strconv.ParseUint(d.Id(), 10, 64) + if err != nil { + return nil, err + } + + req.TrunkID = id + } + + log.Debugf("utilityTrunkCheckPresence: get trunk network") + + trunkItem, err := c.CloudAPI().Trunk().Get(ctx, req) + if err != nil { + return nil, err + } + + return trunkItem, nil +} diff --git a/internal/service/cloudapi/trunk/utility_trunk_list.go b/internal/service/cloudapi/trunk/utility_trunk_list.go new file mode 100644 index 00000000..68e3de1f --- /dev/null +++ b/internal/service/cloudapi/trunk/utility_trunk_list.go @@ -0,0 +1,51 @@ +package trunk + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/trunk" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityTrunkListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*trunk.ListTrunks, error) { + c := m.(*controller.ControllerCfg) + req := trunk.ListRequest{} + + if trunkIDs, ok := d.GetOk("trunk_ids"); ok { + IDs := trunkIDs.([]interface{}) + for _, id := range IDs { + req.IDs = append(req.IDs, uint64(id.(int))) + } + } + if accountIDs, ok := d.GetOk("account_ids"); ok { + IDs := accountIDs.([]interface{}) + for _, id := range IDs { + req.AccountIDs = append(req.AccountIDs, uint64(id.(int))) + } + } + if trunkTags, ok := d.GetOk("trunk_tags"); ok { + req.TrunkTags = trunkTags.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityTrunkListCheckPresence: load trunk network list") + trunkList, err := c.CloudAPI().Trunk().List(ctx, req) + if err != nil { + return nil, err + } + + return trunkList, nil +} diff --git a/internal/service/cloudapi/vfpool/data_source_vfpool.go b/internal/service/cloudapi/vfpool/data_source_vfpool.go new file mode 100644 index 00000000..9fd6c0e0 --- /dev/null +++ b/internal/service/cloudapi/vfpool/data_source_vfpool.go @@ -0,0 +1,165 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceVFPoolRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vfpool, err := utilityVFpoolCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(d.Get("vfpool_id").(int))) + flattenVFPool(d, vfpool) + return nil +} + +func dataSourceVFPoolSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "vfpool_id": { + Type: schema.TypeInt, + Required: true, + }, + "account_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vf_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "nic_name": { + Type: schema.TypeString, + Computed: true, + }, + "vfs_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "claimed": { + Type: schema.TypeBool, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + return res +} + +func DataSourceVFPool() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVFPoolRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVFPoolSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vfpool/data_source_vfpool_list.go b/internal/service/cloudapi/vfpool/data_source_vfpool_list.go new file mode 100644 index 00000000..6238a290 --- /dev/null +++ b/internal/service/cloudapi/vfpool/data_source_vfpool_list.go @@ -0,0 +1,229 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "context" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceVFPoolListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vfpoolList, err := utilityVFpoolListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVFPoolList(vfpoolList)) + d.Set("entry_count", vfpoolList.EntryCount) + return nil +} + +func dataSourceVFPoolListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "gid": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by Grid ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Find by description", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "account_access": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by accountAccess", + }, + "rg_access": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by rgAccess", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "vfpool_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vf_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "nic_name": { + Type: schema.TypeString, + Computed: true, + }, + "vfs_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "claimed": { + Type: schema.TypeBool, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func DataSourceVFPoolList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVFPoolListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVFPoolListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vfpool/flattens.go b/internal/service/cloudapi/vfpool/flattens.go new file mode 100644 index 00000000..84815f18 --- /dev/null +++ b/internal/service/cloudapi/vfpool/flattens.go @@ -0,0 +1,120 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vfpool" +) + +func flattenVFPoolList(vfpooll *vfpool.ListVFPool) []map[string]interface{} { + log.Debugf("flattenVFPoolList start") + res := make([]map[string]interface{}, 0, len(vfpooll.Data)) + for _, vfpool := range vfpooll.Data { + temp := map[string]interface{}{ + "account_access": vfpool.AccountAccess, + "created_time": vfpool.CreatedTime, + "description": vfpool.Description, + "gid": vfpool.GID, + "guid": vfpool.GUID, + "vfpool_id": vfpool.ID, + "name": vfpool.Name, + "rg_access": vfpool.RGAccess, + "status": vfpool.Status, + "updated_time": vfpool.UpdatedTime, + "vfs": flattenVFSList(vfpool.VFS), + } + res = append(res, temp) + } + log.Debugf("flattenVFPoolList end") + return res + +} + +func flattenVFPool(d *schema.ResourceData, item *vfpool.RecordVFPool) error { + log.Debugf("flattenVFPool: start decoded VFPool name %q / ID %d", + item.Name, item.ID) + + d.Set("account_access", item.AccountAccess) + d.Set("created_time", item.CreatedTime) + d.Set("description", item.Description) + d.Set("gid", item.GID) + d.Set("guid", item.GUID) + d.Set("name", item.Name) + d.Set("rg_access", item.RGAccess) + d.Set("status", item.Status) + d.Set("updated_time", item.UpdatedTime) + d.Set("vfs", flattenVFSList(item.VFS)) + + log.Debugf("flattenVFPool: decoded VFPool name %q / ID %d, complete", + item.Name, item.ID) + return nil +} + +func flattenVFSList(vfsItem []vfpool.VFS) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vfsItem)) + for _, item := range vfsItem { + temp := map[string]interface{}{ + "node_id": item.NodeID, + "vf_list": flattenVFList(item.VFList), + } + res = append(res, temp) + } + return res +} + +func flattenVFList(vfItem vfpool.VFList) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vfItem)) + for _, item := range vfItem { + temp := map[string]interface{}{ + "nic_name": item.NicName, + "vfs_info": flattenVFInfoList(item.VFSInfo), + } + res = append(res, temp) + } + return res +} + +func flattenVFInfoList(vfInfo vfpool.VFSInfoList) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vfInfo)) + for _, item := range vfInfo { + temp := map[string]interface{}{ + "id": item.ID, + "claimed": item.Claimed, + "vm_id": item.VMID, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/vfpool/utility_vfpool.go b/internal/service/cloudapi/vfpool/utility_vfpool.go new file mode 100644 index 00000000..3428e727 --- /dev/null +++ b/internal/service/cloudapi/vfpool/utility_vfpool.go @@ -0,0 +1,62 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vfpool" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityVFpoolCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vfpool.RecordVFPool, error) { + c := m.(*controller.ControllerCfg) + req := vfpool.GetRequest{} + + if d.Id() != "" { + vfpoolId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VFPoolID = vfpoolId + } else { + req.VFPoolID = uint64(d.Get("vfpool_id").(int)) + } + + vfpoolData, err := c.CloudAPI().VFPool().Get(ctx, req) + if err != nil { + return nil, err + } + + return vfpoolData, nil +} diff --git a/internal/service/cloudapi/vfpool/utility_vfpool_list.go b/internal/service/cloudapi/vfpool/utility_vfpool_list.go new file mode 100644 index 00000000..acc251ce --- /dev/null +++ b/internal/service/cloudapi/vfpool/utility_vfpool_list.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "context" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vfpool" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityVFpoolListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vfpool.ListVFPool, error) { + c := m.(*controller.ControllerCfg) + req := vfpool.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if gid, ok := d.GetOk("gid"); ok { + req.GID = uint64(gid.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if accountAccess, ok := d.GetOk("account_access"); ok { + req.AccountAccess = uint64(accountAccess.(int)) + } + if rgAccess, ok := d.GetOk("rg_access"); ok { + req.RGAccess = uint64(rgAccess.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + vfpoolList, err := c.CloudAPI().VFPool().List(ctx, req) + if err != nil { + return nil, err + } + + return vfpoolList, nil +} diff --git a/internal/service/cloudapi/vins/data_source_static_route.go b/internal/service/cloudapi/vins/data_source_static_route.go new file mode 100644 index 00000000..a54b67a4 --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_static_route.go @@ -0,0 +1,108 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + staticRoute, err := utilityDataStaticRouteCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(staticRoute.ID, 10)) + flattenStaticRouteData(d, staticRoute) + return nil +} + +func dataSourceStaticRouteSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS", + }, + "route_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the static route", + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + } + return rets +} + +func DataSourceStaticRoute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceStaticRouteRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceStaticRouteSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_static_route_list.go b/internal/service/cloudapi/vins/data_source_static_route_list.go new file mode 100644 index 00000000..f36106d0 --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_static_route_list.go @@ -0,0 +1,122 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceStaticRouteListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + staticRouteList, err := utilityStaticRouteListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenStaticRouteList(staticRouteList)) + d.Set("entry_count", staticRouteList.EntryCount) + + return nil +} + +func dataSourceStaticRouteListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of VINS", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceStaticRouteList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceStaticRouteListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceStaticRouteListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins.go b/internal/service/cloudapi/vins/data_source_vins.go new file mode 100644 index 00000000..7004a2ec --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins.go @@ -0,0 +1,1067 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vins, err := utilityDataVinsCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenVinsData(d, vins) + return nil +} + +func vnfConfigMGMTSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "ip_addr": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "ssh_key": { + Type: schema.TypeString, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func vnfConfigResourcesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func qosSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_brust": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func vnfInterfaceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "flipgroup_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + "listen_ssh": { + Type: schema.TypeBool, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + Description: "mtu", + }, + "libvirt_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "txmode": { + Type: schema.TypeString, + Computed: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Computed: true, + }, + "event_idx": { + Type: schema.TypeString, + Computed: true, + }, + "queues": { + Type: schema.TypeInt, + Computed: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "net_mask": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: qosSchemaMake(), + }, + }, + "sdn_interface_id": { + Type: schema.TypeString, + Computed: true, + }, + "security_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "target": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } +} + +func vnfConfigSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "mgmt": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vnfConfigMGMTSchemaMake(), + }, + }, + "resources": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vnfConfigResourcesSchemaMake(), + }, + }, + } +} + +func vnfDevSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "_ckey": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Unique ID of the account, which this ViNS belongs to.", + }, + "capabilities": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vnfConfigSchemaMake(), + }, + }, + "config_saved": { + Type: schema.TypeBool, + Computed: true, + }, + "custom_pre_cfg": { + Type: schema.TypeBool, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "vnf_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vnfInterfaceSchemaMake(), + }, + }, + "live_migration_job_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "vnf_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vnc_password": { + Type: schema.TypeString, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func vinsComputeSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func reservationSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dhcpConfigSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "dns": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ip_end": { + Type: schema.TypeString, + Computed: true, + }, + "ip_start": { + Type: schema.TypeString, + Computed: true, + }, + "lease": { + Type: schema.TypeInt, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "reservations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: reservationSchemaMake(), + }, + }, + } +} + +func devicesPrimarySchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "iface01": { + Type: schema.TypeString, + Computed: true, + }, + "iface02": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func devicesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "primary": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: devicesPrimarySchemaMake(), + }, + }, + } +} + +func dhcpSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "_ckey": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dhcpConfigSchemaMake(), + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: devicesSchemaMake(), + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "dhcp_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + }, + "routes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: routesSchemaMake(), + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func routesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "route_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the static route", + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func gwConfigSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ext_net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ext_net_ip": { + Type: schema.TypeString, + Computed: true, + }, + "ext_netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: qosSchemaMake(), + }, + }, + } +} + +func gwSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "_ckey": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: gwConfigSchemaMake(), + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: devicesSchemaMake(), + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "gw_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + }, + "routes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: routesSchemaMake(), + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func rulesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "rule_id": { + Type: schema.TypeInt, + Computed: true, + }, + "local_ip": { + Type: schema.TypeString, + Computed: true, + }, + "local_port": { + Type: schema.TypeInt, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "public_port_end": { + Type: schema.TypeInt, + Computed: true, + }, + "public_port_start": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func natConfigSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "net_mask": { + Type: schema.TypeInt, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: rulesSchemaMake(), + }, + }, + } +} + +func natSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "_ckey": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: natConfigSchemaMake(), + }, + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: devicesSchemaMake(), + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "nat_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + }, + "routes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: routesSchemaMake(), + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func vnfsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "dhcp": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dhcpSchemaMake(), + }, + }, + "gw": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: gwSchemaMake(), + }, + }, + "nat": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: natSchemaMake(), + }, + }, + } +} + +func dataSourceVinsSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + }, + "vnf_dev": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vnfDevSchemaMake(), + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Unique ID of the account, which this ViNS belongs to.", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account, which this ViNS belongs to.", + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vinsComputeSchemaMake(), + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "default_qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: qosSchemaMake(), + }, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "User-defined text description of this ViNS.", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_mask": { + Type: schema.TypeInt, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "pre_reservations_num": { + Type: schema.TypeInt, + Computed: true, + }, + "redundant": { + Type: schema.TypeBool, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Unique ID of the resource group, where this ViNS is belongs to (for ViNS created at resource group level, 0 otherwise).", + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "sec_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: vnfsSchemaMake(), + }, + }, + "vxlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + } + return rets +} + +func DataSourceVins() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVinsSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_audits.go b/internal/service/cloudapi/vins/data_source_vins_audits.go new file mode 100644 index 00000000..b41428c9 --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_audits.go @@ -0,0 +1,108 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + audits, err := utilityVinsAuditsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsAudits(audits)) + + return nil +} + +func DataSourceVinsAuditsSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "call": { + Type: schema.TypeString, + Computed: true, + }, + "response_time": { + Type: schema.TypeFloat, + Computed: true, + }, + "statuscode": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } + return rets +} + +func DataSourceVinsAudits() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsAuditsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: DataSourceVinsAuditsSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_ext_net_list.go b/internal/service/cloudapi/vins/data_source_vins_ext_net_list.go new file mode 100644 index 00000000..6e5e82e7 --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_ext_net_list.go @@ -0,0 +1,116 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsExtNetListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + extNetList, err := utilityVinsExtNetListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsExtNetList(extNetList)) + d.Set("entry_count", extNetList.EntryCount) + return nil +} + +func DataSourceVinsExtNetListchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ext_net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "prefix_len": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return rets +} + +func DataSourceVinsExtNetList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsExtNetListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: DataSourceVinsExtNetListchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_ip_list.go b/internal/service/cloudapi/vins/data_source_vins_ip_list.go new file mode 100644 index 00000000..108d87bc --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_ip_list.go @@ -0,0 +1,120 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsIpListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + ips, err := utilityVinsIpListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsIpList(ips)) + d.Set("entry_count", ips.EntryCount) + return nil +} + +func DataSourceVinsIpListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "domainname": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return rets +} + +func DataSourceVinsIpList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsIpListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: DataSourceVinsIpListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_list.go b/internal/service/cloudapi/vins/data_source_vins_list.go new file mode 100644 index 00000000..20e8a1cf --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_list.go @@ -0,0 +1,223 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vinsList, err := utilityVinsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsList(vinsList)) + d.Set("entry_count", vinsList.EntryCount) + + return nil +} + +func dataSourceVinsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by Name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by Account ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by external IP address", + }, + "vnf_dev_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by VNF Device id", + }, + "include_deleted": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Include deleted computes", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "sort by status", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_name": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vxlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceVinsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVinsListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_list_deleted.go b/internal/service/cloudapi/vins/data_source_vins_list_deleted.go new file mode 100644 index 00000000..187418e8 --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_list_deleted.go @@ -0,0 +1,199 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vinsList, err := utilityVinsListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsListDeleted(vinsList)) + d.Set("entry_count", vinsList.EntryCount) + + return nil +} + +func dataSourceVinsListDeletedSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by account ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by resgroup ID", + }, + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by external IP", + }, + "vnfdev_id": { + Type: schema.TypeInt, + Optional: true, + Description: "find by VNF Device id", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_name": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vxlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceVinsListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVinsListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_vins_nat_rule_list.go b/internal/service/cloudapi/vins/data_source_vins_nat_rule_list.go new file mode 100644 index 00000000..07753c5e --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_vins_nat_rule_list.go @@ -0,0 +1,125 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsNatRuleListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + natRules, err := utilityVinsNatRuleListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsNatRuleList(natRules)) + d.Set("entry_count", natRules.EntryCount) + + return nil +} + +func DataSourceVinsNatRuleListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "local_ip": { + Type: schema.TypeString, + Computed: true, + }, + "local_port": { + Type: schema.TypeInt, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "public_port_end": { + Type: schema.TypeInt, + Computed: true, + }, + "public_port_start": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return rets +} + +func DataSourceVinsNatRuleList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsNatRuleListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: DataSourceVinsNatRuleListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/flattens.go b/internal/service/cloudapi/vins/flattens.go new file mode 100644 index 00000000..e9d675a5 --- /dev/null +++ b/internal/service/cloudapi/vins/flattens.go @@ -0,0 +1,630 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" +) + +func flattenMGMT(mgmt vins.RecordMGMT) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "ip_addr": mgmt.IPAddress, + "password": mgmt.Password, + "ssh_key": mgmt.SSHKey, + "user": mgmt.User, + } + res = append(res, temp) + return res +} + +func flattenResources(resources vins.RecordResources) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": resources.CPU, + "ram": resources.RAM, + "node_id": resources.NodeID, + "uuid": resources.UUID, + } + res = append(res, temp) + return res +} + +func flattenConfig(config vins.RecordVNFConfig) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "mgmt": flattenMGMT(config.MGMT), + "resources": flattenResources(config.Resources), + } + res = append(res, temp) + return res +} + +func flattenQOS(qos vins.QOS) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "e_rate": qos.ERate, + "guid": qos.GUID, + "in_brust": qos.InBurst, + "in_rate": qos.InRate, + } + res = append(res, temp) + return res +} + +func flattenInterfaces(interfaces []vins.ItemVNFInterface) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(interfaces)) + for _, vnfInterface := range interfaces { + temp := map[string]interface{}{ + "conn_id": vnfInterface.ConnID, + "conn_type": vnfInterface.ConnType, + "def_gw": vnfInterface.DefGW, + "enabled": vnfInterface.Enabled, + "enable_secgroups": vnfInterface.EnableSecGroups, + "flipgroup_id": vnfInterface.FLIPGroupID, + "guid": vnfInterface.GUID, + "ip_address": vnfInterface.IPAddress, + "listen_ssh": vnfInterface.ListenSSH, + "mac": vnfInterface.MAC, + "mtu": vnfInterface.MTU, + "name": vnfInterface.Name, + "net_id": vnfInterface.NetID, + "net_mask": vnfInterface.NetMask, + "net_type": vnfInterface.NetType, + "node_id": vnfInterface.NodeID, + "pci_slot": vnfInterface.PCISlot, + "bus_number": vnfInterface.BusNumber, + "qos": flattenQOS(vnfInterface.QOS), + "sdn_interface_id": vnfInterface.SDNInterfaceID, + "security_groups": vnfInterface.SecGroups, + "target": vnfInterface.Target, + "type": vnfInterface.Type, + "vnfs": vnfInterface.VNFs, + "libvirt_settings": flattenLibvirtSettings(vnfInterface.LibvirtSettings), + } + res = append(res, temp) + } + + return res +} + +func flattenLibvirtSettings(libvirtSettings vins.LibvirtSettings) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "guid": libvirtSettings.GUID, + "txmode": libvirtSettings.TXMode, + "ioeventfd": libvirtSettings.IOEventFD, + "event_idx": libvirtSettings.EventIDx, + "queues": libvirtSettings.Queues, + "rx_queue_size": libvirtSettings.RXQueueSize, + "tx_queue_size": libvirtSettings.TXQueueSize, + } + res = append(res, temp) + return res +} + +func flattenVNFDev(vnfDev vins.RecordVNFDev) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "_ckey": vnfDev.CKey, + "account_id": vnfDev.AccountID, + "capabilities": vnfDev.Capabilities, + "config": flattenConfig(vnfDev.Config), //in progress + "config_saved": vnfDev.ConfigSaved, + "custom_pre_cfg": vnfDev.CustomPreConfig, + "desc": vnfDev.Description, + "gid": vnfDev.GID, + "guid": vnfDev.GUID, + "vnf_id": vnfDev.ID, + "interfaces": flattenInterfaces(vnfDev.Interfaces), + "live_migration_job_id": vnfDev.LiveMigrationJobID, + "lock_status": vnfDev.LockStatus, + "milestones": vnfDev.Milestones, + "vnf_name": vnfDev.Name, + "status": vnfDev.Status, + "tech_status": vnfDev.TechStatus, + "type": vnfDev.Type, + "vnc_password": vnfDev.VNCPassword, + "vins": vnfDev.VINS, + } + + res = append(res, temp) + + return res +} + +func flattenComputes(computes vins.ListVINSComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computes)) + for _, compute := range computes { + temp := map[string]interface{}{ + "compute_id": compute.ID, + "compute_name": compute.Name, + } + res = append(res, temp) + } + + return res +} + +func flattenReservations(reservations vins.ListReservations) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(reservations)) + for _, reservation := range reservations { + temp := map[string]interface{}{ + "account_id": reservation.AccountID, + "ip": reservation.IP, + "mac": reservation.MAC, + "type": reservation.Type, + "vm_id": reservation.VMID, + } + res = append(res, temp) + } + + return res +} + +func flattenDHCPConfig(config vins.RecordDHCPConfig) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "default_gw": config.DefaultGW, + "dns": config.DNS, + "ip_end": config.IPEnd, + "ip_start": config.IPStart, + "lease": config.Lease, + "netmask": config.NetMask, + "network": config.Network, + "reservations": flattenReservations(config.Reservations), + } + res = append(res, temp) + + return res +} + +func flattenPrimary(primary vins.RecordPrimary) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "dev_id": primary.DevID, + "iface01": primary.IFace01, + "iface02": primary.IFace02, + } + res = append(res, temp) + + return res +} + +func flattenDevices(devices vins.RecordDevices) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "primary": flattenPrimary(devices.Primary), + } + res = append(res, temp) + + return res +} + +func flattenDHCP(dhcp vins.RecordDHCP) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "_ckey": dhcp.CKey, + "account_id": dhcp.AccountID, + "config": flattenDHCPConfig(dhcp.Config), + "created_time": dhcp.CreatedTime, + "devices": flattenDevices(dhcp.Devices), + "gid": dhcp.GID, + "guid": dhcp.GUID, + "dhcp_id": dhcp.ID, + "lock_status": dhcp.LockStatus, + "milestones": dhcp.Milestones, + "owner_id": dhcp.OwnerID, + "owner_type": dhcp.OwnerType, + "pure_virtual": dhcp.PureVirtual, + "routes": flattenStaticRoute(dhcp.Routes), + "status": dhcp.Status, + "tech_status": dhcp.TechStatus, + "type": dhcp.Type, + "zone_id": dhcp.ZoneID, + } + res = append(res, temp) + + return res +} + +func flattenGWConfig(config vins.RecordGWConfig) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "default_gw": config.DefaultGW, + "ext_net_id": config.ExtNetID, + "ext_net_ip": config.ExtNetIP, + "ext_netmask": config.ExtNetMask, + "qos": flattenQOS(config.QOS), + } + res = append(res, temp) + + return res +} + +func flattenGW(gw vins.RecordGW) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "_ckey": gw.CKey, + "account_id": gw.AccountID, + "config": flattenGWConfig(gw.Config), + "created_time": gw.CreatedTime, + "devices": flattenDevices(gw.Devices), + "gid": gw.GID, + "guid": gw.GUID, + "gw_id": gw.ID, + "lock_status": gw.LockStatus, + "milestones": gw.Milestones, + "owner_id": gw.OwnerID, + "owner_type": gw.OwnerType, + "pure_virtual": gw.PureVirtual, + "routes": flattenStaticRoute(gw.Routes), + "status": gw.Status, + "tech_status": gw.TechStatus, + "type": gw.Type, + "zone_id": gw.ZoneID, + } + res = append(res, temp) + + return res +} + +func flattenRules(rules vins.ListNATRulesConfig) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rules)) + for _, rule := range rules { + tmp := map[string]interface{}{ + "rule_id": rule.ID, + "local_ip": rule.LocalIP, + "local_port": rule.LocalPort, + "protocol": rule.Protocol, + "public_port_end": rule.PublicPortEnd, + "public_port_start": rule.PublicPortStart, + "vm_id": rule.VMID, + "vm_name": rule.VMName, + } + res = append(res, tmp) + } + return res +} + +func flattenNATConfig(config vins.NATConfig) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "net_mask": config.NetMask, + "network": config.Network, + "rules": flattenRules(config.Rules), + } + res = append(res, temp) + + return res + +} + +func flattenNAT(nat vins.RecordNAT) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "_ckey": nat.CKey, + "account_id": nat.AccountID, + "created_time": nat.CreatedTime, + "config": flattenNATConfig(nat.Config), + "devices": flattenDevices(nat.Devices), + "gid": nat.GID, + "guid": nat.GUID, + "nat_id": nat.ID, + "lock_status": nat.LockStatus, + "milestones": nat.Milestones, + "owner_id": nat.OwnerID, + "owner_type": nat.OwnerType, + "pure_virtual": nat.PureVirtual, + "routes": flattenStaticRoute(nat.Routes), + "status": nat.Status, + "tech_status": nat.TechStatus, + "type": nat.Type, + "zone_id": nat.ZoneID, + } + res = append(res, temp) + + return res +} + +func flattenVNFS(vnfs vins.RecordVNFs) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "dhcp": flattenDHCP(vnfs.DHCP), + "gw": flattenGW(vnfs.GW), + "nat": flattenNAT(vnfs.NAT), + } + res = append(res, temp) + + return res +} + +func flattenRuleBlock(rules vins.ListNATRulesConfig) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rules)) + for _, rule := range rules { + tmp := map[string]interface{}{ + "int_ip": rule.LocalIP, + "int_port": rule.LocalPort, + "ext_port_start": rule.PublicPortStart, + "ext_port_end": rule.PublicPortEnd, + "proto": rule.Protocol, + "rule_id": rule.ID, + } + res = append(res, tmp) + } + return res +} + +func flattenVins(d *schema.ResourceData, vins *vins.RecordVINS) { + d.Set("vins_id", vins.ID) + d.Set("vnf_dev", flattenVNFDev(vins.VNFDev)) + d.Set("account_id", vins.AccountID) + d.Set("account_name", vins.AccountName) + d.Set("computes", flattenComputes(vins.Computes)) + d.Set("created_by", vins.CreatedBy) + d.Set("created_time", vins.CreatedTime) + d.Set("default_gw", vins.DefaultGW) + d.Set("default_qos", flattenQOS(vins.DefaultQOS)) + d.Set("deleted_by", vins.DeletedBy) + d.Set("deleted_time", vins.DeletedTime) + d.Set("desc", vins.Description) + d.Set("enable_secgroups", vins.EnableSecGroups) + d.Set("gid", vins.GID) + d.Set("guid", vins.GUID) + d.Set("lock_status", vins.LockStatus) + d.Set("manager_id", vins.ManagerID) + d.Set("manager_type", vins.ManagerType) + d.Set("milestones", vins.Milestones) + d.Set("name", vins.Name) + d.Set("net_mask", vins.NetMask) + d.Set("network", vins.Network) + d.Set("pre_reservations_num", vins.PreReservaionsNum) + d.Set("redundant", vins.Redundant) + d.Set("rg_id", vins.RGID) + d.Set("rg_name", vins.RGName) + d.Set("sec_vnf_dev_id", vins.SecVNFDevID) + d.Set("status", vins.Status) + d.Set("updated_by", vins.UpdatedBy) + d.Set("updated_time", vins.UpdatedTime) + d.Set("user_managed", vins.UserManaged) + d.Set("vnfs", flattenVNFS(vins.VNFs)) + d.Set("vxlan_id", vins.VXLANID) + d.Set("nat_rule", flattenRuleBlock(vins.VNFs.NAT.Config.Rules)) + d.Set("zone_id", vins.ZoneID) +} + +func flattenVinsData(d *schema.ResourceData, vins *vins.RecordVINS) { + d.Set("vins_id", vins.ID) + d.Set("vnf_dev", flattenVNFDev(vins.VNFDev)) + d.Set("account_id", vins.AccountID) + d.Set("account_name", vins.AccountName) + d.Set("computes", flattenComputes(vins.Computes)) + d.Set("created_by", vins.CreatedBy) + d.Set("created_time", vins.CreatedTime) + d.Set("default_gw", vins.DefaultGW) + d.Set("default_qos", flattenQOS(vins.DefaultQOS)) + d.Set("deleted_by", vins.DeletedBy) + d.Set("deleted_time", vins.DeletedTime) + d.Set("desc", vins.Description) + d.Set("gid", vins.GID) + d.Set("guid", vins.GUID) + d.Set("lock_status", vins.LockStatus) + d.Set("manager_id", vins.ManagerID) + d.Set("manager_type", vins.ManagerType) + d.Set("milestones", vins.Milestones) + d.Set("name", vins.Name) + d.Set("net_mask", vins.NetMask) + d.Set("network", vins.Network) + d.Set("pre_reservations_num", vins.PreReservaionsNum) + d.Set("redundant", vins.Redundant) + d.Set("rg_id", vins.RGID) + d.Set("rg_name", vins.RGName) + d.Set("sec_vnf_dev_id", vins.SecVNFDevID) + d.Set("status", vins.Status) + d.Set("updated_by", vins.UpdatedBy) + d.Set("updated_time", vins.UpdatedTime) + d.Set("user_managed", vins.UserManaged) + d.Set("vnfs", flattenVNFS(vins.VNFs)) + d.Set("vxlan_id", vins.VXLANID) + d.Set("zone_id", vins.ZoneID) +} + +func flattenVinsAudits(audits vins.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(audits)) + for _, audit := range audits { + temp := map[string]interface{}{ + "call": audit.Call, + "response_time": audit.ResponseTime, + "statuscode": audit.StatusCode, + "timestamp": audit.Timestamp, + "user": audit.User, + } + res = append(res, temp) + } + + return res +} + +func flattenVinsExtNetList(extNetList *vins.ListExtNets) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(extNetList.Data)) + for _, extNet := range extNetList.Data { + temp := map[string]interface{}{ + "default_gw": extNet.DefaultGW, + "ext_net_id": extNet.ExtNetID, + "ip": extNet.IP, + "prefix_len": extNet.PrefixLen, + "status": extNet.Status, + "tech_status": extNet.TechStatus, + } + res = append(res, temp) + } + + return res +} + +func flattenVinsIpList(ips *vins.ListIPs) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ips.Data)) + for _, ip := range ips.Data { + temp := map[string]interface{}{ + "client_type": ip.ClientType, + "domainname": ip.DomainName, + "hostname": ip.Hostname, + "ip": ip.IP, + "mac": ip.MAC, + "type": ip.Type, + "vm_id": ip.VMID, + } + res = append(res, temp) + } + + return res +} + +func flattenVinsList(vl *vins.ListVINS) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vl.Data)) + for _, v := range vl.Data { + temp := map[string]interface{}{ + "account_id": v.AccountID, + "account_name": v.AccountName, + "created_by": v.CreatedBy, + "created_time": v.CreatedTime, + "deleted_by": v.DeletedBy, + "deleted_time": v.DeletedTime, + "external_ip": v.ExternalIP, + "extnet_id": v.ExtnetId, + "free_ips": v.FreeIPs, + "vins_id": v.ID, + "vins_name": v.Name, + "network": v.Network, + "rg_id": v.RGID, + "rg_name": v.RGName, + "status": v.Status, + "updated_by": v.UpdatedBy, + "updated_time": v.UpdatedTime, + "vxlan_id": v.VXLANID, + } + res = append(res, temp) + } + return res +} + +func flattenVinsListDeleted(vl *vins.ListVINS) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vl.Data)) + for _, v := range vl.Data { + temp := map[string]interface{}{ + "account_id": v.AccountID, + "account_name": v.AccountName, + "created_by": v.CreatedBy, + "created_time": v.CreatedTime, + "deleted_by": v.DeletedBy, + "deleted_time": v.DeletedTime, + "external_ip": v.ExternalIP, + "vins_id": v.ID, + "vins_name": v.Name, + "network": v.Network, + "rg_id": v.RGID, + "rg_name": v.RGName, + "status": v.Status, + "updated_by": v.UpdatedBy, + "updated_time": v.UpdatedTime, + "vxlan_id": v.VXLANID, + } + res = append(res, temp) + } + return res +} + +// /4.4.0 +func flattenStaticRouteList(sr *vins.ListStaticRoutes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(sr.Data)) + for _, staticRoute := range sr.Data { + temp := map[string]interface{}{ + "route_id": staticRoute.ID, + "destination": staticRoute.Destination, + "gateway": staticRoute.Gateway, + "guid": staticRoute.GUID, + "netmask": staticRoute.Netmask, + "compute_ids": staticRoute.ComputeIds, + } + res = append(res, temp) + } + + return res +} + +func flattenStaticRouteData(d *schema.ResourceData, route *vins.ItemRoutes) { + d.Set("destination", route.Destination) + d.Set("gateway", route.Gateway) + d.Set("guid", route.GUID) + d.Set("netmask", route.Netmask) + d.Set("compute_ids", route.ComputeIds) + d.Set("route_id", route.ID) +} + +func flattenStaticRoute(sr vins.ListRoutes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(sr)) + for _, staticRoute := range sr { + temp := map[string]interface{}{ + "route_id": staticRoute.ID, + "destination": staticRoute.Destination, + "gateway": staticRoute.Gateway, + "guid": staticRoute.GUID, + "netmask": staticRoute.Netmask, + "compute_ids": staticRoute.ComputeIds, + } + res = append(res, temp) + } + return res +} + +/// + +func flattenVinsNatRuleList(natRules *vins.ListNATRules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(natRules.Data)) + for _, natRule := range natRules.Data { + temp := map[string]interface{}{ + "id": natRule.ID, + "local_ip": natRule.LocalIP, + "local_port": natRule.LocalPort, + "protocol": natRule.Protocol, + "public_port_end": natRule.PublicPortEnd, + "public_port_start": natRule.PublicPortStart, + "vm_id": natRule.VMID, + "vm_name": natRule.VMName, + } + res = append(res, temp) + } + + return res +} diff --git a/internal/service/cloudapi/vins/resource_check_input_values.go b/internal/service/cloudapi/vins/resource_check_input_values.go new file mode 100644 index 00000000..9fd11f41 --- /dev/null +++ b/internal/service/cloudapi/vins/resource_check_input_values.go @@ -0,0 +1,84 @@ +package vins + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + rgId := uint64(d.Get("rg_id").(int)) + req := rg.ListRequest{} + + rgList, err := c.CloudAPI().RG().List(ctx, req) + if err != nil { + return false, err + } + + return len(rgList.FilterByID(rgId).Data) != 0, nil +} + +func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + extNetID := d.Get("ext_net_id").(int) + + if extNetID == 0 || extNetID == -1 { + return true, nil + } + + c := m.(*controller.ControllerCfg) + extNetIDParsed := uint64(extNetID) + req := extnet.ListRequest{} + + extNetList, err := c.CloudAPI().ExtNet().List(ctx, req) + if err != nil { + return false, err + } + + return len(extNetList.FilterByID(extNetIDParsed).Data) != 0, nil +} + +func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + accountId := uint64(d.Get("account_id").(int)) + req := account.ListRequest{} + + accountList, err := c.CloudAPI().Account().List(ctx, req) + if err != nil { + return false, err + } + + return len(accountList.FilterByID(accountId).Data) != 0, nil +} + +func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + gid := uint64(d.Get("gid").(int)) + req := locations.ListRequest{} + + locationList, err := c.CloudAPI().Locations().List(ctx, req) + if err != nil { + return false, err + } + + return len(locationList.FilterByGID(gid).Data) != 0, nil +} + +func existVinsID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + vinsID := uint64(d.Get("vins_id").(int)) + req := vins.ListRequest{} + + vinsList, err := c.CloudAPI().VINS().List(ctx, req) + if err != nil { + return false, err + } + + return len(vinsList.FilterByID(vinsID).Data) != 0, nil +} diff --git a/internal/service/cloudapi/vins/resource_static_route.go b/internal/service/cloudapi/vins/resource_static_route.go new file mode 100644 index 00000000..781f2db4 --- /dev/null +++ b/internal/service/cloudapi/vins/resource_static_route.go @@ -0,0 +1,194 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "fmt" + "strconv" + "strings" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + + if _, ok := d.GetOk("vins_id"); ok { + haveVinsID, err := existVinsID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveVinsID { + return diag.Errorf("resourceStaticRouteCreate: can't create Static Route because Vins ID %d is not allowed or does not exist", d.Get("vins_id").(int)) + } + } + + req := vins.StaticRouteAddRequest{ + VINSID: uint64(d.Get("vins_id").(int)), + Destination: d.Get("destination").(string), + Netmask: d.Get("netmask").(string), + Gateway: d.Get("gateway").(string), + } + + _, err := c.CloudAPI().VINS().StaticRouteAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + staticRouteData, err := getStaticRouteData(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(fmt.Sprintf("%d#%d", req.VINSID, staticRouteData.ID)) + + return resourceStaticRouteRead(ctx, d, m) +} + +func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + warnings := dc.Warnings{} + + staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenStaticRouteData(d, staticRouteData) + + return warnings.Get() +} + +func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + return nil +} + +func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + arr := strings.Split(d.Id(), "#") + if len(arr) != 2 { + return diag.FromErr(fmt.Errorf("broken state id")) + } + + vinsId, _ := strconv.ParseUint(arr[0], 10, 64) + routeId, _ := strconv.ParseUint(arr[1], 10, 64) + + req := vins.StaticRouteDelRequest{ + VINSID: vinsId, + RouteId: routeId, + } + + _, err := c.CloudAPI().VINS().StaticRouteDel(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceStaticRouteSchemaMake() map[string]*schema.Schema { + rets := dataSourceStaticRouteSchemaMake() + rets["route_id"] = &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + Optional: true, + } + rets["compute_ids"] = &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + } + rets["destination"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + } + + rets["gateway"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + } + rets["netmask"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + } + + return rets +} + +func isContainsIds(els []interface{}, el interface{}) bool { + convEl := el.(int) + for _, elOld := range els { + if convEl == elOld.(int) { + return true + } + } + return false +} + +func ResourceStaticRoute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceStaticRouteCreate, + ReadContext: resourceStaticRouteRead, + UpdateContext: resourceStaticRouteUpdate, + DeleteContext: resourceStaticRouteDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout20m, + Read: &constants.Timeout600s, + Update: &constants.Timeout20m, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceStaticRouteSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/resource_vins.go b/internal/service/cloudapi/vins/resource_vins.go new file mode 100644 index 00000000..f8cc2fc8 --- /dev/null +++ b/internal/service/cloudapi/vins/resource_vins.go @@ -0,0 +1,948 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + + if _, ok := d.GetOk("rg_id"); ok { + haveRGID, err := existRGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveRGID { + return diag.Errorf("resourceVinsCreate: can't create ViNS because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + } + + if _, ok := d.GetOk("ext_net_id"); ok { + haveExtNetID, err := existExtNetID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveExtNetID { + return diag.Errorf("resourceVinsCreate: can't create ViNS because ExtNetID %d is not allowed or does not exist", d.Get("ext_net_id").(int)) + } + } + + if _, ok := d.GetOk("account_id"); ok { + haveAccountID, err := existAccountID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveAccountID { + return diag.Errorf("resourceVinsCreate: can't create ViNS because AccountID %d is not allowed or does not exist", d.Get("account_id").(int)) + } + } + + if _, ok := d.GetOk("gid"); ok { + haveGID, err := existGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveGID { + return diag.Errorf("resourceVinsCreate: can't create ViNS because GID %d is not allowed or does not exist", d.Get("gid").(int)) + } + } + + rgId, rgOk := d.GetOk("rg_id") + accountId, accountIdOk := d.GetOk("account_id") + if !rgOk && !accountIdOk { + return diag.Errorf("resourceVinsCreate: no valid accountId or resource group ID specified") + } + + if rgOk { + req := vins.CreateInRGRequest{ + Name: d.Get("name").(string), + RGID: uint64(rgId.(int)), + } + + if ipcidr, ok := d.GetOk("ipcidr"); ok { + req.IPCIDR = ipcidr.(string) + } + + //extnet v1 + req.ExtNetID = int64(d.Get("ext_net_id").(int)) + if extIp, ok := d.GetOk("ext_ip_addr"); ok { + req.ExtIP = extIp.(string) + } + + //extnet v2 + if extNetResp, ok := d.GetOk("ext_net"); ok { + extNetSl := extNetResp.([]interface{}) + extNet := extNetSl[0].(map[string]interface{}) + + req.ExtNetID = int64(extNet["ext_net_id"].(int)) + req.ExtIP = extNet["ext_net_ip"].(string) + } + + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + if preReservationsNum, ok := d.GetOk("pre_reservations_num"); ok { + req.PreReservationsNum = uint64(preReservationsNum.(int)) + } + if dns, ok := d.GetOk("dns"); ok { + dnsInterface := dns.(*schema.Set).List() + req.DNSList = make([]string, 0, len(dnsInterface)) + for _, item := range dnsInterface { + req.DNSList = append(req.DNSList, item.(string)) + } + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + req.EnableSecGroups = d.Get("enable_secgroups").(bool) + + id, err := c.CloudAPI().VINS().CreateInRG(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(id, 10)) + } else if accountIdOk { + req := vins.CreateInAccountRequest{ + Name: d.Get("name").(string), + AccountID: uint64(accountId.(int)), + } + + if gid, ok := d.GetOk("gid"); ok { + req.GID = uint64(gid.(int)) + } + if ipcidr, ok := d.GetOk("ipcidr"); ok { + req.IPCIDR = ipcidr.(string) + } + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + if preReservationsNum, ok := d.GetOk("pre_reservations_num"); ok { + req.PreReservationsNum = uint64(preReservationsNum.(int)) + } + if dns, ok := d.GetOk("dns"); ok { + dnsInterface := dns.(*schema.Set).List() + req.DNSList = make([]string, 0, len(dnsInterface)) + for _, item := range dnsInterface { + req.DNSList = append(req.DNSList, item.(string)) + } + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + req.EnableSecGroups = d.Get("enable_secgroups").(bool) + + id, err := c.CloudAPI().VINS().CreateInAccount(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(id, 10)) + } + + vinsId, _ := strconv.ParseUint(d.Id(), 10, 64) + + warnings := dc.Warnings{} + if ipRes, ok := d.GetOk("ip"); ok { + ipsSlice := ipRes.([]interface{}) + for _, ipInterfase := range ipsSlice { + ip := ipInterfase.(map[string]interface{}) + + req := vins.IPReserveRequest{ + VINSID: vinsId, + Type: ip["type"].(string), + } + + if ipAddr, ok := ip["ip_addr"]; ok { + req.IPAddr = ipAddr.(string) + } + if macAddr, ok := ip["mac_addr"]; ok { + req.MAC = macAddr.(string) + } + if computeId, ok := ip["compute_id"]; ok { + req.ComputeID = uint64(computeId.(int)) + } + _, err := c.CloudAPI().VINS().IPReserve(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + + if natRule, ok := d.GetOk("nat_rule"); ok { + addedNatRules := natRule.([]interface{}) + if len(addedNatRules) > 0 { + for _, natRuleInterface := range addedNatRules { + natRule := natRuleInterface.(map[string]interface{}) + + req := vins.NATRuleAddRequest{ + VINSID: vinsId, + IntIP: natRule["int_ip"].(string), + IntPort: uint(natRule["int_port"].(int)), + ExtPortStart: uint(natRule["ext_port_start"].(int)), + ExtPortEnd: uint(natRule["ext_port_end"].(int)), + Proto: natRule["proto"].(string), + } + + _, err := c.CloudAPI().VINS().NATRuleAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + return append(warnings.Get(), resourceVinsRead(ctx, d, m)...) +} + +func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + // c := m.(*controller.ControllerCfg) + warnings := dc.Warnings{} + + vinsData, err := utilityDataVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + // isEnabled := d.Get("enable").(bool) + + hasChangeState := false + + switch vinsData.Status { + case status.Destroyed: + d.Set("vins_id", 0) + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceVinsCreate(ctx, d, m) + case status.Deleted: + // hasChangeState = true + + // req := vins.RestoreRequest{ + // VINSID: vinsData.ID, + // } + + // _, err := c.CloudAPI().VINS().Restore(ctx, req) + // if err != nil { + // warnings.Add(err) + // } + case status.Modeled: + return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vinsData.Status) + case status.Created: + case status.Enabled: + // if !isEnabled { + // hasChangeState = true + // req := vins.DisableEnableRequest{ + // VINSID: vinsData.ID, + // } + + // _, err := c.CloudAPI().VINS().Disable(ctx, req) + // if err != nil { + // warnings.Add(err) + // } + // } + case status.Enabling: + case status.Disabled: + // if isEnabled { + // hasChangeState = true + // req := vins.DisableEnableRequest{ + // VINSID: vinsData.ID, + // } + + // _, err := c.CloudAPI().VINS().Enable(ctx, req) + // if err != nil { + // warnings.Add(err) + // } + // } + case status.Disabling: + case status.Deleting: + return diag.Errorf("ViNS are in progress with status: %s", vinsData.Status) + } + + if hasChangeState { + vinsData, err = utilityDataVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + flattenVins(d, vinsData) + + return warnings.Get() +} + +func isContainsIp(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["ip_addr"].(string) == elConv["ip_addr"].(string) { + return true + } + } + return false +} + +func isContainsNatRule(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["int_ip"].(string) == elConv["int_ip"].(string) && + elOldConv["int_port"].(int) == elConv["int_port"].(int) && + elOldConv["ext_port_start"].(int) == elConv["ext_port_start"].(int) { + return true + } + } + return false +} + +func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + warnings := dc.Warnings{} + + if _, ok := d.GetOk("rg_id"); ok { + haveRGID, err := existRGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveRGID { + return diag.Errorf("resourceVinsUpdate: can't update ViNS because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) + } + } + + if _, ok := d.GetOk("ext_net_id"); ok { + haveExtNetID, err := existExtNetID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveExtNetID { + return diag.Errorf("resourceVinsUpdate: can't update ViNS because ExtNetID %d is not allowed or does not exist", d.Get("ext_net_id").(int)) + } + } + + if _, ok := d.GetOk("account_id"); ok { + haveAccountID, err := existAccountID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveAccountID { + return diag.Errorf("resourceVinsUpdate: can't update ViNS because AccountID %d is not allowed or does not exist", d.Get("account_id").(int)) + } + } + + if _, ok := d.GetOk("gid"); ok { + haveGID, err := existGID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !haveGID { + return diag.Errorf("resourceVinsUpdate: can't update ViNS because GID %d is not allowed or does not exist", d.Get("gid").(int)) + } + } + + vinsData, err := utilityDataVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + isEnabled := d.Get("enable").(bool) + + hasChangeState := false + + switch vinsData.Status { + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceVinsCreate(ctx, d, m) + case status.Deleted: + if restore, ok := d.GetOk("restore"); ok && restore.(bool) { + req := vins.RestoreRequest{ + VINSID: vinsData.ID, + } + + _, err := c.CloudAPI().VINS().Restore(ctx, req) + if err != nil { + warnings.Add(err) + } + hasChangeState = true + } + case status.Modeled: + return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vinsData.Status) + case status.Created: + case status.Enabled: + if !isEnabled { + req := vins.DisableEnableRequest{ + VINSID: vinsData.ID, + } + + _, err := c.CloudAPI().VINS().Disable(ctx, req) + if err != nil { + warnings.Add(err) + } + hasChangeState = true + } + case status.Enabling: + case status.Disabled: + if isEnabled { + req := vins.DisableEnableRequest{ + VINSID: vinsData.ID, + } + + _, err := c.CloudAPI().VINS().Enable(ctx, req) + if err != nil { + warnings.Add(err) + } + hasChangeState = true + } + case status.Disabling: + case status.Deleting: + return diag.Errorf("ViNS are in progress with status: %s", vinsData.Status) + } + + if hasChangeState { + vinsData, err = utilityDataVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChange("enable") { + enableOld, enableNew := d.GetChange("enable") + if enableOld.(bool) && !enableNew.(bool) { + req := vins.DisableEnableRequest{ + VINSID: vinsData.ID, + } + + _, err := c.CloudAPI().VINS().Disable(ctx, req) + if err != nil { + warnings.Add(err) + } + } else if !enableOld.(bool) && enableNew.(bool) { + req := vins.DisableEnableRequest{ + VINSID: vinsData.ID, + } + + _, err := c.CloudAPI().VINS().Enable(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + if d.HasChange("ext_net_id") { + //extnet v1 + oldExtNetId, newExtNedId := d.GetChange("ext_net_id") + if oldExtNetId.(int) != newExtNedId.(int) { + log.Debugf("resourceVinsUpdate: changing ViNS ID %s - ext_net_id %d -> %d", d.Id(), oldExtNetId.(int), newExtNedId.(int)) + + if oldExtNetId.(int) > 0 { + // there was preexisting external net connection - disconnect ViNS + req := vins.ExtNetDisconnectRequest{VINSID: vinsData.ID} + + _, err := c.CloudAPI().VINS().ExtNetDisconnect(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + if newExtNedId.(int) >= 0 { + // new external network connection requested - connect ViNS + req := vins.ExtNetConnectRequest{ + VINSID: vinsData.ID, + NetID: uint64(newExtNedId.(int)), + IP: "", + } + + extNetIp, ok := d.GetOk("ext_net_ip") + if ok && extNetIp.(string) != "" { + req.IP = extNetIp.(string) + } + + _, err := c.CloudAPI().VINS().ExtNetConnect(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + if d.HasChange("ip") { + deletedIps := make([]interface{}, 0) + addedIps := make([]interface{}, 0) + + oldIpInterface, newIpInterface := d.GetChange("ip") + oldIpSlice := oldIpInterface.([]interface{}) + newIpSlice := newIpInterface.([]interface{}) + + for _, el := range oldIpSlice { + if !isContainsIp(newIpSlice, el) { + deletedIps = append(deletedIps, el) + } + } + + for _, el := range newIpSlice { + if !isContainsIp(oldIpSlice, el) { + addedIps = append(addedIps, el) + } + } + + if len(deletedIps) > 0 { + for _, ipInterfase := range deletedIps { + ip := ipInterfase.(map[string]interface{}) + req := vins.IPReleaseRequest{VINSID: vinsData.ID} + + if ip["ip_addr"].(string) != "" { + req.IPAddr = ip["ip_addr"].(string) + } + if ip["mac_addr"].(string) != "" { + req.MAC = ip["mac_addr"].(string) + } + + _, err := c.CloudAPI().VINS().IPRelese(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + + if len(addedIps) > 0 { + for _, ipInterfase := range addedIps { + ip := ipInterfase.(map[string]interface{}) + req := vins.IPReserveRequest{ + VINSID: vinsData.ID, + Type: ip["type"].(string), + } + + if ip["ip_addr"].(string) != "" { + req.IPAddr = ip["ip_addr"].(string) + } + if ip["mac_addr"].(string) != "" { + req.MAC = ip["mac_addr"].(string) + } + if ip["compute_id"].(int) != 0 { + req.ComputeID = uint64(ip["compute_id"].(int)) + } + + _, err := c.CloudAPI().VINS().IPReserve(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if d.HasChange("nat_rule") { + deletedNatRules := make([]interface{}, 0) + addedNatRules := make([]interface{}, 0) + + oldNatRulesInterface, newNatRulesInterface := d.GetChange("nat_rule") + oldNatRulesSlice := oldNatRulesInterface.([]interface{}) + newNatRulesSlice := newNatRulesInterface.([]interface{}) + + for _, el := range oldNatRulesSlice { + if !isContainsNatRule(newNatRulesSlice, el) { + deletedNatRules = append(deletedNatRules, el) + } + } + + for _, el := range newNatRulesSlice { + if !isContainsNatRule(oldNatRulesSlice, el) { + addedNatRules = append(addedNatRules, el) + } + } + + if len(deletedNatRules) > 0 { + for _, natRuleInterface := range deletedNatRules { + natRule := natRuleInterface.(map[string]interface{}) + req := vins.NATRuleDelRequest{ + VINSID: vinsData.ID, + RuleID: int64(natRule["rule_id"].(int)), + } + + _, err := c.CloudAPI().VINS().NATRuleDel(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + + if len(addedNatRules) > 0 { + for _, natRuleInterface := range addedNatRules { + natRule := natRuleInterface.(map[string]interface{}) + req := vins.NATRuleAddRequest{ + VINSID: vinsData.ID, + IntIP: natRule["int_ip"].(string), + IntPort: uint(natRule["int_port"].(int)), + ExtPortStart: uint(natRule["ext_port_start"].(int)), + } + + if natRule["ext_port_end"].(int) != 0 { + req.ExtPortEnd = uint(natRule["ext_port_end"].(int)) + } + if natRule["proto"].(string) != "" { + req.Proto = natRule["proto"].(string) + } + + _, err := c.CloudAPI().VINS().NATRuleAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if d.HasChange("dns") { + // empty "dns" is allowed, it will update vnfs.dhcp.config.dns from current values to empty list + dnsInterface := d.Get("dns").(*schema.Set).List() + dnsList := make([]string, 0, len(dnsInterface)) + for _, item := range dnsInterface { + dnsList = append(dnsList, item.(string)) + } + + req := vins.DNSApplyRequest{ + VINSID: vinsData.ID, + DNSList: dnsList, + } + + _, err := c.CloudAPI().VINS().DNSApply(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + if d.HasChange("vnfdev_restart") { + if oldRestart, newRestart := d.GetChange("vnfdev_restart"); oldRestart == false && newRestart == true { + req := vins.VNFDevRestartRequest{VINSID: vinsData.ID} + + _, err := c.CloudAPI().VINS().VNFDevRestart(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + if d.HasChange("vnfdev_redeploy") { + if oldRedeploy, newRedeploy := d.GetChange("vnfdev_redeploy"); oldRedeploy == false && newRedeploy == true { + req := vins.VNFDevRedeployRequest{VINSID: vinsData.ID} + + _, err := c.CloudAPI().VINS().VNFDevRedeploy(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + + if d.HasChange("zone_id") { + zoneID := uint64(d.Get("zone_id").(int)) + + req := vins.MigrateToZoneRequest{ + VINSID: vinsData.ID, + ZoneID: zoneID, + } + + _, err := c.CloudAPI().VINS().MigrateToZone(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + return append(warnings.Get(), resourceVinsRead(ctx, d, m)...) +} + +func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + vinsId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := vins.DeleteRequest{ + VINSID: vinsId, + Force: d.Get("force").(bool), + Permanently: d.Get("permanently").(bool), + } + + _, err := c.CloudAPI().VINS().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func extNetSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "ext_net_id": { + Type: schema.TypeInt, + Default: -1, + Optional: true, + }, + "ext_net_ip": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + } +} + +func ipSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"DHCP", "VIP", "EXCLUDED"}, false), + }, + "ip_addr": { + Type: schema.TypeString, + Optional: true, + }, + "mac_addr": { + Type: schema.TypeString, + Optional: true, + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + }, + } +} + +func natRuleSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "int_ip": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "int_port": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "ext_port_start": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "ext_port_end": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "proto": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false), + Computed: true, + }, + "rule_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func resourceVinsSchemaMake() map[string]*schema.Schema { + rets := dataSourceVinsSchemaMake() + rets["name"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + } + rets["rg_id"] = &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + Optional: true, + } + rets["account_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Computed: true, + } + rets["ext_net_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Default: -1, + } + rets["ext_ip_addr"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "", + } + rets["ipcidr"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + } + rets["pre_reservations_num"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + } + rets["gid"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Computed: true, + } + rets["enable"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + } + rets["permanently"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + rets["force"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + rets["ext_net"] = &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: extNetSchemaMake(), + }, + } + rets["ip"] = &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: ipSchemaMake(), + }, + } + rets["nat_rule"] = &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: natRuleSchemaMake(), + }, + } + rets["desc"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "Optional user-defined text description of this ViNS.", + } + rets["restore"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + rets["vnfdev_restart"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + rets["vnfdev_redeploy"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + rets["dns"] = &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + } + rets["vins_id"] = &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + } + rets["zone_id"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of the Zone to put ViNS into", + } + rets["enable_secgroups"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "enable security groups", + } + + return rets +} + +func ResourceVins() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceVinsCreate, + ReadContext: resourceVinsRead, + UpdateContext: resourceVinsUpdate, + DeleteContext: resourceVinsDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout20m, + Read: &constants.Timeout600s, + Update: &constants.Timeout20m, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceVinsSchemaMake(), + } +} diff --git a/internal/service/cloudapi/vins/utility_static_route.go b/internal/service/cloudapi/vins/utility_static_route.go new file mode 100644 index 00000000..704b6f8f --- /dev/null +++ b/internal/service/cloudapi/vins/utility_static_route.go @@ -0,0 +1,107 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "fmt" + "strconv" + "strings" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDataStaticRouteCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ItemRoutes, error) { + c := m.(*controller.ControllerCfg) + req := vins.StaticRouteListRequest{} + var routeId uint64 + + if d.Id() != "" { + arr := strings.Split(d.Id(), "#") + if len(arr) != 2 { + return nil, fmt.Errorf("broken state id") + } + + req.VINSID, _ = strconv.ParseUint(arr[0], 10, 64) + routeId, _ = strconv.ParseUint(arr[1], 10, 64) + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + routeId = uint64(d.Get("route_id").(int)) + } + + log.Debugf("utilityStaticRouteCheckPresence, vins_id: %v", req.VINSID) + staticRouteList, err := c.CloudAPI().VINS().StaticRouteList(ctx, req) + if err != nil { + return nil, err + } + + log.Debugf("utilityStaticRouteCheckPresence: ROUTE ID %v", routeId) + + staticRoute := &vins.ItemRoutes{} + for _, route := range staticRouteList.Data { + if routeId == route.ID { + staticRoute = &route + return staticRoute, nil + } + } + + return nil, fmt.Errorf("static route not found") +} + +func getStaticRouteData(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ItemRoutes, error) { + c := m.(*controller.ControllerCfg) + req := vins.StaticRouteListRequest{} + req.VINSID = uint64(d.Get("vins_id").(int)) + + staticRouteList, err := c.CloudAPI().VINS().StaticRouteList(ctx, req) + if err != nil { + return nil, err + } + + destination := d.Get("destination").(string) + gateway := d.Get("gateway").(string) + + staticRoute := &vins.ItemRoutes{} + for _, route := range staticRouteList.Data { + if destination == route.Destination && gateway == route.Gateway { + staticRoute = &route + return staticRoute, nil + } + } + + return nil, fmt.Errorf("static route not found") +} diff --git a/internal/service/cloudapi/vins/utility_static_route_list.go b/internal/service/cloudapi/vins/utility_static_route_list.go new file mode 100644 index 00000000..005013a2 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_static_route_list.go @@ -0,0 +1,58 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityStaticRouteListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListStaticRoutes, error) { + c := m.(*controller.ControllerCfg) + req := vins.StaticRouteListRequest{} + + req.VINSID = uint64(d.Get("vins_id").(int)) + + log.Debugf("utilityStaticRouteListCheckPresence") + staticRouteList, err := c.CloudAPI().VINS().StaticRouteList(ctx, req) + if err != nil { + return nil, err + } + + return staticRouteList, nil +} diff --git a/internal/service/cloudapi/vins/utility_vins.go b/internal/service/cloudapi/vins/utility_vins.go new file mode 100644 index 00000000..7ab97d26 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDataVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.RecordVINS, error) { + c := m.(*controller.ControllerCfg) + req := vins.GetRequest{} + + if d.Id() != "" { + vinsId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VINSID = vinsId + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + } + + vins, err := c.CloudAPI().VINS().Get(ctx, req) + if err != nil { + return nil, err + } + + return vins, nil +} + diff --git a/internal/service/cloudapi/vins/utility_vins_audits.go b/internal/service/cloudapi/vins/utility_vins_audits.go new file mode 100644 index 00000000..de3b8015 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_audits.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityVinsAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (vins.ListAudits, error) { + c := m.(*controller.ControllerCfg) + req := vins.AuditsRequest{} + + if d.Id() != "" { + vinsId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VINSID = vinsId + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + } + + audits, err := c.CloudAPI().VINS().Audits(ctx, req) + if err != nil { + return nil, err + } + + return audits, nil +} diff --git a/internal/service/cloudapi/vins/utility_vins_ext_net_list.go b/internal/service/cloudapi/vins/utility_vins_ext_net_list.go new file mode 100644 index 00000000..c6be5838 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_ext_net_list.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityVinsExtNetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListExtNets, error) { + c := m.(*controller.ControllerCfg) + req := vins.ExtNetListRequest{ + VINSID: uint64(d.Get("vins_id").(int)), + } + + if d.Id() != "" { + vinsId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VINSID = vinsId + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + } + + extNetList, err := c.CloudAPI().VINS().ExtNetList(ctx, req) + if err != nil { + return nil, err + } + + return extNetList, nil +} diff --git a/internal/service/cloudapi/vins/utility_vins_ip_list.go b/internal/service/cloudapi/vins/utility_vins_ip_list.go new file mode 100644 index 00000000..b0e5edbf --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_ip_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityVinsIpListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListIPs, error) { + c := m.(*controller.ControllerCfg) + req := vins.IPListRequest{} + + if d.Id() != "" { + vinsId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VINSID = vinsId + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + } + + ips, err := c.CloudAPI().VINS().IPList(ctx, req) + if err != nil { + return nil, err + } + + return ips, nil +} diff --git a/internal/service/cloudapi/vins/utility_vins_list.go b/internal/service/cloudapi/vins/utility_vins_list.go new file mode 100644 index 00000000..3f9f4081 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_list.go @@ -0,0 +1,102 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListVINS, error) { + c := m.(*controller.ControllerCfg) + req := vins.ListRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if ext_ip, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = ext_ip.(string) + } + + if VNFDevId, ok := d.GetOk("vnfdev_id"); ok { + req.VNFDevId = uint64(VNFDevId.(int)) + } + + if includeDeleted, ok := d.GetOk("include_deleted"); ok { + req.IncludeDeleted = includeDeleted.(bool) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + log.Debugf("utilityVinsListCheckPresence") + vinsList, err := c.CloudAPI().VINS().List(ctx, req) + if err != nil { + return nil, err + } + + return vinsList, nil +} diff --git a/internal/service/cloudapi/vins/utility_vins_list_deleted.go b/internal/service/cloudapi/vins/utility_vins_list_deleted.go new file mode 100644 index 00000000..4946e8f3 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_list_deleted.go @@ -0,0 +1,89 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityVinsListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListVINS, error) { + c := m.(*controller.ControllerCfg) + req := vins.ListDeletedRequest{} + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if ext_ip, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = ext_ip.(string) + } + if VNFDevId, ok := d.GetOk("vnfdev_id"); ok { + req.VNFDevID = uint64(VNFDevId.(int)) + } + + log.Debugf("utilityVinsListDeletedCheckPresence") + vinsList, err := c.CloudAPI().VINS().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return vinsList, nil +} diff --git a/internal/service/cloudapi/vins/utility_vins_nat_rule_list.go b/internal/service/cloudapi/vins/utility_vins_nat_rule_list.go new file mode 100644 index 00000000..c07014c6 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_vins_nat_rule_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityVinsNatRuleListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListNATRules, error) { + c := m.(*controller.ControllerCfg) + req := vins.NATRuleListRequest{} + + if d.Id() != "" { + vinsId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VINSID = vinsId + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + } + + natRuleList, err := c.CloudAPI().VINS().NATRuleList(ctx, req) + if err != nil { + return nil, err + } + + return natRuleList, nil +} diff --git a/internal/service/cloudapi/zone/data_source_zone.go b/internal/service/cloudapi/zone/data_source_zone.go new file mode 100644 index 00000000..978784fb --- /dev/null +++ b/internal/service/cloudapi/zone/data_source_zone.go @@ -0,0 +1,213 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceZoneRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + zone, err := utilityZoneCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(d.Get("zone_id").(int))) + flattenZone(d, zone) + return nil +} + +func dataSourceZoneSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "zone_id": { + Type: schema.TypeInt, + Required: true, + }, + "auto_start": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "deletable": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "node_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "account_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "extnet_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "vins_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "lbs_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "bservice_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "k8s_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "drs": { + Type: schema.TypeBool, + Computed: true, + }, + "drs_uid": { + Type: schema.TypeString, + Computed: true, + }, + "drs_name": { + Type: schema.TypeString, + Computed: true, + }, + "sso_url": { + Type: schema.TypeString, + Computed: true, + }, + "app_id": { + Type: schema.TypeString, + Computed: true, + }, + "decort_url": { + Type: schema.TypeString, + Computed: true, + }, + "domain": { + Type: schema.TypeString, + Computed: true, + }, + "ping_addr": { + Type: schema.TypeString, + Computed: true, + }, + "broadcast_addr": { + Type: schema.TypeString, + Computed: true, + }, + "ssl_skip_verify": { + Type: schema.TypeBool, + Computed: true, + }, + "sso_type": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func DataSourceZone() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceZoneRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceZoneSchemaMake(), + } +} diff --git a/internal/service/cloudapi/zone/data_source_zone_list.go b/internal/service/cloudapi/zone/data_source_zone_list.go new file mode 100644 index 00000000..cfc00b54 --- /dev/null +++ b/internal/service/cloudapi/zone/data_source_zone_list.go @@ -0,0 +1,230 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceZoneListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + zoneList, err := utilityZoneListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenZoneList(zoneList)) + d.Set("entry_count", zoneList.EntryCount) + return nil +} + +func dataSourceZoneListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "gid": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by Grid ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Find by description", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "deletable": { + Type: schema.TypeBool, + Optional: true, + Description: "Find by deletable", + }, + "node_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by nodeId", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "zone_id": { + Type: schema.TypeInt, + Required: true, + }, + "auto_start": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "deletable": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "node_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "drs": { + Type: schema.TypeBool, + Computed: true, + }, + "drs_uid": { + Type: schema.TypeString, + Computed: true, + }, + "drs_name": { + Type: schema.TypeString, + Computed: true, + }, + "sso_url": { + Type: schema.TypeString, + Computed: true, + }, + "app_id": { + Type: schema.TypeString, + Computed: true, + }, + "decort_url": { + Type: schema.TypeString, + Computed: true, + }, + "domain": { + Type: schema.TypeString, + Computed: true, + }, + "ping_addr": { + Type: schema.TypeString, + Computed: true, + }, + "broadcast_addr": { + Type: schema.TypeString, + Computed: true, + }, + "ssl_skip_verify": { + Type: schema.TypeBool, + Computed: true, + }, + "sso_type": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func DataSourceZoneList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceZoneListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceZoneListSchemaMake(), + } +} diff --git a/internal/service/cloudapi/zone/flattens.go b/internal/service/cloudapi/zone/flattens.go new file mode 100644 index 00000000..8f49584c --- /dev/null +++ b/internal/service/cloudapi/zone/flattens.go @@ -0,0 +1,113 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/zone" +) + +func flattenZone(d *schema.ResourceData, item *zone.RecordZone) error { + log.Debugf("flattenZone: start decoding RecordZone name %q / ID %d", + item.Name, item.ID) + + d.Set("zone_id", int(item.ID)) + d.Set("guid", int(item.GUID)) + d.Set("gid", int(item.GID)) + d.Set("name", item.Name) + d.Set("description", item.Description) + d.Set("deletable", item.Deletable) + d.Set("status", item.Status) + d.Set("created_time", item.CreatedTime) + d.Set("updated_time", item.UpdatedTime) + d.Set("node_ids", item.NodeIDs) + d.Set("account_ids", item.AccountIDs) + d.Set("compute_ids", item.ComputeIDs) + d.Set("extnet_ids", item.ExtnetIDs) + d.Set("vins_ids", item.VinsIDs) + d.Set("lbs_ids", item.LBIDs) + d.Set("bservice_ids", item.BserviceIDs) + d.Set("k8s_ids", item.K8SIDs) + d.Set("auto_start", item.AutoStart) + d.Set("drs", item.DRS) + d.Set("drs_uid", item.DRSUID) + d.Set("drs_name", item.DRSName) + d.Set("sso_url", item.SSOURL) + d.Set("app_id", item.AppID) + d.Set("decort_url", item.DecortURL) + d.Set("ping_addr", item.PingAddr) + d.Set("broadcast_addr", item.BroadcastAddr) + d.Set("ssl_skip_verify", item.SSLSkipVerify) + d.Set("domain", item.Domain) + d.Set("sso_type", item.SSOType) + + log.Debugf("flattenZone: decoded RecordZone name %q / ID %d, complete", + item.Name, item.ID) + return nil +} + +func flattenZoneList(zone *zone.ListZones) []map[string]interface{} { + log.Debugf("flattenZoneList start") + res := make([]map[string]interface{}, 0, len(zone.Data)) + for _, zone := range zone.Data { + temp := map[string]interface{}{ + "zone_id": int(zone.ID), + "guid": int(zone.GUID), + "gid": int(zone.GID), + "name": zone.Name, + "description": zone.Description, + "deletable": zone.Deletable, + "status": zone.Status, + "created_time": zone.CreatedTime, + "updated_time": zone.UpdatedTime, + "node_ids": zone.NodeIDs, + "auto_start": zone.AutoStart, + "drs": zone.DRS, + "drs_uid": zone.DRSUID, + "drs_name": zone.DRSName, + "sso_url": zone.SSOURL, + "app_id": zone.AppID, + "decort_url": zone.DecortURL, + "ping_addr": zone.PingAddr, + "broadcast_addr": zone.BroadcastAddr, + "ssl_skip_verify": zone.SSLSkipVerify, + "domain": zone.Domain, + "sso_type": zone.SSOType, + } + res = append(res, temp) + } + log.Debugf("flattenZoneList end") + return res + +} diff --git a/internal/service/cloudapi/zone/utility_zone.go b/internal/service/cloudapi/zone/utility_zone.go new file mode 100644 index 00000000..c1ac64bd --- /dev/null +++ b/internal/service/cloudapi/zone/utility_zone.go @@ -0,0 +1,62 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/zone" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityZoneCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*zone.RecordZone, error) { + c := m.(*controller.ControllerCfg) + req := zone.GetRequest{} + + if d.Id() != "" { + zoneId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.ID = zoneId + } else { + req.ID = uint64(d.Get("zone_id").(int)) + } + + zoneData, err := c.CloudAPI().Zone().Get(ctx, req) + if err != nil { + return nil, err + } + + return zoneData, nil +} diff --git a/internal/service/cloudapi/zone/utility_zone_list.go b/internal/service/cloudapi/zone/utility_zone_list.go new file mode 100644 index 00000000..65eb3e5f --- /dev/null +++ b/internal/service/cloudapi/zone/utility_zone_list.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/zone" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityZoneListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*zone.ListZones, error) { + c := m.(*controller.ControllerCfg) + req := zone.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if gid, ok := d.GetOk("gid"); ok { + req.GID = uint64(gid.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if deletable, ok := d.GetOk("deletable"); ok { + req.Deletable = deletable.(bool) + } + if nodeID, ok := d.GetOk("nodeId"); ok { + req.NodeID = uint64(nodeID.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + zoneList, err := c.CloudAPI().Zone().List(ctx, req) + if err != nil { + return nil, err + } + + return zoneList, nil +} diff --git a/internal/service/cloudbroker/account/data_source_account.go b/internal/service/cloudbroker/account/data_source_account.go new file mode 100644 index 00000000..80cb11c3 --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Nikita Sorokin, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + acc, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(acc.ID, 10)) + flattenDataAccount(d, acc) + + return nil +} + +func DataSourceAccount() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_audits_list.go b/internal/service/cloudbroker/account/data_source_account_audits_list.go new file mode 100644 index 00000000..2f5e3c93 --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_audits_list.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountAuditsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountAuditsList, err := utilityAccountAuditsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountAuditsList(accountAuditsList)) + + return nil +} + +func DataSourceAccountAuditsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountAuditsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountAuditsListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_available_templates_list.go b/internal/service/cloudbroker/account/data_source_account_available_templates_list.go new file mode 100644 index 00000000..888ecf48 --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_available_templates_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountAvailableTemplatesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountAvailableTemplatesList, err := utilityAccountAvailableTemplatesListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", accountAvailableTemplatesList) + + return nil +} + +func DataSourceAccountAvailableTemplatesList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountAvailableTemplatesListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountAvailableTemplatesListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_computes_list.go b/internal/service/cloudbroker/account/data_source_account_computes_list.go new file mode 100644 index 00000000..62b21a64 --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_computes_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountComputesList, err := utilityAccountComputesListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountComputesList(accountComputesList)) + d.Set("entry_count", accountComputesList.EntryCount) + + return nil +} + +func DataSourceAccountComputesList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountComputesListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountComputesListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_deleted_list.go b/internal/service/cloudbroker/account/data_source_account_deleted_list.go new file mode 100644 index 00000000..87043f40 --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_deleted_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountDeletedListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountDeletedList, err := utilityAccountDeletedListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenListDeleted(accountDeletedList)) + d.Set("entry_count", accountDeletedList.EntryCount) + + return nil +} + +func DataSourceAccountDeletedList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountDeletedListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_disks_list.go b/internal/service/cloudbroker/account/data_source_account_disks_list.go new file mode 100644 index 00000000..09b86f87 --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_disks_list.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountDisksListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountDisksList, err := utilityAccountDisksListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountDisksList(accountDisksList)) + d.Set("entry_count", accountDisksList.EntryCount) + + return nil +} + +func DataSourceAccountDisksList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountDisksListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountDisksListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_flipgroups_list.go b/internal/service/cloudbroker/account/data_source_account_flipgroups_list.go new file mode 100644 index 00000000..b124cb0c --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_flipgroups_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountFlipGroupsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountFlipGroupsList, err := utilityAccountFlipGroupsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountFlipGroupsList(accountFlipGroupsList)) + d.Set("entry_count", accountFlipGroupsList.EntryCount) + + return nil +} + +func DataSourceAccountFlipGroupsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountFlipGroupsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountFlipGroupsListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_get_resource_consumption.go b/internal/service/cloudbroker/account/data_source_account_get_resource_consumption.go new file mode 100644 index 00000000..4533b397 --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_get_resource_consumption.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountResourceConsumptionGetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountResourceConsumptionRec, err := utilityAccountResourceConsumptionGetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenResourceConsumption(d, accountResourceConsumptionRec) + return nil +} + +func DataSourceAccountResourceConsumptionGet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountResourceConsumptionGetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountResourceConsumptionGetSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_list.go b/internal/service/cloudbroker/account/data_source_account_list.go new file mode 100644 index 00000000..e506c44e --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Nikita Sorokin, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountList, err := utilityAccountListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountList(accountList)) + d.Set("entry_count", accountList.EntryCount) + + return nil +} + +func DataSourceAccountList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_resource_consumption_list.go b/internal/service/cloudbroker/account/data_source_account_resource_consumption_list.go new file mode 100644 index 00000000..ba54fcd2 --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_resource_consumption_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountResourceConsumptionListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountResourceConsumptionList, err := utilityAccountResourceConsumptionListCheckPresence(ctx, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccResourceConsumption(accountResourceConsumptionList)) + d.Set("entry_count", accountResourceConsumptionList.EntryCount) + return nil +} + +func DataSourceAccountResourceConsumptionList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountResourceConsumptionListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountResourceConsumptionListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_rg_list.go b/internal/service/cloudbroker/account/data_source_account_rg_list.go new file mode 100644 index 00000000..a2dfda5c --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_rg_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountRGListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountRGList, err := utilityAccountRGListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountRGList(accountRGList)) + d.Set("entry_count", accountRGList.EntryCount) + + return nil +} + +func DataSourceAccountRGList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountRGListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountRGListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/data_source_account_vins_list.go b/internal/service/cloudbroker/account/data_source_account_vins_list.go new file mode 100644 index 00000000..391c79ad --- /dev/null +++ b/internal/service/cloudbroker/account/data_source_account_vins_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccountVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accountVinsList, err := utilityAccountVinsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccountVinsList(accountVinsList)) + d.Set("entry_count", accountVinsList.EntryCount) + + return nil +} + +func DataSourceAccountVinsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccountVinsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccountVinsListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/flattens.go b/internal/service/cloudbroker/account/flattens.go new file mode 100644 index 00000000..f0eb0128 --- /dev/null +++ b/internal/service/cloudbroker/account/flattens.go @@ -0,0 +1,487 @@ +package account + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" +) + +func flattenResourceAccount(d *schema.ResourceData, acc *account.RecordAccount) { + d.Set("dc_location", acc.DCLocation) + d.Set("acl", flattenAccAcl(acc.ACL)) + d.Set("company", acc.Company) + d.Set("companyurl", acc.CompanyURL) + d.Set("cpu_allocation_parameter", acc.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", acc.CPUAllocationRatio) + d.Set("created_by", acc.CreatedBy) + d.Set("created_time", acc.CreatedTime) + d.Set("deactivation_time", acc.DeactivationTime) + d.Set("desc", acc.Description) + d.Set("deleted_by", acc.DeletedBy) + d.Set("deleted_time", acc.DeletedTime) + d.Set("displayname", acc.DisplayName) + d.Set("enable", flattenEnabled(acc.Status)) + d.Set("guid", acc.GUID) + d.Set("account_id", acc.ID) + d.Set("account_name", acc.Name) + d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits)) + d.Set("storage_policy", flattenSTPolicy(acc.ResourceLimits.StoragePolicies)) + d.Set("resource_types", acc.ResTypes) + d.Set("send_access_emails", acc.SendAccessEmails) + d.Set("status", acc.Status) + d.Set("uniq_pools", acc.UniqPools) + d.Set("updated_by", acc.UpdatedBy) + d.Set("updated_time", acc.UpdatedTime) + d.Set("version", acc.Version) + d.Set("vins", acc.VINS) + d.Set("zone_ids", flattenZonesInResource(acc.ZoneIDs)) +} + +func flattenDataAccount(d *schema.ResourceData, acc *account.RecordAccount) { + d.Set("dc_location", acc.DCLocation) + d.Set("acl", flattenAccAcl(acc.ACL)) + d.Set("company", acc.Company) + d.Set("companyurl", acc.CompanyURL) + d.Set("compute_features", acc.ComputeFeatures) + d.Set("cpu_allocation_parameter", acc.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", acc.CPUAllocationRatio) + d.Set("created_by", acc.CreatedBy) + d.Set("created_time", acc.CreatedTime) + d.Set("deactivation_time", acc.DeactivationTime) + d.Set("desc", acc.Description) + d.Set("deleted_by", acc.DeletedBy) + d.Set("deleted_time", acc.DeletedTime) + d.Set("displayname", acc.DisplayName) + d.Set("guid", acc.GUID) + d.Set("account_id", acc.ID) + d.Set("default_zone_id", acc.DefaultZoneID) + d.Set("account_name", acc.Name) + d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits)) + d.Set("resource_types", acc.ResTypes) + d.Set("send_access_emails", acc.SendAccessEmails) + d.Set("status", acc.Status) + d.Set("storage_policy_ids", acc.StoragePolicyIDs) + d.Set("uniq_pools", acc.UniqPools) + d.Set("zone_ids", flattenZones(acc.ZoneIDs)) + d.Set("updated_by", acc.UpdatedBy) + d.Set("updated_time", acc.UpdatedTime) + d.Set("version", acc.Version) + d.Set("vins", acc.VINS) + +} + +func flattenAccountRGList(argl *account.ListRG) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(argl.Data)) + for _, arg := range argl.Data { + temp := map[string]interface{}{ + "computes": flattenAccRGComputes(arg.Computes), + "resources": flattenAccRGResources(arg.Resources), + "created_by": arg.CreatedBy, + "created_time": arg.CreatedTime, + "desc": arg.Description, + "deleted_by": arg.DeletedBy, + "deleted_time": arg.DeletedTime, + "rg_id": arg.ID, + "milestones": arg.Milestones, + "rg_name": arg.Name, + "status": arg.Status, + "updated_by": arg.UpdatedBy, + "updated_time": arg.UpdatedTime, + "vinses": arg.VINSes, + } + res = append(res, temp) + } + return res + +} + +func flattenAccRGComputes(argc account.Computes) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "started": argc.Started, + "stopped": argc.Stopped, + } + res = append(res, temp) + return res +} + +func flattenAccRGResources(argr account.RGResuorces) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "consumed": flattenAccResource(argr.Consumed), + "limits": flattenAccLimits(argr.Limits), + "reserved": flattenAccResource(argr.Reserved), + } + res = append(res, temp) + return res +} + +func flattenAccLimits(l account.Limits) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": l.CPU, + "disksize": l.DiskSize, + "disksizemax": l.DiskSizeMax, + "extips": l.ExtIPs, + "gpu": l.GPU, + "ram": l.RAM, + "seps": l.SEPs, + } + res = append(res, temp) + return res +} + +func flattenAccResource(r account.Resource) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": r.CPU, + "disksize": r.DiskSize, + "disksizemax": r.DiskSizeMax, + "extips": r.ExtIPs, + "gpu": r.GPU, + "ram": r.RAM, + "seps": flattenAccountSeps(r.SEPs), + "policies": flattenAccountPolicies(r.Policies), + } + res = append(res, temp) + return res +} + +func flattenAccountPolicies(policies map[string]account.Policy) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for k, dataVal := range policies { + temp := map[string]interface{}{ + "id": k, + "disk_size": dataVal.DiskSize, + "disk_size_max": dataVal.DiskSizeMax, + "seps": flattenAccountSeps(dataVal.SEPs), + } + res = append(res, temp) + } + return res +} + +func flattenAccAcl(acls []account.ACLWithEmails) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(acls)) + for _, acls := range acls { + tempEmails := make([]string, 0, len(acls.Emails)) + for _, email := range acls.Emails { + tempEmails = append(tempEmails, email) + } + + temp := map[string]interface{}{ + "emails": tempEmails, + "explicit": acls.Explicit, + "guid": acls.GUID, + "right": acls.Right, + "status": acls.Status, + "type": acls.Type, + "user_group_id": acls.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenRgResourceLimits(rl account.ResourceLimits) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cu_c": rl.CuC, + "cu_d": rl.CuD, + "cu_dm": rl.CuDM, + "cu_i": rl.CuI, + "cu_m": rl.CuM, + "gpu_units": rl.GPUUnits, + "storage_policy": flattenSTPolicy(rl.StoragePolicies), + } + res = append(res, temp) + + return res +} + +func flattenSTPolicy(ast []account.StoragePolicy) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ast)) + for _, item := range ast { + temp := map[string]interface{}{ + "id": item.ID, + "limit": item.Limit, + } + res = append(res, temp) + } + return res +} + +func flattenRgAcl(rgAcls []account.ACL) []map[string]interface{} { + res := make([]map[string]interface{}, len(rgAcls)) + for _, rgAcl := range rgAcls { + temp := map[string]interface{}{ + "explicit": rgAcl.Explicit, + "guid": rgAcl.GUID, + "right": rgAcl.Right, + "status": rgAcl.Status, + "type": rgAcl.Type, + "user_group_id": rgAcl.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenListDeleted(al *account.ListAccounts) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(al.Data)) + for _, acc := range al.Data { + temp := map[string]interface{}{ + "dc_location": acc.DCLocation, + "acl": flattenRgAcl(acc.ACL), + "company": acc.Company, + "companyurl": acc.CompanyURL, + "compute_features": acc.ComputeFeatures, + "cpu_allocation_parameter": acc.CPUAllocationParameter, + "cpu_allocation_ratio": acc.CPUAllocationRatio, + "created_by": acc.CreatedBy, + "created_time": acc.CreatedTime, + "deactivation_time": acc.DeactivationTime, + "desc": acc.Description, + "deleted_by": acc.DeletedBy, + "deleted_time": acc.DeletedTime, + "displayname": acc.DisplayName, + "guid": acc.GUID, + "account_id": acc.ID, + "account_name": acc.Name, + "resource_limits": flattenRgResourceLimits(acc.ResourceLimits), + "resource_types": acc.ResTypes, + "send_access_emails": acc.SendAccessEmails, + "status": acc.Status, + "storage_policy_ids": acc.StoragePolicyIDs, + "uniq_pools": acc.UniqPools, + "default_zone_id": acc.DefaultZoneID, + "zone_ids": acc.ZoneIDs, + "updated_by": acc.UpdatedBy, + "updated_time": acc.UpdatedTime, + "version": acc.Version, + "vins": acc.VINS, + } + res = append(res, temp) + } + return res +} + +func flattenAccountList(al *account.ListAccounts) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(al.Data)) + for _, acc := range al.Data { + temp := map[string]interface{}{ + "dc_location": acc.DCLocation, + "acl": flattenRgAcl(acc.ACL), + "company": acc.Company, + "companyurl": acc.CompanyURL, + "compute_features": acc.ComputeFeatures, + "cpu_allocation_parameter": acc.CPUAllocationParameter, + "cpu_allocation_ratio": acc.CPUAllocationRatio, + "created_by": acc.CreatedBy, + "created_time": acc.CreatedTime, + "deactivation_time": acc.DeactivationTime, + "desc": acc.Description, + "deleted_by": acc.DeletedBy, + "deleted_time": acc.DeletedTime, + "displayname": acc.DisplayName, + "guid": acc.GUID, + "account_id": acc.ID, + "account_name": acc.Name, + "resource_limits": flattenRgResourceLimits(acc.ResourceLimits), + "resource_types": acc.ResTypes, + "send_access_emails": acc.SendAccessEmails, + "status": acc.Status, + "storage_policy_ids": acc.StoragePolicyIDs, + "uniq_pools": acc.UniqPools, + "default_zone_id": acc.DefaultZoneID, + "zone_ids": acc.ZoneIDs, + "updated_by": acc.UpdatedBy, + "updated_time": acc.UpdatedTime, + "version": acc.Version, + "vins": acc.VINS, + } + res = append(res, temp) + } + return res +} + +func flattenAccountAuditsList(aal account.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(aal)) + for _, aa := range aal { + temp := map[string]interface{}{ + "call": aa.Call, + "responsetime": aa.ResponseTime, + "statuscode": aa.StatusCode, + "timestamp": aa.Timestamp, + "user": aa.User, + } + res = append(res, temp) + } + return res +} + +func flattenAccountComputesList(acl *account.ListComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(acl.Data)) + for _, acc := range acl.Data { + temp := map[string]interface{}{ + "account_id": acc.AccountID, + "account_name": acc.AccountName, + "cpus": acc.CPUs, + "created_by": acc.CreatedBy, + "created_time": acc.CreatedTime, + "deleted_by": acc.DeletedBy, + "deleted_time": acc.DeletedTime, + "compute_id": acc.ID, + "compute_name": acc.Name, + "ram": acc.RAM, + "registered": acc.Registered, + "rg_id": acc.RGID, + "rg_name": acc.RgName, + "status": acc.Status, + "tech_status": acc.TechStatus, + "total_disks_size": acc.TotalDisksSize, + "updated_by": acc.UpdatedBy, + "updated_time": acc.UpdatedTime, + "user_managed": acc.UserManaged, + "vins_connected": acc.VINSConnected, + } + res = append(res, temp) + } + return res +} + +func flattenAccountDisksList(adl *account.ListDisks) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(adl.Data)) + for _, ad := range adl.Data { + temp := map[string]interface{}{ + "disk_id": ad.ID, + "disk_name": ad.Name, + "pool_name": ad.Pool, + "sep_id": ad.SepID, + "shareable": ad.Shareable, + "size_max": ad.SizeMax, + "type": ad.Type, + } + res = append(res, temp) + } + return res +} + +func flattenAccountFlipGroupsList(afgl *account.ListFLIPGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(afgl.Data)) + for _, afg := range afgl.Data { + temp := map[string]interface{}{ + "account_id": afg.AccountID, + "client_type": afg.ClientType, + "conn_type": afg.ConnType, + "created_by": afg.CreatedBy, + "created_time": afg.CreatedTime, + "default_gw": afg.DefaultGW, + "deleted_by": afg.DeletedBy, + "deleted_time": afg.DeletedTime, + "desc": afg.Description, + "gid": afg.GID, + "guid": afg.GUID, + "fg_id": afg.ID, + "ip": afg.IP, + "milestones": afg.Milestones, + "fg_name": afg.Name, + "net_id": afg.NetID, + "net_type": afg.NetType, + "netmask": afg.Netmask, + "status": afg.Status, + "updated_by": afg.UpdatedBy, + "updated_time": afg.UpdatedTime, + } + res = append(res, temp) + } + return res +} + +func flattenAccountVinsList(avl *account.ListVINS) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(avl.Data)) + for _, av := range avl.Data { + temp := map[string]interface{}{ + "account_id": av.AccountID, + "account_name": av.AccountName, + "computes": av.Computes, + "created_by": av.CreatedBy, + "created_time": av.CreatedTime, + "deleted_by": av.DeletedBy, + "deleted_time": av.DeletedTime, + "external_ip": av.ExternalIP, + "extnet_id": av.ExtnetId, + "free_ips": av.FreeIPs, + "vin_id": av.ID, + "vin_name": av.Name, + "network": av.Network, + "pri_vnf_dev_id": av.PriVNFDevID, + "rg_id": av.RGID, + "rg_name": av.RGName, + "status": av.Status, + "updated_by": av.UpdatedBy, + "updated_time": av.UpdatedTime, + } + res = append(res, temp) + } + return res +} + +func flattenResourceConsumption(d *schema.ResourceData, acc *account.RecordResourceConsumption) { + d.Set("account_id", acc.AccountID) + d.Set("consumed", flattenAccResource(acc.Consumed)) + d.Set("reserved", flattenAccResource(acc.Reserved)) + d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits)) +} + +func flattenAccountSeps(seps map[string]map[string]account.DiskUsage) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(seps)) + for sepKey, sepVal := range seps { + for dataKey, dataVal := range sepVal { + temp := map[string]interface{}{ + "sep_id": sepKey, + "data_name": dataKey, + "disk_size": dataVal.DiskSize, + "disk_size_max": dataVal.DiskSizeMax, + } + res = append(res, temp) + } + } + return res +} + +func flattenAccResourceConsumption(lrc *account.ListResources) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(lrc.Data)) + for _, rc := range lrc.Data { + temp := map[string]interface{}{ + "consumed": flattenAccResource(rc.Consumed), + "reserved": flattenAccResource(rc.Reserved), + "account_id": rc.AccountID, + } + res = append(res, temp) + } + return res +} + +func flattenEnabled(status string) bool { + return status == "CONFIRMED" +} + +func flattenZones(zones []account.ZoneID) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, zone := range zones { + temp := map[string]interface{}{ + "id": zone.ID, + "name": zone.Name, + } + res = append(res, temp) + } + return res +} + +func flattenZonesInResource(zones []account.ZoneID) []int64 { + res := make([]int64, 0) + for _, zone := range zones { + res = append(res, zone.ID) + } + return res +} diff --git a/internal/service/cloudbroker/account/resource_account.go b/internal/service/cloudbroker/account/resource_account.go new file mode 100644 index 00000000..53a62ddb --- /dev/null +++ b/internal/service/cloudbroker/account/resource_account.go @@ -0,0 +1,474 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + "fmt" + "strings" + "time" + + //"log" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourseAccountCreate") + + c := m.(*controller.ControllerCfg) + + req := account.CreateRequest{ + Name: d.Get("account_name").(string), + Username: d.Get("username").(string), + } + + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + + if zoneID, ok := d.GetOk("default_zone_id"); ok { + req.DefaultZoneID = uint64(zoneID.(int)) + } + + if emailaddress, ok := d.GetOk("emailaddress"); ok { + req.EmailAddress = emailaddress.(string) + } + + if sendAccessEmails, ok := d.GetOk("send_access_emails"); ok { + req.SendAccessEmails = sendAccessEmails.(bool) + } + + if uniqPools, ok := d.GetOk("uniq_pools"); ok { + uniqPools := uniqPools.([]interface{}) + for _, pool := range uniqPools { + req.UniqPools = append(req.UniqPools, pool.(string)) + } + } + + if zones, ok := d.GetOk("zone_ids"); ok { + zones := zones.([]interface{}) + for _, zone := range zones { + req.ZoneIDs = append(req.ZoneIDs, uint64(zone.(int))) + } + } + + if resLimits, ok := d.GetOk("resource_limits"); ok { + resLimits := resLimits.([]interface{})[0] + resLimitsConv := resLimits.(map[string]interface{}) + if resLimitsConv["cu_m"] != nil { + maxMemCap := int64(resLimitsConv["cu_m"].(float64)) + if maxMemCap == 0 { + req.MaxMemoryCapacity = -1 + } else { + req.MaxMemoryCapacity = maxMemCap + } + } + if resLimitsConv["cu_dm"] != nil { + maxDiskCap := int64(resLimitsConv["cu_dm"].(float64)) + if maxDiskCap == 0 { + req.MaxVDiskCapacity = -1 + } else { + req.MaxVDiskCapacity = maxDiskCap + } + } + if resLimitsConv["cu_c"] != nil { + maxCPUCap := int64(resLimitsConv["cu_c"].(float64)) + if maxCPUCap == 0 { + req.MaxCPUCapacity = -1 + } else { + req.MaxCPUCapacity = maxCPUCap + } + } + if resLimitsConv["cu_i"] != nil { + maxNumPublicIP := int64(resLimitsConv["cu_i"].(float64)) + if maxNumPublicIP == 0 { + req.MaxNumPublicIP = -1 + } else { + req.MaxNumPublicIP = maxNumPublicIP + } + } + if resLimitsConv["gpu_units"] != nil { + gpuUnits := int64(resLimitsConv["gpu_units"].(float64)) + if gpuUnits == 0 { + req.GPUUnits = -1 + } else { + req.GPUUnits = gpuUnits + } + } + } + + if stPolicy, ok := d.GetOk("storage_policy"); ok { + sp := stPolicy.(*schema.Set).List() + storagePolicies := make([]account.StoragePolicy, 0) + for _, elem := range sp { + stPolicyVal := elem.(map[string]interface{}) + + reqStPolicy := account.StoragePolicy{ + ID: uint64(stPolicyVal["id"].(int)), + Limit: stPolicyVal["limit"].(int), + } + + storagePolicies = append(storagePolicies, reqStPolicy) + } + req.StoragePolicies = storagePolicies + + } + + if compFeaturesInterface, ok := d.GetOk("compute_features"); ok { + compFeaturesInterfaces := compFeaturesInterface.(*schema.Set).List() + + compFeatures := make([]string, 0, len(compFeaturesInterfaces)) + + for _, item := range compFeaturesInterfaces { + compFeatures = append(compFeatures, item.(string)) + } + + req.ComputeFeatures = compFeatures + } + + accountId, err := c.CloudBroker().Account().Create(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(accountId, 10)) + + var w dc.Warnings + + if users, ok := d.GetOk("users"); ok { + addedUsers := users.([]interface{}) + + for _, user := range addedUsers { + userConv := user.(map[string]interface{}) + + req := account.AddUserRequest{ + AccountID: accountId, + Username: userConv["user_id"].(string), + AccessType: userConv["access_type"].(string), + } + + _, err := c.CloudBroker().Account().AddUser(ctx, req) + if err != nil { + w.Add(err) + } + } + } + + if cpuAllocationParameter, ok := d.GetOk("cpu_allocation_parameter"); ok { + cpuAllocationParameter := cpuAllocationParameter.(string) + + req := account.SetCPUAllocationParameterRequest{ + AccountID: accountId, + StrictLoose: cpuAllocationParameter, + } + + log.Debugf("setting account cpu allocation parameter") + _, err := c.CloudBroker().Account().SetCPUAllocationParameter(ctx, req) + if err != nil { + w.Add(err) + } + } + + // if cpuAllocationRatio, ok := d.GetOk("cpu_allocation_ratio"); ok { + // cpuAllocationRatio := cpuAllocationRatio.(float64) + + // req := account.SetCPUAllocationRatioRequest{ + // AccountID: accountId, + // // Ratio: cpuAllocationRatio, + // } + + // log.Debugf("setting account cpu allocation ratio") + // _, err := c.CloudBroker().Account().SetCPUAllocationRatio(ctx, req) + // if err != nil { + // w.Add(err) + // } + // } + + if !d.Get("enable").(bool) { + _, err := c.CloudBroker().Account().Disable(ctx, account.DisableRequest{ + AccountID: accountId, + }) + + if err != nil { + w.Add(err) + } + } + + if _, ok := d.GetOk("available_templates"); ok { + if err := utilityAccountAvailiableTemplatesUpdate(ctx, d, m, true); err != nil { + w.Add(err) + } + } + + return append(resourceAccountRead(ctx, d, m), w.Get()...) +} + +func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccountRead") + + acc, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenResourceAccount(d, acc) + + return nil +} + +func resourceAccountDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccountDelete") + + accountData, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := account.DeleteRequest{ + AccountID: accountData.ID, + Permanently: d.Get("permanently").(bool), + Name: d.Get("account_name").(string), + } + + taskID, err := c.CloudBroker().Account().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskID, `"`), + } + + for { + time.Sleep(time.Second * 5) + task, err := c.CloudBroker().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceAccountDelete: delete account - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot delete account: %v", task.Error)) + } + break + } + } + + d.SetId("") + + return nil +} + +func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccountUpdate") + + c := m.(*controller.ControllerCfg) + + acc, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + + hasChanged := false + + switch acc.Status { + case status.Destroyed: + d.SetId("") + // return resourceAccountCreate(ctx, d, m) + return diag.Errorf("The resource cannot be updated because it has been destroyed") + case status.Destroying: + return diag.Errorf("The account is in progress with status: %s", acc.Status) + case status.Deleted: + if d.Get("restore").(bool) { + taskID, err := c.CloudBroker().Account().Restore(ctx, account.RestoreRequest{ + AccountID: accountId, + }) + + if err != nil { + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskID, `"`), + } + + for { + time.Sleep(time.Second * 5) + task, err := c.CloudBroker().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceAccountUpdate: restore account - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot restore account: %v", task.Error)) + } + break + } + } + if _, ok := d.GetOk("enable"); ok { + if err := utilityAccountEnableUpdate(ctx, d, m, acc); err != nil { + return diag.FromErr(err) + } + } + hasChanged = true + } + case status.Disabled: + log.Debugf("The account is in status: %s, troubles may occur with update. Please, enable account first.", acc.Status) + case status.Confirmed: + } + + if hasChanged { + acc, err = utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChange("enable") { + if err := utilityAccountEnableUpdate(ctx, d, m, acc); err != nil { + return diag.FromErr(err) + } + } + + needUpdateSP := false + if d.HasChange("storage_policy") { + needUpdate, err := utilityAccountUpdateStPolicy(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + needUpdateSP = needUpdate + } + + if d.HasChanges("account_name", "send_access_emails", "uniq_pools", "resource_limits", "desc", "default_zone_id") || needUpdateSP { + if err := utilityAccountUpdate(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("cpu_allocation_parameter") { + if err := utilityAccountCPUParameterUpdate(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("cpu_allocation_ratio") { + if err := utilityAccountCPURatioUpdate(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("users") { + if err := utilityAccountUsersUpdate(ctx, d, m, acc); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("available_templates") { + if err := utilityAccountAvailiableTemplatesUpdate(ctx, d, m, false); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("compute_features") { + if err := utilityAccountComputeFeaturesUpdate(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("zone_ids") { + old, new := d.GetChange("zone_ids") + + toRemoveSet := old.(*schema.Set).Difference(new.(*schema.Set)) + toAddSet := new.(*schema.Set).Difference(old.(*schema.Set)) + + if len(toAddSet.List()) > 0 { + if err := utilityZoneIDsAdd(ctx, d, m, toAddSet); err != nil { + return diag.FromErr(err) + } + } + if len(toRemoveSet.List()) > 0 { + if err := utilityZoneIDsRemove(ctx, d, m, toRemoveSet); err != nil { + return diag.FromErr(err) + } + } + + } + + return resourceAccountRead(ctx, d, m) +} + +func ResourceAccount() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceAccountCreate, + ReadContext: resourceAccountRead, + UpdateContext: resourceAccountUpdate, + DeleteContext: resourceAccountDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceAccountSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/account/schema.go b/internal/service/cloudbroker/account/schema.go new file mode 100644 index 00000000..52b52d97 --- /dev/null +++ b/internal/service/cloudbroker/account/schema.go @@ -0,0 +1,2390 @@ +package account + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceAccountSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_name": { + Type: schema.TypeString, + Required: true, + Description: "account name", + }, + "username": { + Type: schema.TypeString, + Required: true, + Description: "username of owner the account", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Description: "description", + }, + "emailaddress": { + Type: schema.TypeString, + Optional: true, + Description: "email", + }, + "default_zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "email", + }, + "send_access_emails": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "if true send emails when a user is granted access to resources", + }, + "zone_ids": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "uniq_pools": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "users": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "user_id": { + Type: schema.TypeString, + Required: true, + }, + "access_type": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "set cpu allocation parameter", + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + Description: "set cpu allocation ratio", + }, + "available_templates": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Share images with account", + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + Description: "restore a deleted account", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "whether to completely delete the account", + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "enable/disable account", + }, + "resource_limits": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "storage_policy": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Required: true, + }, + "limit": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + "compute_features": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"hugepages", "numa", "cpupin", "vfnic", "dpdk", "changemac", "trunk"}, true), + }, + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "dc_location": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "emails": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "company": { + Type: schema.TypeString, + Computed: true, + }, + "companyurl": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deactivation_time": { + Type: schema.TypeFloat, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "displayname": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "resource_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } +} + +func dataSourceAccountAuditsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "call": { + Type: schema.TypeString, + Computed: true, + }, + "responsetime": { + Type: schema.TypeFloat, + Computed: true, + }, + "statuscode": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } + return res +} + +func dataSourceAccountComputesListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by compute ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by compute name", + }, + "rg_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by RG name", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by tech. status", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by IP address", + }, + "extnet_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by extnet name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by extnet ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "cpus": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "total_disks_size": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vins_connected": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceAccountListDeletedSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "acl": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by ACL", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dc_location": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "company": { + Type: schema.TypeString, + Computed: true, + }, + "companyurl": { + Type: schema.TypeString, + Computed: true, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deactivation_time": { + Type: schema.TypeFloat, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "displayname": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "resource_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "send_access_emails": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "default_zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "zone_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceAccountDisksListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "disk_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by disk ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by disk name", + }, + "disk_max_size": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by disk max size", + }, + "type": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by disk type", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + }, + "pool_name": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceAccountFlipGroupsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ViNS ID", + }, + "vins_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by ViNS name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by extnet ID", + }, + "by_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by IP", + }, + "flipgroup_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by flipgroup ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "fg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "fg_name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceAccountResourceConsumptionGetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + }, + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disksize": { + Type: schema.TypeFloat, + Computed: true, + }, + "disksizemax": { + Type: schema.TypeFloat, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "policies": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disksize": { + Type: schema.TypeFloat, + Computed: true, + }, + "disksizemax": { + Type: schema.TypeFloat, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "policies": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + } + + return res +} + +func dataSourceAccountListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "acl": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by ACL", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dc_location": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "company": { + Type: schema.TypeString, + Computed: true, + }, + "companyurl": { + Type: schema.TypeString, + Computed: true, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deactivation_time": { + Type: schema.TypeFloat, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "displayname": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "default_zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "resource_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "send_access_emails": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "zone_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceAccountResourceConsumptionListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disksize": { + Type: schema.TypeFloat, + Computed: true, + }, + "disksizemax": { + Type: schema.TypeFloat, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "policies": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disksize": { + Type: schema.TypeFloat, + Computed: true, + }, + "disksizemax": { + Type: schema.TypeFloat, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "policies": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceAccountRGListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ViNS ID", + }, + "vm_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by VM ID", + }, + + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "started": { + Type: schema.TypeInt, + Computed: true, + }, + "stopped": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "resources": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disksize": { + Type: schema.TypeFloat, + Computed: true, + }, + "disksizemax": { + Type: schema.TypeInt, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disksize": { + Type: schema.TypeInt, + Computed: true, + }, + "disksizemax": { + Type: schema.TypeInt, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disksize": { + Type: schema.TypeInt, + Computed: true, + }, + "disksizemax": { + Type: schema.TypeInt, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vinses": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Optional: true, + }, + } + return res +} + +func dataSourceAccountVinsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the account", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ViNS ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by external IP", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "Search Result", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "computes": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "vin_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vin_name": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "pri_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceAccountSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + }, + "dc_location": { + Type: schema.TypeString, + Computed: true, + }, + "default_zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "emails": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "company": { + Type: schema.TypeString, + Computed: true, + }, + "companyurl": { + Type: schema.TypeString, + Computed: true, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deactivation_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "displayname": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "resource_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "send_access_emails": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } +} + +func dataSourceAccountAvailableTemplatesListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } + return res +} diff --git a/internal/service/cloudbroker/account/utility_account.go b/internal/service/cloudbroker/account/utility_account.go new file mode 100644 index 00000000..efd978c4 --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account.go @@ -0,0 +1,571 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + "fmt" + "strconv" + "strings" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.RecordAccount, error) { + c := m.(*controller.ControllerCfg) + + accountID := d.Get("account_id").(int) + + req := account.GetRequest{} + + if d.Id() == "" { + req.AccountID = uint64(accountID) + } else { + req.AccountID, _ = strconv.ParseUint(d.Id(), 10, 64) + } + + log.Debugf("utilityAccountCheckPresence: load account") + account, err := c.CloudBroker().Account().Get(ctx, req) + if err != nil { + return nil, err + } + + return account, nil +} + +func utilityAccountEnableUpdate(ctx context.Context, d *schema.ResourceData, m interface{}, acc *account.RecordAccount) error { + c := m.(*controller.ControllerCfg) + + enable := d.Get("enable").(bool) + + if enable && acc.Status == status.Disabled { + _, err := c.CloudBroker().Account().Enable(ctx, account.EnableRequest{ + AccountID: acc.ID, + }) + + if err != nil { + return err + } + } else if !enable && acc.Status == status.Confirmed { + _, err := c.CloudBroker().Account().Disable(ctx, account.DisableRequest{ + AccountID: acc.ID, + }) + + if err != nil { + return err + } + } + + return nil +} + +func utilityAccountCPUParameterUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + + cpuAllocationParameter := d.Get("cpu_allocation_parameter").(string) + + _, err := c.CloudBroker().Account().SetCPUAllocationParameter(ctx, account.SetCPUAllocationParameterRequest{ + AccountID: accountId, + StrictLoose: cpuAllocationParameter, + }) + if err != nil { + return err + } + + return nil +} + +func utilityAccountCPURatioUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + + // cpuAllocacationRatio := d.Get("cpu_allocation_ratio").(float64) + + _, err := c.CloudBroker().Account().SetCPUAllocationRatio(ctx, account.SetCPUAllocationRatioRequest{ + AccountID: accountId, + // Ratio: cpuAllocacationRatio, + }) + if err != nil { + return err + } + + return nil +} + +func utilityAccountUsersUpdate(ctx context.Context, d *schema.ResourceData, m interface{}, acc *account.RecordAccount) error { + c := m.(*controller.ControllerCfg) + + deletedUsers := make([]interface{}, 0) + addedUsers := make([]interface{}, 0) + updatedUsers := make([]interface{}, 0) + + old, new := d.GetChange("users") + oldConv := old.([]interface{}) + newConv := new.([]interface{}) + for _, el := range oldConv { + if !isContainsUser(newConv, el) { + deletedUsers = append(deletedUsers, el) + } + } + + for _, el := range newConv { + if !isContainsUser(oldConv, el) { + duplicate := false + for _, user := range acc.ACL { + if user.UserGroupID == el.(map[string]interface{})["user_id"].(string) { + duplicate = true + } + } + if !duplicate { + addedUsers = append(addedUsers, el) + } else if isChangedUser(oldConv, el) { + updatedUsers = append(updatedUsers, el) + } + } + } + for _, user := range deletedUsers { + userConv := user.(map[string]interface{}) + + _, err := c.CloudBroker().Account().DeleteUser(ctx, account.DeleteUserRequest{ + AccountID: acc.ID, + UserName: userConv["user_id"].(string), + }) + + if err != nil { + return err + } + } + + for _, user := range addedUsers { + userConv := user.(map[string]interface{}) + + _, err := c.CloudBroker().Account().AddUser(ctx, account.AddUserRequest{ + AccountID: acc.ID, + Username: userConv["user_id"].(string), + AccessType: strings.ToUpper(userConv["access_type"].(string)), + }) + + if err != nil { + return err + } + } + + for _, user := range updatedUsers { + userConv := user.(map[string]interface{}) + + _, err := c.CloudBroker().Account().UpdateUser(ctx, account.UpdateUserRequest{ + AccountID: acc.ID, + UserID: userConv["user_id"].(string), + AccessType: strings.ToUpper(userConv["access_type"].(string)), + }) + + if err != nil { + return err + } + } + + return nil +} + +func utilityAccountUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + + req := account.UpdateRequest{ + AccountID: accountId, + SendAccessEmails: d.Get("send_access_emails").(bool), + } + + if d.HasChange("account_name") { + req.Name = d.Get("account_name").(string) + } + + if d.HasChange("desc") { + req.Description = d.Get("desc").(string) + } + + if d.HasChange("default_zone_id") { + req.DefaultZoneID = uint64(d.Get("default_zone_id").(int)) + } + + if d.HasChange("uniq_pools") { + uniqPools := d.Get("uniq_pools").([]interface{}) + + for _, pool := range uniqPools { + req.UniqPools = append(req.UniqPools, pool.(string)) + } + } + + if d.HasChange("resource_limits") { + resLimit := d.Get("resource_limits").([]interface{})[0] + resLimitConv := resLimit.(map[string]interface{}) + + if resLimitConv["cu_m"] != nil { + maxMemCap := int(resLimitConv["cu_m"].(float64)) + if maxMemCap == 0 { + req.MaxMemoryCapacity = -1 + } else { + req.MaxMemoryCapacity = int64(maxMemCap) + } + } + if resLimitConv["cu_dm"] != nil { + maxDiskCap := int(resLimitConv["cu_dm"].(float64)) + if maxDiskCap == 0 { + req.MaxVDiskCapacity = -1 + } else { + req.MaxVDiskCapacity = int64(maxDiskCap) + } + } + if resLimitConv["cu_c"] != nil { + maxCPUCap := int(resLimitConv["cu_c"].(float64)) + if maxCPUCap == 0 { + req.MaxCPUCapacity = -1 + } else { + req.MaxCPUCapacity = int64(maxCPUCap) + } + } + if resLimitConv["cu_i"] != nil { + maxNumPublicIP := int(resLimitConv["cu_i"].(float64)) + if maxNumPublicIP == 0 { + req.MaxNumPublicIP = -1 + } else { + req.MaxNumPublicIP = int64(maxNumPublicIP) + } + } + if resLimitConv["gpu_units"] != nil { + gpuUnits := int(resLimitConv["gpu_units"].(float64)) + if gpuUnits == 0 { + req.GPUUnits = -1 + } else { + req.GPUUnits = int64(gpuUnits) + } + } + } + + _, _, updateStPolicy := utilityGetStoragePolicyUpdate(ctx, d, m) + if len(updateStPolicy) != 0 { + storagePolicies := make([]account.StoragePolicy, 0, len(updateStPolicy)) + for _, stPolicyVal := range updateStPolicy { + reqStPolicy := account.StoragePolicy{ + ID: uint64(stPolicyVal["id"].(int)), + Limit: stPolicyVal["limit"].(int), + } + + storagePolicies = append(storagePolicies, reqStPolicy) + } + req.StoragePolicies = storagePolicies + } + + _, err := c.CloudBroker().Account().Update(ctx, req) + if err != nil { + return err + } + + return nil +} + +func utilityAccountUpdateStPolicy(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + + addSP, delSP, updateSP := utilityGetStoragePolicyUpdate(ctx, d, m) + needUpdate := len(updateSP) > 0 + + if len(addSP) > 0 { + for _, spMap := range addSP { + req := account.AddStoragePolicyRequest{ + AccountID: accountId, + StoragePolicyID: uint64(spMap["id"].(int)), + Limit: spMap["limit"].(int), + } + log.Debugf("utilityAccountUpdateStPolicy: starting to add storage policy ID:%d for account %d", req.StoragePolicyID, req.AccountID) + _, err := c.CloudBroker().Account().AddStoragePolicy(ctx, req) + if err != nil { + return needUpdate, err + } + } + } + + if len(delSP) > 0 { + for _, spMap := range delSP { + req := account.DelStoragePolicyRequest{ + AccountID: accountId, + StoragePolicyID: uint64(spMap["id"].(int)), + } + log.Debugf("utilityAccountUpdateStPolicy: starting to delete storage policy ID:%d from account %d", req.StoragePolicyID, req.AccountID) + _, err := c.CloudBroker().Account().DelStoragePolicy(ctx, req) + if err != nil { + return needUpdate, err + } + } + } + + return needUpdate, nil +} + +func utilityGetStoragePolicyUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) (added, deleted, updated []map[string]interface{}) { + added = make([]map[string]interface{}, 0) + deleted = make([]map[string]interface{}, 0) + updated = make([]map[string]interface{}, 0) + oldSet, newSet := d.GetChange("storage_policy") + oldList := oldSet.(*schema.Set).List() + newList := newSet.(*schema.Set).List() + + for _, oldSP := range oldList { + oldMap := oldSP.(map[string]interface{}) + found := false + for _, newSP := range newList { + newMap := newSP.(map[string]interface{}) + if oldMap["id"] == newMap["id"] { + found = true + if oldMap["limit"] != newMap["limit"] { + updated = append(added, newMap) + } + break + } + if found { + break + } + } + if found { + continue + } + deleted = append(deleted, oldMap) + } + + for _, newSP := range newList { + newMap := newSP.(map[string]interface{}) + found := false + for _, oldSP := range oldList { + oldMap := oldSP.(map[string]interface{}) + if oldMap["id"] == newMap["id"] { + found = true + break + } + } + if found { + continue + } + added = append(added, newMap) + } + + return +} + +func utilityAccountAvailiableTemplatesUpdate(ctx context.Context, d *schema.ResourceData, m interface{}, afterCreate bool) error { + c := m.(*controller.ControllerCfg) + + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + + if afterCreate { + addedAT := d.Get("available_templates").(*schema.Set).List() + imageIds := make([]uint64, 0, len(addedAT)) + + for _, imageId := range addedAT { + imageIds = append(imageIds, uint64(imageId.(int))) + } + + if err := ic.ExistImages(ctx, imageIds, c); err != nil { + return fmt.Errorf("can not grant access for available templates: %w", err) + } + + req := account.GrantAccessTemplatesRequest{ + AccountID: accountId, + ImageIDs: imageIds, + } + + _, err := c.CloudBroker().Account().GrantAccessTemplates(ctx, req) + if err != nil { + return err + } + + return nil + } + + oldSet, newSet := d.GetChange("available_templates") + + revokeAT := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(revokeAT) > 0 { + imageIds := make([]uint64, 0, len(revokeAT)) + + for _, imageId := range revokeAT { + imageIds = append(imageIds, uint64(imageId.(int))) + } + + if err := ic.ExistImages(ctx, imageIds, c); err != nil { + return fmt.Errorf("can not revoke access for available templates: %w", err) + } + + req := account.RevokeAccessTemplatesRequest{ + AccountID: accountId, + ImageIDs: imageIds, + } + + _, err := c.CloudBroker().Account().RevokeAccessTemplates(ctx, req) + if err != nil { + return err + } + } + + addedAT := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedAT) > 0 { + imageIds := make([]uint64, 0, len(addedAT)) + + for _, imageId := range addedAT { + imageIds = append(imageIds, uint64(imageId.(int))) + } + + if err := ic.ExistImages(ctx, imageIds, c); err != nil { + return fmt.Errorf("can not grant access for available templates: %w", err) + } + + req := account.GrantAccessTemplatesRequest{ + AccountID: accountId, + ImageIDs: imageIds, + } + + _, err := c.CloudBroker().Account().GrantAccessTemplates(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func utilityAccountComputeFeaturesUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + compFeaturesInterface := d.Get("compute_features").(*schema.Set).List() + + compFeatures := make([]string, 0, len(compFeaturesInterface)) + for _, item := range compFeaturesInterface { + compFeatures = append(compFeatures, item.(string)) + } + + req := account.UpdateComputeFeaturesRequest{ + AccountID: accountId, + ComputeFeatures: compFeatures, + } + + _, err := c.CloudBroker().Account().UpdateComputeFeatures(ctx, req) + if err != nil { + return err + } + + return nil +} + +func utilityZoneIDsAdd(ctx context.Context, d *schema.ResourceData, m interface{}, toUpdate *schema.Set) error { + c := m.(*controller.ControllerCfg) + + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + zones := toUpdate.List() + + compZones := make([]uint64, 0, len(zones)) + for _, item := range zones { + compZones = append(compZones, uint64(item.(int))) + + } + + req := account.AddZoneRequest{ + AccountID: accountId, + ZoneIDs: compZones, + } + + _, err := c.CloudBroker().Account().AddZone(ctx, req) + if err != nil { + return err + } + + return nil +} + +func utilityZoneIDsRemove(ctx context.Context, d *schema.ResourceData, m interface{}, toRemove *schema.Set) error { + c := m.(*controller.ControllerCfg) + + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + zones := toRemove.List() + + compZones := make([]uint64, 0, len(zones)) + for _, item := range zones { + compZones = append(compZones, uint64(item.(int))) + + } + + req := account.RemoveZoneRequest{ + AccountID: accountId, + ZoneIDs: compZones, + } + + _, err := c.CloudBroker().Account().RemoveZone(ctx, req) + if err != nil { + return err + } + + return nil +} + +func isContainsUser(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["user_id"].(string) == elConv["user_id"].(string) { + return true + } + } + return false +} + +func isChangedUser(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["user_id"].(string) == elConv["user_id"].(string) && + (!strings.EqualFold(elOldConv["access_type"].(string), elConv["access_type"].(string))) { + return true + } + } + return false +} diff --git a/internal/service/cloudbroker/account/utility_account_audits_list.go b/internal/service/cloudbroker/account/utility_account_audits_list.go new file mode 100644 index 00000000..b381430e --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_audits_list.go @@ -0,0 +1,57 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountAuditsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAudits, error) { + c := m.(*controller.ControllerCfg) + req := account.AuditsRequest{ + AccountID: uint64(d.Get("account_id").(int)), + } + + log.Debugf("utilityAccountAuditsListCheckPresence: load account list") + accountAuditsList, err := c.CloudBroker().Account().Audits(ctx, req) + if err != nil { + return nil, err + } + + return accountAuditsList, nil +} diff --git a/internal/service/cloudbroker/account/utility_account_available_templates_list.go b/internal/service/cloudbroker/account/utility_account_available_templates_list.go new file mode 100644 index 00000000..27d3b62b --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_available_templates_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountAvailableTemplatesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]uint64, error) { + c := m.(*controller.ControllerCfg) + + id := uint64(d.Get("account_id").(int)) + + req := account.ListAvailableTemplatesRequest{ + AccountID: id, + } + + log.Debugf("utilityAccountAvailableTemplatesListCheckPresence: load list") + accountAvailableTemplatesList, err := c.CloudBroker().Account().ListAvailableTemplates(ctx, req) + if err != nil { + return nil, err + } + + return accountAvailableTemplatesList, nil +} diff --git a/internal/service/cloudbroker/account/utility_account_computes_list.go b/internal/service/cloudbroker/account/utility_account_computes_list.go new file mode 100644 index 00000000..49b10fc2 --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_computes_list.go @@ -0,0 +1,101 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListComputes, error) { + c := m.(*controller.ControllerCfg) + req := account.ListComputesRequest{ + AccountID: uint64(d.Get("account_id").(int)), + } + + if compute_id, ok := d.GetOk("compute_id"); ok { + req.ComputeID = uint64(compute_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if rg_name, ok := d.GetOk("rg_name"); ok { + req.RGName = rg_name.(string) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if ip_address, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ip_address.(string) + } + + if extnet_name, ok := d.GetOk("extnet_name"); ok { + req.ExtNetName = extnet_name.(string) + } + + if extnet_id, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnet_id.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityAccountComputesListCheckPresence: load account list") + accountComputesList, err := c.CloudBroker().Account().ListComputes(ctx, req) + if err != nil { + return nil, err + } + + return accountComputesList, nil +} diff --git a/internal/service/cloudbroker/account/utility_account_deleted_list.go b/internal/service/cloudbroker/account/utility_account_deleted_list.go new file mode 100644 index 00000000..2a4702b8 --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_deleted_list.go @@ -0,0 +1,79 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListAccounts, error) { + c := m.(*controller.ControllerCfg) + req := account.ListDeletedRequest{} + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if acl, ok := d.GetOk("acl"); ok { + req.ACL = acl.(string) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + log.Debugf("utilityAccountDeletedListCheckPresence: load") + accountDeletedList, err := c.CloudBroker().Account().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return accountDeletedList, nil +} diff --git a/internal/service/cloudbroker/account/utility_account_disks_list.go b/internal/service/cloudbroker/account/utility_account_disks_list.go new file mode 100644 index 00000000..a74deaee --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_disks_list.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountDisksListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListDisks, error) { + c := m.(*controller.ControllerCfg) + req := account.ListDisksRequest{ + AccountID: uint64(d.Get("account_id").(int)), + } + + if disk_id, ok := d.GetOk("disk_id"); ok { + req.DiskID = uint64(disk_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if disk_max_size, ok := d.GetOk("disk_max_size"); ok { + req.DiskMaxSize = uint64(disk_max_size.(int)) + } + + if typeVal, ok := d.GetOk("type"); ok { + req.Type = typeVal.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityAccountDisksListCheckPresence: load account list") + accountDisksList, err := c.CloudBroker().Account().ListDisks(ctx, req) + if err != nil { + return nil, err + } + + return accountDisksList, nil +} diff --git a/internal/service/cloudbroker/account/utility_account_flip_groups.go b/internal/service/cloudbroker/account/utility_account_flip_groups.go new file mode 100644 index 00000000..b2dd4e14 --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_flip_groups.go @@ -0,0 +1,93 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountFlipGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListFLIPGroups, error) { + c := m.(*controller.ControllerCfg) + req := account.ListFLIPGroupsRequest{ + AccountID: uint64(d.Get("account_id").(int)), + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if vins_id, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vins_id.(int)) + } + + if vins_name, ok := d.GetOk("vins_name"); ok { + req.VINSName = vins_name.(string) + } + + if extnet_id, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnet_id.(int)) + } + + if by_ip, ok := d.GetOk("by_ip"); ok { + req.ByIP = by_ip.(string) + } + + if flipgroup_id, ok := d.GetOk("flipgroup_id"); ok { + req.FLIPGroupID = uint64(flipgroup_id.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityAccountFlipGroupsListCheckPresence") + accountFlipGroupsList, err := c.CloudBroker().Account().ListFLIPGroups(ctx, req) + if err != nil { + return nil, err + } + + return accountFlipGroupsList, nil +} diff --git a/internal/service/cloudbroker/account/utility_account_get_resource_consumption.go b/internal/service/cloudbroker/account/utility_account_get_resource_consumption.go new file mode 100644 index 00000000..60a8bf2f --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_get_resource_consumption.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountResourceConsumptionGetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.RecordResourceConsumption, error) { + c := m.(*controller.ControllerCfg) + + id := uint64(d.Get("account_id").(int)) + + req:= account.GetResourceConsumptionRequest { + AccountID: id, + } + + log.Debugf("utilityAccountResourceConsumptionGetCheckPresence: load") + accountResourceConsumptionRec, err := c.CloudBroker().Account().GetResourceConsumption(ctx, req) + if err != nil { + return nil, err + } + + return accountResourceConsumptionRec, nil +} diff --git a/internal/service/cloudbroker/account/utility_account_list.go b/internal/service/cloudbroker/account/utility_account_list.go new file mode 100644 index 00000000..c7b242aa --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_list.go @@ -0,0 +1,86 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListAccounts, error) { + c := m.(*controller.ControllerCfg) + req := account.ListRequest{} + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if acl, ok := d.GetOk("acl"); ok { + req.ACL = acl.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + log.Debugf("utilityAccountListCheckPresence: load account list") + accountList, err := c.CloudBroker().Account().List(ctx, req) + if err != nil { + return nil, err + } + + return accountList, nil +} diff --git a/internal/service/cloudbroker/account/utility_account_resource_consumption_list.go b/internal/service/cloudbroker/account/utility_account_resource_consumption_list.go new file mode 100644 index 00000000..feb995ea --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_resource_consumption_list.go @@ -0,0 +1,53 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityAccountResourceConsumptionListCheckPresence(ctx context.Context, m interface{}) (*account.ListResources, error) { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityAccountResourceConsumptionListCheckPresence: load") + accountResourceConsumptionList, err := c.CloudBroker().Account().ListResourceConsumption(ctx) + if err != nil { + return nil, err + } + + return accountResourceConsumptionList, nil +} diff --git a/internal/service/cloudbroker/account/utility_account_rg_list.go b/internal/service/cloudbroker/account/utility_account_rg_list.go new file mode 100644 index 00000000..b58cd987 --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_rg_list.go @@ -0,0 +1,89 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountRGListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListRG, error) { + c := m.(*controller.ControllerCfg) + req := account.ListRGRequest{ + AccountID: uint64(d.Get("account_id").(int)), + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if vins_id, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vins_id.(int)) + } + + if vm_id, ok := d.GetOk("vm_id"); ok { + req.VMID = uint64(vm_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + log.Debugf("utilityAccountRGListCheckPresence: load account list") + accountRGList, err := c.CloudBroker().Account().ListRG(ctx, req) + if err != nil { + return nil, err + } + + return accountRGList, nil +} diff --git a/internal/service/cloudbroker/account/utility_account_vins_list.go b/internal/service/cloudbroker/account/utility_account_vins_list.go new file mode 100644 index 00000000..8781f120 --- /dev/null +++ b/internal/service/cloudbroker/account/utility_account_vins_list.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package account + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAccountVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListVINS, error) { + c := m.(*controller.ControllerCfg) + req := account.ListVINSRequest{ + AccountID: uint64(d.Get("account_id").(int)), + } + + if vins_id, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vins_id.(int)) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if ext_ip, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = ext_ip.(string) + } + + log.Debugf("utilityAccountVinsListCheckPresence: load account list") + accountVinsList, err := c.CloudBroker().Account().ListVINS(ctx, req) + if err != nil { + return nil, err + } + + return accountVinsList, nil +} diff --git a/internal/service/cloudbroker/audit/data_source_audit.go b/internal/service/cloudbroker/audit/data_source_audit.go new file mode 100644 index 00000000..5a6d7e4d --- /dev/null +++ b/internal/service/cloudbroker/audit/data_source_audit.go @@ -0,0 +1,68 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAuditRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + auditRec, err := utilityAuditCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + flattenAudit(d, auditRec) + d.SetId(d.Get("audit_guid").(string)) + + return nil +} + +func DataSourceAudit() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAuditRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAuditSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/audit/data_source_audit_export_to_file.go b/internal/service/cloudbroker/audit/data_source_audit_export_to_file.go new file mode 100644 index 00000000..029f8e29 --- /dev/null +++ b/internal/service/cloudbroker/audit/data_source_audit_export_to_file.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + "os" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAuditsToFileRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + filePath := "audits.tar.gz" + if userPath, ok := d.GetOk("file_path"); ok { + filePath = userPath.(string) + } + + log.Debugf("dataSourceAuditsToFileRead: create file with name: %s", filePath) + file, err := os.Create(filePath) + defer file.Close() + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + data, err := utilityAuditsToFileCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + log.Debugf("dataSourceAuditsToFileRead: write data to file with name: %s", filePath) + _, err = file.Write(data) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + return nil +} + +func DataSourceAuditsToFile() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAuditsToFileRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAuditToFileSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/audit/data_source_audit_linked_jobs.go b/internal/service/cloudbroker/audit/data_source_audit_linked_jobs.go new file mode 100644 index 00000000..488078f6 --- /dev/null +++ b/internal/service/cloudbroker/audit/data_source_audit_linked_jobs.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceLinkedJobsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + linkedJobs, err := utilityLinkedJobsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenLinkedJobs(linkedJobs)) + + return nil +} + +func DataSourceAuditLinkedJobs() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLinkedJobsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceLinkedJobsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/audit/data_source_audit_list.go b/internal/service/cloudbroker/audit/data_source_audit_list.go new file mode 100644 index 00000000..9aca8223 --- /dev/null +++ b/internal/service/cloudbroker/audit/data_source_audit_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAuditListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + auditList, err := utilityAuditListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAuditList(auditList)) + d.Set("entry_count", auditList.EntryCount) + + return nil +} + +func DataSourceAuditList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAuditListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAuditListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/audit/flattens.go b/internal/service/cloudbroker/audit/flattens.go new file mode 100644 index 00000000..0fbffe3a --- /dev/null +++ b/internal/service/cloudbroker/audit/flattens.go @@ -0,0 +1,103 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/audit" +) + +func flattenAudit(d *schema.ResourceData, au *audit.RecordAudit) { + log.Debugf("flattenAudit: decoded audit guid %s", d.Get("audit_guid").(string)) + + d.Set("args", au.Arguments) + d.Set("call", au.Call) + d.Set("correlation_id", au.CorrelationID) + d.Set("guid", au.GUID) + d.Set("kwargs", au.Kwargs) + d.Set("remote_addr", au.RemoteAddr) + d.Set("responsetime", au.ResponseTime) + d.Set("result", au.Result) + d.Set("status_code", au.StatusCode) + d.Set("timestamp", au.Timestamp) + d.Set("timestamp_end", au.TimestampEnd) + d.Set("ttl", au.TTL) + d.Set("user", au.User) + d.Set("resgroup_id", au.ResgroupID) + d.Set("account_id", au.AccountID) + d.Set("compute_id", au.ComputeID) +} + +func flattenAuditList(au *audit.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(au.Data)) + for _, item := range au.Data { + temp := map[string]interface{}{ + "args": item.Args, + "call": item.Call, + "correlation_id": item.CorrelationID, + "guid": item.GUID, + "kwargs": item.Kwargs, + "remote_addr": item.RemoteAddr, + "result": item.Result, + "responsetime": item.ResponseTime, + "status_code": item.StatusCode, + "timestamp": item.Timestamp, + "timestamp_end": item.TimestampEnd, + "ttl": item.TTL, + "user": item.User, + } + res = append(res, temp) + } + return res +} + +func flattenLinkedJobs(ljl *audit.ListLinkedJobs) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + linkedJobs := *ljl + for _, item := range linkedJobs { + temp := map[string]interface{}{ + "cmd": item.CMD, + "guid": item.GUID, + "nid": item.NID, + "physical_node": item.PhysicalNode, + "state": item.State, + "time_create": item.TimeCreate, + "time_start": item.TimeStart, + "time_stop": item.TimeStop, + "timeout": item.Timeout, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudbroker/audit/schema.go b/internal/service/cloudbroker/audit/schema.go new file mode 100644 index 00000000..7fafc58e --- /dev/null +++ b/internal/service/cloudbroker/audit/schema.go @@ -0,0 +1,315 @@ +package audit + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func dataSourceAuditSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "audit_guid": { + Type: schema.TypeString, + Required: true, + Description: "audit guid", + }, + + "args": { + Type: schema.TypeString, + Computed: true, + }, + "call": { + Type: schema.TypeString, + Computed: true, + }, + "correlation_id": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "kwargs": { + Type: schema.TypeString, + Computed: true, + }, + "remote_addr": { + Type: schema.TypeString, + Computed: true, + }, + "responsetime": { + Type: schema.TypeFloat, + Computed: true, + }, + "result": { + Type: schema.TypeString, + Computed: true, + }, + "status_code": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "timestamp_end": { + Type: schema.TypeFloat, + Computed: true, + }, + "ttl": { + Type: schema.TypeString, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + "resgroup_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceAuditListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "timestamp_at": { + Type: schema.TypeInt, + Optional: true, + Description: "find all audits after point in time (unixtime)", + }, + "timestamp_to": { + Type: schema.TypeInt, + Optional: true, + Description: "find all audits before point in time (unixtime)", + }, + "user": { + Type: schema.TypeString, + Optional: true, + Description: "find by user (Mongo RegExp supported)", + }, + "call": { + Type: schema.TypeString, + Optional: true, + Description: "find by api endpoint (Mongo RegExp supported)", + }, + "min_status_code": { + Type: schema.TypeInt, + Optional: true, + Description: "find by HTTP min status code", + }, + "max_status_code": { + Type: schema.TypeInt, + Optional: true, + Description: "find by HTTP max status code", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "request_id": { + Type: schema.TypeString, + Optional: true, + Description: "request id", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "resgroup_id": { + Type: schema.TypeInt, + Optional: true, + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + }, + "service_id": { + Type: schema.TypeInt, + Optional: true, + }, + "k8s_id": { + Type: schema.TypeInt, + Optional: true, + }, + "flipgroup_id": { + Type: schema.TypeInt, + Optional: true, + }, + "lb_id": { + Type: schema.TypeInt, + Optional: true, + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + }, + "node_id": { + Type: schema.TypeInt, + Optional: true, + }, + "exclude_audit_lines": { + Type: schema.TypeBool, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "call": { + Type: schema.TypeString, + Computed: true, + }, + "correlation_id": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "responsetime": { + Type: schema.TypeFloat, + Computed: true, + }, + "status_code": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + "ttl": { + Type: schema.TypeString, + Computed: true, + }, + "args": { + Type: schema.TypeString, + Computed: true, + }, + "kwargs": { + Type: schema.TypeString, + Computed: true, + }, + "result": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp_end": { + Type: schema.TypeFloat, + Computed: true, + }, + "remote_addr": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry count", + }, + } +} + +func dataSourceLinkedJobsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "audit_guid": { + Type: schema.TypeString, + Required: true, + Description: "audit guid", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cmd": { + Type: schema.TypeString, + Computed: true, + Description: "cmd", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid", + }, + "nid": { + Type: schema.TypeInt, + Computed: true, + Description: "nid", + }, + "physical_node": { + Type: schema.TypeBool, + Computed: true, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: "state", + }, + "time_create": { + Type: schema.TypeInt, + Computed: true, + Description: "time create", + }, + "time_start": { + Type: schema.TypeInt, + Computed: true, + Description: "time start", + }, + "time_stop": { + Type: schema.TypeInt, + Computed: true, + Description: "time stop", + }, + "timeout": { + Type: schema.TypeInt, + Computed: true, + Description: "timeout", + }, + }, + }, + }, + } +} + +func dataSourceAuditToFileSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "file_path": { + Type: schema.TypeString, + Optional: true, + Description: "file path", + }, + } +} diff --git a/internal/service/cloudbroker/audit/utility_audit.go b/internal/service/cloudbroker/audit/utility_audit.go new file mode 100644 index 00000000..365149a1 --- /dev/null +++ b/internal/service/cloudbroker/audit/utility_audit.go @@ -0,0 +1,62 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/audit" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAuditCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*audit.RecordAudit, error) { + c := m.(*controller.ControllerCfg) + req := audit.GetRequest{} + + if d.Id() != "" { + req.AuditGuid = d.Id() + } else { + req.AuditGuid = d.Get("audit_guid").(string) + } + + log.Debugf("utilityAuditCheckPresence: load audit") + auditInfo, err := c.CloudBroker().Audit().Get(ctx, req) + if err != nil { + return nil, err + } + + return auditInfo, nil +} diff --git a/internal/service/cloudbroker/audit/utility_audit_export_to_file.go b/internal/service/cloudbroker/audit/utility_audit_export_to_file.go new file mode 100644 index 00000000..7aa9697c --- /dev/null +++ b/internal/service/cloudbroker/audit/utility_audit_export_to_file.go @@ -0,0 +1,54 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAuditsToFileCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]byte, error) { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityAuditToFileCheckPresence: load audit file") + auditTar, err := c.CloudBroker().Audit().ExportAuditsToFile(ctx) + if err != nil { + return nil, err + } + + return auditTar, nil +} diff --git a/internal/service/cloudbroker/audit/utility_audit_linked_jobs.go b/internal/service/cloudbroker/audit/utility_audit_linked_jobs.go new file mode 100644 index 00000000..f65f5a0f --- /dev/null +++ b/internal/service/cloudbroker/audit/utility_audit_linked_jobs.go @@ -0,0 +1,56 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/audit" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityLinkedJobsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*audit.ListLinkedJobs, error) { + c := m.(*controller.ControllerCfg) + req := audit.LinkedJobsRequest{AuditGuid: d.Get("audit_guid").(string)} + + log.Debugf("utilityLinkedJobsCheckPresence: load linked jobs") + linkedJobsList, err := c.CloudBroker().Audit().LinkedJobs(ctx, req) + if err != nil { + return nil, err + } + + return linkedJobsList, nil +} diff --git a/internal/service/cloudbroker/audit/utility_audit_list.go b/internal/service/cloudbroker/audit/utility_audit_list.go new file mode 100644 index 00000000..ab86a782 --- /dev/null +++ b/internal/service/cloudbroker/audit/utility_audit_list.go @@ -0,0 +1,120 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package audit + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/audit" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAuditListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*audit.ListAudits, error) { + c := m.(*controller.ControllerCfg) + req := audit.ListRequest{} + + if timestampAt, ok := d.GetOk("timestamp_at"); ok { + req.TimestampAt = uint64(timestampAt.(int)) + } + if timestampTo, ok := d.GetOk("timestamp_to"); ok { + req.TimestampTo = uint64(timestampTo.(int)) + } + if user, ok := d.GetOk("user"); ok { + req.User = user.(string) + } + if call, ok := d.GetOk("call"); ok { + req.Call = call.(string) + } + if minStatusCode, ok := d.GetOk("min_status_code"); ok { + req.MinStatusCode = uint64(minStatusCode.(int)) + } + if maxStatusCode, ok := d.GetOk("max_status_code"); ok { + req.MaxStatusCode = uint64(maxStatusCode.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if Page, ok := d.GetOk("page"); ok { + req.Page = uint64(Page.(int)) + } + if RequestID, ok := d.GetOk("request_id"); ok { + req.RequestID = RequestID.(string) + } + if Size, ok := d.GetOk("size"); ok { + req.Size = uint64(Size.(int)) + } + if resgroupID, ok := d.GetOk("resgroup_id"); ok { + req.RGID = uint64(resgroupID.(int)) + } + if computeID, ok := d.GetOk("compute_id"); ok { + req.ComputeID = uint64(computeID.(int)) + } + if accountID, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountID.(int)) + } + if vinsID, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vinsID.(int)) + } + if serviceID, ok := d.GetOk("service_id"); ok { + req.ServiceID = uint64(serviceID.(int)) + } + if k8sID, ok := d.GetOk("k8s_id"); ok { + req.K8SID = uint64(k8sID.(int)) + } + if flipgroupID, ok := d.GetOk("flipgroup_id"); ok { + req.FLIPGroupID = uint64(flipgroupID.(int)) + } + if lbID, ok := d.GetOk("lb_id"); ok { + req.LBID = uint64(lbID.(int)) + } + if sepID, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepID.(int)) + } + if nodeID, ok := d.GetOk("node_id"); ok { + req.NodeID = uint64(nodeID.(int)) + } + if excludeAuditLines, ok := d.GetOk("exclude_audit_lines"); ok { + req.ExcludeAuditLines = excludeAuditLines.(bool) + } + + log.Debugf("utilityAuditListCheckPresence: load audit list") + auditList, err := c.CloudBroker().Audit().List(ctx, req) + if err != nil { + return nil, err + } + + return auditList, nil +} diff --git a/internal/service/cloudbroker/disks/data_source_disk.go b/internal/service/cloudbroker/disks/data_source_disk.go new file mode 100644 index 00000000..9afc7912 --- /dev/null +++ b/internal/service/cloudbroker/disks/data_source_disk.go @@ -0,0 +1,74 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + // "net/url" + + "github.com/google/uuid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + flattenDisk(d, disk) + + return nil +} + +func DataSourceDisk() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/disks/data_source_disk_list.go b/internal/service/cloudbroker/disks/data_source_disk_list.go new file mode 100644 index 00000000..2a20b3ce --- /dev/null +++ b/internal/service/cloudbroker/disks/data_source_disk_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDiskListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskList, err := utilityDiskListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDiskList(diskList)) + d.Set("entry_count", diskList.EntryCount) + + return nil +} + +func DataSourceDiskList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/disks/data_source_disk_list_deleted.go b/internal/service/cloudbroker/disks/data_source_disk_list_deleted.go new file mode 100644 index 00000000..8fc88ae9 --- /dev/null +++ b/internal/service/cloudbroker/disks/data_source_disk_list_deleted.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDiskListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskList, err := utilityDiskListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDiskList(diskList)) + d.Set("entry_count", diskList.EntryCount) + + return nil +} + +func DataSourceDiskListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/disks/data_source_disk_list_unattached.go b/internal/service/cloudbroker/disks/data_source_disk_list_unattached.go new file mode 100644 index 00000000..dff88955 --- /dev/null +++ b/internal/service/cloudbroker/disks/data_source_disk_list_unattached.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Nikita Sorokin, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDiskListUnattachedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskListUnattached, err := utilityDiskListUnattachedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDiskListUnattached(diskListUnattached)) + d.Set("entry_count", diskListUnattached.EntryCount) + + return nil +} + +func DataSourceDiskListUnattached() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskListUnattachedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskListUnattachedSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/disks/data_source_disk_replication.go b/internal/service/cloudbroker/disks/data_source_disk_replication.go new file mode 100644 index 00000000..4fdab025 --- /dev/null +++ b/internal/service/cloudbroker/disks/data_source_disk_replication.go @@ -0,0 +1,90 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceDiskReplicationRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("dataSourceDiskReplicationRead: called for disk with ID: %s", d.Id()) + c := m.(*controller.ControllerCfg) + + req := disks.ReplicationStatusRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + } + + status, err := c.CloudAPI().Disks().ReplicationStatus(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + disk, err := utilityDiskReplicaCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenDiskReplica(d, disk, status) + + log.Debugf("dataSourceDiskReplicationRead: read complete for disk with ID: %s", d.Id()) + + return nil +} + +func DataSourceDiskReplication() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskReplicationRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskReplicationSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/disks/data_source_disk_snapshot.go b/internal/service/cloudbroker/disks/data_source_disk_snapshot.go new file mode 100644 index 00000000..8064f4b9 --- /dev/null +++ b/internal/service/cloudbroker/disks/data_source_disk_snapshot.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + var snapshot disks.ItemSnapshot + label := d.Get("label").(string) + for _, sn := range disk.Snapshots { + if label == sn.Label { + snapshot = sn + break + } + } + if label != snapshot.Label { + return diag.Errorf("Snapshot with label \"%v\" not found", label) + } + + id := uuid.New() + d.SetId(id.String()) + + flattenDiskSnapshot(d, snapshot) + + return nil +} + +func DataSourceDiskSnapshot() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskSnapshotRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskSnapshotSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/disks/data_source_disk_snapshot_list.go b/internal/service/cloudbroker/disks/data_source_disk_snapshot_list.go new file mode 100644 index 00000000..eef364fd --- /dev/null +++ b/internal/service/cloudbroker/disks/data_source_disk_snapshot_list.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDiskSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDiskSnapshotList(disk.Snapshots)) + return nil +} + +func DataSourceDiskSnapshotList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDiskSnapshotListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDiskSnapshotListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/disks/flattens.go b/internal/service/cloudbroker/disks/flattens.go new file mode 100644 index 00000000..cc4f331f --- /dev/null +++ b/internal/service/cloudbroker/disks/flattens.go @@ -0,0 +1,344 @@ +package disks + +import ( + "encoding/json" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenDisk(d *schema.ResourceData, disk *disks.RecordDisk) { + diskAcl, _ := json.Marshal(disk.ACL) + d.Set("account_id", disk.AccountID) + d.Set("account_name", disk.AccountName) + d.Set("acl", string(diskAcl)) + d.Set("discard", disk.Discard) + d.Set("block_size", disk.BlockSize) + d.Set("boot_partition", disk.BootPartition) + d.Set("computes", flattenDiskComputes(disk.Computes)) + d.Set("created_by", disk.CreatedBy) + d.Set("created_time", disk.CreatedTime) + d.Set("deleted_by", disk.DeletedBy) + d.Set("deleted_time", disk.DeletedTime) + d.Set("desc", disk.Description) + d.Set("destruction_time", disk.DestructionTime) + d.Set("devicename", disk.DeviceName) + d.Set("disk_path", disk.DiskPath) + d.Set("gid", disk.GID) + d.Set("guid", disk.GUID) + d.Set("disk_id", disk.ID) + d.Set("image_id", disk.ImageID) + d.Set("images", disk.Images) + d.Set("independent", disk.Independent) + d.Set("iotune", flattenIOTune(disk.IOTune)) + d.Set("iqn", disk.IQN) + d.Set("login", disk.Login) + d.Set("machine_id", disk.MachineID) + d.Set("machine_name", disk.MachineName) + d.Set("milestones", disk.Milestones) + d.Set("disk_name", disk.Name) + d.Set("order", disk.Order) + d.Set("params", disk.Params) + d.Set("parent_id", disk.ParentID) + d.Set("passwd", disk.Password) + d.Set("pci_slot", disk.PCISlot) + d.Set("pool", disk.Pool) + d.Set("purge_attempts", disk.PurgeAttempts) + d.Set("present_to", disk.PresentTo) + d.Set("provision", disk.Provision) + d.Set("purge_time", disk.PurgeTime) + d.Set("replication", flattenDiskReplication(disk.Replication)) + d.Set("reality_device_number", disk.RealityDeviceNumber) + d.Set("reference_id", disk.ReferenceID) + d.Set("res_id", disk.ResID) + d.Set("res_name", disk.ResName) + d.Set("role", disk.Role) + d.Set("sep_id", disk.SEPID) + d.Set("sep_type", disk.SEPType) + d.Set("shareable", disk.Shareable) + d.Set("cache", disk.Cache) + d.Set("size_available", disk.SizeAvailable) + d.Set("size_max", disk.SizeMax) + d.Set("size_used", disk.SizeUsed) + d.Set("snapshots", flattendDiskSnapshotList(disk.Snapshots)) + d.Set("status", disk.Status) + d.Set("storage_policy_id", disk.StoragePolicyID) + d.Set("tech_status", disk.TechStatus) + d.Set("vmid", disk.VMID) + d.Set("updated_by", disk.UpdatedBy) + d.Set("updated_time", disk.UpdatedTime) + d.Set("to_clean", disk.ToClean) +} + +func flattenDiskReplica(d *schema.ResourceData, disk *disks.RecordDisk, statusReplication string) { + diskAcl, _ := json.Marshal(disk.ACL) + d.Set("account_id", disk.AccountID) + d.Set("account_name", disk.AccountName) + d.Set("acl", string(diskAcl)) + d.Set("boot_partition", disk.BootPartition) + d.Set("computes", flattenDiskComputes(disk.Computes)) + d.Set("created_time", disk.CreatedTime) + d.Set("deleted_time", disk.DeletedTime) + d.Set("desc", disk.Description) + d.Set("destruction_time", disk.DestructionTime) + d.Set("devicename", disk.DeviceName) + d.Set("disk_path", disk.DiskPath) + d.Set("gid", disk.GID) + d.Set("guid", disk.GUID) + d.Set("replica_disk_id", disk.ID) + d.Set("image_id", disk.ImageID) + d.Set("images", disk.Images) + d.Set("iotune", flattenIOTune(disk.IOTune)) + d.Set("iqn", disk.IQN) + d.Set("login", disk.Login) + d.Set("milestones", disk.Milestones) + d.Set("disk_name", disk.Name) + d.Set("order", disk.Order) + d.Set("params", disk.Params) + d.Set("parent_id", disk.ParentID) + d.Set("passwd", disk.Password) + d.Set("pci_slot", disk.PCISlot) + d.Set("pool", disk.Pool) + d.Set("purge_attempts", disk.PurgeAttempts) + d.Set("present_to", disk.PresentTo) + d.Set("purge_time", disk.PurgeTime) + d.Set("replication", flattenDiskReplication(disk.Replication)) + d.Set("reality_device_number", disk.RealityDeviceNumber) + d.Set("reference_id", disk.ReferenceID) + d.Set("res_id", disk.ResID) + d.Set("res_name", disk.ResName) + d.Set("role", disk.Role) + d.Set("sep_id", disk.SEPID) + d.Set("sep_type", disk.SEPType) + d.Set("shareable", disk.Shareable) + d.Set("cache", disk.Cache) + d.Set("size_max", disk.SizeMax) + d.Set("size_used", disk.SizeUsed) + d.Set("snapshots", flattendDiskSnapshotList(disk.Snapshots)) + d.Set("status", disk.Status) + d.Set("status_replication", statusReplication) + d.Set("tech_status", disk.TechStatus) + d.Set("vmid", disk.VMID) +} + +func flattenDiskReplication(rep disks.ItemReplication) []map[string]interface{} { + res := []map[string]interface{}{ + { + "disk_id": rep.DiskID, + "pool_id": rep.PoolID, + "role": rep.Role, + "self_volume_id": rep.SelfVolumeID, + "storage_id": rep.StorageID, + "volume_id": rep.VolumeID, + }, + } + return res +} + +func flattenDiskSnapshot(d *schema.ResourceData, snapshot disks.ItemSnapshot) { + d.Set("timestamp", snapshot.Timestamp) + d.Set("guid", snapshot.GUID) + d.Set("reference_id", snapshot.ReferenceID) + d.Set("res_id", snapshot.ResID) + d.Set("snap_set_guid", snapshot.SnapSetGUID) + d.Set("snap_set_time", snapshot.SnapSetTime) +} + +func flattenDiskComputes(computes map[string]string) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computes)) + for key, val := range computes { + tmp := map[string]interface{}{ + "compute_id": key, + "compute_name": val, + } + res = append(res, tmp) + } + return res +} + +func flattenIOTune(iot disks.IOTune) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "read_bytes_sec": iot.ReadBytesSec, + "read_bytes_sec_max": iot.ReadBytesSecMax, + "read_iops_sec": iot.ReadIOPSSec, + "read_iops_sec_max": iot.ReadIOPSSecMax, + "size_iops_sec": iot.SizeIOPSSec, + "total_bytes_sec": iot.TotalBytesSec, + "total_bytes_sec_max": iot.TotalBytesSecMax, + "total_iops_sec": iot.TotalIOPSSec, + "total_iops_sec_max": iot.TotalIOPSSecMax, + "write_bytes_sec": iot.WriteBytesSec, + "write_bytes_sec_max": iot.WriteBytesSecMax, + "write_iops_sec": iot.WriteIOPSSec, + "write_iops_sec_max": iot.WriteIOPSSecMax, + } + + res = append(res, temp) + return res +} + +func flattenDiskList(dl *disks.ListDisks) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, disk := range dl.Data { + diskAcl, _ := json.Marshal(disk.ACL) + temp := map[string]interface{}{ + "account_id": disk.AccountID, + "account_name": disk.AccountName, + "acl": string(diskAcl), + "discard": disk.Discard, + "block_size": disk.BlockSize, + "boot_partition": disk.BootPartition, + "computes": flattenDiskComputes(disk.Computes), + "created_by": disk.CreatedBy, + "created_time": disk.CreatedTime, + "deleted_by": disk.DeletedBy, + "deleted_time": disk.DeletedTime, + "desc": disk.Description, + "destruction_time": disk.DestructionTime, + "devicename": disk.DeviceName, + "disk_path": disk.DiskPath, + "gid": disk.GID, + "guid": disk.GUID, + "disk_id": disk.ID, + "image_id": disk.ImageID, + "images": disk.Images, + "independent": disk.Independent, + "iotune": flattenIOTune(disk.IOTune), + "iqn": disk.IQN, + "login": disk.Login, + "machine_id": disk.MachineID, + "machine_name": disk.MachineName, + "milestones": disk.Milestones, + "disk_name": disk.Name, + "order": disk.Order, + "params": disk.Params, + "parent_id": disk.ParentID, + "passwd": disk.Password, + "pci_slot": disk.PCISlot, + "pool": disk.Pool, + "purge_attempts": disk.PurgeAttempts, + "purge_time": disk.PurgeTime, + "present_to": disk.PresentTo, + "provision": disk.Provision, + "replication": flattenDiskReplication(disk.Replication), + "reality_device_number": disk.RealityDeviceNumber, + "reference_id": disk.ReferenceID, + "res_id": disk.ResID, + "res_name": disk.ResName, + "role": disk.Role, + "sep_id": disk.SEPID, + "sep_type": disk.SEPType, + "shareable": disk.Shareable, + "cache": disk.Cache, + "size_available": disk.SizeAvailable, + "size_max": disk.SizeMax, + "size_used": disk.SizeUsed, + "snapshots": flattendDiskSnapshotList(disk.Snapshots), + "status": disk.Status, + "storage_policy_id": disk.StoragePolicyID, + "tech_status": disk.TechStatus, + "vmid": disk.VMID, + "updated_by": disk.UpdatedBy, + "updated_time": disk.UpdatedTime, + "to_clean": disk.ToClean, + } + res = append(res, temp) + } + return res +} + +func flattendDiskSnapshotList(sl disks.ListSnapshots) []interface{} { + res := make([]interface{}, 0) + for _, snapshot := range sl { + temp := map[string]interface{}{ + "guid": snapshot.GUID, + "label": snapshot.Label, + "reference_id": snapshot.ReferenceID, + "res_id": snapshot.ResID, + "snap_set_guid": snapshot.SnapSetGUID, + "snap_set_time": snapshot.SnapSetTime, + "timestamp": snapshot.Timestamp, + } + res = append(res, temp) + } + + return res +} + +func flattenDiskListUnattached(ul *disks.ListUnattachedDisks) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, unattachedDisk := range ul.Data { + unattachedDiskAcl, _ := json.Marshal(unattachedDisk.ACL) + tmp := map[string]interface{}{ + "_meta": flattens.FlattenMeta(unattachedDisk.Meta), + "account_id": unattachedDisk.AccountID, + "account_name": unattachedDisk.AccountName, + "acl": string(unattachedDiskAcl), + "discard": unattachedDisk.Discard, + "block_size": unattachedDisk.BlockSize, + "boot_partition": unattachedDisk.BootPartition, + "created_time": unattachedDisk.CreatedTime, + "deleted_time": unattachedDisk.DeletedTime, + "desc": unattachedDisk.Description, + "destruction_time": unattachedDisk.DestructionTime, + "disk_path": unattachedDisk.DiskPath, + "gid": unattachedDisk.GID, + "guid": unattachedDisk.GUID, + "disk_id": unattachedDisk.ID, + "image_id": unattachedDisk.ImageID, + "images": unattachedDisk.Images, + "iotune": flattenIOTune(unattachedDisk.IOTune), + "iqn": unattachedDisk.IQN, + "login": unattachedDisk.Login, + "milestones": unattachedDisk.Milestones, + "disk_name": unattachedDisk.Name, + "order": unattachedDisk.Order, + "params": unattachedDisk.Params, + "parent_id": unattachedDisk.ParentID, + "passwd": unattachedDisk.Password, + "pci_slot": unattachedDisk.PCISlot, + "pool": unattachedDisk.Pool, + "present_to": unattachedDisk.PresentTo, + "provision": unattachedDisk.Provision, + "purge_attempts": unattachedDisk.PurgeAttempts, + "purge_time": unattachedDisk.PurgeTime, + "reality_device_number": unattachedDisk.RealityDeviceNumber, + "reference_id": unattachedDisk.ReferenceID, + "res_id": unattachedDisk.ResID, + "res_name": unattachedDisk.ResName, + "role": unattachedDisk.Role, + "sep_id": unattachedDisk.SEPID, + "shareable": unattachedDisk.Shareable, + "cache": unattachedDisk.Cache, + "size_max": unattachedDisk.SizeMax, + "size_used": unattachedDisk.SizeUsed, + "snapshots": flattenDiskSnapshotList(unattachedDisk.Snapshots), + "status": unattachedDisk.Status, + "tech_status": unattachedDisk.TechStatus, + "to_clean": unattachedDisk.ToClean, + "vmid": unattachedDisk.VMID, + } + res = append(res, tmp) + } + return res +} + +func flattenDiskSnapshotList(sl disks.ListSnapshots) []interface{} { + res := make([]interface{}, 0) + for _, snapshot := range sl { + temp := map[string]interface{}{ + "guid": snapshot.GUID, + "label": snapshot.Label, + "reference_id": snapshot.ReferenceID, + "res_id": snapshot.ResID, + "snap_set_guid": snapshot.SnapSetGUID, + "snap_set_time": snapshot.SnapSetTime, + "timestamp": snapshot.Timestamp, + } + res = append(res, temp) + } + + return res +} diff --git a/internal/service/cloudbroker/disks/old_schemas.go b/internal/service/cloudbroker/disks/old_schemas.go new file mode 100644 index 00000000..f9a1e751 --- /dev/null +++ b/internal/service/cloudbroker/disks/old_schemas.go @@ -0,0 +1,401 @@ +package disks + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceDiskV2() *schema.Resource { + s := resourceDiskSchemaMake() + s["blk_discard"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + return &schema.Resource{Schema: s} +} + +func resourceDiskV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + }, + "gid": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + }, + "disk_name": { + Type: schema.TypeString, + Required: true, + }, + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"D", "B", "T"}, false), + Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data, T=Temp'", + }, + + "desc": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Required: true, + }, + "ssd_size": { + Type: schema.TypeInt, + Optional: true, + }, + "iops": { + Type: schema.TypeInt, + Optional: true, + Description: "max IOPS disk can perform", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "node_ids": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "detach": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "detach disk from machine first", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "whether to completely delete the disk, works only with non attached disks", + }, + "shareable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "restore deleting disk", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "iotune": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + + "order": { + Type: schema.TypeInt, + Computed: true, + }, + "params": { + Type: schema.TypeString, + Computed: true, + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + }, + } +} diff --git a/internal/service/cloudbroker/disks/resource_check_input_values.go b/internal/service/cloudbroker/disks/resource_check_input_values.go new file mode 100644 index 00000000..c392f6ca --- /dev/null +++ b/internal/service/cloudbroker/disks/resource_check_input_values.go @@ -0,0 +1,24 @@ +package disks + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + accountID := uint64(d.Get("account_id").(int)) + + if err := ic.ExistAccount(ctx, accountID, c); err != nil { + errs = append(errs, err) + } + + return dc.ErrorsToDiagnostics(errs) +} diff --git a/internal/service/cloudbroker/disks/resource_disk.go b/internal/service/cloudbroker/disks/resource_disk.go new file mode 100644 index 00000000..8ae5adb8 --- /dev/null +++ b/internal/service/cloudbroker/disks/resource_disk.go @@ -0,0 +1,496 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + "errors" + "fmt" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" +) + +func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDiskCreate: called for disk %s", d.Get("disk_name").(string)) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + req := disks.CreateRequest{ + AccountID: uint64(d.Get("account_id").(int)), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + Name: d.Get("disk_name").(string), + Size: uint64(d.Get("size_max").(int)), + } + + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + + if sepID, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepID.(int)) + } + + if pool, ok := d.GetOk("pool"); ok { + req.Pool = pool.(string) + } + + if cache, ok := d.GetOk("cache"); ok { + req.Cache = cache.(string) + } + + if discard, ok := d.GetOk("discard"); ok { + req.Discard = discard.(string) + } + + diskID, err := c.CloudBroker().Disks().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(diskID, 10)) + d.Set("disk_id", diskID) + + w := dc.Warnings{} + + if _, ok := d.GetOk("node_ids"); ok { + log.Debugf("resourceDiskCreate: present for disk %d", d.Get("disk_id")) + if err := resourceDiskChangeNodes(ctx, d, m, true); err != nil { + w.Add(err) + } + log.Debugf("resourceDiskCreate: finished present for disk %d", d.Get("disk_id")) + } + + if _, ok := d.GetOk("block_size"); ok { + if err := resourceDiskChangeBlockSize(ctx, d, m); err != nil { + w.Add(err) + } + } + + if _, ok := d.GetOk("iotune"); ok { + if err := resourceDiskChangeIotune(ctx, d, m); err != nil { + w.Add(err) + } + } + + if shareable := d.Get("shareable"); shareable.(bool) { + if err := resourceDiskChangeShareable(ctx, d, m); err != nil { + w.Add(err) + } + } + + return append(w.Get(), resourceDiskRead(ctx, d, m)...) +} + +func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDiskRead: called for disk_id %d", d.Get("disk_id").(int)) + w := dc.Warnings{} + + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChangeState := false + + switch disk.Status { + case status.Destroyed, status.Purged: + d.Set("disk_id", 0) + d.SetId("") + return diag.Errorf("The resource cannot be read because it has been destroyed") + //return resourceDiskCreate(ctx, d, m) + case status.Deleted: + //hasChangeState = true + //if err := resourceDiskRestore(ctx, d, m); err != nil { + // w.Add(err) + //} + case status.Assigned: + case status.Modeled: + return diag.Errorf("The disk is in status: %s, please, contact support for more information", disk.Status) + case status.Creating: + case status.Created: + case status.Allocated: + case status.Unallocated: + } + + if hasChangeState { + disk, err = utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + flattenDisk(d, disk) + + return w.Get() +} + +func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDiskUpdate: called for disk_id %d", d.Get("disk_id").(int)) + c := m.(*controller.ControllerCfg) + w := dc.Warnings{} + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChangeState := false + + switch disk.Status { + case status.Destroyed, status.Purged: + d.Set("disk_id", 0) + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + //return resourceDiskCreate(ctx, d, m) + case status.Deleted: + hasChangeState = true + if err := resourceDiskRestore(ctx, d, m); err != nil { + return diag.FromErr(err) + } + case status.Assigned: + case status.Modeled: + return diag.Errorf("The disk is in status: %s, please, contact support for more information", disk.Status) + case status.Creating: + case status.Created: + case status.Allocated: + case status.Unallocated: + } + + if hasChangeState { + disk, err = utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChange("storage_policy_id") { + if err := resourceDiskChangeStoragePolicyID(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("size_max") { + oldSize, newSize := d.GetChange("size_max") + if oldSize.(int) > newSize.(int) { + return diag.FromErr(fmt.Errorf("resourceDiskUpdate: Disk ID %s - reducing disk size is not allowed", d.Id())) + } + + log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB", + d.Id(), oldSize.(int), newSize.(int)) + if err := resourceDiskChangeSize(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("disk_name") { + if err := resourceDiskChangeDiskName(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("iotune") { + if err := resourceDiskChangeIotune(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shareable") { + if err := resourceDiskChangeShareable(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("cache", "discard", "block_size") { + updateReq := disks.UpdateRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + } + if d.HasChange("cache") { + updateReq.Cache = d.Get("cache").(string) + } + if d.HasChange("discard") { + updateReq.Discard = d.Get("discard").(string) + } + if d.HasChange("block_size") { + updateReq.BlockSize = d.Get("block_size").(string) + } + if _, err := c.CloudBroker().Disks().Update(ctx, updateReq); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("node_ids") { + log.Debugf("resourceDiskUpdate: present for disk %d", d.Get("disk_id")) + if err := resourceDiskChangeNodes(ctx, d, m, false); err != nil { + w.Add(err) + } + log.Debugf("resourceDiskUpdate: finished present for disk %d", d.Get("disk_id")) + } + + return append(w.Get(), resourceDiskRead(ctx, d, m)...) +} + +func resourceDiskDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDiskDelete: called for disk_id %d", d.Get("disk_id").(int)) + c := m.(*controller.ControllerCfg) + + disk, err := utilityDiskCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + req := disks.DeleteRequest{ + DiskID: disk.ID, + Detach: d.Get("detach").(bool), + Permanently: d.Get("permanently").(bool), + } + + _, err = c.CloudBroker().Disks().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceDiskChangeIotune(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + iotuneRaw := d.Get("iotune") + diskId := uint64(d.Get("disk_id").(int)) + + iot := iotuneRaw.([]interface{})[0] + iotune := iot.(map[string]interface{}) + req := disks.LimitIORequest{ + DiskID: diskId, + ReadBytesSec: uint64(iotune["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotune["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotune["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotune["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotune["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotune["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotune["total_bytes_sec_max"].(int)), + TotalIOPSSecMax: uint64(iotune["total_iops_sec_max"].(int)), + TotalIOPSSec: uint64(iotune["total_iops_sec"].(int)), + WriteBytesSec: uint64(iotune["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotune["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotune["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotune["write_iops_sec_max"].(int)), + } + + if _, ok := iotune["total_iops_sec"]; ok { + req.IOPS = uint64(iotune["total_iops_sec"].(int)) + } + + _, err := c.CloudBroker().Disks().LimitIO(ctx, req) + return err +} + +func resourceDiskChangeShareable(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + diskId := uint64(d.Get("disk_id").(int)) + shareable := d.Get("shareable").(bool) + + if shareable { + _, err := c.CloudBroker().Disks().Share(ctx, disks.ShareRequest{DiskID: diskId}) + return err + } + + _, err := c.CloudBroker().Disks().Unshare(ctx, disks.UnshareRequest{DiskID: diskId}) + return err +} + +func resourceDiskRestore(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + req := disks.RestoreRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + } + + _, err := c.CloudBroker().Disks().Restore(ctx, req) + return err +} + +func resourceDiskChangeDiskName(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + _, err := c.CloudBroker().Disks().Rename(ctx, disks.RenameRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + Name: d.Get("disk_name").(string), + }) + return err +} + +func resourceDiskChangeSize(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + _, err := c.CloudBroker().Disks().Resize2(ctx, disks.ResizeRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + Size: uint64(d.Get("size_max").(int)), + }) + return err +} + +func resourceDiskChangeStoragePolicyID(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + _, err := c.CloudBroker().Disks().ChangeDiskStoragePolicy(ctx, disks.ChangeDiskStoragePolicyRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + }) + return err +} + +func resourceDiskChangeBlockSize(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + _, err := c.CloudBroker().Disks().Update(ctx, disks.UpdateRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + BlockSize: d.Get("block_size").(string), + }) + return err +} + +func resourceDiskChangeNodes(ctx context.Context, d *schema.ResourceData, m interface{}, afterCreate bool) error { + c := m.(*controller.ControllerCfg) + diskID := uint64(d.Get("disk_id").(int)) + presentIDs := make([]interface{}, 0) + var errs error + var oldNodes, newNodes interface{} + + if afterCreate { + nodeIDs := d.Get("node_ids").(*schema.Set).List() + presentIDs = nodeIDs + } else { + oldNodes, newNodes = d.GetChange("node_ids") + nodeIDs := (newNodes.(*schema.Set).Difference(oldNodes.(*schema.Set))).List() + presentIDs = nodeIDs + } + + for _, presentID := range presentIDs { + nodeID := uint64(presentID.(int)) + + req := disks.PresentRequest{ + DiskID: diskID, + NodeID: nodeID, + } + + _, err := c.CloudBroker().Disks().Present(ctx, req) + if err != nil { + errs = errors.Join(err) + } + } + + if afterCreate { + return errs + } + + depresentIDs := (oldNodes.(*schema.Set).Difference(newNodes.(*schema.Set))).List() + if len(depresentIDs) > 0 { + for _, depresentID := range depresentIDs { + nodeID := uint64(depresentID.(int)) + + req := disks.DepresentRequest{ + DiskID: diskID, + NodeID: nodeID, + } + + _, err := c.CloudBroker().Disks().Depresent(ctx, req) + if err != nil { + errs = errors.Join(err) + } + } + } + + return errs +} + +func ResourceDisk() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 3, + + CreateContext: resourceDiskCreate, + ReadContext: resourceDiskRead, + UpdateContext: resourceDiskUpdate, + DeleteContext: resourceDiskDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceDiskSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceDiskV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceDiskUpgradeV1, + Version: 1, + }, + { + Type: resourceDiskV2().CoreConfigSchema().ImpliedType(), + Upgrade: resourceDiskUpgradeV2, + Version: 2, + }, + }, + } +} diff --git a/internal/service/cloudbroker/disks/resource_disk_replication.go b/internal/service/cloudbroker/disks/resource_disk_replication.go new file mode 100644 index 00000000..223edd57 --- /dev/null +++ b/internal/service/cloudbroker/disks/resource_disk_replication.go @@ -0,0 +1,217 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" +) + +func resourceDiskReplicationCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskId := uint64(d.Get("disk_id").(int)) + + log.Debugf("resourceDiskReplicationCreate: called for disk with ID: %d", diskId) + + c := m.(*controller.ControllerCfg) + + err := ic.ExistDiskID(ctx, diskId, m) + if err != nil { + return diag.FromErr(err) + } + + reqCreate := disks.ReplicateRequest{ + DiskID: diskId, + Name: d.Get("disk_name").(string), + SepID: uint64(d.Get("sep_id").(int)), + PoolName: d.Get("pool_name").(string), + } + + diskReplicaId, err := c.CloudBroker().Disks().Replicate(ctx, reqCreate) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(diskReplicaId, 10)) + d.Set("replica_disk_id", diskReplicaId) + + log.Debugf("resourceDiskReplicationCreate: create replica complete for disk with ID: %d", diskId) + + warnings := dc.Warnings{} + + if start, ok := d.GetOk("start"); ok && !start.(bool) { + log.Debugf("resourceDiskReplicationCreate: replication between disk with ID: %d and replica with ID: %d, try to stop", diskId, diskReplicaId) + reqStop := disks.ReplicationStopRequest{ + DiskID: diskId, + } + _, err = c.CloudBroker().Disks().ReplicationStop(ctx, reqStop) + if err != nil { + warnings.Add(err) + } + log.Debugf("resourceDiskReplicationCreate: replication between disk with ID: %d and replica with ID: %d, stoped", diskId, diskReplicaId) + } + return append(resourceDiskReplicationRead(ctx, d, m), warnings.Get()...) +} + +func resourceDiskReplicationRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDiskReplicationRead: called for disk with ID: %s", d.Id()) + c := m.(*controller.ControllerCfg) + + req := disks.ReplicationStatusRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + } + + status, err := c.CloudBroker().Disks().ReplicationStatus(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + diskReplica, err := utilityDiskReplicaCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenDiskReplica(d, diskReplica, status) + + log.Debugf("resourceDiskReplicationRead: read complete for disk with ID: %s", d.Id()) + return nil +} + +func resourceDiskReplicationUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskId := uint64(d.Get("disk_id").(int)) + log.Debugf("resourceDiskReplicationUpdate: called for disk with ID: %d", diskId) + + err := ic.ExistDiskID(ctx, diskId, m) + if err != nil { + return diag.FromErr(err) + } + + if d.HasChange("start") { + if err := utilityDiskReplicationUpdateStartStop(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("pause") { + if err := utilityDiskReplicationUpdatePause(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("reverse") { + if err := utilityDiskReplicationUpdateReverse(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + log.Debugf("resourceDiskReplicationUpdate: read complete for disk with ID: %d", diskId) + return resourceDiskReplicationRead(ctx, d, m) +} + +func resourceDiskReplicationDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diskId := uint64(d.Get("disk_id").(int)) + log.Debugf("resourceDiskReplicationDelete: called for disk with ID: %d", diskId) + + disk, err := utilityDiskReplicaCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + + if d.Get("start").(bool) { + reqStop := disks.ReplicationStopRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + } + + log.Debugf("resourceDiskReplicationDelete: stop replication for disk with ID: %d", diskId) + _, err = c.CloudBroker().Disks().ReplicationStop(ctx, reqStop) + if err != nil { + return diag.FromErr(err) + } + log.Debugf("resourceDiskReplicationDelete: stop replication for disk with ID: %d, complete", diskId) + } + + reqDelete := disks.DeleteRequest{ + DiskID: disk.ID, + Detach: d.Get("detach").(bool), + Permanently: d.Get("permanently").(bool), + } + + log.Debugf("resourceDiskReplicationDelete: delete disk replica for disk with ID: %d", diskId) + _, err = c.CloudBroker().Disks().Delete(ctx, reqDelete) + if err != nil { + return diag.FromErr(err) + } + log.Debugf("resourceDiskReplicationDelete: delete disk replica for disk with ID: %d, complete", diskId) + + d.SetId("") + + return nil +} + +func ResourceDiskReplication() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceDiskReplicationCreate, + ReadContext: resourceDiskReplicationRead, + UpdateContext: resourceDiskReplicationUpdate, + DeleteContext: resourceDiskReplicationDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceDiskReplicationSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/disks/resource_disk_snapshot.go b/internal/service/cloudbroker/disks/resource_disk_snapshot.go new file mode 100644 index 00000000..0a48300f --- /dev/null +++ b/internal/service/cloudbroker/disks/resource_disk_snapshot.go @@ -0,0 +1,145 @@ +package disks + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceDiskSnapshotCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDiskSnapshotCreate: call for disk_id %d, label %s", + d.Get("disk_id").(int), + d.Get("label").(string)) + + _, err := utilityDiskSnapshotCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + diskId := uint64(d.Get("disk_id").(int)) + label := d.Get("label").(string) + d.SetId(fmt.Sprintf("%d#%s", diskId, label)) + + if rollback := d.Get("rollback").(bool); rollback { + err := resourceDiskSnapshotChangeRollback(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + return resourceDiskSnapshotRead(ctx, d, m) +} + +func resourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDiskSnapshotRead: snapshot id %s", d.Id()) + + snapshot, err := utilityDiskSnapshotCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenDiskSnapshot(d, snapshot) + + return nil +} + +func resourceDiskSnapshotUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDiskSnapshotUpdate: snapshot id %s", d.Id()) + + _, err := utilityDiskSnapshotCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + if d.HasChange("rollback") { + err := resourceDiskSnapshotChangeRollback(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceDiskSnapshotRead(ctx, d, m) +} + +func resourceDiskSnapshotDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDiskSnapshotDelete: snapshot id %s", d.Id()) + + _, err := utilityDiskSnapshotCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + + req := disks.SnapshotDeleteRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + Label: d.Get("label").(string), + } + + _, err = c.CloudBroker().Disks().SnapshotDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceDiskSnapshotChangeRollback(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + rollback := d.Get("rollback").(bool) + + if rollback { + label := d.Get("label").(string) + timestamp := uint64(d.Get("timestamp").(int)) + diskId := uint64(d.Get("disk_id").(int)) + + req := disks.SnapshotRollbackRequest{ + DiskID: diskId, + Label: label, + TimeStamp: timestamp, + } + + log.Debugf("resourceDiskUpdate: Snapshot rollback with label %s", label) + if _, err := c.CloudBroker().Disks().SnapshotRollback(ctx, req); err != nil { + return err + } + } + + return nil +} + +func ResourceDiskSnapshot() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceDiskSnapshotCreate, + ReadContext: resourceDiskSnapshotRead, + UpdateContext: resourceDiskSnapshotUpdate, + DeleteContext: resourceDiskSnapshotDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceDiskSnapshotSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/disks/schema.go b/internal/service/cloudbroker/disks/schema.go new file mode 100644 index 00000000..08c3c2c3 --- /dev/null +++ b/internal/service/cloudbroker/disks/schema.go @@ -0,0 +1,2989 @@ +package disks + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceDiskSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "machine_id": { + Type: schema.TypeInt, + Computed: true, + }, + "machine_name": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + }, + "order": { + Type: schema.TypeInt, + Computed: true, + }, + "params": { + Type: schema.TypeString, + Computed: true, + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "size_available": { + Type: schema.TypeFloat, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_id": { + Type: schema.TypeFloat, + Computed: true, + Description: "Storage policy ID", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + } + + return rets +} + +func dataSourceDiskListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by account name", + }, + "disk_max_size": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by max disk size", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "shared": { + Type: schema.TypeBool, + Optional: true, + Description: "Find by shared field", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the account the disks belong to", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by sep id", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Description: "Find by pool name", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Optional: true, + Description: "storage policy ID ", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by rg id", + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by compute id", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "machine_id": { + Type: schema.TypeInt, + Computed: true, + }, + "machine_name": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + }, + "order": { + Type: schema.TypeInt, + Computed: true, + }, + "params": { + Type: schema.TypeString, + Computed: true, + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "size_available": { + Type: schema.TypeFloat, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_id": { + Type: schema.TypeFloat, + Computed: true, + Description: "Storage policy ID", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceDiskListDeletedSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by account name", + }, + "disk_max_size": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by max disk size", + }, + "shared": { + Type: schema.TypeBool, + Optional: true, + Description: "Find by shared field", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the account the disks belong to", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "machine_id": { + Type: schema.TypeInt, + Computed: true, + }, + "machine_name": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + }, + "order": { + Type: schema.TypeInt, + Computed: true, + }, + "params": { + Type: schema.TypeString, + Computed: true, + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "size_available": { + Type: schema.TypeFloat, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_id": { + Type: schema.TypeFloat, + Computed: true, + Description: "Storage policy ID", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceDiskListUnattachedSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by account name", + }, + "disk_max_size": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by max disk size", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the account the disks belong to", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of SEP", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Optional: true, + Description: "storage policy ID ", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "_meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "Meta parameters", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the account the disks belong to", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the subscriber '(account') to whom this disk belongs", + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of disk partitions", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Deleted time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of disk", + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of final deletion", + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + Description: "Disk path", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk ID on the storage side", + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image ID", + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "IDs of images using the disk", + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to read per second", + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to read", + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of io read operations per second", + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of io read operations", + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Size of io operations", + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total size bytes per second", + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total size of bytes per second", + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Total number of io operations per second", + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum total number of io operations per second", + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of bytes to write per second", + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of bytes to write per second", + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of write operations per second", + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum number of write operations per second", + }, + }, + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + Description: "Disk IQN", + }, + "login": { + Type: schema.TypeString, + Computed: true, + Description: "Login to access the disk", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "Milestones", + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of disk", + }, + "order": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk order", + }, + "params": { + Type: schema.TypeString, + Computed: true, + Description: "Disk params", + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the parent disk", + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + Description: "Password to access the disk", + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the pci slot to which the disk is connected", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Description: "Pool for disk location", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of deletion attempts", + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Time of the last deletion attempt", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + Description: "Reality device number", + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the reference to the disk", + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Resource ID", + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource", + }, + "role": { + Type: schema.TypeString, + Computed: true, + Description: "Disk role", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Storage endpoint provider ID to create disk", + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + Description: "Size in GB", + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + Description: "Number of used space, in GB", + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Disk status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "Technical status of the disk", + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + Description: "Virtual Machine ID (Deprecated)", + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceDiskSnapshotListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the snapshot", + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + }, + }, + }, + } + return rets +} + +func dataSourceDiskSnapshotSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "label": { + Type: schema.TypeString, + Required: true, + Description: "Name of the snapshot", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "Snapshot time", + }, + } + return rets +} + +func resourceDiskSnapshotSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + Description: "The unique ID of the subscriber-owner of the disk", + }, + "label": { + Type: schema.TypeString, + Required: true, + //ForceNew: true, + Description: "Name of the snapshot", + }, + "rollback": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Needed in order to make a snapshot rollback", + }, + "timestamp": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Snapshot time", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the snapshot", + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + Description: "Reference to the snapshot", + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + Description: "The set snapshot ID", + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + Description: "The set time of the snapshot", + }, + } +} + +func resourceDiskSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + //ForceNew: true, + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "disk_name": { + Type: schema.TypeString, + Required: true, + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Required: true, + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "node_ids": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "detach": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "detach disk from machine first", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "whether to completely delete the disk, works only with non attached disks", + }, + "shareable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Optional: true, + Default: "none", + Description: "Cache mode for the disk", + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "restore deleting disk", + }, + "discard": { + Type: schema.TypeString, + Optional: true, + Default: "ignore", + ValidateFunc: validation.StringInSlice([]string{"unmap", "ignore"}, false), + }, + "block_size": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"512", "512e", "4k"}, false), + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "machine_id": { + Type: schema.TypeInt, + Computed: true, + }, + "machine_name": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "order": { + Type: schema.TypeInt, + Computed: true, + }, + "params": { + Type: schema.TypeString, + Computed: true, + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + } + + return rets +} + +func dataSourceDiskReplicationSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "Id of primary disk", + }, + "replica_disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "Id of secondary disk", + }, + "status_replication": { + Type: schema.TypeString, + Computed: true, + Description: "Status of replication", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_name": { + Type: schema.TypeString, + Computed: true, + }, + "order": { + Type: schema.TypeInt, + Computed: true, + }, + "params": { + Type: schema.TypeString, + Computed: true, + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return rets +} + +func resourceDiskReplicationSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "Id of primary disk", + }, + "disk_name": { + Type: schema.TypeString, + Required: true, + Description: "Name of disk replica", + }, + "sep_id": { + Type: schema.TypeInt, + Required: true, + Description: "Storage endpoint provider ID to create disk replica", + }, + "pool_name": { + Type: schema.TypeString, + Required: true, + Description: "Pool for disk location", + }, + "pause": { + Type: schema.TypeBool, + Optional: true, + Description: "Resume replication", + }, + "reverse": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Reverse replication", + }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Start/Stop replication", + }, + "detach": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Detach disk from machine first", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Delete disk permanently", + }, + + "replica_disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Id of replica disk", + }, + "status_replication": { + Type: schema.TypeString, + Computed: true, + Description: "Status of replication", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeString, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "iotune": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "order": { + Type: schema.TypeInt, + Computed: true, + }, + "params": { + Type: schema.TypeString, + Computed: true, + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return rets +} diff --git a/internal/service/cloudbroker/disks/state_upgrader.go b/internal/service/cloudbroker/disks/state_upgrader.go new file mode 100644 index 00000000..b7bc3bf8 --- /dev/null +++ b/internal/service/cloudbroker/disks/state_upgrader.go @@ -0,0 +1,28 @@ +package disks + +import ( + "context" + + log "github.com/sirupsen/logrus" +) + +func resourceDiskUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceDiskUpgradeV1: upgrading state") + rawState["present_to"] = make(map[string]uint64) + + return rawState, nil +} + +func resourceDiskUpgradeV2(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceDiskUpgradeV2: upgrading state") + if v, ok := rawState["blk_discard"].(bool); ok { + if v { + rawState["discard"] = "unmap" + } else { + rawState["discard"] = "ignore" + } + } + delete(rawState, "blk_discard") + + return rawState, nil +} diff --git a/internal/service/cloudbroker/disks/utility_disk.go b/internal/service/cloudbroker/disks/utility_disk.go new file mode 100644 index 00000000..842b8838 --- /dev/null +++ b/internal/service/cloudbroker/disks/utility_disk.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.RecordDisk, error) { + c := m.(*controller.ControllerCfg) + req := disks.GetRequest{} + + if d.Id() != "" { + diskID, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DiskID = diskID + } else { + req.DiskID = uint64(d.Get("disk_id").(int)) + } + + log.Debugf("utilityDiskCheckPresence: load disk") + disk, err := c.CloudBroker().Disks().Get(ctx, req) + if err != nil { + return nil, err + } + + return disk, nil +} diff --git a/internal/service/cloudbroker/disks/utility_disk_list.go b/internal/service/cloudbroker/disks/utility_disk_list.go new file mode 100644 index 00000000..280b8e20 --- /dev/null +++ b/internal/service/cloudbroker/disks/utility_disk_list.go @@ -0,0 +1,101 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.ListDisks, error) { + c := m.(*controller.ControllerCfg) + req := disks.ListRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if account_name, ok := d.GetOk("account_name"); ok { + req.AccountName = account_name.(string) + } + if disk_max_size, ok := d.GetOk("disk_max_size"); ok { + req.DiskMaxSize = int64(disk_max_size.(int)) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if shared, ok := d.GetOk("shared"); ok { + req.Shared = shared.(bool) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if pool, ok := d.GetOk("pool"); ok { + req.Pool = pool.(string) + } + if sepID, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepID.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if storagePolicyID, ok := d.GetOk("storage_policy_id"); ok { + req.StoragePolicyID = uint64(storagePolicyID.(int)) + } + if rgID, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgID.(int)) + } + if computeID, ok := d.GetOk("compute_id"); ok { + req.ComputeID = uint64(computeID.(int)) + } + + log.Debugf("utilityDiskListCheckPresence: load disk list") + diskList, err := c.CloudBroker().Disks().List(ctx, req) + if err != nil { + return nil, err + } + + return diskList, nil +} diff --git a/internal/service/cloudbroker/disks/utility_disk_list_deleted.go b/internal/service/cloudbroker/disks/utility_disk_list_deleted.go new file mode 100644 index 00000000..c7d11695 --- /dev/null +++ b/internal/service/cloudbroker/disks/utility_disk_list_deleted.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Nikita Sorokin, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDiskListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.ListDisks, error) { + c := m.(*controller.ControllerCfg) + req := disks.ListDeletedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if account_name, ok := d.GetOk("account_name"); ok { + req.AccountName = account_name.(string) + } + if disk_max_size, ok := d.GetOk("disk_max_size"); ok { + req.DiskMaxSize = int64(disk_max_size.(int)) + } + if shared, ok := d.GetOk("shared"); ok { + req.Shared = shared.(bool) + } + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityDiskListDeletedCheckPresence: load disk list deleted") + diskList, err := c.CloudBroker().Disks().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return diskList, nil +} diff --git a/internal/service/cloudbroker/disks/utility_disk_list_unattached.go b/internal/service/cloudbroker/disks/utility_disk_list_unattached.go new file mode 100644 index 00000000..e1e76274 --- /dev/null +++ b/internal/service/cloudbroker/disks/utility_disk_list_unattached.go @@ -0,0 +1,57 @@ +package disks + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDiskListUnattachedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.ListUnattachedDisks, error) { + c := m.(*controller.ControllerCfg) + req := disks.ListUnattachedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if account_name, ok := d.GetOk("account_name"); ok { + req.AccountName = account_name.(string) + } + if disk_max_size, ok := d.GetOk("disk_max_size"); ok { + req.DiskMaxSize = int64(disk_max_size.(int)) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if sepId, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepId.(int)) + } + if pool, ok := d.GetOk("pool"); ok { + req.Pool = pool.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if storagePolicyID, ok := d.GetOk("storage_policy_id"); ok { + req.StoragePolicyID = uint64(storagePolicyID.(int)) + } + + log.Debugf("utilityDiskListUnattachedCheckPresence: load disk Unattached list") + unattachedList, err := c.CloudBroker().Disks().ListUnattached(ctx, req) + if err != nil { + return nil, err + } + + return unattachedList, nil +} diff --git a/internal/service/cloudbroker/disks/utility_disk_replica.go b/internal/service/cloudbroker/disks/utility_disk_replica.go new file mode 100644 index 00000000..9a56aa6e --- /dev/null +++ b/internal/service/cloudbroker/disks/utility_disk_replica.go @@ -0,0 +1,174 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package disks + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDiskReplicationUpdateStartStop(ctx context.Context, d *schema.ResourceData, m interface{}) error { + diskId := uint64(d.Get("disk_id").(int)) + targetDiskId, _ := strconv.ParseUint(d.Id(), 10, 64) + + log.Debugf("utilityDiskReplicationUpdateStartStop: start update for disk replica with ID: %d", diskId) + c := m.(*controller.ControllerCfg) + + start, ok := d.GetOk("start") + + if ok && start.(bool) { + log.Debugf("utilityDiskReplicationUpdateStartStop: start disk replication from Disk with ID: %d to Disk with ID: %d", diskId, targetDiskId) + req := disks.ReplicationStartRequest{ + DiskID: diskId, + TargetDiskID: targetDiskId, + } + _, err := c.CloudBroker().Disks().ReplicationStart(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicationUpdateStartStop: start disk replication from Disk with ID: %d to Disk with ID: %d, complete", diskId, targetDiskId) + } + + if ok && !start.(bool) { + log.Debugf("utilityDiskReplicationUpdateStartStop: stop disk replication from Disk with ID: %d to Disk with ID: %d", targetDiskId, diskId) + req := disks.ReplicationStopRequest{ + DiskID: targetDiskId, + } + _, err := c.CloudBroker().Disks().ReplicationStop(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicationUpdateStartStop: stop disk replication from Disk with ID: %d to Disk with ID: %d, complete", targetDiskId, diskId) + } + + log.Debugf("utilityDiskReplicationUpdateStartStop: complete update for disk replica with ID: %d", diskId) + return nil +} + +func utilityDiskReplicationUpdatePause(ctx context.Context, d *schema.ResourceData, m interface{}) error { + diskId := uint64(d.Get("disk_id").(int)) + log.Debugf("utilityDiskReplicationUpdatePause: start update for disk replica with ID: %d", diskId) + c := m.(*controller.ControllerCfg) + + pause, ok := d.GetOk("pause") + + if ok && pause.(bool) { + log.Debugf("utilityDiskReplicationUpdatePause: pause disk replication with ID: %d", diskId) + req := disks.ReplicationSuspendRequest{ + DiskID: diskId, + } + _, err := c.CloudBroker().Disks().ReplicationSuspend(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicationUpdatePause: pause disk replication with ID: %d, complete", diskId) + } + + if ok && !pause.(bool) { + log.Debugf("utilityDiskReplicationUpdatePause: resume disk replication with ID: %d", diskId) + req := disks.ReplicationResumeRequest{ + DiskID: diskId, + } + _, err := c.CloudBroker().Disks().ReplicationResume(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicationUpdatePause: resume disk replication with ID: %d, complete", diskId) + } + + log.Debugf("utilityDiskReplicationUpdatePause: complete update for disk replica with ID: %d", diskId) + return nil +} + +func utilityDiskReplicationUpdateReverse(ctx context.Context, d *schema.ResourceData, m interface{}) error { + diskId := uint64(d.Get("disk_id").(int)) + targetDiskId, _ := strconv.ParseUint(d.Id(), 10, 64) + + log.Debugf("utilityDiskReplicaUpdateReverse: start update for disk replica with ID: %d", diskId) + c := m.(*controller.ControllerCfg) + + reverse, ok := d.GetOk("reverse") + + if ok && reverse.(bool) { + log.Debugf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d", diskId, targetDiskId) + req := disks.ReplicationReverseRequest{ + DiskID: diskId, + } + _, err := c.CloudBroker().Disks().ReplicationReverse(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d, complete", diskId, targetDiskId) + } + + if ok && !reverse.(bool) { + log.Debugf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d", targetDiskId, diskId) + req := disks.ReplicationReverseRequest{ + DiskID: targetDiskId, + } + _, err := c.CloudBroker().Disks().ReplicationReverse(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d, complete", targetDiskId, diskId) + } + + log.Debugf("utilityDiskReplicaUpdateReverse: complete update for disk replica with ID: %d", diskId) + return nil +} + +func utilityDiskReplicaCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.RecordDisk, error) { + c := m.(*controller.ControllerCfg) + + req := disks.GetRequest{} + + if d.Id() != "" { + diskId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DiskID = diskId + } else { + req.DiskID = uint64(d.Get("replica_disk_id").(int)) + } + + log.Debugf("utilityDiskReplicaCheckPresence: load disk") + disk, err := c.CloudBroker().Disks().Get(ctx, req) + if err != nil { + return nil, err + } + + return disk, nil +} diff --git a/internal/service/cloudbroker/disks/utility_disk_snapshot.go b/internal/service/cloudbroker/disks/utility_disk_snapshot.go new file mode 100644 index 00000000..1d182aab --- /dev/null +++ b/internal/service/cloudbroker/disks/utility_disk_snapshot.go @@ -0,0 +1,52 @@ +package disks + +import ( + "context" + "fmt" + log "github.com/sirupsen/logrus" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDiskSnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (disks.ItemSnapshot, error) { + log.Debugf("utilityDiskSnapshotCheckPresence: call for disk_id %d, label %s", + d.Get("disk_id").(int), + d.Get("label").(string)) + c := m.(*controller.ControllerCfg) + + req := disks.GetRequest{} + snapshot := disks.ItemSnapshot{} + + if d.Id() != "" { + arr := strings.Split(d.Id(), "#") + if len(arr) != 2 { + return snapshot, fmt.Errorf("broken state id") + } + req.DiskID, _ = strconv.ParseUint(arr[0], 10, 64) + } else { + req.DiskID = uint64(d.Get("disk_id").(int)) + } + + disk, err := c.CloudBroker().Disks().Get(ctx, req) + if err != nil { + return snapshot, err + } + + snapshots := disk.Snapshots + label := d.Get("label").(string) + for _, sn := range snapshots { + if label == sn.Label { + snapshot = sn + break + } + } + if label != snapshot.Label { + return snapshot, fmt.Errorf("snapshot with label \"%v\" not found", label) + } + + return snapshot, nil +} diff --git a/internal/service/cloudbroker/dpdknet/data_source_dpdk.go b/internal/service/cloudbroker/dpdknet/data_source_dpdk.go new file mode 100644 index 00000000..6b88eede --- /dev/null +++ b/internal/service/cloudbroker/dpdknet/data_source_dpdk.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package dpdknet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDPDKNetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + dpdk, err := utilityDPDKNetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + flattenDPDKNet(d, dpdk) + + return nil +} + +func DataSourceDPDKNet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDPDKNetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDPDKNetSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/dpdknet/data_source_dpdk_list.go b/internal/service/cloudbroker/dpdknet/data_source_dpdk_list.go new file mode 100644 index 00000000..ef067e7d --- /dev/null +++ b/internal/service/cloudbroker/dpdknet/data_source_dpdk_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package dpdknet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDPDKNetListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + dpdkList, err := utilityDPDKNetListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDPDKNetList(dpdkList)) + d.Set("entry_count", dpdkList.EntryCount) + + return nil +} + +func DataSourceDPDKNetList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDPDKNetListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDPDKNetListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/dpdknet/flattens.go b/internal/service/cloudbroker/dpdknet/flattens.go new file mode 100644 index 00000000..eb7584db --- /dev/null +++ b/internal/service/cloudbroker/dpdknet/flattens.go @@ -0,0 +1,46 @@ +package dpdknet + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + dpdk "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/dpdknet" +) + +func flattenDPDKNet(d *schema.ResourceData, dpdk *dpdk.RecordDPDKNet) { + d.Set("dpdk_id", dpdk.ID) + d.Set("account_access", dpdk.AccountAccess) + d.Set("created_time", dpdk.CreatedTime) + d.Set("desc", dpdk.Description) + d.Set("gid", dpdk.GID) + d.Set("guid", dpdk.GUID) + d.Set("name", dpdk.Name) + d.Set("rg_access", dpdk.RGAccess) + d.Set("status", dpdk.Status) + d.Set("ovs_bridge", dpdk.OVSBridge) + d.Set("vlan_id", dpdk.VlanID) + d.Set("compute_ids", dpdk.ComputeIDs) + d.Set("updated_time", dpdk.UpdatedTime) + d.Set("enable_secgroups", dpdk.EnableSecGroups) +} + +func flattenDPDKNetList(list *dpdk.ListDPDKNet) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list.Data)) + for _, dpdk := range list.Data { + temp := map[string]interface{}{ + "dpdk_id": dpdk.ID, + "account_access": dpdk.AccountAccess, + "desc": dpdk.Description, + "enable_secgroups": dpdk.EnableSecGroups, + "gid": dpdk.GID, + "guid": dpdk.GUID, + "name": dpdk.Name, + "rg_access": dpdk.RGAccess, + "status": dpdk.Status, + "ovs_bridge": dpdk.OVSBridge, + "vlan_id": dpdk.VlanID, + "compute_ids": dpdk.ComputeIDs, + "updated_time": dpdk.UpdatedTime, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudbroker/dpdknet/resource_check_input_values.go b/internal/service/cloudbroker/dpdknet/resource_check_input_values.go new file mode 100644 index 00000000..19db0b60 --- /dev/null +++ b/internal/service/cloudbroker/dpdknet/resource_check_input_values.go @@ -0,0 +1,24 @@ +package dpdknet + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + gid := uint64(d.Get("gid").(int)) + + if err := ic.ExistGID(ctx, gid, c); err != nil { + errs = append(errs, err) + } + + return dc.ErrorsToDiagnostics(errs) +} diff --git a/internal/service/cloudbroker/dpdknet/resource_dpdk.go b/internal/service/cloudbroker/dpdknet/resource_dpdk.go new file mode 100644 index 00000000..07f9a0d5 --- /dev/null +++ b/internal/service/cloudbroker/dpdknet/resource_dpdk.go @@ -0,0 +1,248 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package dpdknet + +import ( + "context" + "strconv" + + dpdk "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/dpdknet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" +) + +func resourceDPDKNetCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDPDKNetCreate: called for DPDK network %s", d.Get("name").(string)) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + req := dpdk.CreateRequest{ + Name: d.Get("name").(string), + GID: uint64(d.Get("gid").(int)), + VlanID: uint64(d.Get("vlan_id").(int)), + OVSBridge: d.Get("ovs_bridge").(string), + } + + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + + if accountAccess, ok := d.GetOk("account_access"); ok { + IDs := accountAccess.([]interface{}) + for _, ID := range IDs { + req.AccountAccess = append(req.AccountAccess, uint64(ID.(int))) + } + } + if rgAccess, ok := d.GetOk("rg_access"); ok { + IDs := rgAccess.([]interface{}) + for _, ID := range IDs { + req.RGAccess = append(req.RGAccess, uint64(ID.(int))) + } + } + + req.EnableSecGroups = d.Get("enable_secgroups").(bool) + + dpdkID, err := c.CloudBroker().DPDKNet().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(dpdkID, 10)) + d.Set("dpdk_id", dpdkID) + + warnings := dc.Warnings{} + + if err = utilityDPDKNetEnabled(ctx, d, m); err != nil { + warnings.Add(err) + } + + return append(warnings.Get(), resourceDPDKNetRead(ctx, d, m)...) +} + +func resourceDPDKNetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDPDKNetRead: called for pdpk_id %d", d.Get("dpdk_id").(int)) + w := dc.Warnings{} + + dpdkItem, err := utilityDPDKNetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + log.Debugf("status: %s", dpdkItem.Status) + + switch dpdkItem.Status { + case status.Destroyed, status.Purged: + d.Set("dpdk_id", 0) + d.SetId("") + return diag.Errorf("The resource cannot be read because it has been destroyed") + case status.Deleted: + case status.Assigned: + case status.Modeled: + return diag.Errorf("The DPDK network is in status: %s, please, contact support for more information", dpdkItem.Status) + case status.Creating: + case status.Created: + case status.Allocated: + case status.Unallocated: + } + + flattenDPDKNet(d, dpdkItem) + + return w.Get() +} + +func resourceDPDKNetUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDPDKNetUpdate: called for dpdk_id %d", d.Get("dpdk_id").(int)) + c := m.(*controller.ControllerCfg) + w := dc.Warnings{} + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + dpdkItem, err := utilityDPDKNetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch dpdkItem.Status { + case status.Destroyed, status.Purged: + d.Set("dpdk_id", 0) + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + case status.Deleted: + d.Set("dpdk_id", 0) + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been deleted") + case status.Assigned: + case status.Modeled: + return diag.Errorf("The DPDK network is in status: %s, please, contact support for more information", dpdkItem.Status) + case status.Creating: + case status.Created: + case status.Allocated: + case status.Unallocated: + } + + if d.HasChange("enabled") { + if err := utilityDPDKNetEnabled(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("name", "desc", "vlan_id", "ovs_bridge", "account_access", "rg_access", "enable_secgroups") { + if err := utilityDPDKNetUpdate(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + return append(w.Get(), resourceDPDKNetRead(ctx, d, m)...) +} + +func resourceDPDKNetDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceDPDKNetDelete: called for dpdk_id %d", d.Get("dpdk_id").(int)) + c := m.(*controller.ControllerCfg) + + dpdkItem, err := utilityDPDKNetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + req := dpdk.DeleteRequest{ + DPDKID: dpdkItem.ID, + } + + if d.Get("enabled") == true { + req := dpdk.DisableRequest{ + DPDKID: dpdkItem.ID, + } + + if _, err := c.CloudBroker().DPDKNet().Disable(ctx, req); err != nil { + return diag.FromErr(err) + } + } + + _, err = c.CloudBroker().DPDKNet().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceDPDKNet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceDPDKNetCreate, + ReadContext: resourceDPDKNetRead, + UpdateContext: resourceDPDKNetUpdate, + DeleteContext: resourceDPDKNetDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error { + if diff.HasChange("enable") { + diff.SetNewComputed("status") + } + if diff.HasChanges() { + diff.SetNewComputed("updated_time") + } + return nil + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceDPDKNetSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/dpdknet/schema.go b/internal/service/cloudbroker/dpdknet/schema.go new file mode 100644 index 00000000..9c2aeab1 --- /dev/null +++ b/internal/service/cloudbroker/dpdknet/schema.go @@ -0,0 +1,322 @@ +package dpdknet + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func dataSourceDPDKNetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "dpdk_id": { + Type: schema.TypeInt, + Required: true, + Description: "The unique ID of the subscriber-owner of the DPDK network", + }, + "account_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of accounts with access", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of DPDK network", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "DPDK network ID on the storage side", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of network", + }, + "rg_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of resource groups with access", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "DPDK network status", + }, + "ovs_bridge": { + Type: schema.TypeString, + Computed: true, + Description: "OVS bridge in which interfaces for computers created", + }, + "vlan_id": { + Type: schema.TypeInt, + Computed: true, + Description: "vlan ID", + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Compute IDs which uses this DPDK network", + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Updated time", + }, + } + + return res +} + +func dataSourceDPDKNetListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "gid": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by GID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Description: "Find by description", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "compute_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Find by compute IDs", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dpdk_id": { + Type: schema.TypeInt, + Required: true, + Description: "The unique ID of the subscriber-owner of the DPDK network", + }, + "account_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of accounts with access", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "Description of DPDK network", + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the grid (platform)", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "DPDK network ID on the storage side", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of network", + }, + "rg_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of resource groups with access", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "DPDK network status", + }, + "ovs_bridge": { + Type: schema.TypeString, + Computed: true, + Description: "OVS bridge in which interfaces for computers created", + }, + "vlan_id": { + Type: schema.TypeInt, + Computed: true, + Description: "vlan ID", + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Compute IDs which uses this DPDK network", + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Updated time", + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func resourceDPDKNetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "gid": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the grid (platform)", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of network", + }, + "ovs_bridge": { + Type: schema.TypeString, + Required: true, + Description: "OVS bridge in which interfaces for computers created", + }, + "vlan_id": { + Type: schema.TypeInt, + Required: true, + Description: "vlan ID", + }, + "dpdk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The unique ID of the subscriber-owner of the DPDK network", + }, + "account_access": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of accounts with access", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Created time", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Description of DPDK network", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: "Enabled or disabled DPDK network", + }, + "enable_secgroups": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "enable security groups", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "DPDK network ID on the storage side", + }, + "rg_access": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of resource groups with access", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "DPDK network status", + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Compute IDs which uses this DPDK network", + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Updated time", + }, + } + return res +} diff --git a/internal/service/cloudbroker/dpdknet/utility_dpdk.go b/internal/service/cloudbroker/dpdknet/utility_dpdk.go new file mode 100644 index 00000000..6057cafb --- /dev/null +++ b/internal/service/cloudbroker/dpdknet/utility_dpdk.go @@ -0,0 +1,170 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package dpdknet + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + dpdk "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/dpdknet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDPDKNetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*dpdk.RecordDPDKNet, error) { + c := m.(*controller.ControllerCfg) + req := dpdk.GetRequest{} + + if d.Get("dpdk_id") != nil { + if d.Get("dpdk_id").(int) == 0 { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DPDKID = id + } else { + req.DPDKID = uint64(d.Get("dpdk_id").(int)) + } + } else { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DPDKID = id + } + + log.Debugf("utilityDPDKCheckPresence: get DPDK network") + dpdk, err := c.CloudBroker().DPDKNet().Get(ctx, req) + if err != nil { + return nil, err + } + + return dpdk, nil +} + +func utilityDPDKNetEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + dpdkID, _ := strconv.ParseUint(d.Id(), 10, 64) + enabled := d.Get("enabled").(bool) + + if enabled { + req := dpdk.EnableRequest{ + DPDKID: dpdkID, + } + + if _, err := c.CloudBroker().DPDKNet().Enable(ctx, req); err != nil { + return err + } + } else { + req := dpdk.DisableRequest{ + DPDKID: dpdkID, + } + + if _, err := c.CloudBroker().DPDKNet().Disable(ctx, req); err != nil { + return err + } + } + log.Debugf("resourceDPDKNetUpdate: enable=%v DPDK Network ID %s after completing its resource configuration", enabled, d.Id()) + + return nil +} + +func utilityDPDKNetUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + dpdkID, _ := strconv.ParseUint(d.Id(), 10, 64) + + req := dpdk.UpdateRequest{ + DPDKID: dpdkID, + } + + if d.HasChange("name") { + req.Name = d.Get("name").(string) + } + + if d.HasChange("desc") { + req.Description = d.Get("desc").(string) + } + + if d.HasChange("vlan_id") { + req.VlanID = uint64(d.Get("vlan_id").(int)) + } + + if d.HasChange("ovs_bridge") { + req.OVSBridge = d.Get("ovs_bridge").(string) + } + + if d.HasChange("account_access") { + if accountAccess, ok := d.GetOk("account_access"); ok { + IDs := accountAccess.([]interface{}) + for _, ID := range IDs { + req.AccountAccess = append(req.AccountAccess, uint64(ID.(int))) + } + } + } + + if d.HasChange("rg_access") { + if rgAccess, ok := d.GetOk("rg_access"); ok { + IDs := rgAccess.([]interface{}) + for _, ID := range IDs { + req.RGAccess = append(req.RGAccess, uint64(ID.(int))) + } + } + } + + if d.Get("enabled") == true { + req := dpdk.DisableRequest{ + DPDKID: dpdkID, + } + + if _, err := c.CloudBroker().DPDKNet().Disable(ctx, req); err != nil { + return err + } + } + + if d.HasChange("enable_secgroups") { + req.EnableSecGroups = d.Get("enable_secgroups").(bool) + } + + if _, err := c.CloudBroker().DPDKNet().Update(ctx, req); err != nil { + return err + } + + if d.Get("enabled") == true { + req := dpdk.EnableRequest{ + DPDKID: dpdkID, + } + + if _, err := c.CloudBroker().DPDKNet().Enable(ctx, req); err != nil { + return err + } + } + + return nil +} diff --git a/internal/service/cloudbroker/dpdknet/utility_dpdk_list.go b/internal/service/cloudbroker/dpdknet/utility_dpdk_list.go new file mode 100644 index 00000000..a1b5a40b --- /dev/null +++ b/internal/service/cloudbroker/dpdknet/utility_dpdk_list.go @@ -0,0 +1,108 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package dpdknet + +import ( + "context" + + log "github.com/sirupsen/logrus" + dpdk "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/dpdknet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDPDKNetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*dpdk.ListDPDKNet, error) { + c := m.(*controller.ControllerCfg) + req := dpdk.ListRequest{} + + if byID, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byID.(int)) + } + if GID, ok := d.GetOk("gid"); ok { + req.GID = uint64(GID.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if desc, ok := d.GetOk("description"); ok { + req.Description = desc.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if vlanID, ok := d.GetOk("vlan_id"); ok { + req.VlanID = uint64(vlanID.(int)) + } + if computeIDs, ok := d.GetOk("compute_ids"); ok { + IDs := computeIDs.([]interface{}) + for _, ID := range IDs { + req.ComputeIDs = append(req.ComputeIDs, uint64(ID.(int))) + } + } + if computeIDs, ok := d.GetOk("compute_ids"); ok { + IDs := computeIDs.([]interface{}) + for _, ID := range IDs { + req.ComputeIDs = append(req.ComputeIDs, uint64(ID.(int))) + } + } + if accountAccess, ok := d.GetOk("account_access"); ok { + IDs := accountAccess.([]interface{}) + for _, ID := range IDs { + req.AccountAccess = append(req.AccountAccess, uint64(ID.(int))) + } + } + if rgAccess, ok := d.GetOk("rg_access"); ok { + IDs := rgAccess.([]interface{}) + for _, ID := range IDs { + req.RGAccess = append(req.RGAccess, uint64(ID.(int))) + } + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityDPDKListCheckPresence: load DPDK network list") + dpdkList, err := c.CloudBroker().DPDKNet().List(ctx, req) + if err != nil { + return nil, err + } + + return dpdkList, nil +} diff --git a/internal/service/cloudbroker/extnet/data_source_extnet.go b/internal/service/cloudbroker/extnet/data_source_extnet.go new file mode 100644 index 00000000..2c40a19a --- /dev/null +++ b/internal/service/cloudbroker/extnet/data_source_extnet.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceExtnetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + net, err := utilityExtnetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(net.ID, 10)) + flattenRecordExtnet(d, net) + + return nil +} + +func DataSourceExtnetCB() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceExtnetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceExtnetSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/extnet/data_source_extnet_default.go b/internal/service/cloudbroker/extnet/data_source_extnet_default.go new file mode 100644 index 00000000..35f88abc --- /dev/null +++ b/internal/service/cloudbroker/extnet/data_source_extnet_default.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceExtnetDefaultRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + extnetId, err := utilityExtnetDefaultCheckPresence(ctx, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("extnet_id", extnetId) + + return nil +} + +func DataSourceExtnetDefaultCB() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceExtnetDefaultRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceExtnetDefaultSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/extnet/data_source_extnet_list.go b/internal/service/cloudbroker/extnet/data_source_extnet_list.go new file mode 100644 index 00000000..cec89f43 --- /dev/null +++ b/internal/service/cloudbroker/extnet/data_source_extnet_list.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceExtnetListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + netList, err := utilityExtnetListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(uuid.New().String()) + + d.Set("items", flattenListExtnet(netList)) + d.Set("entry_count", netList.EntryCount) + + return nil +} + +func DataSourceExtnetListCB() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceExtnetListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceExtnetListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/extnet/data_source_extnet_reserved_ip.go b/internal/service/cloudbroker/extnet/data_source_extnet_reserved_ip.go new file mode 100644 index 00000000..714bcc40 --- /dev/null +++ b/internal/service/cloudbroker/extnet/data_source_extnet_reserved_ip.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceExtnetReservedIpRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + reservedList, err := utilityExtnetReservedIpCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenExtnetReservedIp(reservedList)) + + return nil +} + +func DataSourceExtnetReservedIp() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceExtnetReservedIpRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceExtnetReservedIpSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/extnet/data_source_extnet_static_route.go b/internal/service/cloudbroker/extnet/data_source_extnet_static_route.go new file mode 100644 index 00000000..d7078675 --- /dev/null +++ b/internal/service/cloudbroker/extnet/data_source_extnet_static_route.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + staticRoute, err := utilityDataStaticRouteCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(staticRoute.ID, 10)) + flattenStaticRouteData(d, staticRoute) + return nil +} + +func DataSourceStaticRoute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceStaticRouteRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceStaticRouteSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/extnet/data_source_extnet_static_route_list.go b/internal/service/cloudbroker/extnet/data_source_extnet_static_route_list.go new file mode 100644 index 00000000..cd669d80 --- /dev/null +++ b/internal/service/cloudbroker/extnet/data_source_extnet_static_route_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceStaticRouteListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + staticRouteList, err := utilityStaticRouteListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenStaticRouteList(staticRouteList)) + d.Set("entry_count", staticRouteList.EntryCount) + + return nil +} + +func DataSourceStaticRouteList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceStaticRouteListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceStaticRouteListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/extnet/flattens.go b/internal/service/cloudbroker/extnet/flattens.go new file mode 100644 index 00000000..0cb6d610 --- /dev/null +++ b/internal/service/cloudbroker/extnet/flattens.go @@ -0,0 +1,271 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenListExtnet(extList *extnet.ListExtNet) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, item := range extList.Data { + temp := map[string]interface{}{ + "ckey": item.CKey, + "meta": flattens.FlattenMeta(item.Meta), + "default": item.Default, + "default_qos": flattenExtnetDefaultQos(item.DefaultQOS), + "desc": item.Description, + "free_ips": item.FreeIPs, + "gid": item.GID, + "guid": item.GUID, + "enable_secgroups": item.EnableSecGroups, + "extnet_id": item.ID, + "ipcidr": item.IPCIDR, + "milestones": item.Milestones, + "name": item.Name, + "network_ids": flattenNetworkIDs(item.NetworkIDs), + "ovs_bridge": item.OVSBridge, + "pre_reservations_num": item.PreReservationsNum, + "pri_vnfdev_id": item.PriVNFDevID, + "shared_with": item.SharedWith, + "status": item.Status, + "vlan_id": item.VLANID, + "check_ips": item.CheckIPs, + "vnfs": flattenExtnetVNFS(item.VNFs), + "zone_id": item.ZoneID, + "sec_vnfdev_id": item.SecVNFDevID, + "redundant": item.Redundant, + "mtu": item.MTU, + } + + res = append(res, temp) + } + + return res +} + +func flattenRecordExtnet(d *schema.ResourceData, recNet *extnet.RecordExtNet) { + d.Set("ckey", recNet.CKey) + d.Set("meta", flattens.FlattenMeta(recNet.Meta)) + d.Set("default", recNet.Default) + d.Set("desc", recNet.Description) + d.Set("free_ips", recNet.FreeIPs) + d.Set("gid", recNet.GID) + d.Set("guid", recNet.GUID) + d.Set("extnet_id", recNet.ID) + d.Set("ipcidr", recNet.IPCIDR) + d.Set("milestones", recNet.Milestones) + d.Set("name", recNet.Name) + d.Set("network_ids", recNet.NetworkIDs) + d.Set("ntp", recNet.NTP) + d.Set("ovs_bridge", recNet.OVSBridge) + d.Set("pre_reservations_num", recNet.PreReservationsNum) + d.Set("pri_vnfdev_id", recNet.PriVNFDevID) + d.Set("shared_with", recNet.SharedWith) + d.Set("status", recNet.Status) + d.Set("vlan_id", recNet.VLANID) + d.Set("check_ips", recNet.CheckIPs) + d.Set("dns", recNet.DNS) + d.Set("excluded", flattenExtnetExcluded(recNet.Excluded)) + d.Set("gateway", recNet.Gateway) + d.Set("network", recNet.Network) + d.Set("prefix", recNet.Prefix) + d.Set("default_qos", flattenExtnetDefaultQos(recNet.DefaultQOS)) + d.Set("vnfs", flattenExtnetVNFS(recNet.VNFs)) + d.Set("reservations", flattenExtnetReservations(recNet.Reservations)) + d.Set("zone_id", recNet.ZoneID) + d.Set("pre_reservations", flattenExtnetReservations(recNet.PreReservations)) + d.Set("sec_vnfdev_id", recNet.SecVNFDevID) + d.Set("redundant", recNet.Redundant) + d.Set("mtu", recNet.MTU) +} + +func flattenRecordExtnetResource(d *schema.ResourceData, recNet *extnet.RecordExtNet, staticRouteList *extnet.ListStaticRoutes) { + d.Set("ckey", recNet.CKey) + d.Set("meta", flattens.FlattenMeta(recNet.Meta)) + d.Set("default", recNet.Default) + d.Set("desc", recNet.Description) + d.Set("free_ips", recNet.FreeIPs) + d.Set("gid", recNet.GID) + d.Set("guid", recNet.GUID) + d.Set("extnet_id", recNet.ID) + d.Set("ipcidr", recNet.IPCIDR) + d.Set("milestones", recNet.Milestones) + d.Set("name", recNet.Name) + d.Set("network_ids", flattenNetworkIDs(recNet.NetworkIDs)) + d.Set("ovs_bridge", recNet.OVSBridge) + d.Set("pre_reservations_num", recNet.PreReservationsNum) + d.Set("pri_vnfdev_id", recNet.PriVNFDevID) + d.Set("shared_with", recNet.SharedWith) + d.Set("status", recNet.Status) + d.Set("vlan_id", recNet.VLANID) + d.Set("check_ips", recNet.CheckIPs) + d.Set("dns", recNet.DNS) + d.Set("excluded", flattenExtnetExcluded(recNet.Excluded)) + d.Set("gateway", recNet.Gateway) + d.Set("network", recNet.Network) + d.Set("ntp", recNet.NTP) + d.Set("prefix", recNet.Prefix) + d.Set("default_qos", flattenExtnetDefaultQos(recNet.DefaultQOS)) + d.Set("vnfs", flattenExtnetVNFS(recNet.VNFs)) + d.Set("reservations", flattenExtnetReservations(recNet.Reservations)) + d.Set("routes", flattenStaticRouteList(staticRouteList)) + d.Set("zone_id", recNet.ZoneID) + d.Set("enable_secgroups", recNet.EnableSecGroups) +} + +func flattenExtnetExcluded(ers extnet.ListReservations) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, er := range ers { + temp := map[string]interface{}{ + "client_type": er.ClientType, + "desc": er.Description, + "domain_name": er.DomainName, + "hostname": er.Hostname, + "ip": er.IP, + "mac": er.MAC, + "type": er.Type, + "vm_id": er.VMID, + } + res = append(res, temp) + } + + return res +} + +func flattenExtnetReservations(ers extnet.ListReservations) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, er := range ers { + temp := map[string]interface{}{ + "account_id": er.AccountID, + "client_type": er.ClientType, + "domain_name": er.DomainName, + "hostname": er.Hostname, + "desc": er.Description, + "ip": er.IP, + "mac": er.MAC, + "type": er.Type, + "vm_id": er.VMID, + } + res = append(res, temp) + } + + return res +} + +func flattenExtnetVNFS(evnfs extnet.VNFs) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "dhcp": evnfs.DHCP, + } + res = append(res, temp) + return res +} + +func flattenExtnetDefaultQos(edqos extnet.QOS) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "e_rate": edqos.ERate, + "guid": edqos.GUID, + "in_burst": edqos.InBurst, + "in_rate": edqos.InRate, + } + res = append(res, temp) + return res +} + +func flattenStaticRouteList(sr *extnet.ListStaticRoutes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(sr.Data)) + for _, staticRoute := range sr.Data { + temp := map[string]interface{}{ + "route_id": staticRoute.ID, + "destination": staticRoute.Destination, + "gateway": staticRoute.Gateway, + "guid": staticRoute.GUID, + "netmask": staticRoute.Netmask, + "compute_ids": staticRoute.ComputeIds, + } + res = append(res, temp) + } + + return res +} + +func flattenStaticRouteData(d *schema.ResourceData, route *extnet.ItemRoutes) { + d.Set("destination", route.Destination) + d.Set("gateway", route.Gateway) + d.Set("guid", route.GUID) + d.Set("netmask", route.Netmask) + d.Set("compute_ids", route.ComputeIds) + d.Set("route_id", route.ID) +} + +func flattenExtnetReservedIp(el []extnet.RecordReservedIP) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(el)) + for _, e := range el { + reservations := make([]map[string]interface{}, 0, len(e.Reservations)) + for _, r := range e.Reservations { + temp := map[string]interface{}{ + "account_id": r.AccountID, + "client_type": r.ClientType, + "domain_name": r.DomainName, + "hostname": r.Hostname, + "ip": r.IP, + "mac": r.Mac, + "type": r.Type, + "vm_id": r.VMID, + } + reservations = append(reservations, temp) + } + item := map[string]interface{}{ + "extnet_id": e.ExtnetID, + "reservations": reservations, + } + res = append(res, item) + } + return res +} + +func flattenNetworkIDs(ex extnet.NetworkIDs) []map[string]interface{} { + res := make([]map[string]interface{}, 0, 1) + temp := map[string]interface{}{ + "primary": ex.Primary, + "secondary": ex.Secondary, + } + res = append(res, temp) + + return res +} diff --git a/internal/service/cloudbroker/extnet/resource_extnet.go b/internal/service/cloudbroker/extnet/resource_extnet.go new file mode 100644 index 00000000..f68d9935 --- /dev/null +++ b/internal/service/cloudbroker/extnet/resource_extnet.go @@ -0,0 +1,404 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" +) + +func resourceExtnetCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("cloudbroker: resourceExtnetCreate called with name '%s'", d.Get("name").(string)) + c := m.(*controller.ControllerCfg) + + if err := ic.ExistGID(ctx, uint64(d.Get("gid").(int)), c); err != nil { + return diag.FromErr(err) + } + if err := checkReserveIp(ctx, d, c); err != nil { + return diag.FromErr(err) + } + + req := extnet.CreateRequest{ + Name: d.Get("name").(string), + GID: uint64(d.Get("gid").(int)), + IPCIDR: d.Get("ipcidr").(string), + VLANID: uint64(d.Get("vlan_id").(int)), + } + + if gateway, ok := d.GetOk("gateway"); ok { + req.Gateway = gateway.(string) + } + + if dns, ok := d.GetOk("dns"); ok { + res := make([]string, 0) + for _, elem := range dns.([]interface{}) { + res = append(res, elem.(string)) + } + + req.DNS = res + } + + if ntp, ok := d.GetOk("ntp"); ok { + res := make([]string, 0) + for _, elem := range ntp.([]interface{}) { + res = append(res, elem.(string)) + } + + req.NTP = res + } + + if check_ips, ok := d.GetOk("check_ips"); ok { + res := make([]string, 0) + for _, elem := range check_ips.([]interface{}) { + res = append(res, elem.(string)) + } + + req.CheckIPs = res + } + + if virtual, ok := d.GetOk("virtual"); ok { + req.Virtual = virtual.(bool) + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + + if start_ip, ok := d.GetOk("start_ip"); ok { + req.StartIP = start_ip.(string) + } + + if end_ip, ok := d.GetOk("end_ip"); ok { + req.EndIP = end_ip.(string) + } + + if pre_reservations_num, ok := d.GetOk("pre_reservations_num"); ok { + req.PreReservationsNum = uint64(pre_reservations_num.(int)) + } + + if ovs_bridge, ok := d.GetOk("ovs_bridge"); ok { + req.OVSBridge = ovs_bridge.(string) + } + + if highly_available, ok := d.GetOk("highly_available"); ok { + req.HAMode = highly_available.(bool) + } + + if sec_vnfdev_ip, ok := d.GetOk("sec_vnfdev_ip"); ok { + req.SecVNFDevIP = sec_vnfdev_ip.(string) + } + + if mtu, ok := d.GetOk("mtu"); ok { + req.MTU = uint(mtu.(int)) + } + + req.EnableSecGroups = d.Get("enable_secgroups").(bool) + + log.Debugf("cloudbroker: Sent create request") + netID, err := c.CloudBroker().ExtNet().Create(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(netID, 10)) + d.Set("extnet_id", netID) + log.Debugf("cloudbroker: Extnet with id %d successfully created on platform", netID) + + var w dc.Warnings + + if d.Get("excluded_ips").(*schema.Set).Len() > 0 { + ips := make([]string, 0) + + for _, ip := range d.Get("excluded_ips").(*schema.Set).List() { + ips = append(ips, ip.(string)) + } + + req := extnet.IPsExcludeRequest{ + NetID: netID, + IPs: ips, + } + + _, err := c.CloudBroker().ExtNet().IPsExclude(ctx, req) + if err != nil { + w.Add(err) + } + } + + if d.Get("shared_with").(*schema.Set).Len() > 0 { + for _, id := range d.Get("shared_with").(*schema.Set).List() { + req := extnet.AccessRemoveRequest{ + NetID: uint64(d.Get("extnet_id").(int)), + AccountID: uint64(id.(int)), + } + + _, err := c.CloudBroker().ExtNet().AccessRemove(ctx, req) + if err != nil { + w.Add(err) + } + } + } + + if d.Get("excluded_ips_range").(*schema.Set).Len() > 0 { + for _, ip := range d.Get("excluded_ips_range").(*schema.Set).List() { + req := extnet.IPsExcludeRangeRequest{ + NetID: uint64(d.Get("extnet_id").(int)), + IPStart: ip.(map[string]interface{})["ip_start"].(string), + IPEnd: ip.(map[string]interface{})["ip_end"].(string), + } + + _, err := c.CloudBroker().ExtNet().IPsExcludeRange(ctx, req) + if err != nil { + w.Add(err) + } + } + } + + if d.Get("enable").(bool) { + log.Debugf("resourceExtnetCreate: trying to enable extnet with ID %d", netID) + _, err := c.CloudBroker().ExtNet().Enable(ctx, extnet.EnableRequest{ + NetID: netID, + }) + + if err != nil { + w.Add(err) + } + } + + // for reserve IP extnet must be enabled + if d.Get("reserved_ip").(*schema.Set).Len() > 0 { + for _, reservedIP := range d.Get("reserved_ip").(*schema.Set).List() { + reservedIPMap := reservedIP.(map[string]interface{}) + req := extnet.AddReserveIPRequest{ + AccountID: uint64(reservedIPMap["account_id"].(int)), + ExtNetID: netID, + } + if ipCount, ok := reservedIPMap["ip_count"]; ok { + req.IPCount = uint64(ipCount.(int)) + } + if reservedIPMap["ips"].(*schema.Set).Len() > 0 { + ips := reservedIPMap["ips"].(*schema.Set).List() + for i, ip := range ips { + if i >= int(req.IPCount) { + break + } + req.IPs = append(req.IPs, ip.(string)) + } + } + + _, err := c.CloudBroker().ExtNet().AddReserveIP(ctx, req) + if err != nil { + w.Add(err) + } + } + } + + return resourceExtnetRead(ctx, d, m) +} + +func resourceExtnetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("cloudbroker: resourceExtnetRead called with id %s", d.Id()) + recNet, err := utilityExtnetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + staticRouteList, err := utilityStaticRouteListInResourceCheckPresence(ctx, m, recNet.ID) + if err != nil { + return diag.FromErr(err) + } + + flattenRecordExtnetResource(d, recNet, staticRouteList) + + return nil +} + +func resourceExtnetUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("cloudbroker: resourceExtnetUpdate called with id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + if err := checkReserveIp(ctx, d, c); err != nil { + return diag.FromErr(err) + } + + recNet, err := utilityExtnetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + if err := handleBasicUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + + if d.HasChange("enable") { + if err := handleEnableUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("default_qos") { + if err := handleDefaultQOSUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("dns") { + if err := handleDNSUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("ntp") { + if err := handleNTPUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("set_default") { + if err := handleSetDefault(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("excluded_ips") { + if err := handleExcludedIPsUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("excluded_ips_range") { + if err := handleExcludedIPsRangeUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("reserved_ip") { + if err := reservedIPsUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shared_with") { + if err := handleSharedWithUpdate(ctx, d, c); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("virtual") { + if err := handleVirtualUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("restart") { + if err := handleRestartUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + if d.HasChange("migrate") { + if err := handleMigrateUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("zone_id") { + if err := handleZoneIDUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("highly_available") { + if err := handleHAUpdate(ctx, d, c, recNet); err != nil { + return diag.FromErr(err) + } + } + + return resourceExtnetRead(ctx, d, m) +} + +func resourceExtnetDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("cloudbroker: resourceExtnetDelete called with id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + netId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := extnet.DestroyRequest{NetID: netId} + + _, err := c.CloudBroker().ExtNet().Destroy(ctx, req) + if err != nil { + return diag.FromErr(err) + } + log.Debugf("cloudbroker: successfully destroyed extnet with id %s", d.Id()) + + return nil +} + +func ResourceExtnetCB() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: resourceExtnetRead, + CreateContext: resourceExtnetCreate, + UpdateContext: resourceExtnetUpdate, + DeleteContext: resourceExtnetDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout300s, + Create: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + CustomizeDiff: validateReserveIPs, + + Schema: resourceExtnetSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/extnet/resource_extnet_static_route.go b/internal/service/cloudbroker/extnet/resource_extnet_static_route.go new file mode 100644 index 00000000..f39dd400 --- /dev/null +++ b/internal/service/cloudbroker/extnet/resource_extnet_static_route.go @@ -0,0 +1,169 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + "fmt" + "strconv" + "strings" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + + if err := ic.ExistExtNet(ctx, uint64(d.Get("extnet_id").(int)), c); err != nil { + return diag.FromErr(err) + } + + req := extnet.StaticRouteAddRequest{ + ExtNetId: uint64(d.Get("extnet_id").(int)), + Destination: d.Get("destination").(string), + Netmask: d.Get("netmask").(string), + Gateway: d.Get("gateway").(string), + } + + if computesIDS, ok := d.GetOk("compute_ids"); ok { + ids := computesIDS.([]interface{}) + + res := make([]uint64, 0, len (ids)) + + for _, id := range ids { + computeId := uint64(id.(int)) + res = append(res, computeId) + } + + req.ComputeIds = res + } + + _, err := c.CloudBroker().ExtNet().StaticRouteAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + staticRouteData, err := getStaticRouteData(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(fmt.Sprintf("%d#%d", req.ExtNetId, staticRouteData.ID)) + + return resourceStaticRouteRead(ctx, d, m) +} + +func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenStaticRouteData(d, staticRouteData) + + return nil +} + +func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + warnings := dc.Warnings{} + + if err := ic.ExistExtNet(ctx, uint64(d.Get("extnet_id").(int)), c); err != nil { + return diag.FromErr(err) + } + + if d.HasChange("compute_ids") { + if err:= utilityStaticRouteComputeIDsUpdate(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + return append(warnings.Get(), resourceStaticRouteRead(ctx, d, m)...) +} + +func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + req := extnet.StaticRouteDelRequest{} + + arr := strings.Split(d.Id(), "#") + if len(arr) != 2 { + return diag.Errorf("broken state id - %s", d.Id()) + } + + req.ExtNetID, _ = strconv.ParseUint(arr[0], 10, 64) + req.RouteId, _ = strconv.ParseUint(arr[1], 10, 64) + + _, err := c.CloudBroker().ExtNet().StaticRouteDel(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceStaticRoute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceStaticRouteCreate, + ReadContext: resourceStaticRouteRead, + UpdateContext: resourceStaticRouteUpdate, + DeleteContext: resourceStaticRouteDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout20m, + Read: &constants.Timeout600s, + Update: &constants.Timeout20m, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceStaticRouteSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/extnet/schema.go b/internal/service/cloudbroker/extnet/schema.go new file mode 100644 index 00000000..1d13e0c5 --- /dev/null +++ b/internal/service/cloudbroker/extnet/schema.go @@ -0,0 +1,1163 @@ +package extnet + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceExtnetDefaultSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceExtnetListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by account ID", + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "network": { + Type: schema.TypeString, + Optional: true, + }, + "vlan_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by VLAN ID", + }, + "vnfdev_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by VnfDEV ID", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "meta", + }, + "default": { + Type: schema.TypeBool, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "default_qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ipcidr": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "network_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "primary": { + Type: schema.TypeInt, + Computed: true, + }, + "secondary": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "ovs_bridge": { + Type: schema.TypeString, + Computed: true, + }, + "pre_reservations_num": { + Type: schema.TypeInt, + Computed: true, + }, + "pri_vnfdev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "vlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dhcp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "check_ips": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "redundant": { + Type: schema.TypeBool, + Computed: true, + }, + "sec_vnfdev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceStaticRouteListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "extnet_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of ExtNet", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceStaticRouteSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "extnet_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ExtNet", + }, + "route_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the static route", + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func dataSourceExtnetSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "extnet_id": { + Type: schema.TypeInt, + Required: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "meta", + }, + "default": { + Type: schema.TypeBool, + Computed: true, + }, + "default_qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ipcidr": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "network_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "primary": { + Type: schema.TypeInt, + Computed: true, + }, + "secondary": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "ovs_bridge": { + Type: schema.TypeString, + Computed: true, + }, + "pre_reservations_num": { + Type: schema.TypeInt, + Computed: true, + }, + "pri_vnfdev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "vlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dhcp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "check_ips": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "dns": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "excluded": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "domain_name": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "prefix": { + Type: schema.TypeInt, + Computed: true, + }, + "reservations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "domain_name": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "ntp": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "redundant": { + Type: schema.TypeBool, + Computed: true, + }, + "sec_vnfdev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + }, + "pre_reservations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "domain_name": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } +} + +func resourceStaticRouteSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "extnet_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ExtNet", + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Unique ID of the static route", + }, + "compute_ids": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "destination": { + Type: schema.TypeString, + Required: true, + }, + "gateway": { + Type: schema.TypeString, + Required: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Required: true, + }, + } +} + +func resourceExtnetSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "External network name", + }, + "gid": { + Type: schema.TypeInt, + Required: true, + Description: "Grid (platform) ID", + }, + "ipcidr": { + Type: schema.TypeString, + Required: true, + // ForceNew: true, + Description: "IP network CIDR", + }, + "vlan_id": { + Type: schema.TypeInt, + Required: true, + // ForceNew: true, + Description: "VLAN ID", + }, + "gateway": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "External network gateway IP address", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "enable security groups", + }, + "dns": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "List of DNS addresses", + }, + "ntp": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "List of NTP addresses", + }, + "check_ips": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "IPs to check network availability", + }, + "virtual": { + Type: schema.TypeBool, + Optional: true, + Description: "If true - platform DHCP server will not be created", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional description", + }, + "start_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Start of IP range to be explicitly included", + }, + "end_ip": { + Type: schema.TypeString, + Optional: true, + Description: "End of IP range to be explicitly included", + }, + "vnfdev_ip": { + Type: schema.TypeString, + Optional: true, + Description: "IP to create VNFDev with", + }, + "pre_reservations_num": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Number of pre created reservations", + }, + "ovs_bridge": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "OpenvSwith bridge name for ExtNet connection", + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Disable/Enable extnet", + }, + "set_default": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Set current extnet as default (can not be undone)", + }, + "excluded_ips": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "IPs to exclude in current extnet pool", + }, + "excluded_ips_range": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_start": { + Type: schema.TypeString, + Required: true, + }, + "ip_end": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + Description: "Range of IPs to exclude in current extnet pool", + }, + "default_qos": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + "restart": { + Type: schema.TypeBool, + Optional: true, + Description: "restart extnet vnf device", + }, + "migrate": { + Type: schema.TypeInt, + Optional: true, + }, + "shared_with": { + Type: schema.TypeSet, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "reserved_ip": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + }, + "ip_count": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(1, 255), + }, + "ips": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "highly_available": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "sec_vnfdev_ip": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "meta", + }, + "default": { + Type: schema.TypeBool, + Computed: true, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "network_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "primary": { + Type: schema.TypeInt, + Computed: true, + }, + "secondary": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "pri_vnfdev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dhcp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "excluded": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "domain_name": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "prefix": { + Type: schema.TypeInt, + Computed: true, + }, + "routes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "reservations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "domain_name": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } +} + +func dataSourceExtnetReservedIpSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "reservations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "domain_name": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + } + return res +} diff --git a/internal/service/cloudbroker/extnet/utility_extnet.go b/internal/service/cloudbroker/extnet/utility_extnet.go new file mode 100644 index 00000000..3eb6a918 --- /dev/null +++ b/internal/service/cloudbroker/extnet/utility_extnet.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityExtnetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*extnet.RecordExtNet, error) { + c := m.(*controller.ControllerCfg) + + req := extnet.GetRequest{} + + if d.Id() != "" { + netId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.NetID = netId + } else { + req.NetID = uint64(d.Get("extnet_id").(int)) + } + + res, err := c.CloudBroker().ExtNet().Get(ctx, req) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/internal/service/cloudbroker/extnet/utility_extnet_default.go b/internal/service/cloudbroker/extnet/utility_extnet_default.go new file mode 100644 index 00000000..5665555e --- /dev/null +++ b/internal/service/cloudbroker/extnet/utility_extnet_default.go @@ -0,0 +1,54 @@ +/* +<<<<<<<< HEAD:internal/dc/utils.go +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +======== +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +>>>>>>>> dev:internal/service/cloudbroker/extnet/utility_extnet_default.go +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +<<<<<<<< HEAD:internal/dc/utils.go +Nikita Sorokin, +======== +Tim Tkachev, +>>>>>>>> dev:internal/service/cloudbroker/extnet/utility_extnet_default.go + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityExtnetDefaultCheckPresence(ctx context.Context, m interface{}) (uint64, error) { + c := m.(*controller.ControllerCfg) + + return c.CloudBroker().ExtNet().GetDefault(ctx) +} diff --git a/internal/service/cloudbroker/extnet/utility_extnet_list.go b/internal/service/cloudbroker/extnet/utility_extnet_list.go new file mode 100644 index 00000000..7f9faac3 --- /dev/null +++ b/internal/service/cloudbroker/extnet/utility_extnet_list.go @@ -0,0 +1,99 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityExtnetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*extnet.ListExtNet, error) { + c := m.(*controller.ControllerCfg) + + req := extnet.ListRequest{} + + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if network, ok := d.GetOk("network"); ok { + req.Network = network.(string) + } + + if vlan_id, ok := d.GetOk("vlan_id"); ok { + req.VLANID = uint64(vlan_id.(int)) + } + + if vnfdev_id, ok := d.GetOk("vnfdev_id"); ok { + req.VNFDevID = uint64(vnfdev_id.(int)) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + res, err := c.CloudBroker().ExtNet().List(ctx, req) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/internal/service/cloudbroker/extnet/utility_extnet_reserved_ip.go b/internal/service/cloudbroker/extnet/utility_extnet_reserved_ip.go new file mode 100644 index 00000000..68c1207b --- /dev/null +++ b/internal/service/cloudbroker/extnet/utility_extnet_reserved_ip.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityExtnetReservedIpCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]extnet.RecordReservedIP, error) { + c := m.(*controller.ControllerCfg) + req := extnet.GetReservedIP{ + AccountID: uint64(d.Get("account_id").(int)), + } + + if extNetID, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extNetID.(int)) + } + + log.Debugf("utilityExtnetReservedIpCheckPresence") + res, err := c.CloudBroker().ExtNet().GetReservedIP(ctx, req) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/internal/service/cloudbroker/extnet/utility_extnet_resource.go b/internal/service/cloudbroker/extnet/utility_extnet_resource.go new file mode 100644 index 00000000..67558f33 --- /dev/null +++ b/internal/service/cloudbroker/extnet/utility_extnet_resource.go @@ -0,0 +1,637 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + "errors" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func handleExcludedIPsUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + old_set, new_set := d.GetChange("excluded_ips") + + detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set)) + if detach_set.Len() > 0 { + ips := make([]string, 0) + for _, detach_ip := range detach_set.List() { + ips = append(ips, detach_ip.(string)) + } + + log.Debugf("cloudbroker: removing %d IP address(es) from excluded list", detach_set.Len()) + req := extnet.IPsIncludeRequest{ + NetID: recNet.ID, + IPs: ips, + } + + _, err := c.CloudBroker().ExtNet().IPsInclude(ctx, req) + if err != nil { + return err + } + } + + attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set)) + if attach_set.Len() > 0 { + ips := make([]string, 0) + for _, attach_ip := range attach_set.List() { + ips = append(ips, attach_ip.(string)) + } + + log.Debugf("cloudbroker: excluding %d IP address(es) from extnet with id %d", attach_set.Len(), recNet.ID) + req := extnet.IPsExcludeRequest{ + NetID: recNet.ID, + IPs: ips, + } + + _, err := c.CloudBroker().ExtNet().IPsExclude(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func handleSetDefault(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + set_default := d.Get("set_default").(bool) + if set_default && !recNet.Default { + req := extnet.SetDefaultRequest{ + NetID: recNet.ID, + } + + _, err := c.CloudBroker().ExtNet().SetDefault(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func handleBasicUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + doBasicUpdate := false + basiUpdateReq := extnet.UpdateRequest{NetID: recNet.ID} + + if d.HasChange("name") { + basiUpdateReq.Name = d.Get("name").(string) + doBasicUpdate = true + } + if d.HasChange("desc") { + basiUpdateReq.Description = d.Get("desc").(string) + doBasicUpdate = true + } + if d.HasChange("mtu") { + basiUpdateReq.MTU = uint64(d.Get("mtu").(int)) + doBasicUpdate = true + } + if d.HasChange("enable_secgroups") { + basiUpdateReq.EnableSecGroups = d.Get("enable_secgroups").(bool) + doBasicUpdate = true + } + + if doBasicUpdate { + _, err := c.CloudBroker().ExtNet().Update(ctx, basiUpdateReq) + if err != nil { + return err + } + } + + return nil +} + +func handleEnableUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + enable := d.Get("enable").(bool) + if enable { + if recNet.Status == status.Disabled { + req := extnet.EnableRequest{NetID: recNet.ID} + _, err := c.CloudBroker().ExtNet().Enable(ctx, req) + if err != nil { + return err + } + } + } else { + if recNet.Status == status.Enabled { + req := extnet.DisableRequest{NetID: recNet.ID} + _, err := c.CloudBroker().ExtNet().Disable(ctx, req) + if err != nil { + return err + } + } + } + + return nil +} + +func handleDefaultQOSUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + qos := d.Get("default_qos").([]interface{})[0].(map[string]interface{}) + + req := extnet.DefaultQOSUpdateRequest{ + NetID: recNet.ID, + IngressRate: uint64(qos["in_rate"].(int)), + IngressBurst: uint64(qos["in_burst"].(int)), + EgressRate: uint64(qos["e_rate"].(int)), + } + + _, err := c.CloudBroker().ExtNet().DefaultQOSUpdate(ctx, req) + if err != nil { + return err + } + + return nil +} + +func handleNTPUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + changed_list := d.Get("ntp").([]interface{}) + + ntp_list := make([]string, 0) + for _, ntp_address := range changed_list { + ntp_list = append(ntp_list, ntp_address.(string)) + } + + req := extnet.NTPApplyRequest{ + NetID: recNet.ID, + NTPList: ntp_list, + } + + _, err := c.CloudBroker().ExtNet().NTPApply(ctx, req) + if err != nil { + return err + } + + return nil +} + +func handleDNSUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + changed_list := d.Get("dns").([]interface{}) + + dns_list := make([]string, 0) + for _, dns_address := range changed_list { + dns_list = append(dns_list, dns_address.(string)) + } + + req := extnet.DNSApplyRequest{ + NetID: recNet.ID, + DNSList: dns_list, + } + + _, err := c.CloudBroker().ExtNet().DNSApply(ctx, req) + if err != nil { + return err + } + + return nil +} + +func handleExcludedIPsRangeUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + old_set, new_set := d.GetChange("excluded_ips_range") + + detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set)) + if detach_set.Len() > 0 { + for _, detach_ip_range := range detach_set.List() { + + log.Debugf("cloudbroker: removing range of IP addreses from excluded range list") + + req := extnet.IPsIncludeRangeRequest{ + NetID: recNet.ID, + IPStart: detach_ip_range.(map[string]interface{})["ip_start"].(string), + IPEnd: detach_ip_range.(map[string]interface{})["ip_end"].(string), + } + + _, err := c.CloudBroker().ExtNet().IPsIncludeRange(ctx, req) + if err != nil { + return err + } + } + } + attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set)) + if attach_set.Len() > 0 { + for _, attach_ip_range := range attach_set.List() { + + log.Debugf("cloudbroker: excluding range of IP addreses from excluded range list") + + req := extnet.IPsExcludeRangeRequest{ + NetID: recNet.ID, + IPStart: attach_ip_range.(map[string]interface{})["ip_start"].(string), + IPEnd: attach_ip_range.(map[string]interface{})["ip_end"].(string), + } + + _, err := c.CloudBroker().ExtNet().IPsExcludeRange(ctx, req) + if err != nil { + return err + } + } + } + return nil +} + +func handleSharedWithUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) error { + oldSet, newSet := d.GetChange("shared_with") + + deletedAccountIds := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedAccountIds) > 0 { + for _, accountIdInterface := range deletedAccountIds { + req := extnet.AccessRemoveRequest{ + NetID: uint64(d.Get("extnet_id").(int)), + AccountID: uint64(accountIdInterface.(int)), + } + + _, err := c.CloudBroker().ExtNet().AccessRemove(ctx, req) + if err != nil { + return err + } + } + } + + addedAccountIds := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedAccountIds) > 0 { + for _, accountIdInterface := range addedAccountIds { + req := extnet.AccessAddRequest{ + NetID: uint64(d.Get("extnet_id").(int)), + AccountID: uint64(accountIdInterface.(int)), + } + + _, err := c.CloudBroker().ExtNet().AccessAdd(ctx, req) + if err != nil { + return err + } + } + } + + return nil +} + +func handleVirtualUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + virtualOld, virtualNew := d.GetChange("virtual") + + if !virtualOld.(bool) && virtualNew.(bool) { + req := extnet.DeviceRemoveRequest{NetID: recNet.ID} + _, err := c.CloudBroker().ExtNet().DeviceRemove(ctx, req) + if err != nil { + return err + } + + } else if virtualOld.(bool) && !virtualNew.(bool) { + req := extnet.DeviceDeployRequest{NetID: recNet.ID} + _, err := c.CloudBroker().ExtNet().DeviceDeploy(ctx, req) + if err != nil { + return err + } + } + return nil +} + +func handleRestartUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + restartOld, restartNew := d.GetChange("restart") + + if !restartOld.(bool) && restartNew.(bool) { + req := extnet.DeviceRestartRequest{NetID: recNet.ID} + _, err := c.CloudBroker().ExtNet().DeviceRestart(ctx, req) + if err != nil { + return err + } + } + return nil +} + +func handleMigrateUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + nodeId := uint64(d.Get("migrate").(int)) + + if err := ic.ExistNode(ctx, nodeId, c); err != nil { + return err + } + + req := extnet.DeviceMigrateRequest{ + NetID: recNet.ID, + NodeID: nodeId, + } + + _, err := c.CloudBroker().ExtNet().DeviceMigrate(ctx, req) + if err != nil { + return err + } + + return nil +} + +func handleZoneIDUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + zoneID := uint64(d.Get("zone_id").(int)) + + req := extnet.MigrateToZoneRequest{ + NetID: recNet.ID, + ZoneID: zoneID, + } + + _, err := c.CloudBroker().ExtNet().MigrateToZone(ctx, req) + if err != nil { + return err + } + + return nil +} + +func handleHAUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + highlyAvailable := d.Get("highly_available").(bool) + + req := extnet.SetHAModeRequest{ + NetID: recNet.ID, + HAMode: highlyAvailable, + } + + _, err := c.CloudBroker().ExtNet().SetHAMode(ctx, req) + if err != nil { + return err + } + + return nil +} + +func checkReserveIp(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) error { + var err error + if d.Get("reserved_ip").(*schema.Set).Len() > 0 { + reservedIPList := d.Get("reserved_ip").(*schema.Set).List() + accountMap := make(map[int]struct{}, len(reservedIPList)) + for _, reservedIP := range reservedIPList { + reservedIPMap := reservedIP.(map[string]interface{}) + accountId := reservedIPMap["account_id"].(int) + if _, ok := accountMap[accountId]; ok { + err = errors.Join(err, fmt.Errorf("checkReserveIp: you must have only one block with id %d", accountId)) + } + accountMap[accountId] = struct{}{} + _, okCount := reservedIPMap["ip_count"] + if !okCount && reservedIPMap["ips"].(*schema.Set).Len() == 0 { + err = errors.Join(err, fmt.Errorf("checkReserveIp: either ip_count or set of ips must be specified")) + } + existErr := ic.ExistAccount(ctx, uint64(accountId), c) + if existErr != nil { + err = errors.Join(err, existErr) + } + } + } + + return err +} + +func reservedIPsUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error { + + addSet, delSet, err := differenceIPReserved(ctx, d, c) + if err != nil { + return err + } + + if len(delSet) > 0 { + for _, del := range delSet { + delMap := del.(map[string]interface{}) + + log.Debugf("reservedIPsUpdate: removing reserved IPs for account %d", delMap["account_id"].(int)) + + req := extnet.DelReserveIPRequest{ + AccountID: uint64(delMap["account_id"].(int)), + ExtNetID: recNet.ID, + } + if ipCount, ok := delMap["ip_count"]; ok { + req.IPCount = uint64(ipCount.(int)) + } + if delIPs, ok := delMap["ips"]; ok { + ips := delIPs.(*schema.Set).List() + for _, ip := range ips { + req.IPs = append(req.IPs, ip.(string)) + } + } + + _, err := c.CloudBroker().ExtNet().DelReserveIP(ctx, req) + if err != nil { + return err + } + } + } + + if len(addSet) > 0 { + for _, add := range addSet { + addMap := add.(map[string]interface{}) + + log.Debugf("reservedIPsUpdate: add reserved IPs for account %d", addMap["account_id"].(int)) + + req := extnet.AddReserveIPRequest{ + AccountID: uint64(addMap["account_id"].(int)), + ExtNetID: recNet.ID, + } + if ipCount, ok := addMap["ip_count"]; ok { + req.IPCount = uint64(ipCount.(int)) + } + if addIPs, ok := addMap["ips"]; ok { + ips := addIPs.(*schema.Set).List() + for _, ip := range ips { + req.IPs = append(req.IPs, ip.(string)) + } + } + + _, err := c.CloudBroker().ExtNet().AddReserveIP(ctx, req) + if err != nil { + return err + } + } + } + + return nil +} + +func differenceIPReserved(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) (addList, delList []interface{}, errs error) { + addList = make([]interface{}, 0) + delList = make([]interface{}, 0) + oldSet, newSet := d.GetChange("reserved_ip") + oldList := oldSet.(*schema.Set).List() + newList := newSet.(*schema.Set).List() + for _, oldReservedIP := range oldList { + oldMap := oldReservedIP.(map[string]interface{}) + found := false + for _, newReservedIP := range newList { + newMap := newReservedIP.(map[string]interface{}) + if newMap["account_id"] == oldMap["account_id"] && newMap["ip_count"] == oldMap["ip_count"] && newMap["ips"] == oldMap["ips"] { + found = true + break + } + if newMap["account_id"] == oldMap["account_id"] { + add := make(map[string]interface{}, 0) + del := make(map[string]interface{}, 0) + delSet := oldMap["ips"].(*schema.Set).Difference(newMap["ips"].(*schema.Set)) + addSet := newMap["ips"].(*schema.Set).Difference(oldMap["ips"].(*schema.Set)) + if delSet.Len() > 0 { + del["account_id"] = oldMap["account_id"].(int) + del["ips"] = delSet + if oldMap["ip_count"].(int)-newMap["ip_count"].(int) >= delSet.Len() { + del["ip_count"] = oldMap["ip_count"].(int) - newMap["ip_count"].(int) + } else { + del["ip_count"] = delSet.Len() + newMap["ip_count"] = newMap["ip_count"].(int) + delSet.Len() + } + } else if newMap["ip_count"].(int) < oldMap["ip_count"].(int) { + del["account_id"] = oldMap["account_id"].(int) + del["ip_count"] = oldMap["ip_count"].(int) - newMap["ip_count"].(int) + } + if addSet.Len() > 0 { + add["account_id"] = oldMap["account_id"].(int) + add["ips"] = addSet + add["ip_count"] = newMap["ip_count"].(int) - oldMap["ip_count"].(int) + if add["ip_count"].(int) < 0 { + add["ip_count"] = 0 + } + if add["ip_count"].(int)-addSet.Len() < 0 { + del["account_id"] = oldMap["account_id"].(int) + if _, ok := del["ip_count"]; ok { + del["ip_count"] = del["ip_count"].(int) + addSet.Len() + } else { + del["ip_count"] = addSet.Len() + } + } + } else if newMap["ip_count"].(int)-oldMap["ip_count"].(int) > 0 { + add["account_id"] = oldMap["account_id"].(int) + add["ip_count"] = newMap["ip_count"].(int) - oldMap["ip_count"].(int) + } + if _, ok := add["account_id"]; ok { + addList = append(addList, add) + } + if _, ok := del["account_id"]; ok { + ipsLen := 0 + if _, ok := del["ips"]; ok { + ipsLen = del["ips"].(*schema.Set).Len() + } + freeCount := del["ip_count"].(int) - ipsLen + if freeCount > 0 { + req := extnet.GetReservedIP{ + AccountID: uint64(del["account_id"].(int)), + ExtNetID: uint64(d.Get("extnet_id").(int)), + } + resIpsList, err := c.CloudBroker().ExtNet().GetReservedIP(ctx, req) + if err != nil { + errs = errors.Join(errs, err) + } + freeIPs := getFreeIps(resIpsList[0].Reservations, newMap["ips"], del["ips"]) + if _, ok := del["ips"]; !ok { + del["ips"] = schema.NewSet(schema.HashString, []interface{}{}) + } + for i := 0; i < freeCount; i++ { + del["ips"].(*schema.Set).Add(freeIPs[i]) + } + } + delList = append(delList, del) + } + found = true + break + } + } + if found { + continue + } + delList = append(delList, oldReservedIP) + } + + for _, newReservedIP := range newList { + newMap := newReservedIP.(map[string]interface{}) + found := false + for _, oldReservedIP := range oldList { + oldMap := oldReservedIP.(map[string]interface{}) + if newMap["account_id"] == oldMap["account_id"] { + found = true + break + } + } + if found { + continue + } + addList = append(addList, newReservedIP) + } + + if errs != nil { + d.Set("reserved_ip", oldSet) + } + + return +} + +// getFreeIps returns array IPs which can be deleted +func getFreeIps(reserved []extnet.Reservations, newIps, delIps interface{}) []string { + newIpsList := make([]interface{}, 0) + delIpsList := make([]interface{}, 0) + if newIps != nil { + newIpsList = newIps.(*schema.Set).List() + } + if delIps != nil { + delIpsList = delIps.(*schema.Set).List() + } + newIpsMap := make(map[string]struct{}, len(newIpsList)) + delIpsMap := make(map[string]struct{}, len(delIpsList)) + freeIPs := make([]string, 0) + for _, ip := range newIpsList { + newIpsMap[ip.(string)] = struct{}{} + } + for _, ip := range delIpsList { + delIpsMap[ip.(string)] = struct{}{} + } + for _, item := range reserved { + if _, ok := newIpsMap[item.IP]; ok { + continue + } + if _, ok := delIpsMap[item.IP]; ok { + continue + } + freeIPs = append(freeIPs, item.IP) + } + return freeIPs +} + +func validateReserveIPs(ctx context.Context, d *schema.ResourceDiff, m interface{}) error { + list := d.Get("reserved_ip").(*schema.Set).List() + var errs error + for _, reservedIP := range list { + reservedIPMap := reservedIP.(map[string]interface{}) + var countIP, ipsLen int + if _, ok := reservedIPMap["ip_count"]; ok { + countIP = reservedIPMap["ip_count"].(int) + } + if _, ok := reservedIPMap["ips"]; ok { + ipsLen = reservedIPMap["ips"].(*schema.Set).Len() + } + if ipsLen > countIP { + errs = errors.Join(errs, fmt.Errorf("for the reserved_ip block with account_id %d the count parameter must be greater than or equal to len the ips array", reservedIPMap["account_id"].(int))) + } + } + return errs +} diff --git a/internal/service/cloudbroker/extnet/utility_extnet_static_route.go b/internal/service/cloudbroker/extnet/utility_extnet_static_route.go new file mode 100644 index 00000000..8f9f68ec --- /dev/null +++ b/internal/service/cloudbroker/extnet/utility_extnet_static_route.go @@ -0,0 +1,158 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + "fmt" + "strconv" + "strings" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDataStaticRouteCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*extnet.ItemRoutes, error) { + c := m.(*controller.ControllerCfg) + req := extnet.StaticRouteListRequest{} + var routeId uint64 + + if d.Id() != "" { + arr := strings.Split(d.Id(), "#") + if len(arr) != 2 { + return nil, fmt.Errorf("broken state id") + } + + req.ExtNetID, _ = strconv.ParseUint(arr[0], 10, 64) + routeId, _ = strconv.ParseUint(arr[1], 10, 64) + } else { + req.ExtNetID = uint64(d.Get("extnet_id").(int)) + routeId = uint64(d.Get("route_id").(int)) + } + + log.Debugf("utilityStaticRouteCheckPresence, extnet id: %v", req.ExtNetID) + staticRouteList, err := c.CloudBroker().ExtNet().StaticRouteList(ctx, req) + if err != nil { + return nil, err + } + + log.Debugf("utilityStaticRouteCheckPresence: ROUTE ID %v", routeId) + + staticRoute := extnet.ItemRoutes{} + for _, route := range staticRouteList.Data { + if routeId == route.ID { + staticRoute = route + return &staticRoute, nil + } + } + + return nil, fmt.Errorf("static route not found") +} + +func getStaticRouteData(ctx context.Context, d *schema.ResourceData, m interface{}) (*extnet.ItemRoutes, error) { + c := m.(*controller.ControllerCfg) + req := extnet.StaticRouteListRequest{} + req.ExtNetID = uint64(d.Get("extnet_id").(int)) + + staticRouteList, err := c.CloudBroker().ExtNet().StaticRouteList(ctx, req) + if err != nil { + return nil, err + } + + destination := d.Get("destination").(string) + gateway := d.Get("gateway").(string) + + staticRoute := extnet.ItemRoutes{} + for _, route := range staticRouteList.Data { + if destination == route.Destination && gateway == route.Gateway { + staticRoute = route + return &staticRoute, nil + } + } + + return nil, fmt.Errorf("static route not found") +} + +func utilityStaticRouteComputeIDsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return err + } + + oldSet, newSet := d.GetChange("compute_ids") + + deletedComputeIDs := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + deletedIds := make([]uint64, 0, len(deletedComputeIDs)) + if len(deletedComputeIDs) > 0 { + for _, computeIdInterface := range deletedComputeIDs { + deletedIds = append(deletedIds, uint64(computeIdInterface.(int))) + } + + req := extnet.StaticRouteAccessRevokeRequest{ + ExtNetID: uint64(d.Get("extnet_id").(int)), + RouteId: staticRouteData.ID, + ComputeIds: deletedIds, + } + + _, err := c.CloudBroker().ExtNet().StaticRouteAccessRevoke(ctx, req) + if err != nil { + return err + } + } + + addedComputeIDs := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + addedIds := make([]uint64, 0, len(addedComputeIDs)) + if len(addedComputeIDs) > 0 { + for _, computeIdInterface := range addedComputeIDs { + addedIds = append(addedIds, uint64(computeIdInterface.(int))) + } + req := extnet.StaticRouteAccessGrantRequest{ + ExtNetID: uint64(d.Get("extnet_id").(int)), + RouteId: staticRouteData.ID, + ComputeIds: addedIds, + } + + _, err := c.CloudBroker().ExtNet().StaticRouteAccessGrant(ctx, req) + if err != nil { + return err + } + } + + return nil +} diff --git a/internal/service/cloudbroker/extnet/utility_extnet_static_route_list.go b/internal/service/cloudbroker/extnet/utility_extnet_static_route_list.go new file mode 100644 index 00000000..c708e091 --- /dev/null +++ b/internal/service/cloudbroker/extnet/utility_extnet_static_route_list.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package extnet + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityStaticRouteListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*extnet.ListStaticRoutes, error) { + c := m.(*controller.ControllerCfg) + req := extnet.StaticRouteListRequest{} + + req.ExtNetID = uint64(d.Get("extnet_id").(int)) + + log.Debugf("utilityStaticRouteListCheckPresence") + staticRouteList, err := c.CloudBroker().ExtNet().StaticRouteList(ctx, req) + if err != nil { + return nil, err + } + + return staticRouteList, nil +} + +func utilityStaticRouteListInResourceCheckPresence(ctx context.Context, m interface{}, extnetId uint64) (*extnet.ListStaticRoutes, error) { + c := m.(*controller.ControllerCfg) + req := extnet.StaticRouteListRequest{ + ExtNetID: extnetId, + } + + log.Debugf("utilityStaticRouteListInResourceCheckPresence") + staticRouteList, err := c.CloudBroker().ExtNet().StaticRouteList(ctx, req) + if err != nil { + return nil, err + } + + return staticRouteList, nil +} \ No newline at end of file diff --git a/internal/service/cloudbroker/flipgroup/data_source_flipgroup.go b/internal/service/cloudbroker/flipgroup/data_source_flipgroup.go new file mode 100644 index 00000000..63d73ab7 --- /dev/null +++ b/internal/service/cloudbroker/flipgroup/data_source_flipgroup.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceFlipgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + flipgroup, err := utilityFlipgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenFlipgroup(d, flipgroup) + d.SetId(strconv.Itoa(d.Get("flipgroup_id").(int))) + + return nil +} + +func DataSourceFlipgroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceFlipgroupRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceFlipgroupSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/flipgroup/data_sourse_flipgroup_list.go b/internal/service/cloudbroker/flipgroup/data_sourse_flipgroup_list.go new file mode 100644 index 00000000..ef312839 --- /dev/null +++ b/internal/service/cloudbroker/flipgroup/data_sourse_flipgroup_list.go @@ -0,0 +1,74 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceFlipgroupListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + flipgroupsList, err := utilityFlipgroupListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenFlipgroupsList(flipgroupsList)) + d.Set("entry_count", flipgroupsList.EntryCount) + + return nil +} + +func DataSourceFlipgroupList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceFlipgroupListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceFlipgroupsListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/flipgroup/flattens.go b/internal/service/cloudbroker/flipgroup/flattens.go new file mode 100644 index 00000000..b211a510 --- /dev/null +++ b/internal/service/cloudbroker/flipgroup/flattens.go @@ -0,0 +1,126 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/flipgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenFlipgroup(d *schema.ResourceData, flip *flipgroup.RecordFLIPGroup) { + d.Set("flipgroup_id", flip.ID) + d.Set("account_id", flip.AccountID) + d.Set("account_name", flip.AccountName) + d.Set("client_ids", flip.ClientIDs) + d.Set("client_names", flip.ClientNames) + d.Set("client_type", flip.ClientType) + d.Set("conn_id", flip.ConnID) + d.Set("conn_type", flip.ConnType) + d.Set("created_by", flip.CreatedBy) + d.Set("created_time", flip.CreatedTime) + d.Set("default_gw", flip.DefaultGW) + d.Set("deleted_by", flip.DeletedBy) + d.Set("deleted_time", flip.DeletedTime) + d.Set("description", flip.Description) + d.Set("gid", flip.GID) + d.Set("guid", flip.GUID) + d.Set("ip", flip.IP) + d.Set("milestones", flip.Milestones) + d.Set("name", flip.Name) + d.Set("net_id", flip.NetID) + d.Set("net_type", flip.NetType) + d.Set("network", flip.Network) + d.Set("status", flip.Status) + d.Set("updated_by", flip.UpdatedBy) + d.Set("updated_time", flip.UpdatedTime) +} + +func flattenFlipgroupResource(d *schema.ResourceData, flip *flipgroup.RecordFLIPGroup) { + d.Set("flipgroup_id", flip.ID) + d.Set("account_id", flip.AccountID) + d.Set("account_name", flip.AccountName) + d.Set("client_ids", flip.ClientIDs) + d.Set("client_names", flip.ClientNames) + d.Set("client_type", flip.ClientType) + d.Set("conn_id", flip.ConnID) + d.Set("conn_type", flip.ConnType) + d.Set("created_by", flip.CreatedBy) + d.Set("created_time", flip.CreatedTime) + d.Set("default_gw", flip.DefaultGW) + d.Set("deleted_by", flip.DeletedBy) + d.Set("deleted_time", flip.DeletedTime) + d.Set("desc", flip.Description) + d.Set("gid", flip.GID) + d.Set("guid", flip.GUID) + d.Set("ip", flip.IP) + d.Set("milestones", flip.Milestones) + d.Set("name", flip.Name) + d.Set("net_id", flip.NetID) + d.Set("net_type", flip.NetType) + d.Set("network", flip.Network) + d.Set("status", flip.Status) + d.Set("updated_by", flip.UpdatedBy) + d.Set("updated_time", flip.UpdatedTime) +} + +func flattenFlipgroupsList(fg *flipgroup.ListFLIPGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(fg.Data)) + for _, flip := range fg.Data { + temp := map[string]interface{}{ + "ckey": flip.CKey, + "meta": flattens.FlattenMeta(flip.Meta), + "flipgroup_id": flip.ID, + "account_id": flip.AccountID, + "client_ids": flip.ClientIDs, + "client_type": flip.ClientType, + "conn_id": flip.ConnID, + "conn_type": flip.ConnType, + "default_gw": flip.DefaultGW, + "description": flip.Description, + "gid": flip.GID, + "guid": flip.GUID, + "ip": flip.IP, + "milestones": flip.Milestones, + "name": flip.Name, + "net_id": flip.NetID, + "net_type": flip.NetType, + "net_mask": flip.NetMask, + "status": flip.Status, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudbroker/flipgroup/resource_check_input_values.go b/internal/service/cloudbroker/flipgroup/resource_check_input_values.go new file mode 100644 index 00000000..dff18a09 --- /dev/null +++ b/internal/service/cloudbroker/flipgroup/resource_check_input_values.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + accountId := uint64(d.Get("account_id").(int)) + netType := d.Get("net_type").(string) + netId := uint64(d.Get("net_id").(int)) + + if err := ic.ExistAccount(ctx, accountId, c); err != nil { + errs = append(errs, err) + } + + switch netType { + case "VINS": + if err := ic.ExistVins(ctx, netId, c); err != nil { + errs = append(errs, err) + } + case "EXTNET": + if err := ic.ExistExtNet(ctx, netId, c); err != nil { + errs = append(errs, err) + } + } + + return dc.ErrorsToDiagnostics(errs) +} diff --git a/internal/service/cloudbroker/flipgroup/resource_flipgroup.go b/internal/service/cloudbroker/flipgroup/resource_flipgroup.go new file mode 100644 index 00000000..29af234b --- /dev/null +++ b/internal/service/cloudbroker/flipgroup/resource_flipgroup.go @@ -0,0 +1,218 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/flipgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + + log "github.com/sirupsen/logrus" +) + +func resourceFlipgroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceFlipgroupCreate called with name: %s, accountID %v", d.Get("name").(string), d.Get("account_id").(int)) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + req := flipgroup.CreateRequest{ + Name: d.Get("name").(string), + NetType: d.Get("net_type").(string), + AccountID: uint64(d.Get("account_id").(int)), + NetID: uint64(d.Get("net_id").(int)), + } + + if IP, ok := d.GetOk("ip"); ok { + req.IP = IP.(string) + } + if clientType, ok := d.GetOk("client_type"); ok { + req.ClientType = clientType.(string) + } + if description, ok := d.GetOk("desc"); ok { + req.Description = description.(string) + } + + resp, err := c.CloudBroker().FLIPGroup().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(fmt.Sprint(resp.ID)) + d.Set("flipgroup_id", resp.ID) + + var warnings dc.Warnings + + if client_ids, ok := d.GetOk("client_ids"); ok { + casted := client_ids.([]interface{}) + addComputesAfterCreation(ctx, &warnings, c, casted, resp.ID) + } + + return append(warnings.Get(), resourceFlipgroupRead(ctx, d, m)...) +} + +func resourceFlipgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceFlipgroupRead: called for flipgroup_id %s, name %s", + d.Id(), d.Get("name").(string)) + + fg, err := utilityFlipgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch fg.Status { + case status.Destroyed: + d.SetId("") + return diag.Errorf("The flipgroup status is destroyed and cannot be read.") + } + + flattenFlipgroupResource(d, fg) + + log.Debugf("resourceFlipgroupRead: after flattenFlipgroupResource: flipgroup_id %s, name %s", + d.Id(), d.Get("name").(string)) + + return nil +} + +func resourceFlipgroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceFlipgroupUpdate called with id: %v", d.Get("flipgroup_id").(int)) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + fg, err := utilityFlipgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch fg.Status { + case status.Destroyed: + d.SetId("") + return diag.Errorf("The flipgroup status is destroyed and cannot be updated.") + } + + var warnings dc.Warnings + basicUpdate := false + req := flipgroup.EditRequest{FLIPGroupID: fg.ID} + + if d.HasChange("desc") { + req.Description = d.Get("desc").(string) + basicUpdate = true + } + + if d.HasChange("name") { + req.Name = d.Get("name").(string) + basicUpdate = true + } + + if basicUpdate { + _, err := c.CloudBroker().FLIPGroup().Edit(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("client_ids") { + handleClientIDsUpdate(ctx, d, c, fg, &warnings) + } + + return append(warnings.Get(), resourceFlipgroupRead(ctx, d, m)...) +} + +func resourceFlipgroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceFlipgroupDelete called with id: %v", d.Get("flipgroup_id").(int)) + c := m.(*controller.ControllerCfg) + + fg, err := utilityFlipgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + req := flipgroup.DeleteRequest{ + FLIPGroupID: fg.ID, + } + + // When FLIPGroup().Delete() is executed, flipgroup automatically is removed from the compute it has been attached to, if any. + // No need to specifically call for FlipGroup().ComputeRemove(). + _, err = c.CloudBroker().FLIPGroup().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceFlipgroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + CreateContext: resourceFlipgroupCreate, + ReadContext: resourceFlipgroupRead, + UpdateContext: resourceFlipgroupUpdate, + DeleteContext: resourceFlipgroupDelete, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout300s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceFlipgroupSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/flipgroup/schema.go b/internal/service/cloudbroker/flipgroup/schema.go new file mode 100644 index 00000000..011f56c7 --- /dev/null +++ b/internal/service/cloudbroker/flipgroup/schema.go @@ -0,0 +1,475 @@ +package flipgroup + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceFlipgroupSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "flipgroup_id": { + Type: schema.TypeInt, + Required: true, + Description: "flipgroup_id", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account_id", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "account_name", + }, + "client_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "client_ids", + }, + "client_names": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "client_names", + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + Description: "client_type", + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + Description: "conn_id", + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + Description: "conn_type", + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + Description: "created_by", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "created_time", + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + Description: "default_gw", + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + Description: "deleted_by", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "deleted_time", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "ip": { + Type: schema.TypeString, + Computed: true, + Description: "ip", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "name", + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + Description: "net_id", + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + Description: "net_type", + }, + "network": { + Type: schema.TypeString, + Computed: true, + Description: "network", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + Description: "updated_by", + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + Description: "updated_time", + }, + } + return rets +} + +func dataSourceFlipgroupsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + Description: "name", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "vins_id", + }, + "vins_name": { + Type: schema.TypeString, + Optional: true, + Description: "vins_name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "extnet_id", + }, + "by_ip": { + Type: schema.TypeString, + Optional: true, + Description: "by_ip", + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "by_id", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Account id", + }, + "conn_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Conn id", + }, + "client_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "client_ids", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Status", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account_id", + }, + "client_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "client_ids", + }, + "client_type": { + Type: schema.TypeString, + Computed: true, + Description: "client_type", + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + Description: "conn_id", + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + Description: "conn_type", + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + Description: "default_gw", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "flipgroup_id": { + Type: schema.TypeInt, + Computed: true, + Description: "flipgroup_id", + }, + "ip": { + Type: schema.TypeString, + Computed: true, + Description: "ip", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "name", + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + Description: "net_id", + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + Description: "net_type", + }, + "net_mask": { + Type: schema.TypeInt, + Computed: true, + Description: "net_mask", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry_count", + }, + } + return res +} + +func resourceFlipgroupSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "Account ID", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Flipgroup name", + }, + "net_id": { + Type: schema.TypeInt, + Required: true, + Description: "EXTNET or ViNS ID", + }, + "net_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS"}, true), + Description: "Network type, EXTNET or VINS", + }, + "client_type": { + Type: schema.TypeString, + Optional: true, + Default: "compute", + Description: "Type of client, 'compute' ('vins' will be later)", + ValidateFunc: validation.StringInSlice([]string{"compute"}, true), + }, + "ip": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "IP address to associate with this group. If empty, the platform will autoselect IP address", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Text description of this Flipgroup instance", + }, + "client_ids": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of clients attached to this Flipgroup instance", + }, + "client_names": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "client_names", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "account_name", + }, + "flipgroup_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + Description: "created_by", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "created_time", + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + Description: "deleted_by", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "deleted_time", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "network": { + Type: schema.TypeString, + Computed: true, + Description: "network", + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + Description: "updated_by", + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + Description: "updated_time", + }, + "net_mask": { + Type: schema.TypeInt, + Computed: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + } +} diff --git a/internal/service/cloudbroker/flipgroup/utility_flipgroup.go b/internal/service/cloudbroker/flipgroup/utility_flipgroup.go new file mode 100644 index 00000000..da1f55a0 --- /dev/null +++ b/internal/service/cloudbroker/flipgroup/utility_flipgroup.go @@ -0,0 +1,66 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/flipgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityFlipgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*flipgroup.RecordFLIPGroup, error) { + log.Debugf("utilityFlipgroupCheckPresence") + c := m.(*controller.ControllerCfg) + req := flipgroup.GetRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.FLIPGroupID = id + } else { + req.FLIPGroupID = uint64(d.Get("flipgroup_id").(int)) + } + + flipgroup, err := c.CloudBroker().FLIPGroup().Get(ctx, req) + if err != nil { + return nil, err + } + + return flipgroup, nil +} diff --git a/internal/service/cloudbroker/flipgroup/utility_flipgroup_list.go b/internal/service/cloudbroker/flipgroup/utility_flipgroup_list.go new file mode 100644 index 00000000..f1b5d58d --- /dev/null +++ b/internal/service/cloudbroker/flipgroup/utility_flipgroup_list.go @@ -0,0 +1,101 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/flipgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityFlipgroupListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*flipgroup.ListFLIPGroups, error) { + c := m.(*controller.ControllerCfg) + req := flipgroup.ListRequest{} + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if vinsId, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vinsId.(int)) + } + if vinsName, ok := d.GetOk("vins_name"); ok { + req.VINSName = vinsName.(string) + } + if extnetId, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnetId.(int)) + } + if byIp, ok := d.GetOk("by_ip"); ok { + req.ByIP = byIp.(string) + } + if byID, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byID.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountId = uint64(accountId.(int)) + } + if clientId, ok := d.GetOk("client_ids"); ok { + clientIds := clientId.([]interface{}) + for _, elem := range clientIds { + req.ClientIDs = append(req.ClientIDs, uint64(elem.(int))) + } + } + if connId, ok := d.GetOk("conn_id"); ok { + req.ConnId = uint64(connId.(int)) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + log.Debugf("utilityFlipgroupListCheckPresence: load flipgroup list") + flipgroupList, err := c.CloudBroker().FLIPGroup().List(ctx, req) + if err != nil { + return nil, err + } + + return flipgroupList, nil +} diff --git a/internal/service/cloudbroker/flipgroup/utility_flipgroup_resource.go b/internal/service/cloudbroker/flipgroup/utility_flipgroup_resource.go new file mode 100644 index 00000000..07f86da7 --- /dev/null +++ b/internal/service/cloudbroker/flipgroup/utility_flipgroup_resource.go @@ -0,0 +1,127 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package flipgroup + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/flipgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func addComputesAfterCreation(ctx context.Context, warnings *dc.Warnings, c *controller.ControllerCfg, compute_ids []interface{}, flipgroupID uint64) { + if len(compute_ids) == 0 { + return + } + + log.Debugf("Adding %v computes to flipgroup [id=%v]...", len(compute_ids), flipgroupID) + + for _, elem := range compute_ids { + compute_id := uint64(elem.(int)) + req := flipgroup.ComputeAddRequest{ + FLIPGroupID: flipgroupID, + ComputeID: compute_id, + } + + _, err := c.CloudBroker().FLIPGroup().ComputeAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } +} + +func handleClientIDsUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, fg *flipgroup.RecordFLIPGroup, warn *dc.Warnings) { + addedClients := make([]interface{}, 0) + removedClients := make([]interface{}, 0) + + old_set, new_set := d.GetChange("client_ids") + oldSlice := old_set.([]interface{}) + newSlice := new_set.([]interface{}) + + for _, oldElem := range oldSlice { + if !containsClient(newSlice, oldElem) { + removedClients = append(removedClients, oldElem) + } + } + + for _, newElem := range newSlice { + if !containsClient(oldSlice, newElem) { + addedClients = append(addedClients, newElem) + } + } + + log.Debugf("Found client_ids change with %v deletion(s) and %v addition(s) [flipgroupID=%v]", len(removedClients), len(addedClients), fg.ID) + + if len(addedClients) > 0 { + for _, id := range addedClients { + req := flipgroup.ComputeAddRequest{ + FLIPGroupID: fg.ID, + ComputeID: uint64(id.(int)), + } + + if _, err := c.CloudBroker().FLIPGroup().ComputeAdd(ctx, req); err != nil { + warn.Add(err) + } + } + } + + if len(removedClients) > 0 { + for _, id := range removedClients { + req := flipgroup.ComputeRemoveRequest{ + FLIPGroupID: fg.ID, + ComputeID: uint64(id.(int)), + } + + if _, err := c.CloudBroker().FLIPGroup().ComputeRemove(ctx, req); err != nil { + warn.Add(err) + } + } + } +} + +func containsClient(set []interface{}, check interface{}) bool { + for _, elem := range set { + elemConv := elem.(int) + checkConv := check.(int) + if elemConv == checkConv { + return true + } + } + + return false +} diff --git a/internal/service/cloudbroker/grid/data_source_grid.go b/internal/service/cloudbroker/grid/data_source_grid.go new file mode 100644 index 00000000..2bb9e9de --- /dev/null +++ b/internal/service/cloudbroker/grid/data_source_grid.go @@ -0,0 +1,68 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceGridRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + grid, err := utilityGridCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId(strconv.FormatUint(grid.ID, 10)) + flattenGrid(d, grid) + + return nil +} + +func DataSourceGrid() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceGridRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceGetGridSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/grid/data_source_grid_get_post_diagnosis.go b/internal/service/cloudbroker/grid/data_source_grid_get_post_diagnosis.go new file mode 100644 index 00000000..f4cbf659 --- /dev/null +++ b/internal/service/cloudbroker/grid/data_source_grid_get_post_diagnosis.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + "os" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceGridGetDiagnosisRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + filePath := "diagnosis.tar.gz" + if userPath, ok := d.GetOk("file_path"); ok { + filePath = userPath.(string) + } + + log.Debugf("dataSourceGridGetDiagnosisRead: create file with name: %s", filePath) + file, err := os.Create(filePath) + defer file.Close() + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + diagnosis, err := utilityGridGetDiagnosisCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + log.Debugf("dataSourceGridGetDiagnosisRead: write data to file with name: %s", filePath) + _, err = file.WriteString(diagnosis) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + return nil +} + +func DataSourceGridGetDiagnosis() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceGridGetDiagnosisRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceGridGetDiagnosisSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/grid/data_source_grid_get_post_status.go b/internal/service/cloudbroker/grid/data_source_grid_get_post_status.go new file mode 100644 index 00000000..ef4334e2 --- /dev/null +++ b/internal/service/cloudbroker/grid/data_source_grid_get_post_status.go @@ -0,0 +1,96 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceGridGetStatusRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + grid, err := utilityGridGetStatusCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("status", grid) + return nil +} + +func DataSourceGridGetStatus() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceGridGetStatusRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceGridGetStatusSchemaMake(), + } +} + +func dataSourceGridPostStatusRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + grid, err := utilityGridPostStatusCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("status", grid) + return nil +} + +func DataSourceGridPostStatus() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceGridPostStatusRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceGridPostStatusSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/grid/data_source_grid_get_settings.go b/internal/service/cloudbroker/grid/data_source_grid_get_settings.go new file mode 100644 index 00000000..3491a7bb --- /dev/null +++ b/internal/service/cloudbroker/grid/data_source_grid_get_settings.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceGridGetSettingsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + gridSettings, err := utilityGridGetSettingsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + flattenGridSettings(d, gridSettings) + + return nil +} + +func DataSourceGridGetSettings() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceGridGetSettingsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceGridGetSettingsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/grid/data_source_grid_list.go b/internal/service/cloudbroker/grid/data_source_grid_list.go new file mode 100644 index 00000000..03d23d69 --- /dev/null +++ b/internal/service/cloudbroker/grid/data_source_grid_list.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceGridListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + gridList, err := utilityGridListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenGridList(gridList)) + d.Set("entry_count", gridList.EntryCount) + return nil +} + +func DataSourceGridList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceGridListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceGridListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/grid/data_source_grid_list_emails.go b/internal/service/cloudbroker/grid/data_source_grid_list_emails.go new file mode 100644 index 00000000..f4106cb0 --- /dev/null +++ b/internal/service/cloudbroker/grid/data_source_grid_list_emails.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceGridListEmailsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + gridListEmails, err := utilityGridListEmailsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", gridListEmails.Data) + d.Set("entry_count", gridListEmails.EntryCount) + return nil +} + +func DataSourceGridListEmails() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceGridListEmailsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceGridListEmailsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/grid/data_sourse_grid_get_consumption.go b/internal/service/cloudbroker/grid/data_sourse_grid_get_consumption.go new file mode 100644 index 00000000..f041071f --- /dev/null +++ b/internal/service/cloudbroker/grid/data_sourse_grid_get_consumption.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceGridGetConsumptionRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + gridGetConsumption, err := utilityGridGetConsumptionCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(d.Get("grid_id").(int))) + d.Set("consumed", flattenGridRecordResource(gridGetConsumption.Consumed)) + d.Set("reserved", flattenGridRecordResource(gridGetConsumption.Reserved)) + return nil +} + +func DataSourceGridGetConsumption() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceGridGetConsumptionRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceGridGetConsumptionSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/grid/data_sourse_grid_list_consumption.go b/internal/service/cloudbroker/grid/data_sourse_grid_list_consumption.go new file mode 100644 index 00000000..52ce9dad --- /dev/null +++ b/internal/service/cloudbroker/grid/data_sourse_grid_list_consumption.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceGridListConsumptionRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + gridListConsumption, err := utilityGridListConsumptionCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenGridListConsumption(gridListConsumption)) + d.Set("entry_count", gridListConsumption.EntryCount) + return nil +} + +func DataSourceGridListConsumption() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceGridListConsumptionRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceGridListConsumptionSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/grid/flattens.go b/internal/service/cloudbroker/grid/flattens.go new file mode 100644 index 00000000..7d943589 --- /dev/null +++ b/internal/service/cloudbroker/grid/flattens.go @@ -0,0 +1,199 @@ +package grid + +import ( + "encoding/json" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenGrid(d *schema.ResourceData, grid *grid.RecordGrid) { + d.Set("auth_broker", flattens.FlattenMeta(grid.AuthBroker)) + d.Set("name", grid.Name) + d.Set("flag", grid.Flag) + d.Set("gid", grid.GID) + d.Set("guid", grid.GUID) + d.Set("location_code", grid.LocationCode) + d.Set("id", grid.ID) + d.Set("network_modes", grid.NetworkModes) + d.Set("sdn_support", grid.SDNSupport) + d.Set("zero_access_enabled", grid.ZeroAccessEnabled) +} + +func flattenGridList(gl *grid.ListGrids) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(gl.Data)) + for _, item := range gl.Data { + temp := map[string]interface{}{ + "resources": flattenGridResources(item.Resources), + "name": item.Name, + "auth_broker": flattens.FlattenMeta(item.AuthBroker), + "flag": item.Flag, + "gid": item.GID, + "guid": item.GUID, + "location_code": item.LocationCode, + "id": item.ID, + "network_modes": item.NetworkModes, + "sdn_support": item.SDNSupport, + "zero_access_enabled": item.ZeroAccessEnabled, + } + res = append(res, temp) + } + return res +} + +func flattenGridListConsumption(gl *grid.ListResourceConsumption) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(gl.Data)) + for _, item := range gl.Data { + temp := map[string]interface{}{ + "consumed": flattenGridRecordResource(item.Consumed), + "reserved": flattenGridRecordResource(item.Reserved), + "id": item.GID, + } + res = append(res, temp) + } + return res +} + +func flattenGridResources(r grid.Resources) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "current": flattenGridRecordResource(r.Current), + "reserved": flattenGridRecordResource(r.Reserved), + } + res = append(res, temp) + return res +} + +func flattenGridRecordResource(rr grid.RecordResource) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": rr.CPU, + "disk_size": rr.DiskSize, + "disk_size_max": rr.DiskSizeMax, + "ext_ips": rr.ExtIPs, + "gpu": rr.GPU, + "ram": rr.RAM, + "seps": flattenGridSeps(rr.SEPs), + "policies": flattenGridPolicies(rr.Policies), + } + res = append(res, temp) + return res +} + +func flattenGridPolicies(policies map[string]grid.PolicyUsage) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(policies)) + for policyID, policy := range policies { + temp := map[string]interface{}{ + "policy_id": policyID, + "disk_size": policy.DiskSize, + "disk_size_max": policy.DiskSizeMax, + "seps": flattenGridSeps(policy.SEPs), + } + res = append(res, temp) + } + return res +} + +func flattenGridSeps(seps map[string]map[string]grid.DiskUsage) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for sepKey, sepVal := range seps { + for dataKey, dataVal := range sepVal { + temp := map[string]interface{}{ + "sep_id": sepKey, + "data_name": dataKey, + "disk_size": dataVal.DiskSize, + "disk_size_max": dataVal.DiskSizeMax, + } + res = append(res, temp) + } + } + return res +} + +func flattenGridSettings(d *schema.ResourceData, gridSettings *grid.RecordSettingsGrid) { + limits, _ := json.Marshal(gridSettings.Limits) + d.Set("allowed_ports", gridSettings.Allowedports) + d.Set("cleanup_retention_period", gridSettings.CleanupRetentionPeriod) + d.Set("cpu_allocation_ratio_vm", gridSettings.CPUAllocationRatioVM) + d.Set("cpu_allocation_ratio", gridSettings.CPUAllocationRatio) + d.Set("custom_backup_path", gridSettings.CustomBackupPath) + d.Set("docker_registry", flattenDockerRegistry(gridSettings.DockerRegistry)) + d.Set("enable_uptime_monitor", gridSettings.EnableUptimeMonitor) + d.Set("extnet_max_pre_reservations_num", gridSettings.ExtnetMaxPreReservationsNum) + d.Set("healthcheck_notifications", flattenHealthcheckNotifications(gridSettings.HealthcheckNotifications)) + d.Set("interface_generation_scheme", gridSettings.InterfaceGenerationScheme) + d.Set("k8s_cleanup_enabled", gridSettings.K8sCleanupEnabled) + d.Set("limits", string(limits)) + d.Set("location_url", gridSettings.LocationURL) + d.Set("mac_address_prefix", gridSettings.MACAddressPrefix) + d.Set("net_qos", flattenNetQOS(gridSettings.NetQOS)) + d.Set("networks", gridSettings.Networks) + d.Set("node_self_stop_timer_uptime_monitor", gridSettings.NodeSelfStopTimerUptimeMonitor) + d.Set("node_self_stop_uptime_monitor", gridSettings.NodeSelfStopUptimeMonitor) + d.Set("prometheus", flattenPrometheus(gridSettings.Prometheus)) + d.Set("vins_max_pre_reservations_num", gridSettings.VinsMaxPreReservationsNum) + d.Set("vnfdev_mgmt_net_range", gridSettings.VnfdevMgmtNetRange) +} + +func flattenDockerRegistry(dr grid.DockerRegistry) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "password": dr.Password, + "server": dr.Server, + "username": dr.Username, + } + res = append(res, temp) + return res +} + +func flattenHealthcheckNotifications(hn grid.HealthcheckNotifications) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "emails": flattenEmails(hn.Emails), + } + res = append(res, temp) + return res +} + +func flattenEmails(emails []grid.Emails) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(emails)) + for _, email := range emails { + temp := map[string]interface{}{ + "address": email.Address, + "enabled": email.Enabled, + } + res = append(res, temp) + } + return res +} + +func flattenNetQOS(netQOS grid.NetQOS) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "extnet": flattenSettingsNetQOS(netQOS.ExtNet), + "vins": flattenSettingsNetQOS(netQOS.VINS), + } + res = append(res, temp) + return res +} + +func flattenSettingsNetQOS(qos grid.SettingsNetQOS) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "e_rate": qos.ERate, + "in_burst": qos.InBurst, + "in_rate": qos.InRate, + } + res = append(res, temp) + return res +} + +func flattenPrometheus(pr grid.Prometheus) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "scrape_interval": pr.ScrapeInterval, + } + res = append(res, temp) + return res +} diff --git a/internal/service/cloudbroker/grid/schema.go b/internal/service/cloudbroker/grid/schema.go new file mode 100644 index 00000000..92a06005 --- /dev/null +++ b/internal/service/cloudbroker/grid/schema.go @@ -0,0 +1,827 @@ +package grid + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func dataSourceGetGridSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "grid_id": { + Type: schema.TypeInt, + Required: true, + }, + "auth_broker": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "flag": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "location_code": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "network_modes": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Computed: true, + }, + "sdn_support": { + Type: schema.TypeBool, + Computed: true, + }, + "zero_access_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + } +} + +func dataSourceGridListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "by id", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "name", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "grid list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "resources": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "current": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "ext_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "ext_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "auth_broker": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "flag": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "location_code": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "network_modes": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Computed: true, + }, + "sdn_support": { + Type: schema.TypeBool, + Computed: true, + }, + "zero_access_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry count", + }, + } + + return rets +} + +func dataSourceGridListEmailsSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "grid list emails", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry count", + }, + } + + return rets +} + +func gridPoliciesSchemaMake() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "policy_id": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + } +} + +func dataSourceGridGetConsumptionSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "grid_id": { + Type: schema.TypeInt, + Required: true, + }, + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "ext_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + "policies": gridPoliciesSchemaMake(), + }, + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "ext_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + "policies": gridPoliciesSchemaMake(), + }, + }, + }, + } +} + +func dataSourceGridListConsumptionSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "items": { + Type: schema.TypeList, + Computed: true, + Description: "grid list consumption", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "ext_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + "policies": gridPoliciesSchemaMake(), + }, + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "ext_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + "policies": gridPoliciesSchemaMake(), + }, + }, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry count", + }, + } + return rets +} + +func dataSourceGridGetStatusSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "status": { + Type: schema.TypeBool, + Computed: true, + }, + } +} + +func dataSourceGridPostStatusSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "status": { + Type: schema.TypeBool, + Computed: true, + }, + } +} + +func dataSourceGridGetDiagnosisSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "gid": { + Type: schema.TypeInt, + Required: true, + }, + "file_path": { + Type: schema.TypeString, + Required: true, + }, + } +} + +func dataSourceGridGetSettingsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "grid_id": { + Type: schema.TypeInt, + Description: "grid (platform) ID", + Required: true, + }, + "allowed_ports": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "cleanup_retention_period": { + Type: schema.TypeInt, + Computed: true, + }, + "docker_registry": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "password": { + Type: schema.TypeString, + Computed: true, + }, + "server": { + Type: schema.TypeString, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "enable_uptime_monitor": { + Type: schema.TypeBool, + Computed: true, + }, + "extnet_max_pre_reservations_num": { + Type: schema.TypeInt, + Computed: true, + }, + "healthcheck_notifications": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "emails": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "k8s_cleanup_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "limits": { + Type: schema.TypeString, + Computed: true, + }, + "location_url": { + Type: schema.TypeString, + Computed: true, + }, + "net_qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "extnet": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "networks": { + Type: schema.TypeString, + Computed: true, + }, + "prometheus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "scrape_interval": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "vins_max_pre_reservations_num": { + Type: schema.TypeInt, + Computed: true, + }, + "vnfdev_mgmt_net_range": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio_vm": { + Type: schema.TypeInt, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeInt, + Computed: true, + }, + "custom_backup_path": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "interface_generation_scheme": { + Type: schema.TypeString, + Computed: true, + }, + "mac_address_prefix": { + Type: schema.TypeString, + Computed: true, + }, + "node_self_stop_timer_uptime_monitor": { + Type: schema.TypeInt, + Computed: true, + }, + "node_self_stop_uptime_monitor": { + Type: schema.TypeBool, + Computed: true, + }, + } +} diff --git a/internal/service/cloudbroker/grid/utility_grid.go b/internal/service/cloudbroker/grid/utility_grid.go new file mode 100644 index 00000000..e1647d59 --- /dev/null +++ b/internal/service/cloudbroker/grid/utility_grid.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityGridCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*grid.RecordGrid, error) { + c := m.(*controller.ControllerCfg) + req := grid.GetRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.GID = id + } else { + req.GID = uint64(d.Get("grid_id").(int)) + } + + log.Debugf("utilityGridCheckPresence: load grid") + gridRec, err := c.CloudBroker().Grid().Get(ctx, req) + if err != nil { + return nil, err + } + + return gridRec, nil +} diff --git a/internal/service/cloudbroker/grid/utility_grid_get_consumption.go b/internal/service/cloudbroker/grid/utility_grid_get_consumption.go new file mode 100644 index 00000000..c4b45fa4 --- /dev/null +++ b/internal/service/cloudbroker/grid/utility_grid_get_consumption.go @@ -0,0 +1,64 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityGridGetConsumptionCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*grid.RecordResourcesConsumption, error) { + c := m.(*controller.ControllerCfg) + req := grid.GetResourceConsumptionRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.GridID = id + } else { + req.GridID = uint64(d.Get("grid_id").(int)) + } + + log.Debugf("utilityGridGetConsumptionCheckPresence: load specific grid") + gridGetConsumption, err := c.CloudBroker().Grid().GetResourceConsumption(ctx,req) + if err != nil { + return nil, err + } + + return gridGetConsumption, nil +} diff --git a/internal/service/cloudbroker/grid/utility_grid_get_post_diagnosis.go b/internal/service/cloudbroker/grid/utility_grid_get_post_diagnosis.go new file mode 100644 index 00000000..137b7b05 --- /dev/null +++ b/internal/service/cloudbroker/grid/utility_grid_get_post_diagnosis.go @@ -0,0 +1,64 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityGridGetDiagnosisCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + req := grid.GetDiagnosisRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.GID = id + } else { + req.GID = uint64(d.Get("gid").(int)) + } + + log.Debugf("utilityGridGetDiagnosisCheckPresence: load grid get diagnosis") + gridGetDiagnosis, err := c.CloudBroker().Grid().GetDiagnosisGET(ctx, req) + if err != nil { + return "", err + } + + return gridGetDiagnosis, nil +} diff --git a/internal/service/cloudbroker/grid/utility_grid_get_post_status.go b/internal/service/cloudbroker/grid/utility_grid_get_post_status.go new file mode 100644 index 00000000..118ab2e4 --- /dev/null +++ b/internal/service/cloudbroker/grid/utility_grid_get_post_status.go @@ -0,0 +1,66 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityGridGetStatusCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityGridListConsumptionCheckPresence: load grid list consumption") + gridGetStatus, err := c.CloudBroker().Grid().StatusGET(ctx) + if err != nil { + return false, err + } + + return gridGetStatus, nil +} + +func utilityGridPostStatusCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityGridListConsumptionCheckPresence: load grid list consumption") + gridGetStatus, err := c.CloudBroker().Grid().Status(ctx) + if err != nil { + return false, err + } + + return gridGetStatus, nil +} diff --git a/internal/service/cloudbroker/grid/utility_grid_get_settings.go b/internal/service/cloudbroker/grid/utility_grid_get_settings.go new file mode 100644 index 00000000..ea70a4cc --- /dev/null +++ b/internal/service/cloudbroker/grid/utility_grid_get_settings.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityGridGetSettingsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*grid.RecordSettingsGrid, error) { + c := m.(*controller.ControllerCfg) + req := grid.GetSettingsRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.GID = id + } else { + req.GID = uint64(d.Get("grid_id").(int)) + } + + log.Debugf("utilityGridutilityGridGetSettingsCheckPresenceCheckPresence: load grid settings") + gridSettingsRec, err := c.CloudBroker().Grid().GetSettings(ctx, req) + if err != nil { + return nil, err + } + + return gridSettingsRec, nil +} diff --git a/internal/service/cloudbroker/grid/utility_grid_list.go b/internal/service/cloudbroker/grid/utility_grid_list.go new file mode 100644 index 00000000..7f5f00ec --- /dev/null +++ b/internal/service/cloudbroker/grid/utility_grid_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityGridListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*grid.ListGrids, error) { + c := m.(*controller.ControllerCfg) + req := grid.ListRequest{} + + if byID, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byID.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityGridListCheckPresence: load grid list") + gridList, err := c.CloudBroker().Grid().List(ctx, req) + if err != nil { + return nil, err + } + + return gridList, nil +} diff --git a/internal/service/cloudbroker/grid/utility_grid_list_emails.go b/internal/service/cloudbroker/grid/utility_grid_list_emails.go new file mode 100644 index 00000000..d3466e64 --- /dev/null +++ b/internal/service/cloudbroker/grid/utility_grid_list_emails.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityGridListEmailsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*grid.ListEmails, error) { + c := m.(*controller.ControllerCfg) + req := grid.ListEmailsRequest{} + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityGridListEmailsCheckPresence: load grid list of emails") + gridListEmails, err := c.CloudBroker().Grid().ListEmails(ctx, req) + if err != nil { + return nil, err + } + + return gridListEmails, nil +} diff --git a/internal/service/cloudbroker/grid/utulity_grid_list_consumption.go b/internal/service/cloudbroker/grid/utulity_grid_list_consumption.go new file mode 100644 index 00000000..ad86209d --- /dev/null +++ b/internal/service/cloudbroker/grid/utulity_grid_list_consumption.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package grid + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityGridListConsumptionCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*grid.ListResourceConsumption, error) { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityGridListConsumptionCheckPresence: load grid list consumption") + gridListConsumption, err := c.CloudBroker().Grid().ListResourceConsumption(ctx) + if err != nil { + return nil, err + } + + return gridListConsumption, nil +} diff --git a/internal/service/cloudbroker/ic/input_checks.go b/internal/service/cloudbroker/ic/input_checks.go new file mode 100644 index 00000000..8ea8271c --- /dev/null +++ b/internal/service/cloudbroker/ic/input_checks.go @@ -0,0 +1,713 @@ +// Input checks +package ic + +import ( + "context" + "fmt" + + cb_account "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + cb_compute "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + cb_disks "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + cb_dpdk "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/dpdknet" + cb_extnet "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet" + cb_gid "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + cb_image "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + cb_k8ci "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8ci" + cb_k8s "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" + cb_lb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + cb_node "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/node" + cb_rg "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + cb_trunk "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/trunk" + cb_vfpool "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vfpool" + cb_vins "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func ExistRG(ctx context.Context, rgId uint64, c *controller.ControllerCfg) error { + req := cb_rg.ListRequest{ + ByID: rgId, + IncludeDeleted: false, + } + + rgList, err := c.CloudBroker().RG().List(ctx, req) + if err != nil { + return err + } + + if len(rgList.Data) == 0 { + return fmt.Errorf("RG with id %v not found", rgId) + } + + return nil +} + +func ExistRGs(ctx context.Context, rgIDs []uint64, c *controller.ControllerCfg) error { + req := cb_rg.ListRequest{} + + rgList, err := c.CloudBroker().RG().List(ctx, req) + if err != nil { + return err + } + + if len(rgList.Data) == 0 { + return fmt.Errorf("you have not been granted access to any resource group") + } + + notFound := make([]uint64, 0, len(rgIDs)) + + for _, rgID := range rgIDs { + found := false + + for _, rg := range rgList.Data { + if rgID == rg.ID { + found = true + break + } + } + + if !found { + notFound = append(notFound, rgID) + } + } + + if len(notFound) > 0 { + return fmt.Errorf("RGs with ids %v not found", notFound) + } + + return nil +} + +func ExistAccouts(ctx context.Context, accountIDs []uint64, c *controller.ControllerCfg) error { + req := cb_account.ListRequest{} + + accList, err := c.CloudBroker().Account().List(ctx, req) + if err != nil { + return err + } + + if len(accList.Data) == 0 { + return fmt.Errorf("you have not been granted access to any account") + } + + notFound := make([]uint64, 0, len(accountIDs)) + + for _, accID := range accountIDs { + found := false + + for _, acc := range accList.Data { + if accID == acc.ID { + found = true + break + } + } + + if !found { + notFound = append(notFound, accID) + } + } + + if len(notFound) > 0 { + return fmt.Errorf("Accounts with ids %v not found", notFound) + } + + return nil +} + +func ExistImage(ctx context.Context, imageId uint64, c *controller.ControllerCfg) error { + req := cb_image.ListRequest{ + ByID: imageId, + } + + listImages, err := c.CloudBroker().Image().List(ctx, req) + if err != nil { + return err + } + + if len(listImages.Data) == 0 { + return fmt.Errorf("image with id %v not found", imageId) + } + + return nil +} + +func ExistImages(ctx context.Context, imageIDs []uint64, c *controller.ControllerCfg) error { + req := cb_image.ListRequest{} + + listImages, err := c.CloudBroker().Image().List(ctx, req) + if err != nil { + return err + } + + if len(listImages.Data) == 0 { + return fmt.Errorf("you have not been granted access to any images") + } + + notFound := make([]uint64, 0, len(imageIDs)) + + for _, imageID := range imageIDs { + found := false + + for _, image := range listImages.Data { + if imageID == image.ID { + found = true + break + } + } + + if !found { + notFound = append(notFound, imageID) + } + } + + if len(notFound) > 0 { + return fmt.Errorf("images with ids %v not found", notFound) + } + + return nil +} + +func ExistVins(ctx context.Context, vinsId uint64, c *controller.ControllerCfg) error { + req := cb_vins.ListRequest{ + ByID: vinsId, + IncludeDeleted: false, + } + + vinsList, err := c.CloudBroker().VINS().List(ctx, req) + if err != nil { + return err + } + + if len(vinsList.Data) == 0 { + return fmt.Errorf("vins with ID %v not found", vinsId) + } + + return nil +} + +func ExistVinses(ctx context.Context, vinsIds []uint64, c *controller.ControllerCfg) []error { + var errs []error + + if len(vinsIds) == 0 { + return errs + } + + req := cb_vins.ListRequest{ + IncludeDeleted: false, + } + + vinsList, err := c.CloudBroker().VINS().List(ctx, req) + if err != nil { + errs = append(errs, err) + return errs + } + + for _, vinsId := range vinsIds { + found := false + + for _, vins := range vinsList.Data { + if vinsId == vins.ID { + found = true + break + } + } + + if !found { + errs = append(errs, fmt.Errorf("VINS with ID %v not found", vinsId)) + } + } + + return errs +} + +func ExistExtNets(ctx context.Context, extNetIds []uint64, c *controller.ControllerCfg) []error { + var errs []error + + if len(extNetIds) == 0 { + return errs + } + + req := cb_extnet.ListRequest{} + + extNetList, err := c.CloudBroker().ExtNet().List(ctx, req) + if err != nil { + errs = append(errs, err) + return errs + } + + for _, extNetId := range extNetIds { + found := false + + for _, extNet := range extNetList.Data { + if extNetId == extNet.ID { + found = true + break + } + } + + if !found { + errs = append(errs, fmt.Errorf("EXTNET with ID %v not found", extNetId)) + } + } + + return errs +} + +func ExistVFPools(ctx context.Context, vfpoolIds []uint64, c *controller.ControllerCfg) []error { + var errs []error + + if len(vfpoolIds) == 0 { + return errs + } + + req := cb_vfpool.ListRequest{} + + vfpoolList, err := c.CloudBroker().VFPool().List(ctx, req) + if err != nil { + errs = append(errs, err) + return errs + } + + for _, vfpoolId := range vfpoolIds { + found := false + + for _, vfpool := range vfpoolList.Data { + if vfpoolId == vfpool.ID { + found = true + break + } + } + + if !found { + errs = append(errs, fmt.Errorf("VFPool with ID %v not found", vfpoolId)) + } + } + + return errs +} + +func ExistDPDKNet(ctx context.Context, dpdkIds []uint64, c *controller.ControllerCfg) []error { + var errs []error + + if len(dpdkIds) == 0 { + return errs + } + + req := cb_dpdk.ListRequest{} + + dpdkList, err := c.CloudBroker().DPDKNet().List(ctx, req) + if err != nil { + errs = append(errs, err) + return errs + } + + for _, dpdkId := range dpdkIds { + found := false + + for _, dpdk := range dpdkList.Data { + if dpdkId == dpdk.ID { + found = true + break + } + } + + if !found { + errs = append(errs, fmt.Errorf("DPDKNet with ID %v not found", dpdkId)) + } + } + + return errs +} + +func ExistTrunkNet(ctx context.Context, trunkIds []uint64, c *controller.ControllerCfg) []error { + var errs []error + + if len(trunkIds) == 0 { + return errs + } + + req := cb_trunk.ListRequest{} + + trunkList, err := c.CloudBroker().Trunk().List(ctx, req) + if err != nil { + errs = append(errs, err) + return errs + } + + for _, trunkId := range trunkIds { + found := false + + for _, trunk := range trunkList.Data { + if trunkId == trunk.ID { + found = true + break + } + } + + if !found { + errs = append(errs, fmt.Errorf("TRUNK Net with ID %v not found", trunkId)) + } + } + + return errs +} + +func ExistExtNetInLb(ctx context.Context, extNetId uint64, c *controller.ControllerCfg) error { + if extNetId == 0 { + return nil + } + req := cb_extnet.ListRequest{ + ByID: extNetId, + } + + extNetList, err := c.CloudBroker().ExtNet().List(ctx, req) + if err != nil { + return err + } + + if len(extNetList.Data) == 0 { + return fmt.Errorf("EXTNET with ID %v not found", extNetId) + } + + return nil +} + +func ExistExtNetInRG(ctx context.Context, extNetId, accountId uint64, c *controller.ControllerCfg) error { + req := cb_extnet.ListRequest{ + AccountID: accountId, + ByID: extNetId, + } + + listExtNet, err := c.CloudBroker().ExtNet().List(ctx, req) + if err != nil { + return err + } + + if len(listExtNet.Data) == 0 { + return fmt.Errorf("EXTNET with ID %v not found for account with id %d", extNetId, accountId) + } + + return nil +} + +func ExistExtNetInVins(ctx context.Context, extNetId int, c *controller.ControllerCfg) error { + if extNetId == 0 || extNetId == -1 { + return nil + } + req := cb_extnet.ListRequest{ + ByID: uint64(extNetId), + } + + extNetList, err := c.CloudBroker().ExtNet().List(ctx, req) + if err != nil { + return err + } + + if len(extNetList.Data) == 0 { + return fmt.Errorf("EXTNET with ID %v not found", extNetId) + } + + return nil +} + +func ExistExtNet(ctx context.Context, extNetId uint64, c *controller.ControllerCfg) error { + + req := cb_extnet.ListRequest{ + ByID: extNetId, + Status: "Enabled", + } + + extNetList, err := c.CloudBroker().ExtNet().List(ctx, req) + if err != nil { + return err + } + + if len(extNetList.Data) == 0 { + return fmt.Errorf("EXTNET with ID %v not found", extNetId) + } + + return nil +} + +func ExistVinsInLb(ctx context.Context, vinsId uint64, c *controller.ControllerCfg) error { + if vinsId == 0 { + return nil + } + + req := cb_vins.ListRequest{ + ByID: vinsId, + } + + vinsList, err := c.CloudBroker().VINS().List(ctx, req) + if err != nil { + return err + } + + if len(vinsList.Data) == 0 { + return fmt.Errorf("VINS with ID %v not found", vinsId) + } + + return nil +} + +func ExistGID(ctx context.Context, gid uint64, c *controller.ControllerCfg) error { + req := cb_gid.ListRequest{} + + gridList, err := c.CloudBroker().Grid().List(ctx, req) + if err != nil { + return err + } + + for _, grid := range gridList.Data { + if grid.GID == gid { + return nil + } + } + + return fmt.Errorf("GID with id %v not found", gid) +} + +func ExistNode(ctx context.Context, nodeId uint64, c *controller.ControllerCfg) error { + req := cb_node.ListRequest{ + ByID: nodeId, + } + + nodeList, err := c.CloudBroker().Node().List(ctx, req) + if err != nil { + return err + } + + if len(nodeList.Data) == 0 { + return fmt.Errorf("node with id %v not found", nodeList) + } + + return nil +} + +func ExistLB(ctx context.Context, lbId uint64, c *controller.ControllerCfg) error { + + req := cb_lb.ListRequest{ + ByID: lbId, + } + + lbList, err := c.CloudBroker().LB().List(ctx, req) + if err != nil { + return err + } + + if len(lbList.Data) == 0 { + return fmt.Errorf("LB with ID %v not found", lbId) + } + + return nil + +} + +func ExistAccount(ctx context.Context, accountId uint64, c *controller.ControllerCfg) error { + req := cb_account.ListRequest{ + ByID: accountId, + } + + accountList, err := c.CloudBroker().Account().List(ctx, req) + if err != nil { + return err + } + + if len(accountList.Data) == 0 { + return fmt.Errorf("account with id %d not found", accountId) + } + + return nil +} + +func ExistK8CI(ctx context.Context, k8ciId uint64, c *controller.ControllerCfg) error { + req := cb_k8ci.ListRequest{ + ByID: k8ciId, + } + + k8ciList, err := c.CloudBroker().K8CI().List(ctx, req) + if err != nil { + return err + } + + if len(k8ciList.Data) == 0 { + return fmt.Errorf("k8ci with id %d not found", k8ciId) + } + + return nil +} + +func ExistExtNetInK8s(ctx context.Context, extNetId uint64, c *controller.ControllerCfg) error { + if extNetId == 0 { + return nil + } + req := cb_extnet.ListRequest{ + ByID: extNetId, + } + + extNetList, err := c.CloudBroker().ExtNet().List(ctx, req) + if err != nil { + return err + } + + if len(extNetList.Data) == 0 { + return fmt.Errorf("EXTNET with ID %v not found", extNetId) + } + + return nil +} + +func ExistVinsInK8s(ctx context.Context, vinsId uint64, c *controller.ControllerCfg) error { + if vinsId == 0 { + return nil + } + + req := cb_vins.ListRequest{ + ByID: vinsId, + } + + vinsList, err := c.CloudBroker().VINS().List(ctx, req) + if err != nil { + return err + } + + if len(vinsList.Data) == 0 { + return fmt.Errorf("VINS with ID %v not found", vinsId) + } + + return nil +} + +func ExistK8s(ctx context.Context, k8sId uint64, c *controller.ControllerCfg) error { + req := cb_k8s.ListRequest{ + ByID: k8sId, + } + + k8sList, err := c.CloudBroker().K8S().List(ctx, req) + if err != nil { + return err + } + + if len(k8sList.Data) == 0 { + return fmt.Errorf("k8s with id %d not found", k8sId) + } + + return nil +} + +func IsMoreThanOneDisksTypeB(ctx context.Context, disks interface{}, chipset string) error { + count := 0 + + key := "bus_number" + if chipset == "i440fx" { + key = "pci_slot" + } + + for _, elem := range disks.([]interface{}) { + diskVal := elem.(map[string]interface{}) + + if val, ok := diskVal[key].(int); ok && val == 6 { + count++ + } + + if count > 1 { + return fmt.Errorf("block disks have more 1 disk type 'B'") + } + } + + return nil +} + +func ExistDiskID(ctx context.Context, diskId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + req := cb_disks.ListRequest{ + ByID: diskId, + } + + diskList, err := c.CloudBroker().Disks().List(ctx, req) + if err != nil { + return err + } + + if len(diskList.Data) == 0 { + return fmt.Errorf("resourceDiskReplication: can't create or update Disk replication because DiskID %d is not allowed or does not exist", diskId) + } + + if diskList.Data[0].SEPType != "TATLIN" { + return fmt.Errorf("resourceDiskReplication: can't create or update Disk replication because DiskID %d is not TATLIN SEP Type", diskId) + } + + return nil +} + +func ExistBlankCompute(ctx context.Context, computeId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + req := cb_compute.GetRequest{ComputeID: computeId} + + // check for compute existence + computeRecord, err := c.CloudBroker().Compute().Get(ctx, req) + if err != nil { + return fmt.Errorf("ComputeID %d is not allowed or does not exist", computeId) + } + + // check if compute was created as blank + computeImageId := computeRecord.ImageID + bootImageId := -1 + for _, d := range computeRecord.Disks { + if computeRecord.Chipset == "i440fx" { + if d.PCISlot == 6 { + bootImageId = int(d.ImageID) + break + } + } else { + if d.BusNumber == 6 { + bootImageId = int(d.ImageID) + break + } + } + } + + if computeImageId != 0 && bootImageId != 0 { + return fmt.Errorf("ComputeID %d is not allowed because it is not blank compute (either compute imageId or boot imageId are not zero)", computeId) + } + + return nil +} + +func ExistPlatformDisk(ctx context.Context, diskId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + req := cb_disks.ListRequest{ + ByID: diskId, + } + + diskList, err := c.CloudBroker().Disks().List(ctx, req) + if err != nil { + return err + } + + if len(diskList.Data) != 1 { + return fmt.Errorf("DiskID %d is not allowed or does not exist", diskId) + } + + return nil +} + +func ExistSDNNet(ctx context.Context, sdnIds []string, c *controller.ControllerCfg) []error { + var errs []error + + for _, uniqueIdentifier := range sdnIds { + if uniqueIdentifier == "" { + continue + } + req := logicalports.GetByUniqueIdentifierRequest{ID: uniqueIdentifier} + _, err := c.SDN().LogicalPorts().GetByUniqueIdentifier(ctx, req) + if err != nil { + errs = append(errs, fmt.Errorf("SDN logical port with unique identifier %q not found", uniqueIdentifier)) + } + } + + return errs +} diff --git a/internal/service/cloudbroker/image/data_source_image.go b/internal/service/cloudbroker/image/data_source_image.go new file mode 100644 index 00000000..c6b4aa7c --- /dev/null +++ b/internal/service/cloudbroker/image/data_source_image.go @@ -0,0 +1,67 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + image, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId(strconv.FormatUint(image.ID, 10)) + flattenImage(d, image) + return nil +} + +func DataSourceImage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceImageRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceImageSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/image/data_source_image_list.go b/internal/service/cloudbroker/image/data_source_image_list.go new file mode 100644 index 00000000..fda82b15 --- /dev/null +++ b/internal/service/cloudbroker/image/data_source_image_list.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceImageListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + imageList, err := utilityImageListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenImageList(imageList)) + d.Set("entry_count", imageList.EntryCount) + return nil +} + +func DataSourceImageList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceImageListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceImageListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/image/flattens.go b/internal/service/cloudbroker/image/flattens.go new file mode 100644 index 00000000..156a0537 --- /dev/null +++ b/internal/service/cloudbroker/image/flattens.go @@ -0,0 +1,253 @@ +package image + +import ( + "encoding/json" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" +) + +func flattenImage(d *schema.ResourceData, img *image.RecordImage) { + cdPresentedTo, _ := json.Marshal(img.CdPresentedTo) + + log.Debugf("flattenImageID %d", img.ID) + d.Set("image_id", img.ID) + d.Set("unc_path", img.UNCPath) + d.Set("account_id", img.AccountID) + d.Set("acl", flattenAcl(img.ACL)) + d.Set("architecture", img.Architecture) + d.Set("boot_type", img.BootType) + d.Set("bootable", img.Bootable) + d.Set("computeci_id", img.ComputeCIID) + d.Set("cd_presented_to", string(cdPresentedTo)) + d.Set("deleted_time", img.DeletedTime) + d.Set("desc", img.Description) + d.Set("drivers", img.Drivers) + d.Set("enabled", img.Enabled) + d.Set("gid", img.GID) + d.Set("guid", img.GUID) + d.Set("history", flattenHistory(img.History)) + d.Set("hot_resize", img.HotResize) + d.Set("independent", img.Independent) + d.Set("last_modified", img.LastModified) + d.Set("link_to", img.LinkTo) + d.Set("links_to", img.LinksTo) + d.Set("milestones", img.Milestones) + d.Set("name", img.Name) + d.Set("network_interface_naming", img.NetworkInterfaceNaming) + d.Set("password", img.Password) + d.Set("pool_name", img.Pool) + d.Set("present_to", img.PresentTo) + d.Set("provider_name", img.ProviderName) + d.Set("purge_attempts", img.PurgeAttempts) + d.Set("reference_id", img.ReferenceID) + d.Set("res_id", img.ResID) + d.Set("res_name", img.ResName) + d.Set("rescuecd", img.RescueCD) + d.Set("sep_id", img.SEPID) + d.Set("shared_with", img.SharedWith) + d.Set("size", img.Size) + d.Set("snapshot_id", img.SnapshotID) + d.Set("status", img.Status) + d.Set("storage_policy_id", img.StoragePolicyID) + d.Set("tech_status", img.TechStatus) + d.Set("to_clean", img.ToClean) + d.Set("target_ids", img.LinksTo) + d.Set("image_type", img.Type) + d.Set("url", img.URL) + d.Set("username", img.Username) + d.Set("version", img.Version) +} + +func flattenAcl(acl image.ListACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(acl)) + for _, val := range acl { + temp := map[string]interface{}{ + "explicit": val.Explicit, + "guid": val.GUID, + "right": val.Right, + "status": val.Status, + "type": val.Type, + "user_group_id": val.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenHistory(history image.ListHistory) []map[string]interface{} { + temp := make([]map[string]interface{}, 0, len(history)) + for _, item := range history { + t := map[string]interface{}{ + "id": item.ID, + "guid": item.GUID, + "timestamp": item.Timestamp, + } + temp = append(temp, t) + } + return temp +} + +func flattenImageList(il *image.ListImages) []map[string]interface{} { + log.Debug("flattenImageList") + res := make([]map[string]interface{}, 0, len(il.Data)) + for _, item := range il.Data { + cdPresentedTo, _ := json.Marshal(item.CdPresentedTo) + + temp := map[string]interface{}{ + "image_id": item.ID, + "unc_path": item.UNCPath, + "account_id": item.AccountID, + "acl": flattenAcl(item.ACL), + "architecture": item.Architecture, + "boot_type": item.BootType, + "bootable": item.Bootable, + "computeci_id": item.ComputeCIID, + "cd_presented_to": string(cdPresentedTo), + "deleted_time": item.DeletedTime, + "desc": item.Description, + "drivers": item.Drivers, + "enabled": item.Enabled, + "gid": item.GID, + "guid": item.GUID, + "history": flattenHistory(item.History), + "hot_resize": item.HotResize, + "independent": item.Independent, + "last_modified": item.LastModified, + "link_to": item.LinkTo, + "links_to": item.LinksTo, + "milestones": item.Milestones, + "name": item.Name, + "network_interface_naming": item.NetworkInterfaceNaming, + "password": item.Password, + "pool_name": item.Pool, + "present_to": item.PresentTo, + "provider_name": item.ProviderName, + "purge_attempts": item.PurgeAttempts, + "reference_id": item.ReferenceID, + "res_id": item.ResID, + "res_name": item.ResName, + "rescuecd": item.RescueCD, + "sep_id": item.SEPID, + "shared_with": item.SharedWith, + "size": item.Size, + "snapshot_id": item.SnapshotID, + "status": item.Status, + "storage_policy_id": item.StoragePolicyID, + "tech_status": item.TechStatus, + "to_clean": item.ToClean, + "image_type": item.Type, + "url": item.URL, + "username": item.Username, + "version": item.Version, + "virtual": item.Virtual, + } + res = append(res, temp) + } + return res +} + +func flattenEco(m interface{}) string { + log.Debug("flattenEco") + output := "" + switch d := m.(type) { + case string: + output = d + case int: + output = strconv.Itoa(d) + case int64: + output = strconv.FormatInt(d, 10) + case float64: + output = strconv.FormatInt(int64(d), 10) + default: + } + return output +} + +func flattenPackages(pg image.Packages) []map[string]interface{} { + log.Debug("flattenPackages") + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "libvirt_bin": flattenLibvirtBin(pg), + "libvirt_daemon": flattenLibvirtDaemon(pg), + "lvm2_lockd": flattenLvm2Lockd(pg), + "openvswitch_common": flattenOpenvswitchCommon(pg), + "openvswitch_switch": flattenOpenvswitchSwitch(pg), + "qemu_system_x86": flattenQemuSystemX86(pg), + "sanlock": flattenSanlock(pg), + } + res = append(res, temp) + return res +} + +func flattenLibvirtBin(lb image.Packages) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "installed_size": lb.LibvirtBin.InstalledSize, + "ver": lb.LibvirtBin.Ver, + } + res = append(res, temp) + return res +} + +func flattenLibvirtDaemon(ld image.Packages) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "installed_size": ld.LibvirtDaemon.InstalledSize, + "ver": ld.LibvirtDaemon.Ver, + } + res = append(res, temp) + return res +} + +func flattenLvm2Lockd(ll image.Packages) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "installed_size": ll.Lvm2Lockd.InstalledSize, + "ver": ll.Lvm2Lockd.Ver, + } + res = append(res, temp) + return res +} + +func flattenOpenvswitchCommon(oc image.Packages) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "installed_size": oc.OpenvswitchCommon.InstalledSize, + "ver": oc.OpenvswitchCommon.Ver, + } + res = append(res, temp) + return res +} + +func flattenOpenvswitchSwitch(os image.Packages) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "installed_size": os.OpenvswitchSwitch.InstalledSize, + "ver": os.OpenvswitchSwitch.Ver, + } + res = append(res, temp) + return res +} + +func flattenQemuSystemX86(qs image.Packages) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "installed_size": qs.QemuSystemX86.InstalledSize, + "ver": qs.QemuSystemX86.Ver, + } + res = append(res, temp) + return res +} + +func flattenSanlock(sl image.Packages) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "installed_size": sl.Sanlock.InstalledSize, + "ver": sl.Sanlock.Ver, + } + res = append(res, temp) + return res +} diff --git a/internal/service/cloudbroker/image/old_schemas.go b/internal/service/cloudbroker/image/old_schemas.go new file mode 100644 index 00000000..6378b37a --- /dev/null +++ b/internal/service/cloudbroker/image/old_schemas.go @@ -0,0 +1,1394 @@ +package image + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" +) + +func resourceCDROMImageV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "url": { + Type: schema.TypeString, + Required: true, + Description: "URL where to download ISO from", + }, + "gid": { + Type: schema.TypeInt, + Required: true, + Description: "grid (platform) ID where this template should be create in", + }, + "drivers": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "username_dl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "username for upload binary media", + }, + "password_dl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "password for upload binary media", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "architecture": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "binary architecture of this image, one of X86_64", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "enabled_stacks": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + Description: "unc path", + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "meta", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true}, + "type": { + Type: schema.TypeString, + Computed: true}, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + Description: "Boot type of image bios or uefi", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "image id", + }, + "image_type": { + Type: schema.TypeString, + Computed: true, + Description: "Image type linux, windows or other", + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + Description: "", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech atatus", + }, + "version": { + Type: schema.TypeString, + Computed: true, + Description: "version", + }, + "size": { + Type: schema.TypeInt, + Computed: true, + Description: "image size", + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func resourceImageV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "url": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "URL where to download media from", + }, + "file_path": { + Type: schema.TypeString, + Optional: true, + Description: "path to image file", + }, + "gid": { + Type: schema.TypeInt, + Required: true, + Description: "grid (platform) ID where this template should be create in", + }, + "boot_type": { + Type: schema.TypeString, + Required: true, + Description: "Boot type of image bios or uefi", + }, + "image_type": { + Type: schema.TypeString, + Required: true, + Description: "Image type linux, windows or other", + }, + "drivers": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "network_interface_naming": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, true), + Description: "select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming", + }, + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "username_dl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "username for upload binary media", + }, + "password_dl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "password for upload binary media", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "architecture": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "binary architecture of this image, one of X86_64", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "sync_mode": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Create image from a media identified by URL (in synchronous mode)", + }, + "enabled_stacks": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + + "accounts": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + Description: "unc path", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true}, + "type": { + Type: schema.TypeString, + Computed: true}, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "image id", + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + Description: "", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "present_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech atatus", + }, + "version": { + Type: schema.TypeString, + Computed: true, + Description: "version", + }, + "size": { + Type: schema.TypeInt, + Computed: true, + Description: "image size", + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func resourceVirtualImageV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "link_to": { + Type: schema.TypeInt, + Required: true, + Description: "ID of real image to link this virtual image to upon creation", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "username": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Optional username for the image", + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "enabled_stacks": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + + "unc_path": { + Type: schema.TypeString, + Computed: true, + Description: "unc path", + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "meta", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + Description: "binary architecture of this image, one of X86_64", + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + Description: "Boot type of image bios or uefi", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "grid (platform) ID where this template should be create in", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image id", + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_name": { + Type: schema.TypeString, + Computed: true, + Description: "pool for image create", + }, + "present_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "storage endpoint provider ID", + }, + "size": { + Type: schema.TypeInt, + Computed: true, + Description: "image size", + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech atatus", + }, + "image_type": { + Type: schema.TypeString, + Computed: true, + Description: "Image type linux, windows or other", + }, + "url": { + Type: schema.TypeString, + Computed: true, + Description: "URL where to download media from", + }, + "version": { + Type: schema.TypeString, + Computed: true, + Description: "version", + }, + }, + } +} + +func resourceImageFromBlankComputeV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + Description: "Compute Id", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "boot_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true), + Description: "Boot type of image BIOS or UEFI", + }, + "image_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "other"}, true), + Description: "Image type linux, windows or other", + }, + + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "async_mode": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "create an image in async/sync mode", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "enabled_stacks": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + + "accounts": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "network_interface_naming": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, true), + Description: "select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming", + }, + + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true}, + "type": { + Type: schema.TypeString, + Computed: true}, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "url": { + Type: schema.TypeString, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceImageFromPlatformDiskV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "Disk Id", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "boot_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true), + Description: "Boot type of image BIOS or UEFI", + }, + "image_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "other"}, true), + Description: "Image type linux, windows or other", + }, + "architecture": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"X86_64"}, true), + Description: "Image type linux, windows or other", + }, + + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + }, + "drivers": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86"}, false), // observe case while validating + Type: schema.TypeString, + }, + Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "async_mode": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "create an image in async/sync mode", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "enabled_stacks": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + + "accounts": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "network_interface_naming": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, true), + Description: "select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming", + }, + + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true}, + "type": { + Type: schema.TypeString, + Computed: true}, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "url": { + Type: schema.TypeString, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} diff --git a/internal/service/cloudbroker/image/resource_cdrom_image.go b/internal/service/cloudbroker/image/resource_cdrom_image.go new file mode 100644 index 00000000..ef5253ab --- /dev/null +++ b/internal/service/cloudbroker/image/resource_cdrom_image.go @@ -0,0 +1,238 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceCDROMImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceCDROMImageCreate: called for image %s", d.Get("name").(string)) + c := m.(*controller.ControllerCfg) + req := image.CreateCDROMImageRequest{ + Name: d.Get("name").(string), + URL: d.Get("url").(string), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + if username, ok := d.GetOk("username_dl"); ok { + req.UsernameDL = username.(string) + } + if password, ok := d.GetOk("password_dl"); ok { + req.PasswordDl = password.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if sepId, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepId.(int)) + } + if poolName, ok := d.GetOk("pool_name"); ok { + req.PoolName = poolName.(string) + } + + imageId, err := c.CloudBroker().Image().CreateCDROMImage(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(imageId, 10)) + + return resourceImageRead(ctx, d, m) +} + +func resourceCDROMImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceCDROMImageRead: called for %s id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + flattenImage(d, img) + + return nil +} + +func resourceCDROMImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceCDROMImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + imageData, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := image.DeleteCDROMImageRequest{ + ImageID: imageData.ID, + } + + _, err = c.CloudBroker().Image().DeleteCDROMImage(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceCDROMImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceCDROMImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + if d.HasChange("enabled") { + err := resourceImageChangeEnabled(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shared_with") { + err := resourceImageShare(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("computeci_id") { + err := resourceImageChangeComputeci(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("name", "password_dl", "username_dl", "account_id", "bootable", "hot_resize") { + err := resourceImageCDROMEdit(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return nil +} + +func resourceImageCDROMEdit(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*controller.ControllerCfg) + req := image.EditRequest{} + + req.ImageID = uint64(d.Get("image_id").(int)) + if d.HasChange("name") { + req.Name = d.Get("name").(string) + } + if d.HasChange("username_dl") { + req.Username = d.Get("username_dl").(string) + } + if d.HasChange("password_dl") { + req.Password = d.Get("password_dl").(string) + } + if d.HasChange("account_id") { + req.AccountID = uint64(d.Get("account_id").(int)) + } + if d.HasChange("bootable") { + req.Bootable = d.Get("bootable").(bool) + } + if d.HasChange("hot_resize") { + req.HotResize = d.Get("hot_resize").(bool) + } + + _, err := c.CloudBroker().Image().Edit(ctx, req) + if err != nil { + return err + } + return nil +} + +func ResourceCDROMImage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceCDROMImageCreate, + ReadContext: resourceCDROMImageRead, + UpdateContext: resourceCDROMImageUpdate, + DeleteContext: resourceCDROMImageDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceCDROMImageSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceCDROMImageV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourcePresentTOUpgradeV1, + Version: 1, + }, + }, + } +} diff --git a/internal/service/cloudbroker/image/resource_check_input_values.go b/internal/service/cloudbroker/image/resource_check_input_values.go new file mode 100644 index 00000000..c4a66714 --- /dev/null +++ b/internal/service/cloudbroker/image/resource_check_input_values.go @@ -0,0 +1,50 @@ +package image + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func checkParamsExistenceBlankCompute(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + accountID := uint64(d.Get("account_id").(int)) + computeId := uint64(d.Get("compute_id").(int)) + + if err := ic.ExistBlankCompute(ctx, computeId, c); err != nil { + errs = append(errs, err) + } + + if _, ok := d.GetOk("account_id"); ok { + if err := ic.ExistAccount(ctx, accountID, c); err != nil { + errs = append(errs, err) + } + } + + return dc.ErrorsToDiagnostics(errs) +} + +func checkParamsExistencePlatformDisk(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + accountID := uint64(d.Get("account_id").(int)) + diskId := uint64(d.Get("disk_id").(int)) + + if err := ic.ExistPlatformDisk(ctx, diskId, c); err != nil { + errs = append(errs, err) + } + + if _, ok := d.GetOk("account_id"); ok { + if err := ic.ExistAccount(ctx, accountID, c); err != nil { + errs = append(errs, err) + } + } + + return dc.ErrorsToDiagnostics(errs) +} diff --git a/internal/service/cloudbroker/image/resource_image.go b/internal/service/cloudbroker/image/resource_image.go new file mode 100644 index 00000000..5ccce973 --- /dev/null +++ b/internal/service/cloudbroker/image/resource_image.go @@ -0,0 +1,387 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string)) + + url, _ := d.GetOk("url") + + c := m.(*controller.ControllerCfg) + + syncMode := d.Get("sync_mode").(bool) + log.Debugf("resourceImageCreate: sync_mode = %t", d.Get("sync_mode").(bool)) + var imageId uint64 + + req, err := CreateRequest(ctx, d, m, url.(string)) + + if syncMode { + if err != nil { + return diag.FromErr(err) + } + imageId, err = c.CloudBroker().Image().CreateImage(ctx, req) + log.Debugf("resourceImageCreate: imageID = %d", imageId) + if err != nil { + return diag.FromErr(err) + } + } else { + if err != nil { + return diag.FromErr(err) + } + taskID, err := c.CloudBroker().Image().AsyncCreateImage(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskID, `"`), + } + + for { + time.Sleep(time.Second * 15) + task, err := c.CloudBroker().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceAccountDelete: delete account - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot delete account: %v", task.Error)) + } + id, err := task.Result.ID() + imageId = uint64(id) + if err != nil { + return diag.FromErr(err) + } + break + } + } + } + + d.SetId(strconv.FormatUint(imageId, 10)) + + var w dc.Warnings + + if _, ok := d.GetOk("shared_with"); ok { + if err := resourceImageShare(ctx, d, m); err != nil { + w.Add(err) + } + } + + return append(resourceImageRead(ctx, d, m), w.Get()...) +} + +func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageRead: called for %s id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + flattenImage(d, img) + + return nil +} + +func resourceImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + _, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := image.DeleteRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } + + _, err = c.CloudBroker().Image().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + if d.HasChange("enabled") { + err := resourceImageChangeEnabled(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shared_with") { + err := resourceImageShare(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("computeci_id") { + err := resourceImageChangeComputeci(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize", "network_interface_naming") { + err := resourceImageEdit(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return nil +} + +func resourceImageChangeEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + imageId := uint64(d.Get("image_id").(int)) + + if d.Get("enabled").(bool) { + req := image.EnableRequest{ + ImageID: imageId, + } + + _, err := c.CloudBroker().Image().Enable(ctx, req) + if err != nil { + return err + } + } else { + req := image.DisableRequest{ + ImageID: imageId, + } + + _, err := c.CloudBroker().Image().Disable(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func resourceImageShare(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceImageShare: called for %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*controller.ControllerCfg) + + imageID, _ := strconv.ParseUint(d.Id(), 10, 64) + + sharedWith := d.Get("shared_with").([]interface{}) + if len(sharedWith) == 0 { + req := image.RevokeAccessRequest{ + ImageID: imageID, + AccountIDs: []int64{-1}, + } + _, err := c.CloudBroker().Image().RevokeAccess(ctx, req) + if err != nil { + return err + } + return nil + } + + req := image.ShareRequest{ + ImageId: imageID, + } + accIds := []uint64{} + for _, accId := range sharedWith { + accIds = append(accIds, uint64(accId.(int))) + } + req.AccountIDs = accIds + + getReq := image.GetRequest{ImageID: imageID} + + for { + image, err := c.CloudBroker().Image().Get(ctx, getReq) + if err != nil { + return err + } + if image.Status != "CREATING" { + break + } + time.Sleep(time.Second * 10) + } + + _, err := c.CloudBroker().Image().Share(ctx, req) + if err != nil { + return err + } + + return nil +} + +func resourceImageChangeComputeci(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + imageId := uint64(d.Get("image_id").(int)) + computeci := uint64(d.Get("computeci_id").(int)) + + if computeci == 0 { + req := image.ComputeCIUnsetRequest{ + ImageID: imageId, + } + + _, err := c.CloudBroker().Image().ComputeCIUnset(ctx, req) + if err != nil { + return err + } + } else { + req := image.ComputeCISetRequest{ + ImageID: imageId, + ComputeCIID: computeci, + } + + _, err := c.CloudBroker().Image().ComputeCISet(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*controller.ControllerCfg) + req := image.EditRequest{} + + req.ImageID = uint64(d.Get("image_id").(int)) + if d.HasChange("name") { + req.Name = d.Get("name").(string) + } + if d.HasChange("username") { + req.Username = d.Get("username").(string) + } + if d.HasChange("password") { + req.Password = d.Get("password").(string) + } + if d.HasChange("account_id") { + req.AccountID = uint64(d.Get("account_id").(int)) + } + if d.HasChange("bootable") { + req.Bootable = d.Get("bootable").(bool) + } + if d.HasChange("hot_resize") { + req.HotResize = d.Get("hot_resize").(bool) + } + if d.HasChange("network_interface_naming") { + req.NetworkInterfaceNaming = d.Get("network_interface_naming").(string) + } + _, err := c.CloudBroker().Image().Edit(ctx, req) + if err != nil { + return err + } + return nil +} + +func ResourceImage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceImageCreate, + ReadContext: resourceImageRead, + UpdateContext: resourceImageUpdate, + DeleteContext: resourceImageDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceImageSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceImageV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourcePresentTOUpgradeV1, + Version: 1, + }, + }, + } +} diff --git a/internal/service/cloudbroker/image/resource_image_from_blank_compute.go b/internal/service/cloudbroker/image/resource_image_from_blank_compute.go new file mode 100644 index 00000000..82a5281d --- /dev/null +++ b/internal/service/cloudbroker/image/resource_image_from_blank_compute.go @@ -0,0 +1,286 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceImageFromBlankComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromBlankComputeCreate: called for image %s", d.Get("name").(string)) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistenceBlankCompute(ctx, d, c); diags != nil { + return diags + } + + req := compute.CreateTemplateFromBlankRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + Name: d.Get("name").(string), + BootType: d.Get("boot_type").(string), + ImageType: d.Get("image_type").(string), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + if username, ok := d.GetOk("username"); ok { + req.Username = username.(string) + } + if password, ok := d.GetOk("password"); ok { + req.Password = password.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if poolName, ok := d.GetOk("pool_name"); ok { + req.PoolName = poolName.(string) + } + if hotresize, ok := d.GetOk("hot_resize"); ok { + req.HotResize = hotresize.(bool) + } + + var imageId uint64 + var err error + asyncMode := d.Get("async_mode").(bool) + if !asyncMode { + imageId, err = c.CloudBroker().Compute().CreateTemplateFromBlank(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } else { + taskId, err := c.CloudBroker().Compute().CreateTemplateFromBlankAsync(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskId, `"`), + } + + for { + task, err := c.CloudBroker().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceImageFromBlankComputeCreate: instance creating - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot create image instance: %v", task.Error)) + } + + id, err := task.Result.ID() + imageId = uint64(id) + if err != nil { + return diag.FromErr(err) + } + break + } + + time.Sleep(time.Second * 20) + } + } + + d.SetId(strconv.FormatUint(imageId, 10)) + d.Set("image_id", imageId) + + var w dc.Warnings + + if _, ok := d.GetOk("shared_with"); ok { + if err := resourceImageShare(ctx, d, m); err != nil { + w.Add(err) + } + } + + return append(resourceImageFromBlankComputeRead(ctx, d, m), w.Get()...) +} + +func resourceImageFromBlankComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromBlankComputeRead: called for %s id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + flattenImage(d, img) + + return nil +} + +func resourceImageFromBlankComputeDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromBlankComputeDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + _, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := image.DeleteRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } + + _, err = c.CloudBroker().Image().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceImageFromBlankComputeUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromBlankComputeUpdate: called for %s, id: %s", d.Get("name").(string), d.Id()) + + c := m.(*controller.ControllerCfg) + if diags := checkParamsExistenceBlankCompute(ctx, d, c); diags != nil { + return diags + } + + // we do not allow change of compute_id, but allow resource update after import + old, _ := d.GetChange("compute_id") + if old.(int) != 0 && d.HasChange("compute_id") { + return diag.Errorf("resourceImageFromBlankComputeUpdate: can't update Image because compute_id is not allowed to be changed") + } + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + if d.HasChange("enabled") { + err := resourceImageChangeEnabled(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shared_with") { + err := resourceImageShare(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("computeci_id") { + err := resourceImageChangeComputeci(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize", "network_interface_naming") { + err := resourceImageEdit(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shared_with") { + err := resourceImageShare(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceImageFromBlankComputeRead(ctx, d, m) +} + +func ResourceImageFromBlankCompute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceImageFromBlankComputeCreate, + ReadContext: resourceImageFromBlankComputeRead, + UpdateContext: resourceImageFromBlankComputeUpdate, + DeleteContext: resourceImageFromBlankComputeDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout30m, + Read: &constants.Timeout900s, + Update: &constants.Timeout900s, + Delete: &constants.Timeout900s, + Default: &constants.Timeout900s, + }, + + Schema: resourceImageFromBlankComputeSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceImageFromBlankComputeV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourcePresentTOUpgradeV1, + Version: 1, + }, + }, + } +} diff --git a/internal/service/cloudbroker/image/resource_image_from_platform_disk.go b/internal/service/cloudbroker/image/resource_image_from_platform_disk.go new file mode 100644 index 00000000..c2afa05d --- /dev/null +++ b/internal/service/cloudbroker/image/resource_image_from_platform_disk.go @@ -0,0 +1,287 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceImageFromPlatformDiskCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromPlatformDiskCreate: called for image %s", d.Get("name").(string)) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistencePlatformDisk(ctx, d, c); diags != nil { + return diags + } + + req := disks.FromPlatformDiskRequest{ + DiskID: uint64(d.Get("disk_id").(int)), + Name: d.Get("name").(string), + BootType: d.Get("boot_type").(string), + ImageType: d.Get("image_type").(string), + Bootable: d.Get("bootable").(bool), // default is true + } + + if username, ok := d.GetOk("username"); ok { + req.Username = username.(string) + } + if password, ok := d.GetOk("password"); ok { + req.Password = password.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if poolName, ok := d.GetOk("pool_name"); ok { + req.PoolName = poolName.(string) + } + + if hotresize, ok := d.GetOk("hot_resize"); ok { + req.HotResize = hotresize.(bool) + } + + var imageId uint64 + var err error + asyncMode := d.Get("async_mode").(bool) + if !asyncMode { + imageId, err = c.CloudBroker().Disks().FromPlatformDisk(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } else { + taskId, err := c.CloudBroker().Disks().FromPlatformDiskAsync(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskId, `"`), + } + + for { + task, err := c.CloudBroker().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceImageFromPlatformDiskCreate: instance creating - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot create image instance: %v", task.Error)) + } + + id, err := task.Result.ID() + imageId = uint64(id) + if err != nil { + return diag.FromErr(err) + } + break + } + + time.Sleep(time.Second * 20) + } + } + + d.SetId(strconv.FormatUint(imageId, 10)) + d.Set("image_id", imageId) + + var w dc.Warnings + + if _, ok := d.GetOk("shared_with"); ok { + if err := resourceImageShare(ctx, d, m); err != nil { + w.Add(err) + } + } + + return append(resourceImageFromPlatformDiskRead(ctx, d, m), w.Get()...) +} + +func resourceImageFromPlatformDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromPlatformDiskRead: called for %s id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + flattenImage(d, img) + + return nil +} + +func resourceImageFromPlatformDiskDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromPlatformDiskDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + _, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := image.DeleteRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } + + _, err = c.CloudBroker().Image().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceImageFromPlatformDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageFromPlatformDiskUpdate: called for %s, id: %s", d.Get("name").(string), d.Id()) + + c := m.(*controller.ControllerCfg) + if diags := checkParamsExistencePlatformDisk(ctx, d, c); diags != nil { + return diags + } + + // we do not allow change of disk_id, but allow resource update after import + old, _ := d.GetChange("disk_id") + if old.(int) != 0 && d.HasChange("disk_id") { + return diag.Errorf("resourceImageFromPlatformDiskUpdate: can't update Image because disk_id is not allowed to be changed") + } + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + if d.HasChange("enabled") { + err := resourceImageChangeEnabled(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shared_with") { + err := resourceImageShare(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("computeci_id") { + err := resourceImageChangeComputeci(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize", "network_interface_naming") { + err := resourceImageEdit(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shared_with") { + err := resourceImageShare(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceImageFromPlatformDiskRead(ctx, d, m) +} + +func ResourceImageFromPlatformDisk() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceImageFromPlatformDiskCreate, + ReadContext: resourceImageFromPlatformDiskRead, + UpdateContext: resourceImageFromPlatformDiskUpdate, + DeleteContext: resourceImageFromPlatformDiskDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout30m, + Read: &constants.Timeout900s, + Update: &constants.Timeout900s, + Delete: &constants.Timeout900s, + Default: &constants.Timeout900s, + }, + + Schema: resourceImageFromPlatformDiskSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceImageFromPlatformDiskV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourcePresentTOUpgradeV1, + Version: 1, + }, + }, + } +} diff --git a/internal/service/cloudbroker/image/resource_multi_image.go b/internal/service/cloudbroker/image/resource_multi_image.go new file mode 100644 index 00000000..fd2996fd --- /dev/null +++ b/internal/service/cloudbroker/image/resource_multi_image.go @@ -0,0 +1,274 @@ +package image + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceMultiImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceMultiImageCreate: called for image %s", d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + + targetIDsRaw := d.Get("target_ids").([]interface{}) + targetIDs := make([]uint64, 0, len(targetIDsRaw)) + for _, id := range targetIDsRaw { + targetIDs = append(targetIDs, uint64(id.(int))) + } + + req := image.CreateMultiImageRequest{ + Name: d.Get("name").(string), + TargetIDs: targetIDs, + AccountID: uint64(d.Get("account_id").(int)), + } + + imageId, err := c.CloudBroker().Image().CreateMultiImage(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(imageId, 10)) + d.Set("image_id", imageId) + + var w dc.Warnings + + if !d.Get("enabled").(bool) { + if err := resourceImageChangeEnabled(ctx, d, m); err != nil { + w.Add(err) + } + } + + if _, ok := d.GetOk("shared_with"); ok { + if err := resourceImageShare(ctx, d, m); err != nil { + w.Add(err) + } + } + + if _, ok := d.GetOk("computeci_id"); ok { + if err := resourceImageChangeComputeci(ctx, d, m); err != nil { + w.Add(err) + } + } + + updReq := image.EditRequest{} + updReq.ImageID = uint64(d.Get("image_id").(int)) + + if _, ok := d.GetOk("username"); ok { + updReq.Username = d.Get("username").(string) + } + if _, ok := d.GetOk("password"); ok { + updReq.Password = d.Get("password").(string) + } + if _, ok := d.GetOk("account_id"); ok { + updReq.AccountID = uint64(d.Get("account_id").(int)) + } + if _, ok := d.GetOkExists("bootable"); ok { + updReq.Bootable = d.Get("bootable").(bool) + } + if _, ok := d.GetOkExists("hot_resize"); ok { + updReq.HotResize = d.Get("hot_resize").(bool) + } + if _, ok := d.GetOk("network_interface_naming"); ok { + updReq.NetworkInterfaceNaming = d.Get("network_interface_naming").(string) + } + _, err = c.CloudBroker().Image().Edit(ctx, updReq) + if err != nil { + w.Add(err) + } + + return append(resourceMultiImageRead(ctx, d, m), w.Get()...) +} + +func resourceMultiImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceMultiImageRead: called for %s id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + flattenImage(d, img) + + return nil +} + +func resourceMultiImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceMultiImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + _, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := image.DeleteRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } + + _, err = c.CloudBroker().Image().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceMultiImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceMultiImageUpdate: called for %s, id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + if d.HasChange("enabled") { + err := resourceImageChangeEnabled(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shared_with") { + err := resourceImageShare(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("computeci_id") { + err := resourceImageChangeComputeci(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize") { + err := resourceImageEdit(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("target_ids") { + err := resourceMultiImageUpdateLinks(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceMultiImageRead(ctx, d, m) +} + +func resourceMultiImageUpdateLinks(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceMultiImageUpdateLinks: called for %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*controller.ControllerCfg) + + imageID := uint64(d.Get("image_id").(int)) + + oldRaw, newRaw := d.GetChange("target_ids") + oldIDs := oldRaw.([]interface{}) + newIDs := newRaw.([]interface{}) + + oldSet := make(map[uint64]bool) + for _, id := range oldIDs { + oldSet[uint64(id.(int))] = true + } + + newSet := make(map[uint64]bool) + for _, id := range newIDs { + newSet[uint64(id.(int))] = true + } + + toAdd := make([]uint64, 0) + for id := range newSet { + if !oldSet[id] { + toAdd = append(toAdd, id) + } + } + + toRemove := make([]uint64, 0) + for id := range oldSet { + if !newSet[id] { + toRemove = append(toRemove, id) + } + } + + if len(toAdd) > 0 { + req := image.MultiImageAddLinksRequest{ + ImageID: imageID, + TargetIDs: toAdd, + } + _, err := c.CloudBroker().Image().MultiImageAddLinks(ctx, req) + if err != nil { + return err + } + } + + if len(toRemove) > 0 { + req := image.MultiImageDelLinksRequest{ + ImageID: imageID, + TargetIDs: toRemove, + } + _, err := c.CloudBroker().Image().MultiImageDelLinks(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func ResourceMultiImage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceMultiImageCreate, + ReadContext: resourceMultiImageRead, + UpdateContext: resourceMultiImageUpdate, + DeleteContext: resourceMultiImageDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceMultiImageSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/image/resource_virtual_image.go b/internal/service/cloudbroker/image/resource_virtual_image.go new file mode 100644 index 00000000..a6814c87 --- /dev/null +++ b/internal/service/cloudbroker/image/resource_virtual_image.go @@ -0,0 +1,214 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceVirtualImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + req := image.CreateVirtualRequest{ + Name: d.Get("name").(string), + TargetID: uint64(d.Get("link_to").(int)), + AccountID: uint64(d.Get("account_id").(int)), + } + + imageId, err := c.CloudBroker().Image().CreateVirtual(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(imageId, 10)) + + return resourceImageRead(ctx, d, m) +} + +func resourceVirtualImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceVirtualImageRead: called for %s id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + flattenImage(d, img) + + return nil +} + +func resourceVirtualImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceVirtualImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + _, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := image.DeleteRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } + + _, err = c.CloudBroker().Image().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceVirtualImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceVirtualImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id()) + + img, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch img.Status { + case status.Modeled: + return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status) + case status.Destroyed, status.Purged: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + } + + if d.HasChange("enabled") { + err := resourceImageChangeEnabled(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shared_with") { + err := resourceImageShare(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("computeci_id") { + err := resourceImageChangeComputeci(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize") { + err := resourceImageEdit(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("link_to") { + err := resourceImageLink(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return nil +} + +func resourceImageLink(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceVirtualImageLink: called for %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*controller.ControllerCfg) + req := image.LinkRequest{ + ImageID: uint64(d.Get("image_id").(int)), + TargetID: uint64(d.Get("link_to").(int)), + } + + _, err := c.CloudBroker().Image().Link(ctx, req) + if err != nil { + return err + } + + return nil +} + +func ResourceVirtualImage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceVirtualImageCreate, + ReadContext: resourceVirtualImageRead, + UpdateContext: resourceVirtualImageUpdate, + DeleteContext: resourceVirtualImageDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceVirtualImageSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceVirtualImageV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourcePresentTOUpgradeV1, + Version: 1, + }, + }, + } +} diff --git a/internal/service/cloudbroker/image/schema.go b/internal/service/cloudbroker/image/schema.go new file mode 100644 index 00000000..68184ffd --- /dev/null +++ b/internal/service/cloudbroker/image/schema.go @@ -0,0 +1,2267 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceImageListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Description: "find by storage endpoint provider ID", + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "find by name", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "find by status", + }, + "architecture": { + Type: schema.TypeString, + Optional: true, + Description: "find by architecture", + }, + "type_image": { + Type: schema.TypeList, + Optional: true, + Description: "find by type", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "image_size": { + Type: schema.TypeInt, + Optional: true, + Description: "find by image size", + }, + "sep_name": { + Type: schema.TypeString, + Optional: true, + Description: "find by SEP name", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Description: "find by pool", + }, + "public": { + Type: schema.TypeBool, + Optional: true, + Description: "find by public True or False", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Description: "find by hot resize True or False", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Description: "find by bootable True or False", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: "find by enabled True or False", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "image list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unc_path": { + Type: schema.TypeString, + Computed: true, + Description: "unc path", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + Description: "binary architecture of this image, one of X86_64", + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + Description: "Boot type of image bios or uefi", + }, + "bootable": { + Type: schema.TypeBool, + Computed: true, + Description: "Does this image boot OS", + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]", + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "grid (platform) ID where this template should be create in", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "image id", + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "links_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the rescue disk", + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + Description: "Optional password for the image", + }, + "pool_name": { + Type: schema.TypeString, + Computed: true, + Description: "pool for image create", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "storage endpoint provider ID", + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + Description: "image size", + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech atatus", + }, + "image_type": { + Type: schema.TypeString, + Computed: true, + Description: "Image type linux, windows or other", + }, + "url": { + Type: schema.TypeString, + Computed: true, + Description: "URL where to download media from", + }, + "username": { + Type: schema.TypeString, + Computed: true, + Description: "Optional username for the image", + }, + "version": { + Type: schema.TypeString, + Computed: true, + Description: "version", + }, + "virtual": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry count", + }, + } + + return rets +} + +func dataSourceImageSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "image_id": { + Type: schema.TypeInt, + Required: true, + Description: "image id", + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + Description: "unc path", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + Description: "binary architecture of this image, one of X86_64", + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + Description: "Boot type of image bios or uefi", + }, + "bootable": { + Type: schema.TypeBool, + Computed: true, + Description: "Does this image boot OS", + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]", + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "grid (platform) ID where this template should be create in", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "links_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the rescue disk", + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + Description: "Optional password for the image", + }, + "pool_name": { + Type: schema.TypeString, + Computed: true, + Description: "pool for image create", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "storage endpoint provider ID", + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + Description: "image size", + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "image_type": { + Type: schema.TypeString, + Computed: true, + Description: "Image type linux, windows or other", + }, + "url": { + Type: schema.TypeString, + Computed: true, + Description: "URL where to download media from", + }, + "username": { + Type: schema.TypeString, + Computed: true, + Description: "Optional username for the image", + }, + "version": { + Type: schema.TypeString, + Computed: true, + Description: "version", + }, + } +} + +func resourceCDROMImageSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "url": { + Type: schema.TypeString, + Required: true, + Description: "URL where to download ISO from", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the storage policy", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "username_dl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "username for upload binary media", + }, + "password_dl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "password for upload binary media", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "architecture": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "binary architecture of this image, one of X86_64", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + Description: "unc path", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + Description: "Boot type of image bios or uefi", + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "image id", + }, + "image_type": { + Type: schema.TypeString, + Computed: true, + Description: "Image type linux, windows or other", + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + Description: "", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech atatus", + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + Description: "version", + }, + "size": { + Type: schema.TypeInt, + Computed: true, + Description: "image size", + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } +} + +func resourceImageSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "url": { + Type: schema.TypeString, + Required: true, + Description: "URL where to download media from", + }, + "boot_type": { + Type: schema.TypeString, + Required: true, + Description: "Boot type of image bios or uefi", + }, + "image_type": { + Type: schema.TypeString, + Required: true, + Description: "Image type linux, windows or other", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the storage policy", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "network_interface_naming": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, true), + Description: "select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming", + }, + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "username_dl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "username for upload binary media", + }, + "password_dl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "password for upload binary media", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + Description: "binary architecture of this image, one of X86_64", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "sync_mode": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Create image from a media identified by URL (in synchronous mode)", + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + Description: "unc path", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "image id", + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + Description: "", + }, + "links_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech atatus", + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + Description: "version", + }, + "size": { + Type: schema.TypeInt, + Computed: true, + Description: "image size", + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } +} + +func resourceVirtualImageSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "link_to": { + Type: schema.TypeInt, + Required: true, + Description: "ID of real image to link this virtual image to upon creation", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "username": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Optional username for the image", + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + + "unc_path": { + Type: schema.TypeString, + Computed: true, + Description: "unc path", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + Description: "binary architecture of this image, one of X86_64", + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + Description: "Boot type of image bios or uefi", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "grid (platform) ID where this template should be create in", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Image id", + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_name": { + Type: schema.TypeString, + Computed: true, + Description: "pool for image create", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "storage endpoint provider ID", + }, + "size": { + Type: schema.TypeInt, + Computed: true, + Description: "image size", + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech atatus", + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "image_type": { + Type: schema.TypeString, + Computed: true, + Description: "Image type linux, windows or other", + }, + "url": { + Type: schema.TypeString, + Computed: true, + Description: "URL where to download media from", + }, + "version": { + Type: schema.TypeString, + Computed: true, + Description: "version", + }, + } +} + +func resourceMultiImageSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "target_ids": { + Type: schema.TypeList, + Required: true, + Description: "IDs of real images to link this multi image to", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the multi image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Account id to make the image exclusive", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "username": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Optional username for the image", + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + + "unc_path": { + Type: schema.TypeString, + Computed: true, + Description: "unc path", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "links_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_name": { + Type: schema.TypeString, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "image_type": { + Type: schema.TypeString, + Computed: true, + }, + "url": { + Type: schema.TypeString, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func resourceImageFromBlankComputeSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + Description: "Compute Id", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "Storage policy ID", + }, + "boot_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true), + Description: "Boot type of image BIOS or UEFI", + }, + "image_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "unknown"}, true), + Description: "Image type linux, windows or unknown", + }, + + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "async_mode": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "create an image in async/sync mode", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "network_interface_naming": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, true), + Description: "select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming", + }, + + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "links_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "url": { + Type: schema.TypeString, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func resourceImageFromPlatformDiskSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Required: true, + Description: "Disk Id", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rescue disk", + }, + "boot_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true), + Description: "Boot type of image BIOS or UEFI", + }, + "image_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "unknown"}, true), + Description: "Image type linux, windows or unknown", + }, + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "pool for image create", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "async_mode": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "create an image in async/sync mode", + }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Does this image boot OS", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "computeci_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "network_interface_naming": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, true), + Description: "select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming", + }, + + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "unc_path": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "cd_presented_to": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "history": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "last_modified": { + Type: schema.TypeInt, + Computed: true, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + }, + "links_to": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "rescuecd": { + Type: schema.TypeBool, + Computed: true, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "snapshot id", + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "url": { + Type: schema.TypeString, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + } +} diff --git a/internal/service/cloudbroker/image/state_upgrader.go b/internal/service/cloudbroker/image/state_upgrader.go new file mode 100644 index 00000000..d58e2d67 --- /dev/null +++ b/internal/service/cloudbroker/image/state_upgrader.go @@ -0,0 +1,14 @@ +package image + +import ( + "context" + + log "github.com/sirupsen/logrus" +) + +func resourcePresentTOUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourcePresentTOUpgradeV1: upgrading state") + rawState["present_to"] = make(map[string]uint64) + + return rawState, nil +} diff --git a/internal/service/cloudbroker/image/utility_image.go b/internal/service/cloudbroker/image/utility_image.go new file mode 100644 index 00000000..1afa2ee3 --- /dev/null +++ b/internal/service/cloudbroker/image/utility_image.go @@ -0,0 +1,60 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.RecordImage, error) { + c := m.(*controller.ControllerCfg) + req := image.GetRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.ImageID = id + } else { + req.ImageID = uint64(d.Get("image_id").(int)) + } + + image, err := c.CloudBroker().Image().Get(ctx, req) + if err != nil { + return nil, err + } + + return image, nil +} diff --git a/internal/service/cloudbroker/image/utility_image_list.go b/internal/service/cloudbroker/image/utility_image_list.go new file mode 100644 index 00000000..0d94e2ec --- /dev/null +++ b/internal/service/cloudbroker/image/utility_image_list.go @@ -0,0 +1,105 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.ListImages, error) { + c := m.(*controller.ControllerCfg) + req := image.ListRequest{} + + if sepId, ok := d.GetOk("sep_id"); ok { + req.SepID = uint64(sepId.(int)) + } + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if typeImage, ok := d.GetOk("type_image"); ok { + for _, v := range typeImage.([]interface{}) { + req.TypeImage = append(req.TypeImage, v.(string)) + } + } + if imageSize, ok := d.GetOk("image_size"); ok { + req.ImageSize = uint64(imageSize.(int)) + } + if sepName, ok := d.GetOk("sep_name"); ok { + req.SEPName = sepName.(string) + } + if pool, ok := d.GetOk("pool"); ok { + req.Pool = pool.(string) + } + if public, ok := d.GetOkExists("public"); ok { + req.Public = public.(bool) + } + if hotResize, ok := d.GetOkExists("hot_resize"); ok { + req.HotResize = hotResize.(bool) + } + if bootable, ok := d.GetOkExists("bootable"); ok { + req.Bootable = bootable.(bool) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if enabled, ok := d.GetOkExists("enabled"); ok { + req.Enabled = enabled.(bool) + } + if storagePolicyID, ok := d.GetOk("storage_policy_id"); ok { + req.StoragePolicyID = uint64(storagePolicyID.(int)) + } + log.Debugf("utilityImageListCheckPresence: load image list") + imageList, err := c.CloudBroker().Image().List(ctx, req) + if err != nil { + return nil, err + } + + return imageList, nil +} diff --git a/internal/service/cloudbroker/image/utility_resource_create.go b/internal/service/cloudbroker/image/utility_resource_create.go new file mode 100644 index 00000000..4f32a6eb --- /dev/null +++ b/internal/service/cloudbroker/image/utility_resource_create.go @@ -0,0 +1,81 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package image + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" +) + +func CreateRequest(ctx context.Context, d *schema.ResourceData, m interface{}, url string) (image.CreateRequest, error) { + req := image.CreateRequest{ + Name: d.Get("name").(string), + URL: url, + BootType: d.Get("boot_type").(string), + ImageType: d.Get("image_type").(string), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + if hotresize, ok := d.GetOk("hot_resize"); ok { + req.HotResize = hotresize.(bool) + } + if username, ok := d.GetOk("username"); ok { + req.Username = username.(string) + } + if password, ok := d.GetOk("password"); ok { + req.Password = password.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if usernameDL, ok := d.GetOk("username_dl"); ok { + req.UsernameDL = usernameDL.(string) + } + if passwordDL, ok := d.GetOk("password_dl"); ok { + req.PasswordDL = passwordDL.(string) + } + if sepId, ok := d.GetOk("sep_id"); ok { + req.SEPID = uint64(sepId.(int)) + } + if poolName, ok := d.GetOk("pool_name"); ok { + req.PoolName = poolName.(string) + } + if bootable, ok := d.GetOk("bootable"); ok { + req.Bootable = bootable.(bool) + } + if networkInterfaceNaming, ok := d.GetOk("network_interface_naming"); ok { + req.NetworkInterfaceNaming = networkInterfaceNaming.(string) + } + return req, nil +} diff --git a/internal/service/cloudbroker/k8ci/data_source_k8ci.go b/internal/service/cloudbroker/k8ci/data_source_k8ci.go new file mode 100644 index 00000000..a65366ef --- /dev/null +++ b/internal/service/cloudbroker/k8ci/data_source_k8ci.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8ci + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8CIRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + data, err := utilityK8CICheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("k8ci_id").(int))) + flattenK8CIItems(d, data) + + return nil +} + +func DataSourceK8CI() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8CIRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8CISchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8ci/data_source_k8ci_list.go b/internal/service/cloudbroker/k8ci/data_source_k8ci_list.go new file mode 100644 index 00000000..a6ba3603 --- /dev/null +++ b/internal/service/cloudbroker/k8ci/data_source_k8ci_list.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8ci + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8CIListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + list, err := utilityK8CIListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(uuid.New().String()) + d.Set("items", flattenK8CIListItems(list)) + d.Set("entry_count", list.EntryCount) + + return nil +} + +func DataSourceK8CIList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8CIListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8CIListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8ci/data_source_k8ci_list_deleted.go b/internal/service/cloudbroker/k8ci/data_source_k8ci_list_deleted.go new file mode 100644 index 00000000..33c26d1a --- /dev/null +++ b/internal/service/cloudbroker/k8ci/data_source_k8ci_list_deleted.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8ci + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8CIListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + list, err := utilityK8CIListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(uuid.New().String()) + d.Set("items", flattenK8CIListItems(list)) + d.Set("entry_count", list.EntryCount) + + return nil +} + +func DataSourceK8CIListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8CIListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8CIListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8ci/flattens.go b/internal/service/cloudbroker/k8ci/flattens.go new file mode 100644 index 00000000..1613c65f --- /dev/null +++ b/internal/service/cloudbroker/k8ci/flattens.go @@ -0,0 +1,88 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8ci + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8ci" +) + +func flattenK8CIListItems(list *k8ci.ListK8CI) []map[string]interface{} { + log.Debug("flattenK8CIListItems") + res := make([]map[string]interface{}, 0, len(list.Data)) + for _, item := range list.Data { + temp := map[string]interface{}{ + "created_time": item.CreatedTime, + "desc": item.Description, + "gid": item.GID, + "guid": item.GUID, + "k8ci_id": item.ID, + "lb_image_id": item.LBImageID, + "master_image_id": item.MasterImageID, + "max_master_count": item.MaxMasterCount, + "max_worker_count": item.MaxWorkerCount, + "name": item.Name, + "shared_with": item.SharedWith, + "status": item.Status, + "version": item.Version, + "worker_image_id": item.WorkerImageID, + } + res = append(res, temp) + } + + return res +} + +func flattenK8CIItems(d *schema.ResourceData, data *k8ci.RecordK8CI) error { + log.Debugf("flattenK8CI: ID %d", data.ID) + + d.Set("desc", data.Description) + d.Set("gid", data.GID) + d.Set("guid", data.GUID) + d.Set("k8ci_id", data.ID) + d.Set("lb_image_id", data.LBImageID) + d.Set("master_image_id", data.MasterImageID) + d.Set("max_master_count", data.MaxMasterCount) + d.Set("max_worker_count", data.MaxWorkerCount) + d.Set("milestones", data.Milestones) + d.Set("name", data.Name) + d.Set("network_plugins", data.NetworkPlugins) + d.Set("shared_with", data.SharedWith) + d.Set("status", data.Status) + d.Set("version", data.Version) + d.Set("worker_image_id", data.WorkerImageID) + + return nil +} diff --git a/internal/service/cloudbroker/k8ci/resource_check_input_values.go b/internal/service/cloudbroker/k8ci/resource_check_input_values.go new file mode 100644 index 00000000..822e62ce --- /dev/null +++ b/internal/service/cloudbroker/k8ci/resource_check_input_values.go @@ -0,0 +1,60 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8ci + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" +) + +func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + masterImageId := uint64(d.Get("master_image_id").(int)) + workerImageId := uint64(d.Get("worker_image_id").(int)) + + if err := ic.ExistImage(ctx, masterImageId, c); err != nil { + errs = append(errs, err) + } + + if err := ic.ExistImage(ctx, workerImageId, c); err != nil { + errs = append(errs, err) + } + + return dc.ErrorsToDiagnostics(errs) +} diff --git a/internal/service/cloudbroker/k8ci/resource_k8ci.go b/internal/service/cloudbroker/k8ci/resource_k8ci.go new file mode 100644 index 00000000..e890c37f --- /dev/null +++ b/internal/service/cloudbroker/k8ci/resource_k8ci.go @@ -0,0 +1,358 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8ci + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8ci" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceK8CICreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8CICreate: called for k8ci %s", d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + req := k8ci.CreateRequest{ + Name: d.Get("name").(string), + Version: d.Get("version").(string), + MaxMasterCount: uint64(d.Get("max_master_count").(int)), + MaxWorkerCount: uint64(d.Get("max_worker_count").(int)), + MasterImageID: uint64(d.Get("master_image_id").(int)), + WorkerImageID: uint64(d.Get("worker_image_id").(int)), + } + + var networkPlugins []string + for _, item := range d.Get("network_plugins").([]interface{}) { + networkPlugins = append(networkPlugins, item.(string)) + } + req.NetworkPlugins = networkPlugins + + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + if sharedWithInterface, ok := d.GetOk("shared_with"); ok { + sharedWithList := sharedWithInterface.(*schema.Set).List() + var sharedWith []uint64 + for _, item := range sharedWithList { + sharedWith = append(sharedWith, uint64(item.(int))) + } + req.SharedWith = sharedWith + } + + k8ciID, err := c.CloudBroker().K8CI().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(k8ciID, 10)) + + warnings := dc.Warnings{} + + if enabled, ok := d.GetOk("enabled"); ok { + log.Debugf("resourceK8CICreate: enable=%t k8ci_id %d after completing its resource configuration", enabled, k8ciID) + if enabled.(bool) { + enabledReq := k8ci.EnableRequest{ + K8CIID: k8ciID, + } + if _, err := c.CloudBroker().K8CI().Enable(ctx, enabledReq); err != nil { + warnings.Add(err) + } + } else { + disableReq := k8ci.DisableRequest{ + K8CIID: k8ciID, + } + if _, err := c.CloudBroker().K8CI().Disable(ctx, disableReq); err != nil { + warnings.Add(err) + } + } + } + + return append(warnings.Get(), resourceK8CIRead(ctx, d, m)...) +} + +func resourceK8CIRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + // c := m.(*controller.ControllerCfg) + log.Debugf("resourceK8CIRead: called for k8ci id %s, name %s", d.Id(), d.Get("name").(string)) + + k8ciRec, err := utilityK8CICheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch k8ciRec.Status { + case status.Deleted: + // restoreReq := k8ci.RestoreRequest{K8CIID: k8ciRec.ID} + + // _, err := c.CloudBroker().K8CI().Restore(ctx, restoreReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // if enabled, ok := d.GetOk("enabled"); ok { + // if enabled.(bool) { + // enabledReq := k8ci.EnableRequest{K8CIID: k8ciRec.ID} + // _, err := c.CloudBroker().K8CI().Enable(ctx, enabledReq) + // if err != nil { + // return diag.FromErr(err) + // } + // } + // } + // hasChanged = true + case status.Destroyed: + d.SetId("") + // return resourceK8CICreate(ctx, d, m) + return diag.Errorf("The resource cannot be updated because it has been destroyed") + case status.Disabled: + log.Debugf("The k8ci is in status: %s, troubles may occur with update. Please, enable k8ci first.", k8ciRec.Status) + case status.Redeploying: + case status.Deleting: + case status.Destroying: + return diag.Errorf("The k8ci is in progress with status: %s", k8ciRec.Status) + case status.Modeled: + return diag.Errorf("The k8ci is in status: %s, please, contact support for more information", k8ciRec.Status) + } + + if hasChanged { + k8ciRec, err = utilityK8CICheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + flattenK8CIItems(d, k8ciRec) + + return nil +} + +func resourceK8CIUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8CIUpdate: called for k8ci %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + k8ciRec, err := utilityK8CICheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + warnings := dc.Warnings{} + + hasChanged := false + + switch k8ciRec.Status { + case status.Deleted: + restoreReq := k8ci.RestoreRequest{K8CIID: k8ciRec.ID} + _, err := c.CloudBroker().K8CI().Restore(ctx, restoreReq) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + if enabled, ok := d.GetOk("enabled"); ok { + if enabled.(bool) { + enabledReq := k8ci.EnableRequest{K8CIID: k8ciRec.ID} + _, err := c.CloudBroker().K8CI().Enable(ctx, enabledReq) + if err != nil { + warnings.Add(err) + } + } else { + disableReq := k8ci.DisableRequest{K8CIID: k8ciRec.ID} + if _, err := c.CloudBroker().K8CI().Disable(ctx, disableReq); err != nil { + warnings.Add(err) + } + } + } + hasChanged = true + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceK8CICreate(ctx, d, m) + case status.Disabled: + log.Debugf("The k8ci is in status: %s, troubles may occur with update. Please, enable k8ci first.", k8ciRec.Status) + case status.Redeploying: + case status.Deleting: + case status.Destroying: + return diag.Errorf("The k8ci is in progress with status: %s", k8ciRec.Status) + case status.Modeled: + return diag.Errorf("The k8ci is in status: %s, please, contact support for more information", k8ciRec.Status) + } + + if hasChanged { + k8ciRec, err = utilityK8CICheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChange("enabled") { + err := resourceK8CIChangeEnable(ctx, d, k8ciRec.ID, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("shared_with") { + err := resourceK8CIChangeSharedWith(ctx, d, k8ciRec.ID, m) + if err != nil { + return diag.FromErr(err) + } + } + + return append(resourceK8CIRead(ctx, d, m), warnings.Get()...) +} + +func resourceK8CIDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8CIDelete: called for k8ci %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*controller.ControllerCfg) + k8ciId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := k8ci.DeleteRequest{ + K8CIID: k8ciId, + } + if permanently, ok := d.GetOk("permanently"); ok { + req.Permanently = permanently.(bool) + } + + if _, err := c.CloudBroker().K8CI().Delete(ctx, req); err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceK8CI() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceK8CICreate, + ReadContext: resourceK8CIRead, + UpdateContext: resourceK8CIUpdate, + DeleteContext: resourceK8CIDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout30m, + Read: &constants.Timeout600s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceK8CISchemaMake(), + } +} + +func resourceK8CIChangeEnable(ctx context.Context, d *schema.ResourceData, k8ciId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + enabled := d.Get("enabled").(bool) + if enabled { + req := k8ci.EnableRequest{ + K8CIID: k8ciId, + } + if _, err := c.CloudBroker().K8CI().Enable(ctx, req); err != nil { + return err + } + } else { + req := k8ci.DisableRequest{ + K8CIID: k8ciId, + } + if _, err := c.CloudBroker().K8CI().Disable(ctx, req); err != nil { + return err + } + } + + return nil +} + +func resourceK8CIChangeSharedWith(ctx context.Context, d *schema.ResourceData, k8ciId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + oldSet, newSet := d.GetChange("shared_with") + + deletedSharedWith := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedSharedWith) > 0 { + for _, userAcessInterface := range deletedSharedWith { + removeReq := k8ci.AccessRemoveRequest{ + K8CIID: k8ciId, + AccountId: uint64(userAcessInterface.(int)), + } + + if _, err := c.CloudBroker().K8CI().AccessRemove(ctx, removeReq); err != nil { + return err + } + } + } + + addedSharedWith := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedSharedWith) > 0 { + for _, userAcessInterface := range addedSharedWith { + removeReq := k8ci.AccessAddRequest{ + K8CIID: k8ciId, + AccountId: uint64(userAcessInterface.(int)), + } + + if _, err := c.CloudBroker().K8CI().AccessAdd(ctx, removeReq); err != nil { + return err + } + } + } + + return nil +} diff --git a/internal/service/cloudbroker/k8ci/schema.go b/internal/service/cloudbroker/k8ci/schema.go new file mode 100644 index 00000000..4c628196 --- /dev/null +++ b/internal/service/cloudbroker/k8ci/schema.go @@ -0,0 +1,440 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ +package k8ci + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func dataSourceK8CISchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8ci_id": { + Type: schema.TypeInt, + Required: true, + Description: "K8CI ID", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "lb_image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "LB Image ID", + }, + "master_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "max_master_count": { + Type: schema.TypeInt, + Computed: true, + }, + "max_worker_count": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "K8CI name", + }, + "network_plugins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "K8CI Status", + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + "worker_driver": { + Type: schema.TypeString, + Computed: true, + }, + "worker_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceK8CIListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "network_plugin": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by network plugin", + }, + "include_disabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Include deleted k8cis in result", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "k8ci_id": { + Type: schema.TypeInt, + Computed: true, + Description: "K8CI ID", + }, + "lb_image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "LB Image ID", + }, + "master_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "max_master_count": { + Type: schema.TypeInt, + Computed: true, + }, + "max_worker_count": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "K8CI name", + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "K8CI Status", + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + "worker_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceK8CIListDeletedSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "network_plugin": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by network plugin", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "k8ci_id": { + Type: schema.TypeInt, + Computed: true, + Description: "K8CI ID", + }, + "lb_image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "LB Image ID", + }, + "master_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "max_master_count": { + Type: schema.TypeInt, + Computed: true, + }, + "max_worker_count": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "K8CI name", + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "K8CI Status", + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + "worker_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func resourceK8CISchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "K8CI name", + }, + "version": { + Type: schema.TypeString, + Required: true, + }, + "master_image_id": { + Type: schema.TypeInt, + Required: true, + }, + "max_master_count": { + Type: schema.TypeInt, + Required: true, + }, + "max_worker_count": { + Type: schema.TypeInt, + Required: true, + }, + "worker_image_id": { + Type: schema.TypeInt, + Required: true, + }, + "network_plugins": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + }, + "permanently": { + Type: schema.TypeBool, + Default: false, + Optional: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Optional: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "k8ci_id": { + Type: schema.TypeInt, + Computed: true, + Description: "K8CI ID", + }, + "lb_image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "LB Image ID", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "shared_with": { + Type: schema.TypeSet, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "K8CI Status", + }, + } +} diff --git a/internal/service/cloudbroker/k8ci/utility_k8ci.go b/internal/service/cloudbroker/k8ci/utility_k8ci.go new file mode 100644 index 00000000..e1758cdf --- /dev/null +++ b/internal/service/cloudbroker/k8ci/utility_k8ci.go @@ -0,0 +1,64 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8ci + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8ci" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityK8CICheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8ci.RecordK8CI, error) { + c := m.(*controller.ControllerCfg) + req := k8ci.GetRequest{} + + if d.Id() != "" { + k8ciId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.K8CIID = k8ciId + } else { + req.K8CIID = uint64(d.Get("k8ci_id").(int)) + } + + + res, err := c.CloudBroker().K8CI().Get(ctx, req) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/internal/service/cloudbroker/k8ci/utility_k8ci_list.go b/internal/service/cloudbroker/k8ci/utility_k8ci_list.go new file mode 100644 index 00000000..23c4c7e0 --- /dev/null +++ b/internal/service/cloudbroker/k8ci/utility_k8ci_list.go @@ -0,0 +1,81 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8ci + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8ci" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityK8CIListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8ci.ListK8CI, error) { + c := m.(*controller.ControllerCfg) + + req := k8ci.ListRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if network_plugin, ok := d.GetOk("network_plugin"); ok { + req.NetworkPlugins = network_plugin.(string) + } + if include_disabled, ok := d.GetOk("include_disabled"); ok { + req.IncludeDisabled = include_disabled.(bool) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + resList, err := c.CloudBroker().K8CI().List(ctx, req) + if err != nil { + return nil, err + } + + return resList, nil +} diff --git a/internal/service/cloudbroker/k8ci/utility_k8ci_list_deleted.go b/internal/service/cloudbroker/k8ci/utility_k8ci_list_deleted.go new file mode 100644 index 00000000..efd62dc4 --- /dev/null +++ b/internal/service/cloudbroker/k8ci/utility_k8ci_list_deleted.go @@ -0,0 +1,75 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8ci + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8ci" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityK8CIListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8ci.ListK8CI, error) { + c := m.(*controller.ControllerCfg) + + req := k8ci.ListDeletedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if network_plugin, ok := d.GetOk("network_plugin"); ok { + req.NetworkPlugins = network_plugin.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + resList, err := c.CloudBroker().K8CI().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return resList, nil +} diff --git a/internal/service/cloudbroker/k8s/data_source_k8s.go b/internal/service/cloudbroker/k8s/data_source_k8s.go new file mode 100644 index 00000000..537d1d4d --- /dev/null +++ b/internal/service/cloudbroker/k8s/data_source_k8s.go @@ -0,0 +1,142 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func dataSourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("dataSourceK8sRead: called with k8s id %d", d.Get("k8s_id").(int)) + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId(strconv.FormatUint(cluster.ID, 10)) + + k8sList, err := utilityK8sListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + curK8s := k8s.ItemK8S{} + for _, k8sCluster := range k8sList.Data { + if k8sCluster.ID == cluster.ID { + curK8s = k8sCluster + } + } + if curK8s.ID == 0 { + return diag.Errorf("Cluster with id %d not found in List clusters", cluster.ID) + } + + d.Set("desc", curK8s.Description) + d.Set("gid", curK8s.GID) + d.Set("guid", curK8s.GUID) + d.Set("milestones", curK8s.Milestones) + d.Set("service_account", flattenServiceAccount(curK8s.ServiceAccount)) + d.Set("ssh_key", curK8s.SSHKey) + d.Set("vins_id", curK8s.VINSID) + + masterComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Masters.DetailedInfo)) + workersComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Workers)) + for _, masterNode := range cluster.K8SGroups.Masters.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, masterNode.ID) + if err != nil { + return diag.FromErr(err) + } + masterComputeList = append(masterComputeList, *compute) + } + for _, worker := range cluster.K8SGroups.Workers { + for _, info := range worker.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) + if err != nil { + return diag.FromErr(err) + } + workersComputeList = append(workersComputeList, *compute) + } + } + + c := m.(*controller.ControllerCfg) + + getConfigReq := k8s.GetConfigRequest{K8SID: cluster.ID} + + kubeconfig, err := c.CloudBroker().K8S().GetConfig(ctx, getConfigReq) + if err != nil { + log.Warnf("could not get kubeconfig: %v", err) + } + + d.Set("kubeconfig", kubeconfig) + + if cluster.LBID != 0 { + getLbReq := lb.GetRequest{LBID: cluster.LBID} + lb, err := c.CloudBroker().LB().Get(ctx, getLbReq) + if err != nil { + return diag.FromErr(err) + } + + d.Set("extnet_id", lb.ExtNetID) + d.Set("lb_ip", lb.PrimaryNode.FrontendIP) + } + + flattenK8sData(d, cluster, masterComputeList, workersComputeList) + return nil +} + +func DataSourceK8s() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8s/data_source_k8s_computes.go b/internal/service/cloudbroker/k8s/data_source_k8s_computes.go new file mode 100644 index 00000000..898abea4 --- /dev/null +++ b/internal/service/cloudbroker/k8s/data_source_k8s_computes.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sComputesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("dataSourceK8sComputesRead: called with k8s id %d", d.Get("k8s_id").(int)) + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(cluster.ID, 10)) + flattenK8sDataComputes(d, cluster) + + return nil +} + +func DataSourceK8sComputes() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sComputesRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout60s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sComputesSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8s/data_source_k8s_list.go b/internal/service/cloudbroker/k8s/data_source_k8s_list.go new file mode 100644 index 00000000..1d24bca2 --- /dev/null +++ b/internal/service/cloudbroker/k8s/data_source_k8s_list.go @@ -0,0 +1,75 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debug("dataSourceK8sListRead starting") + list, err := utilityK8sListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenK8sItems(list)) + d.Set("entry_count", list.EntryCount) + + return nil +} + +func DataSourceK8sList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8s/data_source_k8s_list_deleted.go b/internal/service/cloudbroker/k8s/data_source_k8s_list_deleted.go new file mode 100644 index 00000000..08ec8004 --- /dev/null +++ b/internal/service/cloudbroker/k8s/data_source_k8s_list_deleted.go @@ -0,0 +1,75 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debug("dataSourceK8sListDeletedRead starting") + list, err := utilityK8sListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenK8sItems(list)) + d.Set("entry_count", list.EntryCount) + + return nil +} + +func DataSourceK8sListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8s/data_source_k8s_wg.go b/internal/service/cloudbroker/k8s/data_source_k8s_wg.go new file mode 100644 index 00000000..9152f74c --- /dev/null +++ b/internal/service/cloudbroker/k8s/data_source_k8s_wg.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("dataSourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int)) + + wg, workersComputeList, err := utilityDataK8sWgCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(wg.ID, 10)) + flattenWg(d, wg, workersComputeList) + + return nil +} + +func DataSourceK8sWg() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sWgRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sWgSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8s/data_source_k8s_wg_cloud_init.go b/internal/service/cloudbroker/k8s/data_source_k8s_wg_cloud_init.go new file mode 100644 index 00000000..f4828b45 --- /dev/null +++ b/internal/service/cloudbroker/k8s/data_source_k8s_wg_cloud_init.go @@ -0,0 +1,74 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sWgCloudInitRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("dataSourceK8sWgCloudInitRead: called with k8s id %d and wg id %d", d.Get("k8s_id").(int), d.Get("wg_id").(int)) + + metaData, err := utilityK8sWgCloudInitCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("cloud_init", metaData) + + return nil +} + +func DataSourceK8sWgCloudInit() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sWgCloudInitRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sWgCloudInitSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8s/data_source_k8s_wg_list.go b/internal/service/cloudbroker/k8s/data_source_k8s_wg_list.go new file mode 100644 index 00000000..b3c2b494 --- /dev/null +++ b/internal/service/cloudbroker/k8s/data_source_k8s_wg_list.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceK8sWgListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("dataSourceK8sWgListRead: called with k8s id %d and wg id %d", d.Get("k8s_id").(int), d.Get("wg_id").(int)) + wgList, err := utilityK8sWgListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("k8s_id").(int))) + + workersComputeList := make(map[uint64][]compute.RecordCompute) + for _, worker := range *wgList { + workersComputeList[worker.ID] = make([]compute.RecordCompute, 0, len(worker.DetailedInfo)) + for _, info := range worker.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) + if err != nil { + return diag.FromErr(err) + } + workersComputeList[worker.ID] = append(workersComputeList[worker.ID], *compute) + } + } + flattenItemsWg(d, *wgList, workersComputeList) + + return nil +} + +func DataSourceK8sWgList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceK8sWgListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceK8sWgListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8s/flattens.go b/internal/service/cloudbroker/k8s/flattens.go new file mode 100644 index 00000000..b505f1b8 --- /dev/null +++ b/internal/service/cloudbroker/k8s/flattens.go @@ -0,0 +1,419 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "encoding/json" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" +) + +func flattenResourceK8sCP(d *schema.ResourceData, k8s k8s.RecordK8S, masters []compute.RecordCompute) { + d.Set("acl", flattenAcl(k8s.ACL)) + d.Set("account_id", k8s.AccountID) + d.Set("account_name", k8s.AccountName) + d.Set("k8sci_id", k8s.CIID) + d.Set("bservice_id", k8s.BServiceID) + d.Set("created_by", k8s.CreatedBy) + d.Set("created_time", k8s.CreatedTime) + d.Set("desc", k8s.Description) + d.Set("deleted_by", k8s.DeletedBy) + d.Set("deleted_time", k8s.DeletedTime) + d.Set("k8s_ci_name", k8s.K8CIName) + d.Set("with_lb", k8s.LBID != 0) + d.Set("lb_id", k8s.LBID) + d.Set("k8s_id", k8s.ID) + d.Set("name", k8s.Name) + d.Set("rg_id", k8s.RGID) + d.Set("rg_name", k8s.RGName) + d.Set("status", k8s.Status) + d.Set("tech_status", k8s.TechStatus) + d.Set("updated_by", k8s.UpdatedBy) + d.Set("updated_time", k8s.UpdatedTime) + d.Set("network_plugin", k8s.NetworkPlugin) + d.Set("highly_available_lb", k8s.HighlyAvailableLB) + d.Set("address_vip", flattenAddressVIP(k8s.AddressVIP)) + d.Set("extnet_only", k8s.ExtnetOnly) + d.Set("zone_id", k8s.ZoneID) + + flattenCPParams(d, k8s.K8SGroups.Masters, masters) +} + +func flattenCPParams(d *schema.ResourceData, mastersGroup k8s.MasterGroup, masters []compute.RecordCompute) { + d.Set("cpu", mastersGroup.CPU) + d.Set("detailed_info", flattenDetailedInfo(mastersGroup.DetailedInfo, masters)) + d.Set("disk", mastersGroup.Disk) + d.Set("master_id", mastersGroup.ID) + d.Set("master_name", mastersGroup.Name) + d.Set("num", mastersGroup.Num) + d.Set("ram", mastersGroup.RAM) +} + +func flattenK8sData(d *schema.ResourceData, cluster *k8s.RecordK8S, masters []compute.RecordCompute, workers []compute.RecordCompute) { + d.Set("acl", flattenAcl(cluster.ACL)) + d.Set("account_id", cluster.AccountID) + d.Set("account_name", cluster.AccountName) + d.Set("bservice_id", cluster.BServiceID) + d.Set("k8sci_id", cluster.CIID) + d.Set("created_by", cluster.CreatedBy) + d.Set("created_time", cluster.CreatedTime) + d.Set("deleted_by", cluster.DeletedBy) + d.Set("deleted_time", cluster.DeletedTime) + d.Set("desc", cluster.Description) + d.Set("k8s_id", cluster.ID) + d.Set("k8s_ci_name", cluster.K8CIName) + d.Set("k8s_groups", flattenK8sGroups(cluster.K8SGroups, masters, workers)) + d.Set("lb_id", cluster.LBID) + d.Set("network_plugin", cluster.NetworkPlugin) + d.Set("name", cluster.Name) + d.Set("rg_id", cluster.RGID) + d.Set("rg_name", cluster.RGName) + d.Set("status", cluster.Status) + d.Set("tech_status", cluster.TechStatus) + d.Set("updated_by", cluster.UpdatedBy) + d.Set("updated_time", cluster.UpdatedTime) + d.Set("highly_available_lb", cluster.HighlyAvailableLB) + d.Set("address_vip", flattenAddressVIP(cluster.AddressVIP)) + d.Set("extnet_only", cluster.ExtnetOnly) + d.Set("with_lb", cluster.WithLB) + d.Set("zone_id", cluster.ZoneID) +} + +func flattenAddressVIP(addressVIP k8s.K8SAddressVIP) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "backend_ip": addressVIP.BackendIP, + "frontend_ip": addressVIP.FrontendIP, + } + res = append(res, temp) + return res +} + +func flattenAcl(acl k8s.RecordACLGroup) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "account_acl": flattenAclList(acl.AccountACL), + "k8s_acl": flattenAclList(acl.K8SACL), + "rg_acl": flattenAclList(acl.RGACL), + } + + res = append(res, temp) + return res +} + +func flattenAclList(aclList k8s.ListACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(aclList)) + for _, acl := range aclList { + temp := map[string]interface{}{ + "explicit": acl.Explicit, + "guid": acl.GUID, + "right": acl.Right, + "status": acl.Status, + "type": acl.Type, + "user_group_id": acl.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenK8sGroups(k8sGroups k8s.RecordK8SGroups, masters []compute.RecordCompute, workers []compute.RecordCompute) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "masters": flattenMasterGroup(k8sGroups.Masters, masters), + "workers": flattenWorkerGroup(k8sGroups.Workers, workers), + } + res = append(res, temp) + return res +} + +func flattenMasterGroup(mastersGroup k8s.MasterGroup, masters []compute.RecordCompute) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": mastersGroup.CPU, + "detailed_info": flattenDetailedInfo(mastersGroup.DetailedInfo, masters), + "disk": mastersGroup.Disk, + "master_id": mastersGroup.ID, + "name": mastersGroup.Name, + "num": mastersGroup.Num, + "ram": mastersGroup.RAM, + } + + res = append(res, temp) + return res +} + +func flattenDetailedInfo(detailedInfoList k8s.ListDetailedInfo, computes []compute.RecordCompute) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(detailedInfoList)) + if computes != nil { + for i, detailedInfo := range detailedInfoList { + temp := map[string]interface{}{ + "external_ip": detailedInfo.ExternalIp, + "compute_id": detailedInfo.ID, + "name": detailedInfo.Name, + "status": detailedInfo.Status, + "tech_status": detailedInfo.TechStatus, + "interfaces": flattenInterfaces(computes[i].Interfaces), + } + res = append(res, temp) + } + } else { + for _, detailedInfo := range detailedInfoList { + temp := map[string]interface{}{ + "external_ip": detailedInfo.ExternalIp, + "compute_id": detailedInfo.ID, + "name": detailedInfo.Name, + "status": detailedInfo.Status, + "tech_status": detailedInfo.TechStatus, + } + res = append(res, temp) + } + } + + return res +} + +func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(interfaces)) + for _, interfaceCompute := range interfaces { + temp := map[string]interface{}{ + "def_gw": interfaceCompute.DefGW, + "ip_address": interfaceCompute.IPAddress, + } + res = append(res, temp) + } + + return res +} + +func flattenWorkerGroup(k8SGroupList k8s.ListK8SGroup, workers []compute.RecordCompute) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(k8SGroupList)) + for _, k8sGroup := range k8SGroupList { + labels := make([]string, 0) + for _, label := range k8sGroup.Labels { + if strings.HasPrefix(label, "workersGroupName") { + continue + } + labels = append(labels, label) + } + temp := map[string]interface{}{ + "annotations": k8sGroup.Annotations, + "cpu": k8sGroup.CPU, + "detailed_info": flattenDetailedInfo(k8sGroup.DetailedInfo, workers), + "disk": k8sGroup.Disk, + "guid": k8sGroup.GUID, + "id": k8sGroup.ID, + "labels": labels, + "name": k8sGroup.Name, + "num": k8sGroup.Num, + "ram": k8sGroup.RAM, + "taints": k8sGroup.Taints, + } + + res = append(res, temp) + } + return res +} + +func flattenServiceAccount(sa k8s.ServiceAccount) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "guid": sa.GUID, + "password": sa.Password, + "username": sa.Username, + } + res = append(res, temp) + return res +} + +func flattenK8sItems(k8sList *k8s.ListK8S) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(k8sList.Data)) + for _, item := range k8sList.Data { + aclStrArray := make([]string, 0, len(item.ACL)) + for _, acl := range item.ACL { + aclStrArray = append(aclStrArray, acl.(string)) + } + data, _ := json.Marshal(item.Config) + temp := map[string]interface{}{ + "account_id": item.AccountID, + "account_name": item.Name, + "acl": aclStrArray, + "bservice_id": item.BServiceID, + "k8sci_id": item.CIID, + "kubeconfig": string(data), + "created_by": item.CreatedBy, + "created_time": item.CreatedTime, + "deleted_by": item.DeletedBy, + "deleted_time": item.DeletedTime, + "desc": item.Description, + "extnet_id": item.ExtNetID, + "gid": item.GID, + "guid": item.GUID, + "k8s_id": item.ID, + "lb_id": item.LBID, + "milestones": item.Milestones, + "k8s_name": item.Name, + "network_plugin": item.NetworkPlugin, + "rg_id": item.RGID, + "rg_name": item.RGName, + "service_account": flattenServiceAccount(item.ServiceAccount), + "ssh_key": item.SSHKey, + "status": item.Status, + "tech_status": item.TechStatus, + "updated_by": item.UpdatedBy, + "updated_time": item.UpdatedTime, + "vins_id": item.VINSID, + "zone_id": item.ZoneID, + "workers_groups": flattenWorkersGroupList(item.WorkersGroup), + } + + res = append(res, temp) + } + return res +} + +func flattenWorkersGroupList(k8SGroupList k8s.ListK8SGroup) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(k8SGroupList)) + for _, k8sGroup := range k8SGroupList { + labels := make([]string, 0) + for _, label := range k8sGroup.Labels { + if strings.HasPrefix(label, "workersGroupName") { + continue + } + labels = append(labels, label) + } + temp := map[string]interface{}{ + "annotations": k8sGroup.Annotations, + "guid": k8sGroup.GUID, + "id": k8sGroup.ID, + "labels": labels, + "taints": k8sGroup.Taints, + } + + res = append(res, temp) + } + return res +} + +func flattenK8sDataComputes(d *schema.ResourceData, cluster *k8s.RecordK8S) { + d.Set("k8s_id", cluster.ID) + d.Set("masters", flattenMasterComputes(cluster)) + d.Set("workers", flattenWorkerComputes(cluster)) +} + +func flattenMasterComputes(cluster *k8s.RecordK8S) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(cluster.K8SGroups.Masters.DetailedInfo)) + for _, comp := range cluster.K8SGroups.Masters.DetailedInfo { + temp := map[string]interface{}{ + "id": comp.ID, + "name": comp.Name, + "status": comp.Status, + "tech_status": comp.TechStatus, + "group_name": cluster.K8SGroups.Masters.Name, + } + res = append(res, temp) + } + + return res +} + +func flattenWorkerComputes(cluster *k8s.RecordK8S) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(cluster.K8SGroups.Workers)) + for _, wg := range cluster.K8SGroups.Workers { + for _, comp := range wg.DetailedInfo { + temp := map[string]interface{}{ + "id": comp.ID, + "name": comp.Name, + "status": comp.Status, + "tech_status": comp.TechStatus, + "group_name": wg.Name, + } + res = append(res, temp) + } + } + + return res +} + +func flattenItemsWg(d *schema.ResourceData, wgList k8s.ListK8SGroup, computes map[uint64][]compute.RecordCompute) { + d.Set("items", flattenWgList(wgList, computes)) +} + +func flattenWgList(wgList k8s.ListK8SGroup, computesMap map[uint64][]compute.RecordCompute) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, wg := range wgList { + computes := computesMap[wg.ID] + temp := map[string]interface{}{ + "annotations": wg.Annotations, + "cpu": wg.CPU, + "wg_id": wg.ID, + "detailed_info": flattenDetailedInfo(wg.DetailedInfo, computes), + "disk": wg.Disk, + "guid": wg.GUID, + "labels": wg.Labels, + "name": wg.Name, + "num": wg.Num, + "ram": wg.RAM, + "taints": wg.Taints, + } + + res = append(res, temp) + } + return res +} + +func flattenWg(d *schema.ResourceData, wg *k8s.RecordK8SGroup, computes []compute.RecordCompute) { + labels := make([]string, 0) + for _, label := range wg.Labels { + if strings.HasPrefix(label, "workersGroupName") { + continue + } + + labels = append(labels, label) + } + + d.Set("annotations", wg.Annotations) + d.Set("cpu", wg.CPU) + d.Set("detailed_info", flattenDetailedInfo(wg.DetailedInfo, computes)) + d.Set("disk", wg.Disk) + d.Set("guid", wg.GUID) + d.Set("labels", labels) + d.Set("name", wg.Name) + d.Set("num", wg.Num) + d.Set("ram", wg.RAM) + d.Set("taints", wg.Taints) +} diff --git a/internal/service/cloudbroker/k8s/resource_check_input_values.go b/internal/service/cloudbroker/k8s/resource_check_input_values.go new file mode 100644 index 00000000..0a6acb59 --- /dev/null +++ b/internal/service/cloudbroker/k8s/resource_check_input_values.go @@ -0,0 +1,76 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + rgid := uint64(d.Get("rg_id").(int)) + k8ciId := uint64(d.Get("k8sci_id").(int)) + extNetId := uint64(d.Get("extnet_id").(int)) + vinsId := uint64(d.Get("vins_id").(int)) + + if err := ic.ExistRG(ctx, rgid, c); err != nil { + errs = append(errs, err) + } + + if err := ic.ExistK8CI(ctx, k8ciId, c); err != nil { + errs = append(errs, err) + } + + if _, ok := d.GetOk("extnet_id"); ok { + if err := ic.ExistExtNetInK8s(ctx, extNetId, c); err != nil { + errs = append(errs, err) + } + } + + if _, ok := d.GetOk("vins_id"); ok { + if err := ic.ExistVinsInK8s(ctx, vinsId, c); err != nil { + errs = append(errs, err) + } + } + + return dc.ErrorsToDiagnostics(errs) +} diff --git a/internal/service/cloudbroker/k8s/resource_k8s_cp.go b/internal/service/cloudbroker/k8s/resource_k8s_cp.go new file mode 100644 index 00000000..7db650a5 --- /dev/null +++ b/internal/service/cloudbroker/k8s/resource_k8s_cp.go @@ -0,0 +1,667 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Tim Tkachev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sControlPlaneCreate: called with name %s, rg %d", d.Get("name").(string), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + createReq := k8s.CreateRequest{ + Name: d.Get("name").(string), + RGID: uint64(d.Get("rg_id").(int)), + K8CIID: uint64(d.Get("k8sci_id").(int)), + WorkerGroupName: "temp", + NetworkPlugin: d.Get("network_plugin").(string), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + if num, ok := d.GetOk("num"); ok { + createReq.MasterNum = uint64(num.(int)) + } else { + createReq.MasterNum = 1 + } + + if cpu, ok := d.GetOk("cpu"); ok { + createReq.MasterCPU = uint64(cpu.(int)) + } else { + createReq.MasterCPU = 2 + } + + if ram, ok := d.GetOk("ram"); ok { + createReq.MasterRAM = uint64(ram.(int)) + } else { + createReq.MasterRAM = 2048 + } + + if disk, ok := d.GetOk("disk"); ok { + createReq.MasterDisk = uint64(disk.(int)) + } else { + createReq.MasterDisk = 0 + } + + if sepId, ok := d.GetOk("sep_id"); ok { + createReq.MasterSEPID = uint64(sepId.(int)) + } + + if sepPool, ok := d.GetOk("sep_pool"); ok { + createReq.MasterSEPPool = sepPool.(string) + } + + if withLB, ok := d.GetOk("with_lb"); ok { + createReq.WithLB = withLB.(bool) + } else { + createReq.WithLB = true + } + + if extNet, ok := d.GetOk("extnet_id"); ok { + createReq.ExtNetID = uint64(extNet.(int)) + } else { + createReq.ExtNetID = 0 + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + createReq.ZoneID = uint64(zoneID.(int)) + } + + if vins, ok := d.GetOk("vins_id"); ok { + createReq.VinsId = uint64(vins.(int)) + } else { + createReq.VinsId = 0 + } + + if haMode, ok := d.GetOk("ha_mode"); ok { + createReq.HighlyAvailable = haMode.(bool) + } + + if additionalSans, ok := d.GetOk("additional_sans"); ok { + addSans := additionalSans.([]interface{}) + resSans := make([]string, 0) + for _, san := range addSans { + resSans = append(resSans, san.(string)) + } + + createReq.AdditionalSANs = resSans + } + + if clusterConfig, ok := d.GetOk("cluster_config"); ok { + createReq.ClusterConfiguration = clusterConfig.(string) + } + + if kubeletConfig, ok := d.GetOk("kubelet_config"); ok { + createReq.KubeletConfiguration = kubeletConfig.(string) + } + + if kubeProxyConfig, ok := d.GetOk("kube_proxy_config"); ok { + createReq.KubeProxyConfiguration = kubeProxyConfig.(string) + } + + if joinConfig, ok := d.GetOk("join_config"); ok { + createReq.JoinConfiguration = joinConfig.(string) + } + + if initConfig, ok := d.GetOk("init_config"); ok { + createReq.InitConfiguration = initConfig.(string) + } + + if oidcCertificate, ok := d.GetOk("oidc_cert"); ok { + createReq.OidcCertificate = oidcCertificate.(string) + } + + if chipset, ok := d.GetOk("chipset"); ok { + createReq.Chipset = chipset.(string) + } + + if extNetOnly, ok := d.GetOk("extnet_only"); ok { + createReq.ExtNetOnly = extNetOnly.(bool) + } + + if desc, ok := d.GetOk("desc"); ok { + createReq.Description = desc.(string) + } + + if lbSysctlParams, ok := d.GetOk("lb_sysctl_params"); ok { + syscrlSliceMaps := lbSysctlParams.([]interface{}) + res := make([]map[string]interface{}, 0, len(syscrlSliceMaps)) + for _, syscrlMap := range syscrlSliceMaps { + tempMap := make(map[string]interface{}) + for k, v := range syscrlMap.(map[string]interface{}) { + if intVal, err := strconv.Atoi(v.(string)); err == nil { + tempMap[k] = intVal + continue + } + tempMap[k] = v.(string) + } + res = append(res, tempMap) + } + createReq.LbSysctlParams = res + } + + resp, err := c.CloudBroker().K8S().Create(ctx, createReq) + if err != nil { + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(resp, `"`), + } + + for { + task, err := c.CloudBroker().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceK8sControlPlaneCreate: instance creating - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot create k8s instance: %v", task.Error)) + } + + id, err := task.Result.ID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(id)) + break + } + + time.Sleep(time.Second * 20) + } + + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + delWGReq := k8s.WorkersGroupDeleteRequest{ + K8SID: cluster.ID, + WorkersGroupID: cluster.K8SGroups.Workers[0].ID, + } + + _, err = c.CloudBroker().K8S().WorkersGroupDelete(ctx, delWGReq) + if err != nil { + return diag.FromErr(err) + } + + return resourceK8sCPRead(ctx, d, m) +} + +func resourceK8sCPRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sCPRead: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) + + k8sData, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + switch k8sData.Status { + case status.Modeled: + return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", k8sData.Status) + case status.Destroying: + return diag.Errorf("The k8s cluster is in progress with status: %s", k8sData.Status) + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + case status.Disabled: + log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", k8sData.Status) + } + c := m.(*controller.ControllerCfg) + + if d.Get("start").(bool) { + if k8sData.TechStatus == "STOPPED" { + req := k8s.StartRequest{ + K8SID: k8sData.ID, + } + _, err := c.CloudBroker().K8S().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + k8sList, err := utilityResourceK8sListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + curK8s := k8s.ItemK8S{} + for _, k8sCluster := range k8sList.Data { + if k8sCluster.ID == k8sData.ID { + curK8s = k8sCluster + } + } + if curK8s.ID == 0 { + return diag.Errorf("Cluster with id %d not found", k8sData.ID) + } + + d.Set("vins_id", curK8s.VINSID) + + masterComputeList := make([]compute.RecordCompute, 0, len(k8sData.K8SGroups.Masters.DetailedInfo)) + for _, masterNode := range k8sData.K8SGroups.Masters.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, masterNode.ID) + if err != nil { + return diag.FromErr(err) + } + masterComputeList = append(masterComputeList, *compute) + } + + var warnings dc.Warnings + + if _, ok := d.GetOk("k8s_id"); !ok { + for _, worker := range k8sData.K8SGroups.Workers { + err := fmt.Errorf("found worker-group with ID %d. Make sure to import it to decort_k8s_wg resource if you wish to manage it", worker.ID) + warnings.Add(err) + } + } + + flattenResourceK8sCP(d, *k8sData, masterComputeList) + + lbGetReq := lb.GetRequest{ + LBID: k8sData.LBID, + } + + if d.Get("with_lb").(bool) || k8sData.LBID != 0 { + lb, err := c.CloudBroker().LB().Get(ctx, lbGetReq) + if err != nil { + return diag.FromErr(err) + } + + d.Set("extnet_id", lb.ExtNetID) + d.Set("lb_ip", lb.PrimaryNode.FrontendIP) + } + + kubeconfigReq := k8s.GetConfigRequest{ + K8SID: k8sData.ID, + } + + kubeconfig, err := c.CloudBroker().K8S().GetConfig(ctx, kubeconfigReq) + if err != nil { + log.Warnf("could not get kubeconfig: %v", err) + } + + d.Set("kubeconfig", kubeconfig) + + return warnings.Get() +} + +func resourceK8sCPUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sControlPlaneUpdate: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + k8sData, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch k8sData.Status { + case status.Modeled: + return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", k8sData.Status) + case status.Deleted: + err := handleRestore(ctx, d, c, k8sData) + if err != nil { + return diag.FromErr(err) + } + hasChanged = true + case status.Destroying: + return diag.Errorf("The k8s cluster is in progress with status: %s", k8sData.Status) + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + case status.Disabled: + log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", k8sData.Status) + } + + if hasChanged { + k8sData, err = utilityK8sCheckPresence(ctx, d, m) + if k8sData == nil { + d.SetId("") + if err != nil { + return diag.FromErr(err) + } + return nil + } + } + + if d.HasChanges("name", "desc") { + err := handleUpdate(ctx, d, c, k8sData) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("enabled") { + err := handleEnable(ctx, c, d.Get("enabled").(bool), k8sData.ID) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("zone_id") { + start := d.Get("start").(bool) + err := handleZoneID(ctx, c, k8sData.ID, uint64(d.Get("zone_id").(int)), start) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("start") { + err := handleStart(ctx, c, d.Get("start").(bool), k8sData) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("num") { + err := handleUpdateNum(ctx, d, c, k8sData) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("lb_sysctl_params") && d.Get("with_lb").(bool) { + err := handleUpdateLbSysctlParams(ctx, d, c, k8sData) + if err != nil { + return diag.FromErr(err) + } + } + + return nil +} + +func resourceK8sCPDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sControlPlaneDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) + + k8sData, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := k8s.DeleteRequest{ + K8SID: k8sData.ID, + } + + if val, ok := d.GetOk("permanently"); ok { + req.Permanently = val.(bool) + } + + _, err = c.CloudBroker().K8S().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceK8sCP() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceK8sCPCreate, + ReadContext: resourceK8sCPRead, + UpdateContext: resourceK8sCPUpdate, + DeleteContext: resourceK8sCPDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout30m, + Read: &constants.Timeout600s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceK8sCPSchemaMake(), + } +} + +func handleUpdateNum(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, k8sData *k8s.RecordK8S) error { + + oldVal, newVal := d.GetChange("num") + + if oldVal.(int) > newVal.(int) { + ids := make([]uint64, 0) + for i := oldVal.(int) - 1; i >= newVal.(int); i-- { + id := k8sData.K8SGroups.Masters.DetailedInfo[i].ID + ids = append(ids, id) + } + + req := k8s.DeleteMasterFromGroupRequest{ + K8SID: k8sData.ID, + MasterGroupID: k8sData.K8SGroups.Masters.ID, + MasterIDs: ids, + } + + _, err := c.CloudBroker().K8S().DeleteMasterFromGroup(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func handleUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, k8sData *k8s.RecordK8S) error { + updateReq := k8s.UpdateRequest{K8SID: k8sData.ID} + + if d.HasChange("name") { + updateReq.Name = d.Get("name").(string) + } + + if d.HasChange("desc") { + updateReq.Description = d.Get("desc").(string) + } + + _, err := c.CloudBroker().K8S().Update(ctx, updateReq) + if err != nil { + return err + } + + return nil +} + +func handleRestore(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, k8sData *k8s.RecordK8S) error { + + if restore, ok := d.GetOk("restore"); ok && restore.(bool) { + restoreReq := k8s.RestoreRequest{ + K8SID: k8sData.ID, + } + + _, err := c.CloudBroker().K8S().Restore(ctx, restoreReq) + if err != nil { + return err + } + + err = handleEnable(ctx, c, d.Get("enabled").(bool), k8sData.ID) + if err != nil { + return err + } + + err = handleStart(ctx, c, d.Get("start").(bool), k8sData) + if err != nil { + return err + } + } + + return nil +} + +func handleEnable(ctx context.Context, c *controller.ControllerCfg, enable bool, k8sId uint64) error { + if enable { + enableReq := k8s.EnableRequest{K8SID: k8sId} + + _, err := c.CloudBroker().K8S().Enable(ctx, enableReq) + if err != nil { + return err + } + + } else { + disableReq := k8s.DisableRequest{K8SID: k8sId} + + _, err := c.CloudBroker().K8S().Disable(ctx, disableReq) + if err != nil { + return err + } + } + return nil +} + +func handleStart(ctx context.Context, c *controller.ControllerCfg, start bool, k8sData *k8s.RecordK8S) error { + if start { + if k8sData.TechStatus == "STOPPED" { + startReq := k8s.StartRequest{K8SID: k8sData.ID} + + _, err := c.CloudBroker().K8S().Start(ctx, startReq) + if err != nil { + return err + } + } + } else { + if k8sData.TechStatus == "STARTED" { + stopReq := k8s.StopRequest{K8SID: k8sData.ID} + + _, err := c.CloudBroker().K8S().Stop(ctx, stopReq) + if err != nil { + return err + } + } + } + return nil +} + +func handleZoneID(ctx context.Context, c *controller.ControllerCfg, k8sId uint64, zoneID uint64, start bool) error { + + if start { + stopReq := k8s.StopRequest{ + K8SID: k8sId, + } + + _, err := c.CloudBroker().K8S().Stop(ctx, stopReq) + if err != nil { + return err + } + } + + req := k8s.MigrateToZoneRequest{ + K8SID: k8sId, + ZoneID: zoneID, + } + + _, err := c.CloudBroker().K8S().MigrateToZone(ctx, req) + if err != nil { + return err + } + + if start { + startReq := k8s.StartRequest{ + K8SID: k8sId, + } + + _, err := c.CloudBroker().K8S().Start(ctx, startReq) + if err != nil { + return err + } + } + + return nil +} + +func handleUpdateLbSysctlParams(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, k8sData *k8s.RecordK8S) error { + + lbSysctlParams := d.Get("lb_sysctl_params").([]interface{}) + res := make([]map[string]interface{}, 0, len(lbSysctlParams)) + for _, syscrlMap := range lbSysctlParams { + tempMap := make(map[string]interface{}) + for k, v := range syscrlMap.(map[string]interface{}) { + if intVal, err := strconv.Atoi(v.(string)); err == nil { + tempMap[k] = intVal + continue + } + tempMap[k] = v.(string) + } + res = append(res, tempMap) + } + + if len(res) > 0 { + req := lb.UpdateSysctParamsRequest{ + LBID: k8sData.LBID, + SysctlParams: res, + } + + _, err := c.CloudBroker().LB().UpdateSysctlParams(ctx, req) + return err + } + return nil +} diff --git a/internal/service/cloudbroker/k8s/resource_k8s_wg.go b/internal/service/cloudbroker/k8s/resource_k8s_wg.go new file mode 100644 index 00000000..e3c02d60 --- /dev/null +++ b/internal/service/cloudbroker/k8s/resource_k8s_wg.go @@ -0,0 +1,278 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" +) + +func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sWgCreate: called with k8s id %d", d.Get("k8s_id").(int)) + c := m.(*controller.ControllerCfg) + + if err := ic.ExistK8s(ctx, uint64(d.Get("k8s_id").(int)), c); err != nil { + return diag.FromErr(err) + } + + req := k8s.WorkersGroupAddRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + Name: d.Get("name").(string), + WorkerNum: uint64(d.Get("num").(int)), + WorkerCPU: uint64(d.Get("cpu").(int)), + WorkerRAM: uint64(d.Get("ram").(int)), + WorkerSEPID: uint64(d.Get("worker_sep_id").(int)), + WorkerSEPPool: d.Get("worker_sep_pool").(string), + Chipset: d.Get("chipset").(string), + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + if d.Get("disk") == nil { + req.WorkerDisk = 0 + } else { + req.WorkerDisk = uint64(d.Get("disk").(int)) + } + + labels, _ := d.Get("labels").([]interface{}) + for _, label := range labels { + if !strings.HasPrefix(label.(string), "workersGroupName") { + req.Labels = append(req.Labels, label.(string)) + } + } + + annotations, _ := d.Get("annotations").([]interface{}) + for _, annotation := range annotations { + req.Annotations = append(req.Annotations, annotation.(string)) + } + + taints, _ := d.Get("taints").([]interface{}) + for _, taint := range taints { + req.Taints = append(req.Taints, taint.(string)) + } + + if cloudInit, ok := d.GetOk("cloud_init"); ok { + req.UserData = cloudInit.(string) + } + + resp, err := c.CloudBroker().K8S().WorkersGroupAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(resp, `"`), + } + + for { + task, err := c.CloudBroker().Tasks().Get(ctx, taskReq) + if err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceK8sWgCreate: instance creating - %s", task.Stage) + + if task.Completed { + if task.Error != "" { + return diag.FromErr(fmt.Errorf("cannot create k8sWg instance: %v", task.Error)) + } + + wgId, err := task.Result.ID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(fmt.Sprintf("%d#%d", d.Get("k8s_id").(int), wgId)) + break + } + + time.Sleep(time.Second * 20) + } + + return resourceK8sWgRead(ctx, d, m) +} + +func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int)) + + wg, err := utilityK8sWgCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + workersComputeList := make([]compute.RecordCompute, 0) + for _, info := range wg.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) + if err != nil { + return diag.FromErr(err) + } + workersComputeList = append(workersComputeList, *compute) + } + + d.Set("wg_id", wg.ID) + if strings.Contains(d.Id(), "#") { + k8sId, err := strconv.Atoi(strings.Split(d.Id(), "#")[0]) + if err != nil { + return diag.FromErr(err) + } + + d.Set("k8s_id", k8sId) + } else { + d.Set("k8s_id", d.Get("k8s_id")) + } + d.SetId(fmt.Sprintf("%d#%d", d.Get("k8s_id").(int), wg.ID)) + + flattenWg(d, wg, workersComputeList) + + return nil +} + +func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sWgUpdate: called with k8s id %d", d.Get("k8s_id").(int)) + + c := m.(*controller.ControllerCfg) + + if err := ic.ExistK8s(ctx, uint64(d.Get("k8s_id").(int)), c); err != nil { + return diag.FromErr(err) + } + + wg, err := utilityK8sWgCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + if d.HasChange("num") { + if newNum := d.Get("num").(int); uint64(newNum) > wg.Num { + req := k8s.WorkerAddRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + Num: uint64(newNum) - wg.Num, + Chipset: d.Get("chipset").(string), + } + + _, err := c.CloudBroker().K8S().WorkerAdd(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + for i := int(wg.Num) - 1; i >= newNum; i-- { + req := k8s.DeleteWorkerFromGroupRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + WorkerID: wg.DetailedInfo[i].ID, + } + + _, err := c.CloudBroker().K8S().DeleteWorkerFromGroup(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + if d.HasChange("cloud_init") { + req := k8s.UpdateWorkerNodesMetaDataRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + UserData: d.Get("cloud_init").(string), + } + + _, err := c.CloudBroker().K8S().UpdateWorkerNodesMetaData(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + + return nil +} + +func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceK8sWgDelete: called with k8s id %d", d.Get("k8s_id").(int)) + + wg, err := utilityK8sWgCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := k8s.WorkersGroupDeleteRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + } + + _, err = c.CloudBroker().K8S().WorkersGroupDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceK8sWg() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceK8sWgCreate, + ReadContext: resourceK8sWgRead, + UpdateContext: resourceK8sWgUpdate, + DeleteContext: resourceK8sWgDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout20m, + Read: &constants.Timeout20m, + Update: &constants.Timeout20m, + Delete: &constants.Timeout20m, + Default: &constants.Timeout20m, + }, + + Schema: resourceK8sWgSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/k8s/schema.go b/internal/service/cloudbroker/k8s/schema.go new file mode 100644 index 00000000..d6d879cb --- /dev/null +++ b/internal/service/cloudbroker/k8s/schema.go @@ -0,0 +1,1913 @@ +package k8s + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators" +) + +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +func dataSourceK8sComputesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + }, + "masters": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "group_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "workers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "group_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } +} + +func dataSourceK8sListDeletedSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by ipAddress", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RGID", + }, + "lb_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by LBID", + }, + "basic_service_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by BasicServiceID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by Tech Status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "bservice_id": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "k8sci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_id": { + Type: schema.TypeInt, + Computed: true, + }, + "kubeconfig": { + Type: schema.TypeString, + Computed: true, + Description: "Kubeconfig for cluster access.", + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_name": { + Type: schema.TypeString, + Computed: true, + }, + "network_plugin": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "service_account": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "ssh_key": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "workers_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "annotations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "disk": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "num": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceK8sListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by ipAddress", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RGID", + }, + "lb_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by LBID", + }, + "basic_service_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by BasicServiceID", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by Tech Status", + }, + "include_deleted": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Include deleted k8s in result", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "bservice_id": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "k8sci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_id": { + Type: schema.TypeInt, + Computed: true, + }, + "kubeconfig": { + Type: schema.TypeString, + Computed: true, + Description: "Kubeconfig for cluster access.", + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_name": { + Type: schema.TypeString, + Computed: true, + }, + "network_plugin": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "service_account": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "ssh_key": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "workers_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "annotations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceK8sWgCloudInitSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + Description: "Kubernetes cluster ID", + }, + "wg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the workers compute group", + }, + "cloud_init": { + Type: schema.TypeString, + Computed: true, + Description: "Worker group Cloud init", + }, + } +} + +func dataSourceK8sWgListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "annotations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "disk": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "wg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "num": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + } +} + +func dataSourceK8sWgSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of k8s instance.", + }, + "wg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of k8s worker Group.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the worker group.", + }, + "num": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of worker nodes to create.", + }, + "cpu": { + Type: schema.TypeInt, + Computed: true, + Description: "Worker node CPU count.", + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + Description: "Worker node RAM in MB.", + }, + "disk": { + Type: schema.TypeInt, + Computed: true, + Description: "Worker node boot disk size. If unspecified or 0, size is defined by OS image size.", + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "annotations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + } +} + +func dataSourceK8sSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "k8s_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "rg_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "bservice_id": { + Type: schema.TypeInt, + Computed: true, + }, + "k8sci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_ci_name": { + Type: schema.TypeString, + Computed: true, + }, + "k8s_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "masters": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "disk": { + Type: schema.TypeInt, + Computed: true, + }, + "master_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "num": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "workers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "annotations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "disk": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "num": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + }, + }, + }, + "kubeconfig": { + Type: schema.TypeString, + Computed: true, + Description: "Kubeconfig for cluster access.", + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "lb_ip": { + Type: schema.TypeString, + Computed: true, + Description: "IP address of default load balancer.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "network_plugin": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "service_account": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "ssh_key": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func resourceK8sCPSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the cluster.", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "Resource group ID that this instance belongs to.", + }, + "k8sci_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the k8s catalog item to base this instance on.", + }, + "network_plugin": { + Type: schema.TypeString, + Required: true, + Description: "Network plugin to be used", + ValidateFunc: validation.StringInSlice([]string{"flannel", "weavenet", "calico"}, true), + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the storage policy", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "num": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.IntInSlice([]int{1, 3, 5}), + Description: "Number of VMs to create. Can be either 1 or 3 or 5", + }, + "cpu": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Node CPU count.", + }, + "ram": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.All( + validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + validators.DivisibleBy(constants.RAM_DIVISIBILITY), + ), + Description: "Node RAM in MB.", + }, + "disk": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Node boot disk size in GB.", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Storage Endpoint ID", + }, + "sep_pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Storage Endpoint Pool", + }, + "with_lb": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Create k8s with load balancer if true.", + }, + "extnet_only": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Use only selected ExtNet for infrastructure connections", + }, + "join_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting.", + }, + "kube_proxy_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting.", + }, + "kubelet_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. insert a valid JSON string with all levels of nesting.", + }, + "cluster_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to define global settings and configurations for the entire cluster. It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. insert a valid JSON string with all levels of nesting.", + }, + "init_config": { + Type: schema.TypeString, + Optional: true, + Description: "is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting.", + }, + "additional_sans": { + Type: schema.TypeList, + Optional: true, + Description: "Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ha_mode": { + Type: schema.TypeBool, + Optional: true, + Description: "Use Highly Available schema for LB deploy", + }, + "oidc_cert": { + Type: schema.TypeString, + Optional: true, + Description: "insert ssl certificate in x509 pem format", + }, + "chipset": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"Q35", "i440fx"}, false), + Default: "Q35", + Description: "Type of the emulated system. Possible values: i440fx, Q35. Default: Q35", + }, + "lb_sysctl_params": { + Type: schema.TypeList, + Optional: true, + Description: "Custom sysctl values for Load Balancer instance. Applied on boot.", + Elem: &schema.Schema{ + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of default vins for this instace.", + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Description: "Text description of this instance.", + }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Start k8s cluster.", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Enable k8s cluster", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "whether to completely delete the account", + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "master_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Master group ID.", + }, + "master_name": { + Type: schema.TypeString, + Computed: true, + Description: "Master group name.", + }, + "lb_ip": { + Type: schema.TypeString, + Computed: true, + Description: "IP address of default load balancer.", + }, + "default_wg_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of default workers group for this instace.", + }, + "kubeconfig": { + Type: schema.TypeString, + Computed: true, + Description: "Kubeconfig for cluster access.", + }, + "k8s_id": { + Type: schema.TypeInt, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "k8s_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "rg_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "bservice_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "k8s_ci_name": { + Type: schema.TypeString, + Computed: true, + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "ssh_key": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func resourceK8sWgSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "k8s_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of k8s instance.", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the worker group.", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the storage policy", + }, + "num": { + Type: schema.TypeInt, + Optional: true, + Default: 1, + Description: "Number of worker nodes to create.", + }, + "cpu": { + Type: schema.TypeInt, + Optional: true, + Default: 1, + Description: "Worker node CPU count.", + }, + "ram": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.All( + validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + validators.DivisibleBy(constants.RAM_DIVISIBILITY), + ), + Description: "Node RAM in MB.", + }, + "chipset": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"Q35", "i440fx"}, false), + Default: "Q35", + Description: "Type of the emulated system. Possible values: i440fx, Q35. Default: Q35", + }, + "disk": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Worker node boot disk size. If unspecified or 0, size is defined by OS image size.", + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "annotations": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "worker_sep_id": { + Type: schema.TypeInt, + Optional: true, + }, + "worker_sep_pool": { + Type: schema.TypeString, + Optional: true, + }, + "cloud_init": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: cloudInitDiffSupperss, + }, + "wg_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of k8s worker Group.", + }, + "detailed_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + } +} diff --git a/internal/service/cloudbroker/k8s/utility_k8s.go b/internal/service/cloudbroker/k8s/utility_k8s.go new file mode 100644 index 00000000..90411286 --- /dev/null +++ b/internal/service/cloudbroker/k8s/utility_k8s.go @@ -0,0 +1,91 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8S, error) { + c := m.(*controller.ControllerCfg) + req := k8s.GetRequest{} + + if d.Id() != "" { + k8sId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.K8SID = k8sId + } else { + req.K8SID = uint64(d.Get("k8s_id").(int)) + } + + k8s, err := c.CloudBroker().K8S().Get(ctx, req) + if err != nil { + return nil, err + } + + return k8s, nil +} + +func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}, computeID uint64) (*compute.RecordCompute, error) { + c := m.(*controller.ControllerCfg) + req := compute.GetRequest{ + ComputeID: computeID, + } + + compute, err := c.CloudBroker().Compute().Get(ctx, req) + if err != nil { + return nil, err + } + + return compute, nil +} + +func utilityResourceK8sListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ListK8S, error) { + c := m.(*controller.ControllerCfg) + req := k8s.ListRequest{} + + if byID, ok := d.GetOk("k8s_id"); ok { + req.ByID = uint64(byID.(int)) + } + + k8sList, err := c.CloudBroker().K8S().List(ctx, req) + if err != nil { + return nil, err + } + + return k8sList, nil +} diff --git a/internal/service/cloudbroker/k8s/utility_k8s_list.go b/internal/service/cloudbroker/k8s/utility_k8s_list.go new file mode 100644 index 00000000..9025a856 --- /dev/null +++ b/internal/service/cloudbroker/k8s/utility_k8s_list.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityK8sListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ListK8S, error) { + c := m.(*controller.ControllerCfg) + req := k8s.ListRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if ip_address, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ip_address.(string) + } + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + if lb_id, ok := d.GetOk("lb_id"); ok { + req.LBID = uint64(lb_id.(int)) + } + if bservice_id, ok := d.GetOk("bservice_id"); ok { + req.BasicServiceID = uint64(bservice_id.(int)) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + if includeDeleted, ok := d.GetOk("include_deleted"); ok { + req.IncludeDeleted = includeDeleted.(bool) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + k8sList, err := c.CloudBroker().K8S().List(ctx, req) + if err != nil { + return nil, err + } + + return k8sList, nil +} diff --git a/internal/service/cloudbroker/k8s/utility_k8s_list_deleted.go b/internal/service/cloudbroker/k8s/utility_k8s_list_deleted.go new file mode 100644 index 00000000..6a2c7433 --- /dev/null +++ b/internal/service/cloudbroker/k8s/utility_k8s_list_deleted.go @@ -0,0 +1,83 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityK8sListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ListK8S, error) { + c := m.(*controller.ControllerCfg) + req := k8s.ListDeletedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if ip_address, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ip_address.(string) + } + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + if lb_id, ok := d.GetOk("lb_id"); ok { + req.LBID = uint64(lb_id.(int)) + } + if bservice_id, ok := d.GetOk("bservice_id"); ok { + req.BasicServiceID = uint64(bservice_id.(int)) + } + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + k8sList, err := c.CloudBroker().K8S().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return k8sList, nil +} diff --git a/internal/service/cloudbroker/k8s/utility_k8s_wg.go b/internal/service/cloudbroker/k8s/utility_k8s_wg.go new file mode 100644 index 00000000..49e3ed0f --- /dev/null +++ b/internal/service/cloudbroker/k8s/utility_k8s_wg.go @@ -0,0 +1,168 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package k8s + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8SGroup, error) { + c := m.(*controller.ControllerCfg) + var wgId int + var k8sId int + var err error + + if strings.Contains(d.Id(), "#") { + wgId, err = strconv.Atoi(strings.Split(d.Id(), "#")[1]) + if err != nil { + return nil, err + } + k8sId, err = strconv.Atoi(strings.Split(d.Id(), "#")[0]) + if err != nil { + return nil, err + } + } else { + wgId, err = strconv.Atoi(d.Id()) + if err != nil { + return nil, err + } + k8sId = d.Get("k8s_id").(int) + } + + req := k8s.GetRequest{ + K8SID: uint64(k8sId), + } + + cluster, err := c.CloudBroker().K8S().Get(ctx, req) + if err != nil { + return nil, err + } + + for _, wg := range cluster.K8SGroups.Workers { + if wg.ID == uint64(wgId) { + return &wg, nil + } + } + + return nil, fmt.Errorf("not found wg with id: %v in k8s cluster: %v", wgId, cluster.ID) +} + +func utilityDataK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8SGroup, []compute.RecordCompute, error) { + c := m.(*controller.ControllerCfg) + + k8sId := uint64(d.Get("k8s_id").(int)) + wgId := uint64(d.Get("wg_id").(int)) + + k8sGetReq := k8s.GetRequest{ + K8SID: k8sId, + } + + cluster, err := c.CloudBroker().K8S().Get(ctx, k8sGetReq) + if err != nil { + return nil, nil, err + } + + curWg := k8s.RecordK8SGroup{} + for _, wg := range cluster.K8SGroups.Workers { + if wg.ID == wgId { + curWg = wg + break + } + } + if curWg.ID == 0 { + return nil, nil, fmt.Errorf("WG with id %v in k8s cluster %v not found", wgId, k8sId) + } + + workersComputeList := make([]compute.RecordCompute, 0) + for _, info := range curWg.DetailedInfo { + compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) + if err != nil { + return nil, nil, err + } + + workersComputeList = append(workersComputeList, *compute) + } + + return &curWg, workersComputeList, nil +} + +func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ListK8SGroup, error) { + c := m.(*controller.ControllerCfg) + req := k8s.GetRequest{} + + if d.Id() != "" { + k8sId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.K8SID = k8sId + } else { + req.K8SID = uint64(d.Get("k8s_id").(int)) + } + + cluster, err := c.CloudBroker().K8S().Get(ctx, req) + if err != nil { + return nil, err + } + + return &cluster.K8SGroups.Workers, nil +} + +func utilityK8sWgCloudInitCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + req := k8s.GetWorkerNodesMetaDataRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: uint64(d.Get("wg_id").(int)), + } + + cloudInit, err := c.CloudBroker().K8S().GetWorkerNodesMetaData(ctx, req) + if err != nil { + return "", err + } + + return cloudInit, nil +} + +func cloudInitDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool { + if newVal != "" && newVal != oldVal { + log.Debugf("networkSubresIPAddreDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal) + return false + } + log.Debugf("networkSubresIPAddreDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal) + return true // suppress difference +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute.go b/internal/service/cloudbroker/kvmvm/data_source_compute.go new file mode 100644 index 00000000..1e741186 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute.go @@ -0,0 +1,76 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + // "net/url" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + compFacts, err := utilityComputeCheckPresence(ctx, d, m) + if compFacts == nil { + d.SetId("") + return diag.FromErr(err) + } + + pciList, err := utilityComputePCIDevicesList(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if err = flattenDataCompute(d, compFacts, pciList); err != nil { + return diag.FromErr(err) + } + + return nil +} + +func DataSourceCompute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_affinity_relations.go b/internal/service/cloudbroker/kvmvm/data_source_compute_affinity_relations.go new file mode 100644 index 00000000..00b710bb --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_affinity_relations.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeAffinityRelationsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + affinityRelationsList, err := utilityComputeAffinityRelationsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenAffinityRelations(d, affinityRelationsList) + + return nil +} + +func DataSourceComputeAffinityRelations() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeAffinityRelationsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeAffinityRelationsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_audits.go b/internal/service/cloudbroker/kvmvm/data_source_compute_audits.go new file mode 100644 index 00000000..77f833d5 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_audits.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeAudits, err := utilityComputeAuditsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenComputeAudits(computeAudits)) + d.Set("entry_count", computeAudits.EntryCount) + return nil +} + +func DataSourceComputeAudits() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeAuditsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeAuditsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_boot_order_get.go b/internal/service/cloudbroker/kvmvm/data_source_compute_boot_order_get.go new file mode 100644 index 00000000..e75d4a58 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_boot_order_get.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeBootOrderGetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + result, err := utilityComputeBootOrderGetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("boot_order", result) + + return nil +} + +func DataSourceComputeBootOrderGet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeBootOrderGetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeBootOrderGetSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_cpu_alignment_profile.go b/internal/service/cloudbroker/kvmvm/data_source_compute_cpu_alignment_profile.go new file mode 100644 index 00000000..4d604047 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_cpu_alignment_profile.go @@ -0,0 +1,98 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeCPUAlignmentProfileRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + profile, err := utilityComputeGetCPUAlignmentProfile(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("model", profile.Model) + d.Set("name", profile.Name) + d.Set("vendor", profile.Vendor) + + return nil +} + +func dataSourceComputeCPUAlignmentProfileSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the compute instance", + }, + "model": { + Type: schema.TypeString, + Computed: true, + Description: "CPU model of the alignment profile", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the CPU alignment profile", + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + Description: "CPU vendor of the alignment profile", + }, + } +} + +func DataSourceComputeCPUAlignmentProfile() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeCPUAlignmentProfileRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeCPUAlignmentProfileSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_get_audits.go b/internal/service/cloudbroker/kvmvm/data_source_compute_get_audits.go new file mode 100644 index 00000000..2f10b03e --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_get_audits.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeGetAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeAudits, err := utilityComputeGetAuditsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenComputeGetAudits(computeAudits)) + return nil +} + +func DataSourceComputeGetAudits() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeGetAuditsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeGetAuditsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_get_console_url.go b/internal/service/cloudbroker/kvmvm/data_source_compute_get_console_url.go new file mode 100644 index 00000000..cdc9812f --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_get_console_url.go @@ -0,0 +1,74 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "strings" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeGetConsoleUrlRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeConsoleUrl, err := utilityComputeGetConsoleUrlCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + result := strings.ReplaceAll(computeConsoleUrl, "\"", "") + result = strings.ReplaceAll(result, "\\", "") + d.Set("console_url", result) + + return nil +} + +func DataSourceComputeGetConsoleUrl() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeGetConsoleUrlRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeGetConsoleUrlSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_get_log.go b/internal/service/cloudbroker/kvmvm/data_source_compute_get_log.go new file mode 100644 index 00000000..1b7583cb --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_get_log.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeGetLogRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeGetLog, err := utilityComputeGetLogCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("log", computeGetLog) + + return nil +} + +func DataSourceComputeGetLog() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeGetLogRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeGetLogSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_list.go b/internal/service/cloudbroker/kvmvm/data_source_compute_list.go new file mode 100644 index 00000000..4b695855 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_list.go @@ -0,0 +1,77 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeList, err := utilityDataComputeListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + result := computeList + if d.Get("ignore_k8s").(bool) { + // matches automatically generated names like "s234-g2134-c1" etc + result = matchComputes(computeList) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenComputeList(result)) + d.Set("entry_count", computeList.EntryCount) + + return nil +} + +func DataSourceComputeList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_list_deleted.go b/internal/service/cloudbroker/kvmvm/data_source_compute_list_deleted.go new file mode 100644 index 00000000..12c99425 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_list_deleted.go @@ -0,0 +1,78 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeList, err := utilityDataComputeListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + result := computeList + if d.Get("ignore_k8s").(bool) { + // matches automatically generated names like "s234-g2134-c1" etc + result = matchDeletedComputes(computeList) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDeletedComputeList(result)) + d.Set("entry_count", computeList.EntryCount) + + return nil +} + +func DataSourceComputeListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_migrate_storage_info.go b/internal/service/cloudbroker/kvmvm/data_source_compute_migrate_storage_info.go new file mode 100644 index 00000000..6706ff4c --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_migrate_storage_info.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeMigrateStorageInfoRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + result, err := utilityComputeMigrateStorageInfoCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("migrate_storage_info", result) + + return nil +} + +func DataSourceComputeMigrateStorageInfo() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeMigrateStorageInfoRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeMigrateStorageInfoSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_pci_device_list.go b/internal/service/cloudbroker/kvmvm/data_source_compute_pci_device_list.go new file mode 100644 index 00000000..d799e3d9 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_pci_device_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputePCIDeviceListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computePCIDeviceList, err := utilityComputePCIDeviceListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenPCIDevice(computePCIDeviceList.Data)) + d.Set("entry_count", computePCIDeviceList.EntryCount) + + return nil +} + +func DataSourceComputePCIDeviceList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputePCIDeviceListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputePCIDeviceListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_pfw_list.go b/internal/service/cloudbroker/kvmvm/data_source_compute_pfw_list.go new file mode 100644 index 00000000..4f55b6ec --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_pfw_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputePfwListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computePfwList, err := utilityComputePfwListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenPfwList(computePfwList)) + d.Set("entry_count", computePfwList.EntryCount) + + return nil +} + +func DataSourceComputePfwList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputePfwListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputePfwListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_snapshot_list.go b/internal/service/cloudbroker/kvmvm/data_source_compute_snapshot_list.go new file mode 100644 index 00000000..f0cc2488 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_snapshot_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeSnapshotList, err := utilityComputeSnapshotListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenSnapshotList(computeSnapshotList)) + d.Set("entry_count", computeSnapshotList.EntryCount) + + return nil +} + +func DataSourceComputeSnapshotList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeSnapshotListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeSnapshotListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_snapshot_usage.go b/internal/service/cloudbroker/kvmvm/data_source_compute_snapshot_usage.go new file mode 100644 index 00000000..29864538 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_snapshot_usage.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeSnapshotUsageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeSnapshotUsage, err := utilityComputeSnapshotUsageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenSnapshotUsage(*computeSnapshotUsage)) + + return nil +} + +func DataSourceComputeSnapshotUsage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeSnapshotUsageRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeSnapshotUsageSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_user_list.go b/internal/service/cloudbroker/kvmvm/data_source_compute_user_list.go new file mode 100644 index 00000000..acc701ff --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_user_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeUserListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeUserList, err := utilityComputeUserListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenUserList(d, computeUserList) + + return nil +} + +func DataSourceComputeUserList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeUserListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeUserListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute_vgpu_list.go b/internal/service/cloudbroker/kvmvm/data_source_compute_vgpu_list.go new file mode 100644 index 00000000..ba26c75a --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/data_source_compute_vgpu_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceComputeVGPUListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computeVGPUList, err := utilityComputeVGPUListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVGPU(computeVGPUList.Data)) + d.Set("entry_count", computeVGPUList.EntryCount) + + return nil +} + +func DataSourceComputeVGPUList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceComputeVGPUListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceComputeVGPUListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/kvmvm/flattens.go b/internal/service/cloudbroker/kvmvm/flattens.go new file mode 100644 index 00000000..6ccb2345 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/flattens.go @@ -0,0 +1,1087 @@ +package kvmvm + +import ( + "encoding/json" + "fmt" + "sort" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenCompute(d *schema.ResourceData, computeRec *compute.RecordCompute, pciList *compute.ListPCIDevices) error { + log.Debugf("flattenCompute: ID %d, RG ID %d", computeRec.ID, computeRec.RGID) + + customFields, _ := json.Marshal(computeRec.CustomFields) + devices, _ := json.Marshal(computeRec.Devices) + userData, _ := json.Marshal(computeRec.Userdata) + bootDisk := findBootDisk(computeRec.Disks, computeRec.Chipset) + + if len(computeRec.Interfaces) > 0 { + log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(computeRec.Interfaces)) + if err := d.Set("network", parseComputeInterfacesToNetworks(d.Get("network").(*schema.Set).List(), computeRec.Interfaces)); err != nil { + return err + } + } + d.Set("account_id", computeRec.AccountID) + d.Set("account_name", computeRec.AccountName) + d.Set("acl", flattenListACLInterface(computeRec.ACL)) + d.Set("affinity_label", computeRec.AffinityLabel) + d.Set("affinity_weight", computeRec.AffinityWeight) + d.Set("affinity_rules", flattenAffinityRules(computeRec.AffinityRules)) + d.Set("anti_affinity_rules", flattenAffinityRules(computeRec.AntiAffinityRules)) + d.Set("arch", computeRec.Arch) + d.Set("auto_start_w_node", computeRec.AutoStart) + d.Set("boot_order", computeRec.BootOrder) + d.Set("boot_disk_id", bootDisk.ID) + // we intentionally use the SizeMax field, do not change it until the BootDiskSize field is fixed on the platform + d.Set("boot_disk_size", bootDisk.SizeMax) + d.Set("boot_disk_discard", bootDisk.Discard) + d.Set("boot_image_id", bootDisk.ImageID) + d.Set("chipset", computeRec.Chipset) + d.Set("clock", computeRec.Clock) + d.Set("cd_image_id", computeRec.CdImageId) + d.Set("clone_reference", computeRec.CloneReference) + d.Set("clones", computeRec.Clones) + d.Set("computeci_id", computeRec.ComputeCIID) + d.Set("cpu", computeRec.CPUs) + d.Set("created_by", computeRec.CreatedBy) + d.Set("created_time", computeRec.CreatedTime) + d.Set("custom_fields", string(customFields)) + d.Set("deleted_by", computeRec.DeletedBy) + d.Set("deleted_time", computeRec.DeletedTime) + d.Set("description", computeRec.Description) + d.Set("devices", string(devices)) + err := d.Set("disks", flattenComputeDisks(computeRec.Disks, d.Get("disks").([]interface{}), d.Get("extra_disks").(*schema.Set).List(), bootDisk.ID)) + if err != nil { + return err + } + d.Set("driver", computeRec.Driver) + d.Set("gid", computeRec.GID) + d.Set("guid", computeRec.GUID) + d.Set("compute_id", computeRec.ID) + d.Set("image_id", computeRec.ImageID) + d.Set("image_name", computeRec.ImageName) + d.Set("interfaces", flattenInterfaces(computeRec.Interfaces)) + d.Set("lock_status", computeRec.LockStatus) + d.Set("loader_meta_iso", flattenLoaderMetaIso(computeRec.LoaderMetaIso)) + d.Set("manager_id", computeRec.ManagerID) + d.Set("manager_type", computeRec.ManagerType) + d.Set("migrationjob", computeRec.MigrationJob) + d.Set("milestones", computeRec.Milestones) + d.Set("natable_vins_id", computeRec.NatableVINSID) + d.Set("natable_vins_ip", computeRec.NatableVINSIP) + d.Set("natable_vins_name", computeRec.NatableVINSName) + d.Set("natable_vins_network", computeRec.NatableVINSNetwork) + d.Set("natable_vins_network_name", computeRec.NatableVINSNetworkName) + d.Set("need_reboot", computeRec.NeedReboot) + d.Set("numa_node_id", computeRec.NumaNodeId) + d.Set("os_users", flattenOSUsers(computeRec.OSUsers)) + d.Set("pinned", computeRec.PinnedToNode) + d.Set("preferred_cpu", computeRec.PreferredCPU) + d.Set("ram", computeRec.RAM) + d.Set("reference_id", computeRec.ReferenceID) + d.Set("registered", computeRec.Registered) + d.Set("res_name", computeRec.ResName) + d.Set("reserved_node_cpus", computeRec.ReservedNodeCpus) + d.Set("rg_name", computeRec.RGName) + d.Set("rg_id", computeRec.RGID) + d.Set("snap_sets", flattenSnapSets(computeRec.SnapSets)) + d.Set("started", computeRec.TechStatus == "STARTED") + d.Set("node_id", computeRec.NodeID) + d.Set("node_name", computeRec.NodeName) + d.Set("stateless_sep_id", computeRec.StatelessSEPID) + d.Set("stateless_sep_type", computeRec.StatelessSEPType) + d.Set("status", computeRec.Status) + d.Set("tags", flattenTags(computeRec.Tags)) + d.Set("tech_status", computeRec.TechStatus) + d.Set("updated_by", computeRec.UpdatedBy) + d.Set("updated_time", computeRec.UpdatedTime) + d.Set("user_data", string(userData)) + d.Set("user_managed", computeRec.UserManaged) + d.Set("read_only", computeRec.ReadOnly) + d.Set("vnc_password", computeRec.VNCPassword) + d.Set("vgpus", flattenVGPUs(computeRec.VGPUs)) + d.Set("pci_devices", flattenPCI(*pciList)) + d.Set("loader_type", computeRec.LoaderType) + d.Set("boot_type", computeRec.BootType) + d.Set("hot_resize", computeRec.HotResize) + d.Set("network_interface_naming", computeRec.NetworkInterfaceNaming) + d.Set("zone_id", computeRec.ZoneID) + d.Set("os_version", computeRec.OSVersion) + d.Set("cpu_pin", computeRec.CPUPin) + d.Set("cpu_alignment_profile", computeRec.CPUAlignmentProfile.Name) + d.Set("numa_affinity", computeRec.NumaAffinity) + d.Set("hp_backed", computeRec.HPBacked) + d.Set("weight", computeRec.Weight) + return nil +} + +func flattenCPUAlignmentProfile(profile compute.CPUAlignmentProfile) []map[string]interface{} { + if profile.Name == "" && profile.Model == "" && profile.Vendor == "" { + return nil + } + return []map[string]interface{}{ + { + "name": profile.Name, + "model": profile.Model, + "vendor": profile.Vendor, + }, + } +} + +func flattenPCI(pciList compute.ListPCIDevices) []uint64 { + res := make([]uint64, 0, len(pciList.Data)) + + for _, v := range pciList.Data { + res = append(res, v.ID) + } + + return res +} + +func flattenTags(tags map[string]interface{}) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(tags)) + + for k, v := range tags { + res = append(res, map[string]interface{}{ + "key": k, + "val": v, + }) + } + + return res +} + +func flattenSnapSets(snaps compute.ListSnapshots) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(snaps)) + + for _, snap := range snaps { + res = append(res, map[string]interface{}{ + "disks": snap.Disks, + "guid": snap.GUID, + "label": snap.Label, + "timestamp": snap.Timestamp, + }) + } + + return res +} + +func flattenOSUsers(users compute.ListOSUsers) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(users)) + + for _, user := range users { + res = append(res, map[string]interface{}{ + "guid": user.GUID, + "login": user.Login, + "password": user.Password, + "public_key": user.PubKey, + }) + } + + return res +} + +func flattenInterfaces(ifaces compute.ListInterfaces) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ifaces)) + for _, iface := range ifaces { + res = append(res, map[string]interface{}{ + "bus_number": iface.BusNumber, + "conn_id": iface.ConnID, + "conn_type": iface.ConnType, + "def_gw": iface.DefGW, + "enabled": iface.Enabled, + "enable_secgroups": iface.EnableSecGroups, + "flip_group_id": iface.FLIPGroupID, + "guid": iface.GUID, + "ip_address": iface.IPAddress, + "listen_ssh": iface.ListenSSH, + "mac": iface.MAC, + "mtu": iface.MTU, + "name": iface.Name, + "net_id": iface.NetID, + "netmask": iface.NetMask, + "net_type": iface.NetType, + "node_id": iface.NodeID, + "pci_slot": iface.PCISlot, + "qos": flattenQOS(iface.QOS), + "sdn_interface_id": iface.SDNInterfaceID, + "security_groups": iface.SecGroups, + "target": iface.Target, + "type": iface.Type, + "trunk_tags": iface.TrunkTags, + "vnfs": iface.VNFs, + "libvirt_settings": flattenLibvirtSettings(iface.LibvirtSettings), + }) + } + return res +} + +func flattenLibvirtSettings(libvirtSettings compute.LibvirtSettings) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "guid": libvirtSettings.GUID, + "txmode": libvirtSettings.TXMode, + "ioeventfd": libvirtSettings.IOEventFD, + "event_idx": libvirtSettings.EventIDx, + "queues": libvirtSettings.Queues, + "rx_queue_size": libvirtSettings.RXQueueSize, + "tx_queue_size": libvirtSettings.TXQueueSize, + } + res = append(res, temp) + return res +} + +func flattenQOS(qos compute.QOS) []map[string]interface{} { + return []map[string]interface{}{ + { + "e_rate": qos.ERate, + "guid": qos.GUID, + "in_brust": qos.InBurst, + "in_rate": qos.InRate, + }, + } +} + +func flattenComputeDisks(disksList compute.ListDisks, disksBlocks, extraDisks []interface{}, bootDiskId uint64) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(disksList)) + + sort.Slice(disksList, func(i, j int) bool { + return disksList[i].ID < disksList[j].ID + }) + + indexDataDisks := 0 + + for _, disk := range disksList { + if disk.ID == bootDiskId || findInExtraDisks(uint(disk.ID), extraDisks) { //skip main bootdisk and extraDisks + continue + } + + var pernamentlyValue bool + if indexDataDisks < len(disksBlocks) { + if diskBlock, ok := disksBlocks[indexDataDisks].(map[string]interface{}); ok { + if perm, exists := diskBlock["permanently"]; exists { + if permBool, ok := perm.(bool); ok { + pernamentlyValue = permBool + } + } + } + } + + var nodeIds *schema.Set + if indexDataDisks < len(disksBlocks) { + if diskBlock, ok := disksBlocks[indexDataDisks].(map[string]interface{}); ok { + if nodeIds, exists := diskBlock["node_ids"]; exists { + nodeIds = nodeIds.(*schema.Set) + } + } + } + + temp := map[string]interface{}{ + "disk_name": disk.Name, + "node_ids": nodeIds, + "size": disk.SizeMax, + "sep_id": disk.SEPID, + "pci_slot": disk.PCISlot, + "bus_number": disk.BusNumber, + "pool": disk.Pool, + "desc": disk.Description, + "image_id": disk.ImageID, + "independent": disk.Independent, + "disk_id": disk.ID, + "shareable": disk.Shareable, + "size_used": disk.SizeUsed, + "size_max": disk.SizeMax, + "present_to": disk.PresentTo, + "storage_policy_id": disk.StoragePolicyID, + "to_clean": disk.ToClean, + "permanently": pernamentlyValue, + "devicename": disk.DeviceName, + "create_by": disk.CreatedBy, + "create_time": disk.CreatedTime, + "delete_by": disk.DeletedBy, + "delete_time": disk.DeletedTime, + "update_time": disk.UpdatedTime, + "cache": disk.Cache, + "discard": disk.Discard, + "block_size": disk.BlockSize, + "provision": disk.Provision, + "iotune": flattenIOTune(disk.IOTune), + } + res = append(res, temp) + indexDataDisks++ + } + + return res +} + +func findInExtraDisks(diskId uint, extraDisks []interface{}) bool { + for _, ExtraDisk := range extraDisks { + if diskId == uint(ExtraDisk.(int)) { + return true + } + } + return false +} + +func flattenAffinityRules(rules compute.ListRules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rules)) + + for _, rule := range rules { + res = append(res, map[string]interface{}{ + "topology": rule.Topology, + "policy": rule.Policy, + "mode": rule.Mode, + "key": rule.Key, + "value": rule.Value, + }) + } + + return res +} + +func flattenComputeList(computes *compute.ListComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computes.Data)) + for _, computeItem := range computes.Data { + + customFields, _ := json.Marshal(computeItem.CustomFields) + devices, _ := json.Marshal(computeItem.Devices) + userData, _ := json.Marshal(computeItem.Userdata) + temp := map[string]interface{}{ + "acl": flattenListACLInterface(computeItem.ACL), + "account_id": computeItem.AccountID, + "account_name": computeItem.AccountName, + "affinity_label": computeItem.AffinityLabel, + "affinity_rules": flattenListRules(computeItem.AffinityRules), + "affinity_weight": computeItem.AffinityWeight, + "anti_affinity_rules": flattenListRules(computeItem.AntiAffinityRules), + "arch": computeItem.Arch, + "auto_start_w_node": computeItem.AutoStart, + "chipset": computeItem.Chipset, + "clock": computeItem.Clock, + "cd_image_id": computeItem.CdImageId, + "boot_order": computeItem.BootOrder, + "boot_image_id": computeItem.BootImageID, + "bootdisk_size": computeItem.BootDiskSize, + "clone_reference": computeItem.CloneReference, + "clones": computeItem.Clones, + "computeci_id": computeItem.ComputeCIID, + "cpus": computeItem.CPUs, + "created_by": computeItem.CreatedBy, + "created_time": computeItem.CreatedTime, + "custom_fields": string(customFields), + "deleted_by": computeItem.DeletedBy, + "deleted_time": computeItem.DeletedTime, + "desc": computeItem.Description, + "devices": string(devices), + "disks": flattenDisks(computeItem.Disks), + "driver": computeItem.Driver, + "gid": computeItem.GID, + "guid": computeItem.GUID, + "hp_backed": computeItem.HPBacked, + "compute_id": computeItem.ID, + "cpu_alignment_profiles": flattenCPUAlignmentProfile(computeItem.CPUAlignmentProfile), + "cpu_pin": computeItem.CPUPin, + "interfaces": flattenInterfaces(computeItem.Interfaces), + "live_migration_job_id": computeItem.LiveMigrationJobID, + "lock_status": computeItem.LockStatus, + "manager_id": computeItem.ManagerID, + "manager_type": computeItem.ManagerType, + "migrationjob": computeItem.MigrationJob, + "milestones": computeItem.Milestones, + "nid": computeItem.NID, + "name": computeItem.Name, + "need_reboot": computeItem.NeedReboot, + "numa_affinity": computeItem.NumaAffinity, + "numa_node_id": computeItem.NumaNodeId, + "os_users": flattenOSUsers(computeItem.OSUsers), + "os_version": computeItem.OSVersion, + "pinned": computeItem.PinnedToNode, + "preferred_cpu": computeItem.PreferredCPU, + "qemu_guest": flattenQemuQuest(computeItem.QemuQuest), + "ram": computeItem.RAM, + "reference_id": computeItem.ReferenceID, + "registered": computeItem.Registered, + "res_name": computeItem.ResName, + "reserved_node_cpus": computeItem.ReservedNodeCpus, + "rg_id": computeItem.RGID, + "rg_name": computeItem.RGName, + "snap_sets": flattenSnapSets(computeItem.SnapSets), + "node_id": computeItem.NodeID, + "node_name": computeItem.NodeName, + "stateless_sep_id": computeItem.StatelessSEPID, + "stateless_sep_type": computeItem.StatelessSEPType, + "status": computeItem.Status, + "tags": flattenTags(computeItem.Tags), + "tech_status": computeItem.TechStatus, + "total_disk_size": computeItem.TotalDiskSize, + "updated_by": computeItem.UpdatedBy, + "updated_time": computeItem.UpdatedTime, + "user_data": string(userData), + "user_managed": computeItem.UserManaged, + "read_only": computeItem.ReadOnly, + "vgpus": computeItem.VGPUs, + "vins_connected": computeItem.VINSConnected, + "loader_type": computeItem.LoaderType, + "boot_type": computeItem.BootType, + "hot_resize": computeItem.HotResize, + "network_interface_naming": computeItem.NetworkInterfaceNaming, + "zone_id": computeItem.ZoneID, + "weight": computeItem.Weight, + } + res = append(res, temp) + } + + return res +} + +func flattenDeletedComputeList(computes *compute.ListDeletedComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computes.Data)) + for _, computeItem := range computes.Data { + customFields, _ := json.Marshal(computeItem.CustomFields) + devices, _ := json.Marshal(computeItem.Devices) + userData, _ := json.Marshal(computeItem.Userdata) + temp := map[string]interface{}{ + "acl": flattenListACLInterface(computeItem.ACL), + "account_id": computeItem.AccountID, + "account_name": computeItem.AccountName, + "affinity_label": computeItem.AffinityLabel, + "affinity_rules": flattenListRules(computeItem.AffinityRules), + "affinity_weight": computeItem.AffinityWeight, + "anti_affinity_rules": flattenListRules(computeItem.AntiAffinityRules), + "arch": computeItem.Arch, + "auto_start_w_node": computeItem.AutoStart, + "chipset": computeItem.Chipset, + "clock": computeItem.Clock, + "cd_image_id": computeItem.CdImageId, + "boot_order": computeItem.BootOrder, + "bootdisk_size": computeItem.BootDiskSize, + "boot_image_id": computeItem.BootImageID, + "clone_reference": computeItem.CloneReference, + "clones": computeItem.Clones, + "computeci_id": computeItem.ComputeCIID, + "cpus": computeItem.CPUs, + "created_by": computeItem.CreatedBy, + "created_time": computeItem.CreatedTime, + "custom_fields": string(customFields), + "deleted_by": computeItem.DeletedBy, + "deleted_time": computeItem.DeletedTime, + "desc": computeItem.Description, + "devices": string(devices), + "disks": flattenDisks(computeItem.Disks), + "driver": computeItem.Driver, + "gid": computeItem.GID, + "guid": computeItem.GUID, + "hp_backed": computeItem.HPBacked, + "compute_id": computeItem.ID, + "cpu_alignment_profiles": flattenCPUAlignmentProfile(computeItem.CPUAlignmentProfile), + "cpu_pin": computeItem.CPUPin, + "interfaces": flattenInterfaces(computeItem.Interfaces), + "lock_status": computeItem.LockStatus, + "manager_id": computeItem.ManagerID, + "manager_type": computeItem.ManagerType, + "migrationjob": computeItem.MigrationJob, + "milestones": computeItem.Milestones, + "name": computeItem.Name, + "need_reboot": computeItem.NeedReboot, + "numa_affinity": computeItem.NumaAffinity, + "numa_node_id": computeItem.NumaNodeId, + "os_users": flattenOSUsers(computeItem.OSUsers), + "os_version": computeItem.OSVersion, + "pinned": computeItem.PinnedToNode, + "preferred_cpu": computeItem.PreferredCPU, + "ram": computeItem.RAM, + "reference_id": computeItem.ReferenceID, + "registered": computeItem.Registered, + "res_name": computeItem.ResName, + "reserved_node_cpus": computeItem.ReservedNodeCpus, + "rg_id": computeItem.RGID, + "rg_name": computeItem.RGName, + "snap_sets": flattenSnapSets(computeItem.SnapSets), + "node_id": computeItem.NodeID, + "node_name": computeItem.NodeName, + "stateless_sep_id": computeItem.StatelessSEPID, + "stateless_sep_type": computeItem.StatelessSEPType, + "status": computeItem.Status, + "tags": flattenTags(computeItem.Tags), + "tech_status": computeItem.TechStatus, + "total_disk_size": computeItem.TotalDiskSize, + "updated_by": computeItem.UpdatedBy, + "updated_time": computeItem.UpdatedTime, + "user_data": string(userData), + "user_managed": computeItem.UserManaged, + "vgpus": computeItem.VGPUs, + "vins_connected": computeItem.VINSConnected, + "loader_type": computeItem.LoaderType, + "boot_type": computeItem.BootType, + "hot_resize": computeItem.HotResize, + "network_interface_naming": computeItem.NetworkInterfaceNaming, + "zone_id": computeItem.ZoneID, + "weight": computeItem.Weight, + } + res = append(res, temp) + } + return res +} + +func flattenListACLInterface(listAcl []interface{}) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(listAcl)) + for _, aclInterface := range listAcl { + acl := aclInterface.(map[string]interface{}) + temp := map[string]interface{}{ + "explicit": acl["explicit"], + "guid": acl["guid"], + "right": acl["right"], + "status": acl["status"], + "type": acl["type"], + "user_group_id": acl["user_group_id"], + } + res = append(res, temp) + } + return res +} + +func flattenListACL(listAcl compute.ListACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(listAcl)) + for _, acl := range listAcl { + temp := map[string]interface{}{ + "explicit": acl.Explicit, + "guid": acl.GUID, + "right": acl.Right, + "status": acl.Status, + "type": acl.Type, + "user_group_id": acl.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenListComputeACL(listAcl []compute.ItemComputeACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(listAcl)) + for _, acl := range listAcl { + temp := map[string]interface{}{ + "explicit": acl.Explicit, + "guid": acl.GUID, + "right": acl.Right, + "status": acl.Status, + "type": acl.Type, + "user_group_id": acl.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenListRules(listRules compute.ListRules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(listRules)) + for _, rule := range listRules { + temp := map[string]interface{}{ + "guid": rule.GUID, + "key": rule.Key, + "mode": rule.Mode, + "policy": rule.Policy, + "topology": rule.Topology, + "value": rule.Value, + } + res = append(res, temp) + } + return res +} + +func flattenDisks(disks []compute.InfoDisk) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, disk := range disks { + temp := map[string]interface{}{ + // "bus_number": disk.BusNumber, + "disk_id": disk.ID, + // "pci_slot": disk.PCISlot, + "sep_id": disk.SepID, + } + res = append(res, temp) + } + return res +} + +func flattenLoaderMetaIso(loaderMetaIso compute.LoaderMetaIso) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "device_name": loaderMetaIso.DeviceName, + "path": loaderMetaIso.Path, + } + res = append(res, temp) + return res +} + +func flattenComputeAudits(computeAudits compute.ListDetailedAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computeAudits.Data)) + for _, computeAudit := range computeAudits.Data { + temp := map[string]interface{}{ + "call": computeAudit.Call, + "responsetime": computeAudit.ResponseTime, + "statuscode": computeAudit.StatusCode, + "timestamp": computeAudit.Timestamp, + "user": computeAudit.User, + } + res = append(res, temp) + } + return res +} + +func flattenComputeGetAudits(computeAudits compute.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computeAudits)) + for _, computeAudit := range computeAudits { + temp := map[string]interface{}{ + "epoch": computeAudit.Epoch, + "message": computeAudit.Message, + } + res = append(res, temp) + } + return res +} + +func flattenPfwList(computePfws *compute.ListPFW) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computePfws.Data)) + for _, computePfw := range computePfws.Data { + temp := map[string]interface{}{ + "pfw_id": computePfw.ID, + "local_ip": computePfw.LocalIP, + "local_port": computePfw.LocalPort, + "protocol": computePfw.Protocol, + "public_port_end": computePfw.PublicPortEnd, + "public_port_start": computePfw.PublicPortStart, + "vm_id": computePfw.VMID, + } + res = append(res, temp) + } + return res +} + +func flattenUserList(d *schema.ResourceData, userList *compute.ListUsers) { + d.Set("account_acl", flattenListACL(userList.Data.AccountACL)) + d.Set("compute_acl", flattenListComputeACL(userList.Data.ComputeACL)) + d.Set("rg_acl", flattenListACL(userList.Data.RGACL)) +} + +func flattenSnapshotList(computeSnapshots *compute.ListSnapShot) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computeSnapshots.Data)) + for _, snp := range computeSnapshots.Data { + temp := map[string]interface{}{ + "disks": snp.Disks, + "guid": snp.GUID, + "label": snp.Label, + "timestamp": snp.Timestamp, + } + res = append(res, temp) + } + return res +} + +func flattenAffinityRelations(d *schema.ResourceData, ar *compute.RecordAffinityRelations) { + d.Set("other_node", flattenNodes(ar.OtherNode)) + d.Set("other_node_indirect", flattenNodes(ar.OtherNodeIndirect)) + d.Set("other_node_indirect_soft", flattenNodes(ar.OtherNodeIndirectSoft)) + d.Set("other_node_soft", flattenNodes(ar.OtherNodeSoft)) + d.Set("same_node", flattenNodes(ar.SameNode)) + d.Set("same_node_soft", flattenNodes(ar.SameNodeSoft)) +} + +func flattenSnapshotUsage(computeSnapshotUsages compute.ListSnapshotUsage) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computeSnapshotUsages)) + for _, computeUsage := range computeSnapshotUsages { + temp := map[string]interface{}{ + "count": computeUsage.Count, + "stored": computeUsage.Stored, + "label": computeUsage.Label, + "timestamp": computeUsage.Timestamp, + } + res = append(res, temp) + } + return res +} + +func flattenPCIDevice(deviceList []compute.ItemPCIDevice) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(deviceList)) + for _, dev := range deviceList { + temp := map[string]interface{}{ + "ckey": dev.CKey, + "meta": flattens.FlattenMeta(dev.Meta), + "compute_id": dev.ComputeID, + "description": dev.Description, + "guid": dev.GUID, + "hwpath": dev.HwPath, + "device_id": dev.ID, + "name": dev.Name, + "rg_id": dev.RGID, + "node_id": dev.NodeID, + "status": dev.Status, + "system_name": dev.SystemName, + } + res = append(res, temp) + } + return res +} + +func flattenVGPU(vgpuList []compute.ItemVGPU) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vgpuList)) + for _, dev := range vgpuList { + temp := map[string]interface{}{ + "account_id": dev.AccountID, + "created_time": dev.CreatedTime, + "deleted_time": dev.DeletedTime, + "gid": dev.GID, + "guid": dev.GUID, + "vgpu_id": dev.ID, + "last_claimed_by": dev.LastClaimedBy, + "last_update_time": dev.LastUpdateTime, + "mode": dev.Mode, + "pci_slot": dev.PCISlot, + "pgpuid": dev.PGPUID, + "profile_id": dev.ProfileID, + "ram": dev.RAM, + "reference_id": dev.ReferenceID, + "rg_id": dev.RGID, + "status": dev.Status, + "type": dev.Type, + "vm_id": dev.VMID, + } + res = append(res, temp) + } + return res +} + +func flattenNodes(m []interface{}) []string { + var output []string + for _, item := range m { + switch d := item.(type) { + case string: + output = append(output, d) + case int: + output = append(output, strconv.Itoa(d)) + case int64: + output = append(output, strconv.FormatInt(d, 10)) + case float64: + output = append(output, strconv.FormatInt(int64(d), 10)) + default: + output = append(output, "") + } + } + return output +} + +func flattenDataCompute(d *schema.ResourceData, compFacts *compute.RecordCompute, pciList *compute.ListPCIDevices) error { + // This function expects that compFacts string contains response from API compute/get, + // i.e. detailed information about compute instance. + // + // NOTE: this function modifies ResourceData argument - as such it should never be called + // from resourceComputeExists(...) method + + log.Debugf("flattenCompute: ID %d, RG ID %d", compFacts.ID, compFacts.RGID) + + customFields, _ := json.Marshal(compFacts.CustomFields) + devices, _ := json.Marshal(compFacts.Devices) + userData, _ := json.Marshal(compFacts.Userdata) + // general fields setting + d.SetId(fmt.Sprintf("%d", compFacts.ID)) + d.Set("account_id", compFacts.AccountID) + d.Set("account_name", compFacts.AccountName) + d.Set("acl", flattenListACLInterface(compFacts.ACL)) + d.Set("affinity_label", compFacts.AffinityLabel) + d.Set("affinity_rules", flattenAffinityRules(compFacts.AffinityRules)) + d.Set("affinity_weight", compFacts.AffinityWeight) + d.Set("anti_affinity_rules", flattenAffinityRules(compFacts.AntiAffinityRules)) + d.Set("arch", compFacts.Arch) + d.Set("auto_start_w_node", compFacts.AutoStart) + d.Set("boot_order", compFacts.BootOrder) + d.Set("boot_image_id", compFacts.ImageID) + d.Set("chipset", compFacts.Chipset) + d.Set("clock", compFacts.Clock) + d.Set("cd_image_id", compFacts.CdImageId) + d.Set("clone_reference", compFacts.CloneReference) + d.Set("clones", compFacts.Clones) + d.Set("computeci_id", compFacts.ComputeCIID) + d.Set("cpu_alignment_profiles", flattenCPUAlignmentProfile(compFacts.CPUAlignmentProfile)) + d.Set("cpu_pin", compFacts.CPUPin) + d.Set("cpus", compFacts.CPUs) + d.Set("created_by", compFacts.CreatedBy) + d.Set("created_time", compFacts.CreatedTime) + d.Set("custom_fields", string(customFields)) + d.Set("deleted_by", compFacts.DeletedBy) + d.Set("deleted_time", compFacts.DeletedTime) + d.Set("desc", compFacts.Description) + d.Set("devices", string(devices)) + d.Set("disks", flattenDisk(compFacts.Disks)) + d.Set("driver", compFacts.Driver) + d.Set("gid", compFacts.GID) + d.Set("guid", compFacts.GUID) + d.Set("hp_backed", compFacts.HPBacked) + d.Set("image_id", compFacts.ImageID) + d.Set("image_name", compFacts.ImageName) + d.Set("interfaces", flattenInterfaces(compFacts.Interfaces)) + d.Set("live_migration_job_id", compFacts.LiveMigrationJobID) + d.Set("lock_status", compFacts.LockStatus) + d.Set("manager_id", compFacts.ManagerID) + d.Set("manager_type", compFacts.ManagerType) + d.Set("migrationjob", compFacts.MigrationJob) + d.Set("milestones", compFacts.Milestones) + d.Set("name", compFacts.Name) + d.Set("natable_vins_id", compFacts.NatableVINSID) + d.Set("natable_vins_ip", compFacts.NatableVINSIP) + d.Set("natable_vins_name", compFacts.NatableVINSName) + d.Set("natable_vins_network", compFacts.NatableVINSNetwork) + d.Set("natable_vins_network_name", compFacts.NatableVINSNetworkName) + d.Set("need_reboot", compFacts.NeedReboot) + d.Set("numa_affinity", compFacts.NumaAffinity) + d.Set("numa_node_id", compFacts.NumaNodeId) + d.Set("os_users", flattenOSUsers(compFacts.OSUsers)) + d.Set("pinned", compFacts.PinnedToNode) + d.Set("preferred_cpu", compFacts.PreferredCPU) + d.Set("qemu_guest", flattenQemuQuest(compFacts.QemuQuest)) + d.Set("ram", compFacts.RAM) + d.Set("reference_id", compFacts.ReferenceID) + d.Set("registered", compFacts.Registered) + d.Set("res_name", compFacts.ResName) + d.Set("reserved_node_cpus", compFacts.ReservedNodeCpus) + d.Set("rg_id", compFacts.RGID) + d.Set("rg_name", compFacts.RGName) + d.Set("snap_sets", flattenSnapSets(compFacts.SnapSets)) + d.Set("node_id", compFacts.NodeID) + d.Set("node_name", compFacts.NodeName) + d.Set("stateless_sep_id", compFacts.StatelessSEPID) + d.Set("stateless_sep_type", compFacts.StatelessSEPType) + d.Set("status", compFacts.Status) + d.Set("tags", flattenTags(compFacts.Tags)) + d.Set("tech_status", compFacts.TechStatus) + d.Set("updated_by", compFacts.UpdatedBy) + d.Set("updated_time", compFacts.UpdatedTime) + d.Set("user_data", string(userData)) + d.Set("user_managed", compFacts.UserManaged) + d.Set("read_only", compFacts.ReadOnly) + d.Set("vnc_password", compFacts.VNCPassword) + d.Set("vgpus", flattenVGPUs(compFacts.VGPUs)) + d.Set("pci_devices", flattenPCI(*pciList)) + d.Set("loader_type", compFacts.LoaderType) + d.Set("boot_type", compFacts.BootType) + d.Set("hot_resize", compFacts.HotResize) + d.Set("network_interface_naming", compFacts.NetworkInterfaceNaming) + d.Set("zone_id", compFacts.ZoneID) + d.Set("loader_meta_iso", flattenLoaderMetaIso(compFacts.LoaderMetaIso)) + d.Set("os_version", compFacts.OSVersion) + d.Set("weight", compFacts.Weight) + //extra fields setting + bootDisk := findBootDisk(compFacts.Disks, compFacts.Chipset) + if bootDisk != nil { + d.Set("boot_disk_size", bootDisk.SizeMax) + d.Set("boot_disk_id", bootDisk.ID) // we may need boot disk ID in resize operations + d.Set("sep_id", bootDisk.SEPID) + d.Set("pool", bootDisk.Pool) + } + + return nil +} + +// Parse the list of interfaces from compute/get response into a list of networks +// attached to this compute +func parseComputeInterfacesToNetworks(networks []interface{}, ifaces compute.ListInterfaces) []interface{} { + // return value will be used to d.Set("network") item of dataSourceCompute schema + length := len(ifaces) + log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length) + + result := []interface{}{} + for _, value := range ifaces { + elem := make(map[string]interface{}) + // Keys in this map should correspond to the Schema definition for "network" + elem["net_id"] = value.NetID + elem["net_type"] = value.NetType + elem["ip_address"] = value.IPAddress + elem["mac"] = value.MAC + elem["mtu"] = value.MTU + elem["net_mask"] = value.NetMask + elem["sdn_interface_id"] = value.SDNInterfaceID + elem["weight"] = flattenNetworkWeight(networks, value.NetID, value.NetType) + elem["enabled"] = value.Enabled + + result = append(result, elem) + } + + return result +} + +func flattenNetworkWeight(networks []interface{}, netID uint64, netType string) int { + for _, network := range networks { + ns := network.(map[string]interface{}) + if ns["net_id"].(int) == int(netID) && ns["net_type"].(string) == netType { + weight := ns["weight"].(int) + return weight + } + } + return 0 +} + +func flattenDisk(diskList compute.ListDisks) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(diskList)) + for _, disk := range diskList { + temp := map[string]interface{}{ + "ckey": disk.CKey, + "meta": flattens.FlattenMeta(disk.Meta), + "account_id": disk.AccountID, + "discard": disk.Discard, + "block_size": disk.BlockSize, + "boot_partition": disk.BootPartition, + "bus_number": disk.BusNumber, + "created_time": disk.CreatedTime, + "created_by": disk.CreatedBy, + "deleted_time": disk.DeletedTime, + "deleted_by": disk.DeletedBy, + "devicename": disk.DeviceName, + "desc": disk.Description, + "destruction_time": disk.DestructionTime, + "disk_path": disk.DiskPath, + "gid": disk.GID, + "guid": disk.GUID, + "disk_id": disk.ID, + "image_id": disk.ImageID, + "images": disk.Images, + "independent": disk.Independent, + "iotune": flattenIOTune(disk.IOTune), + "iqn": disk.IQN, + "login": disk.Login, + "milestones": disk.Milestones, + "name": disk.Name, + "params": disk.Params, + "parent_id": disk.ParentID, + "passwd": disk.Password, + "pci_slot": disk.PCISlot, + "pool": disk.Pool, + "purge_attempts": disk.PurgeAttempts, + "present_to": disk.PresentTo, + "purge_time": disk.PurgeTime, + "replication": flattenDiskReplication(disk.Replication), + "reality_device_number": disk.RealityDeviceNumber, + "reference_id": disk.ReferenceID, + "res_id": disk.ResID, + "res_name": disk.ResName, + "role": disk.Role, + "sep_id": disk.SEPID, + "shareable": disk.Shareable, + "size_available": disk.SizeAvailable, + "size_max": disk.SizeMax, + "size_used": disk.SizeUsed, + "snapshots": flattendDiskSnapshotList(disk.Snapshots), + "status": disk.Status, + "storage_policy_id": disk.StoragePolicyID, + "tech_status": disk.TechStatus, + "type": disk.Type, + "to_clean": disk.ToClean, + "provision": disk.Provision, + "updated_time": disk.UpdatedTime, + } + res = append(res, temp) + } + return res +} + +func flattenDiskReplication(rep compute.ItemReplication) []map[string]interface{} { + res := []map[string]interface{}{ + { + "disk_id": rep.DiskID, + "pool_id": rep.PoolID, + "role": rep.Role, + "self_volume_id": rep.SelfVolumeID, + "storage_id": rep.StorageID, + "volume_id": rep.VolumeID, + }, + } + return res +} + +func flattenIOTune(iot compute.IOTune) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "read_bytes_sec": iot.ReadBytesSec, + "read_bytes_sec_max": iot.ReadBytesSecMax, + "read_iops_sec": iot.ReadIOPSSec, + "read_iops_sec_max": iot.ReadIOPSSecMax, + "size_iops_sec": iot.SizeIOPSSec, + "total_bytes_sec": iot.TotalBytesSec, + "total_bytes_sec_max": iot.TotalBytesSecMax, + "total_iops_sec": iot.TotalIOPSSec, + "total_iops_sec_max": iot.TotalIOPSSecMax, + "write_bytes_sec": iot.WriteBytesSec, + "write_bytes_sec_max": iot.WriteBytesSecMax, + "write_iops_sec": iot.WriteIOPSSec, + "write_iops_sec_max": iot.WriteIOPSSecMax, + } + + res = append(res, temp) + return res +} + +func flattendDiskSnapshotList(sl compute.ListDetailedSnapshots) []interface{} { + res := make([]interface{}, 0) + for _, snapshot := range sl { + temp := map[string]interface{}{ + "guid": snapshot.GUID, + "label": snapshot.Label, + "res_id": snapshot.ResID, + "snap_set_guid": snapshot.SnapSetGUID, + "snap_set_time": snapshot.SnapSetTime, + "timestamp": snapshot.TimeStamp, + } + res = append(res, temp) + } + + return res + +} + +func flattenVGPUs(vgpus []compute.VGPUItem) []map[string]interface{} { + res := make([]map[string]interface{}, len(vgpus)) + + for i, vgpu := range vgpus { + + res[i] = map[string]interface{}{ + "id": int(vgpu.ID), + "gid": int(vgpu.GID), + "type": vgpu.Type, + "mode": vgpu.Mode, + "status": vgpu.Status, + "profile_id": vgpu.ProfileID, + "ram": int(vgpu.RAM), + "last_update_time": int(vgpu.LastUpdateTime), + "created_time": int(vgpu.CreatedTime), + "deleted_time": int(vgpu.DeletedTime), + "vmid": int(vgpu.VMID), + "pgpuid": int(vgpu.PGPuid), + "reference_id": vgpu.ReferenceID, + "account_id": int(vgpu.AccountID), + "rg_id": int(vgpu.RgID), + "last_claimed_by": int(vgpu.LastClaimedBy), + "pci_slot": int(vgpu.PCISlot), + "bus_number": int(vgpu.BusNumber), + "guid": int(vgpu.GUID), + } + } + + return res +} + +func flattenQemuQuest(qemuQuest compute.QemuQuest) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + + temp := map[string]interface{}{ + "enabled": qemuQuest.Enabled, + "enabled_agent_features": qemuQuest.EnabledAgentFeatures, + "guid": qemuQuest.GUID, + "last_update": uint64(qemuQuest.LastUpdate), + "user": qemuQuest.User, + } + + res = append(res, temp) + + return res +} diff --git a/internal/service/cloudbroker/kvmvm/models.go b/internal/service/cloudbroker/kvmvm/models.go new file mode 100644 index 00000000..2a63815f --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/models.go @@ -0,0 +1,10 @@ +package kvmvm + +type updatedNetwork struct { + DetachMap []map[string]interface{} + ChangeIPMap []map[string]interface{} + ChangeMacMap []map[string]interface{} + ChangeMTUMap []map[string]interface{} + AttachMap []map[string]interface{} + EnableMap []map[string]interface{} +} diff --git a/internal/service/cloudbroker/kvmvm/old_schemas.go b/internal/service/cloudbroker/kvmvm/old_schemas.go new file mode 100644 index 00000000..0ad2edc8 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/old_schemas.go @@ -0,0 +1,1077 @@ +package kvmvm + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators" +) + +func resourceComputeResourceV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "ID of the resource group where this compute should be deployed.", + }, + "driver": { + Type: schema.TypeString, + Required: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86"}, false), // observe case while validating + Description: "Hardware architecture of this compute instance.", + }, + "cpu": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, constants.MAX_CPUS_PER_COMPUTE), + Description: "Number of CPUs to allocate to this compute instance.", + }, + "ram": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.All( + validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + validators.DivisibleBy(constants.RAM_DIVISIBILITY), + ), + Description: "Amount of RAM in MB to allocate to this compute instance.", + }, + "image_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the OS image to base this compute instance on.", + }, + "chipset": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"Q35", "i440fx"}, false), // observe case while validating + Description: "Type of the emulated system.", + }, + "without_boot_disk": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state.", + }, + "boot_disk_size": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.", + }, + "cloud_init": { + Type: schema.TypeString, + Optional: true, + Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional text description of this compute instance.", + }, + "started": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Is compute started.", + }, + "alt_boot_id": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: "ID of CD-ROM live image to boot", + }, + "stack_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of stack to start compute", + }, + "is": { + Type: schema.TypeString, + Optional: true, + Description: "system name", + }, + "ipa_type": { + Type: schema.TypeString, + Optional: true, + Description: "compute purpose", + }, + "custom_fields": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "network": { + Type: schema.TypeSet, + Optional: true, + MinItems: 1, + MaxItems: constants.MAX_NETWORKS_PER_COMPUTE, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS", "VFNIC", "DPDK"}, false), // observe case while validating + Description: "Type of the network for this connection, either EXTNET or VINS.", + }, + "net_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the network for this connection.", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: networkSubresIPAddreDiffSupperss, + Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address associated with this connection. MAC address is assigned automatically.", + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "weight the network if you need to sort network list, the smallest attach first. zero or null weight attach last", + }, + "mtu": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + //Default: 1500, + ValidateFunc: validation.IntBetween(1, 9216), + Description: "Maximum transmission unit, used only for DPDK type, must be 1-9216", + }, + }, + }, + Description: "Optional network connection(s) for this compute. You may specify several network blocks, one for each connection.", + }, + + "libvirt_settings": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"VINS", "VFNIC", "DPDK"}, false), // observe case while validating + Description: "Type of the network", + }, + "net_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the network", + }, + "txmode": { + Type: schema.TypeString, + Default: "", + Optional: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Default: "", + Optional: true, + }, + "event_idx": { + Type: schema.TypeString, + Default: "", + Optional: true, + }, + "queues": { + Type: schema.TypeInt, + Default: 0, + Optional: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Default: 0, + Optional: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Default: 0, + Optional: true, + }, + }, + }, + Description: "Configure libvirt virtio interface parameters. You can only delete values locally. Data on the platform cannot be deleted.", + }, + + "affinity_label": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Set affinity label for compute", + }, + "affinity_rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topology": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false), + Description: "compute or node, for whom rule applies", + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false), + Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule", + }, + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false), + Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'", + }, + "key": { + Type: schema.TypeString, + Required: true, + Description: "key that are taken into account when analyzing this rule will be identified", + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: "value that must match the key to be taken into account when analyzing this rule", + }, + }, + }, + }, + "delete_async_mode": { + Type: schema.TypeBool, + Computed: true, + Description: "async mode", + }, + "anti_affinity_rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topology": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false), + Description: "compute or node, for whom rule applies", + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false), + Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule", + }, + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false), + Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'", + }, + "key": { + Type: schema.TypeString, + Required: true, + Description: "key that are taken into account when analyzing this rule will be identified", + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: "value that must match the key to be taken into account when analyzing this rule", + }, + }, + }, + }, + "disks": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_name": { + Type: schema.TypeString, + Required: true, + Description: "Name for disk", + }, + "size": { + Type: schema.TypeInt, + Required: true, + Description: "Disk size in GiB", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Storage endpoint provider ID; by default the same with boot disk", + }, + "disk_type": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false), + Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Pool name; by default will be chosen automatically", + }, + "node_ids": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Optional description", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Specify image id for create disk from template", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Description: "Disk deletion status", + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk ID", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "extra_disks": { + Type: schema.TypeSet, + Optional: true, + MaxItems: constants.MAX_EXTRA_DISKS_PER_COMPUTE, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.", + }, + "tags": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Required: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "port_forwarding": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "public_port_start": { + Type: schema.TypeInt, + Required: true, + }, + "public_port_end": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + }, + "local_port": { + Type: schema.TypeInt, + Optional: true, + }, + "proto": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false), + }, + "rule_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "user_access": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + }, + "access_type": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "snapshot": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "rollback": { + Type: schema.TypeSet, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "cd": { + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cdrom_id": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + "pin_to_stack": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "auto_start_w_node": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "force_pin": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "If true - enable compute, else - disable", + }, + "pause": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "reset": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "force_stop": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Flag for redeploy compute", + }, + "force_resize": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Flag for resize compute", + }, + "detach_disks": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "numa_affinity": { + Type: schema.TypeString, + Optional: true, + Default: "none", + ValidateFunc: validation.StringInSlice([]string{"none", "strict", "loose"}, false), // observe case while validating + Description: "Rule for VM placement with NUMA affinity.", + }, + "cpu_pin": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node.", + }, + "hp_backed": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Use Huge Pages to allocate RAM of the virtual machine. The system must be pre-configured by allocating Huge Pages on the physical node.", + }, + "preferred_cpu": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Recommended isolated CPUs. Field is ignored if compute.cpupin=False or compute.pinned=False", + }, + "pci_devices": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "ID of the connected pci devices", + }, + // Computed properties + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the account this compute instance belongs to.", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account this compute instance belongs to.", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "arch": { + Type: schema.TypeString, + Computed: true, + }, + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "boot_disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "This compute instance boot disk ID.", + }, + "cd_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "clone_reference": { + Type: schema.TypeInt, + Computed: true, + }, + "clones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devices": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "flip_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + "listen_ssh": { + Type: schema.TypeBool, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_brust": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "libvirt_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "txmode": { + Type: schema.TypeString, + Computed: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Computed: true, + }, + "event_idx": { + Type: schema.TypeString, + Computed: true, + }, + "queues": { + Type: schema.TypeInt, + Computed: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "target": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "migrationjob": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_ip": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_name": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network_name": { + Type: schema.TypeString, + Computed: true, + }, + "need_reboot": { + Type: schema.TypeBool, + Computed: true, + }, + "numa_node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "GUID of this guest OS user.", + }, + + "login": { + Type: schema.TypeString, + Computed: true, + Description: "Login name of this guest OS user.", + }, + + "password": { + Type: schema.TypeString, + Computed: true, + //Sensitive: true, + Description: "Password of this guest OS user.", + }, + + "public_key": { + Type: schema.TypeString, + Computed: true, + Description: "SSH public key of this guest OS user.", + }, + }, + }, + Description: "Guest OS users provisioned on this compute instance.", + }, + "pinned": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "reserved_node_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource group where this compute instance is located.", + }, + "snap_sets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "stack_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the stack, on which VM started", + }, + "stateless_sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stateless_sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vnc_password": { + Type: schema.TypeString, + Computed: true, + }, + "vgpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "virtual_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "virtual_image_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceComputeResourceV2() *schema.Resource { + s := resourceComputeSchemaMake() + // Add blk_discard + s["disks"].Elem.(*schema.Resource).Schema["blk_discard"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + // Add boot_disk_blk_discard + s["boot_disk_blk_discard"] = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + } + return &schema.Resource{Schema: s} +} diff --git a/internal/service/cloudbroker/kvmvm/resource_check_input_values.go b/internal/service/cloudbroker/kvmvm/resource_check_input_values.go new file mode 100644 index 00000000..afdfc065 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/resource_check_input_values.go @@ -0,0 +1,96 @@ +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" +) + +func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + errs := []error{} + + if err := ic.ExistRG(ctx, uint64(d.Get("rg_id").(int)), c); err != nil { + errs = append(errs, err) + } + + if !d.Get("create_blank").(bool) { + if err := ic.ExistImage(ctx, uint64(d.Get("image_id").(int)), c); err != nil { + errs = append(errs, err) + } + } + + if netErrs := existNetworks(ctx, d, c); errs != nil { + errs = append(errs, netErrs...) + } + + if disks, ok := d.GetOk("disks"); ok { + if err := ic.IsMoreThanOneDisksTypeB(ctx, disks, d.Get("chipset").(string)); err != nil { + errs = append(errs, err) + } + } + + return dc.ErrorsToDiagnostics(errs) +} + +func existNetworks(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) []error { + var errs []error + var vinsIds, extNetIds, vfpoolIds, dpdkIds, trunkIds []uint64 + var sdnIds []string + + networksIface, ok := d.GetOk("network") + if !ok { + return nil + } + + networkList := networksIface.(*schema.Set).List() + for _, elem := range networkList { + network := elem.(map[string]interface{}) + + switch network["net_type"].(string) { + case "VINS": + vinsIds = append(vinsIds, uint64(network["net_id"].(int))) + case "EXTNET": + extNetIds = append(extNetIds, uint64(network["net_id"].(int))) + case "VFNIC": + vfpoolIds = append(vfpoolIds, uint64(network["net_id"].(int))) + case "DPDK": + dpdkIds = append(dpdkIds, uint64(network["net_id"].(int))) + case "TRUNK": + trunkIds = append(trunkIds, uint64(network["net_id"].(int))) + case "SDN": + sdnIds = append(sdnIds, network["sdn_interface_id"].(string)) + default: + continue + } + } + + if vinsErrs := ic.ExistVinses(ctx, vinsIds, c); vinsErrs != nil { + errs = append(errs, vinsErrs...) + } + + if extNetErrs := ic.ExistExtNets(ctx, extNetIds, c); extNetErrs != nil { + errs = append(errs, extNetErrs...) + } + + if vfpoolErrs := ic.ExistVFPools(ctx, vfpoolIds, c); vfpoolErrs != nil { + errs = append(errs, vfpoolErrs...) + } + + if dpdkErrs := ic.ExistDPDKNet(ctx, dpdkIds, c); dpdkErrs != nil { + errs = append(errs, dpdkErrs...) + } + + if trunkErrs := ic.ExistTrunkNet(ctx, trunkIds, c); trunkErrs != nil { + errs = append(errs, trunkErrs...) + } + + if sdnErrs := ic.ExistSDNNet(ctx, sdnIds, c); sdnErrs != nil { + errs = append(errs, sdnErrs...) + } + + return errs +} diff --git a/internal/service/cloudbroker/kvmvm/resource_compute.go b/internal/service/cloudbroker/kvmvm/resource_compute.go new file mode 100644 index 00000000..cb3c24ba --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/resource_compute.go @@ -0,0 +1,1129 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Nikita Sorokin, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "errors" + "fmt" + "sort" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/kvmx86" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int)) + c := m.(*controller.ControllerCfg) + + createReqX86 := kvmx86.CreateRequest{} + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + if desc, ok := d.GetOk("description"); ok { + createReqX86.Description = desc.(string) + } + + if sepID, ok := d.GetOk("sep_id"); ok { + createReqX86.SEPID = uint64(sepID.(int)) + } + + if pool, ok := d.GetOk("pool"); ok { + createReqX86.Pool = pool.(string) + } + + if nodeID, ok := d.GetOk("node_id"); ok { + createReqX86.NodeID = uint64(nodeID.(int)) + } + + if bootSize, ok := d.GetOk("boot_disk_size"); ok { + createReqX86.BootDisk = uint64(bootSize.(int)) + } + + if bootDiskCache, ok := d.GetOk("boot_disk_cache"); ok { + createReqX86.BootDiskCache = bootDiskCache.(string) + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + createReqX86.ZoneID = uint64(zoneID.(int)) + } + + if bootDiskDiscard, ok := d.GetOk("boot_disk_discard"); ok { + createReqX86.BootDiskDiscard = bootDiskDiscard.(string) + } + + if networks, ok := d.GetOk("network"); ok { + if networks.(*schema.Set).Len() > 0 { + ns := networks.(*schema.Set).List() + sort.Slice(ns, func(i, j int) bool { + weightI := ns[i].(map[string]interface{})["weight"].(int) + weightJ := ns[j].(map[string]interface{})["weight"].(int) + if weightI == 0 { + return false + } + if weightJ == 0 { + return true + } + return weightI < weightJ + }) + interfacesX86 := make([]kvmx86.Interface, 0) + for _, elem := range ns { + netInterfaceVal := elem.(map[string]interface{}) + + reqInterface := kvmx86.Interface{ + NetType: netInterfaceVal["net_type"].(string), + NetID: uint64(netInterfaceVal["net_id"].(int)), + } + + if enabledNetwork(d.GetRawConfig().GetAttr("network"), reqInterface.NetID, reqInterface.NetType) { + reqInterface.Enabled = netInterfaceVal["enabled"].(bool) + } + + if reqInterface.NetType == "DPDK" || reqInterface.NetType == "EXTNET" || reqInterface.NetType == "TRUNK" { + reqInterface.MTU = uint64(netInterfaceVal["mtu"].(int)) + } + + if reqInterface.NetType == "DPDK" || reqInterface.NetType == "VFNIC" { + if netMask, netMaskSet := netInterfaceVal["net_mask"]; netMaskSet { + reqInterface.NetMask = uint64(netMask.(int)) + } + } + + ipaddr, ipSet := netInterfaceVal["ip_address"] + if ipSet { + reqInterface.IPAddr = ipaddr.(string) + } + + macaddr, macSet := netInterfaceVal["mac"] + if macSet { + reqInterface.MAC = macaddr.(string) + } + + sdnID, sdnSet := netInterfaceVal["sdn_interface_id"] + if sdnSet { + reqInterface.SDNInterfaceID = sdnID.(string) + } + + interfacesX86 = append(interfacesX86, reqInterface) + } + createReqX86.Interfaces = interfacesX86 + + } + } + + if disks, ok := d.GetOk("disks"); ok { + disksX86 := make([]kvmx86.DataDisk, 0) + + for _, elem := range disks.([]interface{}) { + diskVal := elem.(map[string]interface{}) + reqDataDisk := kvmx86.DataDisk{ + DiskName: diskVal["disk_name"].(string), + Size: uint64(diskVal["size"].(int)), + StoragePolicyID: uint64(diskVal["storage_policy_id"].(int)), + } + if sepId, ok := diskVal["sep_id"]; ok { + reqDataDisk.SepID = uint64(sepId.(int)) + } + if pool, ok := diskVal["pool"]; ok { + reqDataDisk.Pool = pool.(string) + } + if desc, ok := diskVal["desc"]; ok { + reqDataDisk.Description = desc.(string) + } + if imageID, ok := diskVal["image_id"]; ok { + reqDataDisk.ImageID = uint64(imageID.(int)) + } + if cache, ok := diskVal["cache"]; ok { + reqDataDisk.Cache = cache.(string) + } + if discard, ok := diskVal["discard"]; ok { + reqDataDisk.Discard = discard.(string) + } + disksX86 = append(disksX86, reqDataDisk) + } + + createReqX86.DataDisks = disksX86 + + } + + if cloudInit, ok := d.GetOk("cloud_init"); ok { + userdata := cloudInit.(string) + if userdata != "" && userdata != "applied" { + createReqX86.Userdata = strings.TrimSpace(userdata) + } + } + + var computeId uint64 + + createReqX86.RGID = uint64(d.Get("rg_id").(int)) + createReqX86.Name = d.Get("name").(string) + createReqX86.CPU = uint64(d.Get("cpu").(int)) + createReqX86.RAM = uint64(d.Get("ram").(int)) + createReqX86.StoragePolicyID = uint64(d.Get("storage_policy_id").(int)) + + if image, ok := d.GetOk("image_id"); ok { + createReqX86.ImageID = uint64(image.(int)) + } + if withoutBootDisk, ok := d.GetOk("without_boot_disk"); ok { + createReqX86.WithoutBootDisk = withoutBootDisk.(bool) + } + + if custom_fields, ok := d.GetOk("custom_fields"); ok { + val := custom_fields.(string) + val = strings.ReplaceAll(val, "\\", "") + val = strings.ReplaceAll(val, "\n", "") + val = strings.ReplaceAll(val, "\t", "") + val = strings.TrimSpace(val) + + createReqX86.CustomField = val + } + + if numaAffinity, ok := d.GetOk("numa_affinity"); ok { + createReqX86.NumaAffinity = numaAffinity.(string) + } + createReqX86.CPUPin = d.Get("cpu_pin").(bool) + createReqX86.HPBacked = d.Get("hp_backed").(bool) + createReqX86.Chipset = d.Get("chipset").(string) + if clock, ok := d.GetOk("clock"); ok { + createReqX86.Clock = clock.(string) + } + + if preferredCPU, ok := d.GetOk("preferred_cpu"); ok { + preferredList := preferredCPU.([]interface{}) + if len(preferredList) > 0 { + for _, v := range preferredList { + cpuNum := v.(int) + createReqX86.PreferredCPU = append(createReqX86.PreferredCPU, int64(cpuNum)) + } + } + } + + if osVersion, ok := d.GetOk("os_version"); ok { + createReqX86.OSVersion = osVersion.(string) + } + + log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86") + var apiResp uint64 + var err error + if d.Get("create_blank").(bool) { + log.Debugf("resourceComputeCreate: using createBlank endpoint") + createBlankReq := kvmx86.CreateBlankRequest{ + RGID: createReqX86.RGID, + Name: createReqX86.Name, + CPU: createReqX86.CPU, + RAM: createReqX86.RAM, + StoragePolicyID: createReqX86.StoragePolicyID, + WithoutBootDisk: createReqX86.WithoutBootDisk, + BootDisk: createReqX86.BootDisk, + SEPID: createReqX86.SEPID, + Pool: createReqX86.Pool, + DataDisks: createReqX86.DataDisks, + Interfaces: createReqX86.Interfaces, + Description: createReqX86.Description, + Chipset: createReqX86.Chipset, + PreferredCPU: createReqX86.PreferredCPU, + ZoneID: createReqX86.ZoneID, + OSVersion: createReqX86.OSVersion, + } + apiResp, err = c.CloudBroker().KVMX86().CreateBlank(ctx, createBlankReq) + } else { + apiResp, err = c.CloudBroker().KVMX86().Create(ctx, createReqX86) + } + + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(apiResp, 10)) + computeId = apiResp + + warnings := dc.Warnings{} + + simpleCompRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + warnings.Add(err) + } + + cleanup := false + defer func() { + if cleanup { + req := compute.DeleteRequest{ + ComputeID: computeId, + Permanently: true, + DetachDisks: true, + } + + if _, err := c.CloudBroker().Compute().Delete(ctx, req); err != nil { + log.Errorf("resourceComputeCreate: could not delete compute after failed creation: %v", err) + } + + d.SetId("") + } + }() + + log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", computeId, d.Get("name").(string)) + + updateReq := compute.UpdateRequest{} + + loaderType, loaderTypeOk := d.GetOk("loader_type") + bootType, bootTypeOk := d.GetOk("boot_type") + hotResize, hotResizeOk := d.GetOkExists("hot_resize") + networkInterfaceNaming, networkInterfaceNamingOk := d.GetOk("network_interface_naming") + weight, weightOk := d.GetOk("weight") + + if loaderTypeOk { + updateReq.LoaderType = loaderType.(string) + } + + if bootTypeOk { + updateReq.BootType = bootType.(string) + } + + if hotResizeOk { + updateReq.HotResize = hotResize.(bool) + } + + if networkInterfaceNamingOk { + updateReq.NetworkInterfaceNaming = networkInterfaceNaming.(string) + } + + if weightOk { + updateReq.Weight = uint64(weight.(int)) + } + + if loaderTypeOk || bootTypeOk || hotResizeOk || networkInterfaceNamingOk || weightOk { + log.Debugf("resourceComputeCreate: change loaderType or bootType or hotResize or networkInterfaceNaming or weight on ComputeID: %d", computeId) + updateReq.ComputeID = computeId + _, err := c.CloudBroker().Compute().Update(ctx, updateReq) + if err != nil { + warnings.Add(err) + } + } + + if ars, ok := d.GetOk("pci_devices"); ok { + log.Debugf("resourceComputeCreate: add pci devices on ComputeID: %d", computeId) + addedPciDevices := ars.(*schema.Set).List() + if len(addedPciDevices) > 0 { + for _, v := range addedPciDevices { + devicesConv := v.(int) + req := compute.AttachPCIDeviceRequest{ + ComputeID: computeId, + DeviceID: uint64(devicesConv), + } + + _, err := c.CloudBroker().Compute().AttachPCIDevice(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + extraDisks, ok := d.GetOk("extra_disks") + if ok && extraDisks.(*schema.Set).Len() > 0 { + log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", extraDisks.(*schema.Set).Len()) + err := utilityComputeExtraDisksConfigure(ctx, d, m, false) + if err != nil { + log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", computeId, err) + cleanup = true + return diag.FromErr(err) + } + } + + if !cleanup { + + if enabled, ok := d.GetOk("enabled"); ok { + if enabled.(bool) { + req := compute.EnableRequest{ComputeID: computeId} + log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId) + if _, err := c.CloudBroker().Compute().Enable(ctx, req); err != nil { + warnings.Add(err) + } + } else { + req := compute.DisableRequest{ComputeID: computeId} + log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId) + if _, err := c.CloudBroker().Compute().Disable(ctx, req); err != nil { + warnings.Add(err) + } + } + } + + if libvirtSettings, ok := d.GetOk("libvirt_settings"); ok { + if libvirtSettings.(*schema.Set).Len() > 0 { + lvs := libvirtSettings.(*schema.Set).List() + for _, elem := range lvs { + netLibvirtMap := elem.(map[string]interface{}) + + netType := netLibvirtMap["net_type"].(string) + netId := uint64(netLibvirtMap["net_id"].(int)) + var mac string + for _, iface := range simpleCompRec.Interfaces { + if iface.NetID == netId && iface.NetType == netType { + mac = iface.MAC + break + } + } + if mac == "" { + warnings.Add(fmt.Errorf("add libvirt virtio: Network with type %s and id %d is not connected to the compute %d", netType, netId, computeId)) + continue + } + log.Debugf("resourceComputeCreate: Configure libvirt virtio interface parameters on Network with type %s and id %d", netType, netId) + req := compute.SetNetConfigRequest{ + ComputeID: computeId, + MAC: mac, + TXMode: netLibvirtMap["txmode"].(string), + IOEventFD: netLibvirtMap["ioeventfd"].(string), + EventIDx: netLibvirtMap["event_idx"].(string), + Queues: uint64(netLibvirtMap["queues"].(int)), + RXQueueSize: uint64(netLibvirtMap["rx_queue_size"].(int)), + TXQueueSize: uint64(netLibvirtMap["tx_queue_size"].(int)), + } + + _, err := c.CloudBroker().Compute().SetNetConfig(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if secGroups, ok := d.GetOk("security_groups"); ok { + if secGroups.(*schema.Set).Len() > 0 { + sgl := secGroups.(*schema.Set).List() + for _, elem := range sgl { + secGroupsMap := elem.(map[string]interface{}) + + netType := secGroupsMap["net_type"].(string) + netId := uint64(secGroupsMap["net_id"].(int)) + var mac string + for _, iface := range simpleCompRec.Interfaces { + if iface.NetID == netId && iface.NetType == netType { + mac = iface.MAC + break + } + } + if mac == "" { + warnings.Add(fmt.Errorf("add security groups: Network with type %s and id %d is not connected to the compute %d", netType, netId, computeId)) + continue + } + secGroupsIDs := make([]uint64, 0) + for _, id := range secGroupsMap["security_groups"].(*schema.Set).List() { + secGroupsIDs = append(secGroupsIDs, uint64(id.(int))) + } + log.Debugf("resourceComputeCreate: Configure security groups interface parameters on Network with type %s and id %d", netType, netId) + req := compute.ChangeSecGroupsRequest{ + ComputeID: computeId, + Interface: mac, + SecGroups: secGroupsIDs, + EnableSecGroups: secGroupsMap["enable_secgroups"].(bool), + } + + _, err := c.CloudBroker().Compute().ChangeSecGroups(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if start, ok := d.GetOk("started"); ok && start.(bool) { + req := compute.StartRequest{ComputeID: computeId} + if nodeID, ok := d.GetOk("node_id"); ok { + req.NodeID = uint64(nodeID.(int)) + } + if altBootID, ok := d.Get("alt_boot_id").(int); ok { + req.AltBootID = uint64(altBootID) + } + log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", computeId) + if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil { + warnings.Add(err) + } + } else if ok && !start.(bool) { + req := compute.StopRequest{ComputeID: computeId} + log.Debugf("resourceComputeCreate: stoping Compute ID %d after completing its resource configuration", computeId) + if _, err := c.CloudBroker().Compute().Stop(ctx, req); err != nil { + warnings.Add(err) + } + } + + if pin, ok := d.GetOk("pin_to_node"); ok && pin.(bool) { + start, _ := d.GetOk("started") + _, nodeOk := d.GetOk("node_id") + + if !start.(bool) && !nodeOk { + warnings.Add(errors.New("cannot pin to node a VM, that is not started and node_id is not set")) + } else { + req := compute.PinToNodeRequest{ + ComputeID: computeId, + TargetNodeID: uint64(d.Get("node_id").(int)), + } + + if force, ok := d.Get("force_pin").(bool); ok { + req.Force = force + } + + if autoStart, ok := d.Get("auto_start_w_node").(bool); ok { + req.AutoStart = autoStart + } + + _, err := c.CloudBroker().Compute().PinToNode(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + + if affinityLabel, ok := d.GetOk("affinity_label"); ok { + req := compute.AffinityLabelSetRequest{ + ComputeIDs: []uint64{ + computeId, + }, + AffinityLabel: affinityLabel.(string), + } + + _, err := c.CloudBroker().Compute().AffinityLabelSet(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + if profileName, ok := d.GetOk("cpu_alignment_profile"); ok { + req := compute.SetCPUAlignmentProfileRequest{ + ComputeIDs: []int64{int64(computeId)}, + CPUAlignmentProfile: profileName.(string), + } + _, err := c.CloudBroker().Compute().SetCPUAlignmentProfile(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + if ars, ok := d.GetOk("affinity_rules"); ok { + log.Debugf("resourceComputeCreate: Create affinity rules on ComputeID: %d", computeId) + addedAR := ars.([]interface{}) + if len(addedAR) > 0 { + for _, ar := range addedAR { + arConv := ar.(map[string]interface{}) + req := compute.AffinityRuleAddRequest{ + ComputeIDs: []uint64{computeId}, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudBroker().Compute().AffinityRuleAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if ars, ok := d.GetOk("anti_affinity_rules"); ok { + log.Debugf("resourceComputeCreate: Create anti affinity rules on ComputeID: %d", computeId) + addedAR := ars.([]interface{}) + if len(addedAR) > 0 { + for _, ar := range addedAR { + arConv := ar.(map[string]interface{}) + req := compute.AntiAffinityRuleAddRequest{ + ComputeIDs: []uint64{computeId}, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudBroker().Compute().AntiAffinityRuleAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + if tags, ok := d.GetOk("tags"); ok { + log.Debugf("resourceComputeCreate: Create tags on ComputeID: %d", computeId) + addedTags := tags.(*schema.Set).List() + if len(addedTags) > 0 { + for _, tagInterface := range addedTags { + tagItem := tagInterface.(map[string]interface{}) + req := compute.TagAddRequest{ + ComputeIDs: []uint64{computeId}, + Key: tagItem["key"].(string), + Value: tagItem["value"].(string), + } + + _, err := c.CloudBroker().Compute().TagAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if pfws, ok := d.GetOk("port_forwarding"); ok { + log.Debugf("resourceComputeCreate: Create port farwarding on ComputeID: %d", computeId) + addedPfws := pfws.(*schema.Set).List() + if len(addedPfws) > 0 { + for _, pfwInterface := range addedPfws { + pfwItem := pfwInterface.(map[string]interface{}) + req := compute.PFWAddRequest{ + ComputeID: computeId, + PublicPortStart: uint64(pfwItem["public_port_start"].(int)), + Proto: pfwItem["proto"].(string), + } + if pfwItem["local_port"].(int) != 0 { + req.LocalBasePort = uint64(pfwItem["local_port"].(int)) + } + if int64(pfwItem["public_port_end"].(int)) != 0 { + req.PublicPortEnd = int64(pfwItem["public_port_end"].(int)) + } + + pwfId, err := c.CloudBroker().Compute().PFWAdd(ctx, req) + if err != nil { + warnings.Add(err) + } + d.Set("rule_id", pwfId) + } + } + } + + if userAcess, ok := d.GetOk("user_access"); ok { + log.Debugf("resourceComputeCreate: Create user access on ComputeID: %d", computeId) + usersAcess := userAcess.(*schema.Set).List() + if len(usersAcess) > 0 { + for _, userAcessInterface := range usersAcess { + userAccessItem := userAcessInterface.(map[string]interface{}) + req := compute.UserGrantRequest{ + ComputeID: computeId, + Username: userAccessItem["username"].(string), + AccessType: userAccessItem["access_type"].(string), + } + + _, err := c.CloudBroker().Compute().UserGrant(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if snapshotList, ok := d.GetOk("snapshot"); ok { + log.Debugf("resourceComputeCreate: Create snapshot on ComputeID: %d", computeId) + snapshots := snapshotList.(*schema.Set).List() + if len(snapshots) > 0 { + for _, snapshotInterface := range snapshots { + snapshotItem := snapshotInterface.(map[string]interface{}) + req := compute.SnapshotCreateRequest{ + ComputeID: computeId, + Label: snapshotItem["label"].(string), + } + + _, err := c.CloudBroker().Compute().SnapshotCreate(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + } + + if cdtList, ok := d.GetOk("cd"); ok { + log.Debugf("resourceComputeCreate: Create cd on ComputeID: %d", computeId) + cds := cdtList.(*schema.Set).List() + if len(cds) > 0 { + snapshotItem := cds[0].(map[string]interface{}) + req := compute.CDInsertRequest{ + ComputeID: computeId, + CDROMID: uint64(snapshotItem["cdrom_id"].(int)), + } + + _, err := c.CloudBroker().Compute().CDInsert(ctx, req) + if err != nil { + warnings.Add(err) + } + } + } + + if !d.Get("pin_to_node").(bool) && d.Get("auto_start_w_node").(bool) { + req := compute.UpdateRequest{ + ComputeID: computeId, + AutoStart: d.Get("auto_start_w_node").(bool), + CPUPin: d.Get("cpu_pin").(bool), + HPBacked: d.Get("hp_backed").(bool), + } + _, err := c.CloudBroker().Compute().Update(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + if d.Get("pause").(bool) { + req := compute.PauseRequest{ + ComputeID: computeId, + } + _, err := c.CloudBroker().Compute().Pause(ctx, req) + if err != nil { + warnings.Add(err) + } + } + + if _, ok := d.GetOk("disks"); ok { + err := utilityComputeCreatePresentDisk(ctx, d, m) + if err != nil { + warnings.Add(err) + } + if err := utilityComputeCreateBlockSize(ctx, d, m); err != nil { + warnings.Add(err) + } + if err := utilityComputeCreateIOTune(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + if readOnly, ok := d.GetOk("read_only"); ok { + if readOnly.(bool) { + if err := utilityComputeUpdateReadOnly(ctx, d, m); err != nil { + warnings.Add(err) + } + } + } + + } + + log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", computeId, d.Get("name").(string)) + + // We may reuse dataSourceComputeRead here as we maintain similarity + // between Compute resource and Compute data source schemas + // Compute read function will also update resource ID on success, so that Terraform + // will know the resource exists + + return append(resourceComputeRead(ctx, d, m), warnings.Get()...) +} + +func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceComputeRead: called for Compute name %s, RG ID %d", + d.Get("name").(string), d.Get("rg_id").(int)) + + // c := m.(*controller.ControllerCfg) + + computeRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + pciList, err := utilityComputePCIDevicesList(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + hasChanged := false + + switch computeRec.Status { + case status.Deleted: + // restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID} + // enableReq := compute.EnableRequest{ComputeID: computeRec.ID} + + // _, err := c.CloudBroker().Compute().Restore(ctx, restoreReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // _, err = c.CloudBroker().Compute().Enable(ctx, enableReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // hasChanged = true + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be read because it has been destroyed") + // return resourceComputeCreate(ctx, d, m) + case status.Disabled: + log.Debugf("The compute is in status: %s, troubles may occur with update. Please, enable compute first.", computeRec.Status) + case status.Redeploying: + case status.Deleting: + case status.Destroying: + return diag.Errorf("The compute is in progress with status: %s", computeRec.Status) + case status.Modeled: + return diag.Errorf("The compute is in status: %s, please, contact support for more information", computeRec.Status) + } + + if hasChanged { + computeRec, err = utilityComputeCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + pciList, err = utilityComputePCIDevicesList(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + d.SetId(strconv.FormatUint(computeRec.ID, 10)) + + if err = flattenCompute(d, computeRec, pciList); err != nil { + return diag.FromErr(err) + } + + log.Debugf("resourceComputeRead: after flattenCompute: Compute ID %s, name %q, RG ID %d", + d.Id(), d.Get("name").(string), d.Get("rg_id").(int)) + + return nil +} + +func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceComputeUpdate: called for Compute ID %s / name %s, RGID %d", + d.Id(), d.Get("name").(string), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + computeRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + // check compute statuses + switch computeRec.Status { + case status.Deleted: + if restore, ok := d.GetOk("restore"); ok && restore.(bool) { + if err := utilityComputeRestore(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + case status.Destroyed: + d.SetId("") + return resourceComputeCreate(ctx, d, m) + case status.Disabled: + log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", computeRec.Status) + case status.Redeploying: + case status.Deleting: + case status.Destroying: + return diag.Errorf("The compute is in progress with status: %s", computeRec.Status) + case status.Modeled: + return diag.Errorf("The compute is in status: %s, please, contant the support for more information", computeRec.Status) + } + warnings := dc.Warnings{} + + if d.HasChange("enabled") { + if err := utilityComputeEnabled(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("started") { + if err := utilityComputeStarted(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("cpu", "ram") { + if err := utilityComputeResize(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("boot_disk_size") { + if err := utilityComputeBootDiskResize(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("boot_disk_cache") { + if err := utilityComputeUpdateBootDiskCache(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("boot_disk_discard") { + if err := utilityComputeUpdateBootDiskDiscard(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("extra_disks") { + err := utilityComputeExtraDisksConfigure(ctx, d, m, true) // pass do_delta = true to apply changes, if any + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("pin_to_node") { + if err := utilityComputePinToNode(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("description", + "name", + "clock", + "numa_affinity", + "cpu_pin", + "hp_backed", + "chipset", + "auto_start_w_node", + "preferred_cpu", + "loader_type", + "boot_type", + "hot_resize", + "network_interface_naming", + "os_version", + "weight") { + if err := utilityComputeUpdate(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChanges("network", "libvirt_settings") { + err = utilityComputeNetworksConfigure(ctx, d, m) // pass do_delta = true to apply changes, if any + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("security_groups") { + err = utilityComputeSecGroupsConfigure(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("disks") { + if err := utilityComputeUpdateDisks(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("affinity_label") { + if err := utilityComputeUpdateAffinityLabel(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("affinity_rules") { + if err := utilityComputeUpdateAffinityRules(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("anti_affinity_rules") { + if err := utilityComputeUpdateAntiAffinityRules(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("tags") { + if err := utilityComputeUpdateTags(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("port_forwarding") { + if err := utilityComputeUpdatePFW(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("user_access") { + if err := utilityComputeUpdateUserAccess(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("snapshot") { + if err := utilityComputeUpdateSnapshot(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("rollback") { + if err := utilityComputeRollback(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("cd") { + if err := utilityComputeUpdateCD(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("pause") { + if err := utilityComputePause(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("reset") { + if err := utilityComputeReset(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("image_id") { + if err := utilityComputeUpdateImage(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("custom_fields") { + if err := utilityComputeUpdateCustomFields(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("pci_devices") { + if err := utilityComputeUpdatePciDevices(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("zone_id") { + if err := utilityComputeUpdateZoneID(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("read_only") { + if err := utilityComputeUpdateReadOnly(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("cpu_alignment_profile") { + if err := utilityComputeUpdateCPUAlignmentProfile(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + return append(resourceComputeRead(ctx, d, m), warnings.Get()...) +} + +func resourceComputeDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + // NOTE: this function destroys target Compute instance "permanently", so + // there is no way to restore it. + // If compute being destroyed has some extra disks attached, they are + // detached from the compute + log.Debugf("resourceComputeDelete: called for Compute name %s, RG ID %d", + d.Get("name").(string), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + req := compute.DeleteRequest{ + ComputeID: computeId, + Permanently: d.Get("permanently").(bool), + DetachDisks: d.Get("detach_disks").(bool), + } + + if _, err := c.CloudBroker().Compute().Delete(ctx, req); err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceCompute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 3, + + CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error { + if diff.HasChanges() || diff.HasChanges("chipset", "pin_to_node", "auto_start_w_node", "libvirt_settings", "network", "affinity_rules", "anti_affinity_rules", + "extra_disks", "tags", "port_forwarding", "user_access", "snapshot", "pci_devices", "preferred_cpu", "security_groups") { + diff.SetNewComputed("updated_time") + diff.SetNewComputed("updated_by") + } + if diff.HasChanges("pin_to_node") { + diff.SetNewComputed("pinned") + } + if diff.HasChanges("started") { + diff.SetNewComputed("tech_status") + diff.SetNewComputed("updated_time") + diff.SetNewComputed("updated_by") + } + return nil + }, + + CreateContext: resourceComputeCreate, + ReadContext: resourceComputeRead, + UpdateContext: resourceComputeUpdate, + DeleteContext: resourceComputeDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceComputeSchemaMake(), + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceComputeResourceV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceCompueteStateUpgradeV1, + Version: 1, + }, + { + Type: resourceComputeResourceV2().CoreConfigSchema().ImpliedType(), + Upgrade: resourceComputeStateUpgradeV2, + Version: 2, + }, + }, + } +} diff --git a/internal/service/cloudbroker/kvmvm/schema.go b/internal/service/cloudbroker/kvmvm/schema.go new file mode 100644 index 00000000..1243516d --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/schema.go @@ -0,0 +1,4881 @@ +package kvmvm + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators" +) + +func dataSourceComputeSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + Description: "Get compute by id", + }, + + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the account this compute instance belongs to.", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account this compute instance belongs to.", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "affinity_label": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "key": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + "topology": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "anti_affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "key": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + "topology": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "arch": { + Type: schema.TypeString, + Computed: true, + }, + "auto_start_w_node": { + Type: schema.TypeBool, + Computed: true, + }, + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "boot_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "chipset": { + Type: schema.TypeString, + Computed: true, + }, + "clock": { + Type: schema.TypeString, + Computed: true, + }, + "cd_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "clone_reference": { + Type: schema.TypeInt, + Computed: true, + }, + "clones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cpu_alignment_profiles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "cpu_pin": { + Type: schema.TypeBool, + Computed: true, + }, + "cpus": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "custom_fields": { //NEED + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "devices": { //NEED + Type: schema.TypeString, + Computed: true, + }, + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "discard": { + Type: schema.TypeString, + Computed: true, + }, + "block_size": { + Type: schema.TypeString, + Computed: true, + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "cache": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "params": { + Type: schema.TypeString, + Computed: true, + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Computed: true, + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + }, + "replication": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool_id": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "self_volume_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_id": { + Type: schema.TypeString, + Computed: true, + }, + "volume_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Description: "Replication status", + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_available": { + Type: schema.TypeFloat, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeFloat, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_id": { + Type: schema.TypeInt, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hp_backed": { + Type: schema.TypeBool, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + }, + "pci_devices": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "flip_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + "listen_ssh": { + Type: schema.TypeBool, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + + "qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_brust": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "libvirt_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "txmode": { + Type: schema.TypeString, + Computed: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Computed: true, + }, + "event_idx": { + Type: schema.TypeString, + Computed: true, + }, + "queues": { + Type: schema.TypeInt, + Computed: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "target": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "trunk_tags": { + Type: schema.TypeString, + Computed: true, + }, + "sdn_interface_id": { + Type: schema.TypeString, + Computed: true, + }, + "security_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "live_migration_job_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "migrationjob": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_ip": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_name": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network_name": { + Type: schema.TypeString, + Computed: true, + }, + "need_reboot": { + Type: schema.TypeBool, + Computed: true, + }, + "numa_affinity": { + Type: schema.TypeString, + Computed: true, + }, + "numa_node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "public_key": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "os_version": { + Type: schema.TypeString, + Computed: true, + }, + "pinned": { + Type: schema.TypeInt, + Computed: true, + }, + "preferred_cpu": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "qemu_guest": { + Type: schema.TypeList, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "enabled_agent_features": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "last_update": { + Type: schema.TypeInt, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "reserved_node_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "snap_sets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_name": { + Type: schema.TypeString, + Computed: true, + }, + "stateless_sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stateless_sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tags": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Computed: true, + }, + "val": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "loader_meta_iso": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "device_name": { + Type: schema.TypeString, + Computed: true, + }, + "path": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "user_data": { + Type: schema.TypeString, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "read_only": { + Type: schema.TypeBool, + Computed: true, + Description: "Shows if compute is locked to read-only operations.", + }, + "vnc_password": { + Type: schema.TypeString, + Computed: true, + }, + "vgpus": { + Type: schema.TypeList, + Computed: true, + Description: "List of virtual GPUs", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "profile_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "last_update_time": { + Type: schema.TypeInt, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + "pgpuid": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "last_claimed_by": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + //extra parameters + "boot_disk_size": { + Type: schema.TypeInt, + Computed: true, + }, + "boot_disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Computed: true, + }, + "loader_type": { + Type: schema.TypeString, + Computed: true, + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceComputeListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by AccountID", + }, + "rg_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by resgroup name", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by RGID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by tech status", + }, + "node_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by node name.", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "Find by IP address", + }, + "node_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by node ID", + }, + "cd_image_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by CD image ID", + }, + "extnet_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by Extnet name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by Extnet ID", + }, + "includedeleted": { + Type: schema.TypeBool, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "ignore_k8s": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If set to true, ignores any VMs associated with any k8s cluster", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_label": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "key": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + "topology": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "anti_affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "key": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + "topology": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "arch": { + Type: schema.TypeString, + Computed: true, + }, + "auto_start_w_node": { + Type: schema.TypeBool, + Computed: true, + }, + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "bootdisk_size": { + Type: schema.TypeInt, + Computed: true, + }, + "boot_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "chipset": { + Type: schema.TypeString, + Computed: true, + }, + "clock": { + Type: schema.TypeString, + Computed: true, + }, + "cd_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "clone_reference": { + Type: schema.TypeInt, + Computed: true, + }, + "clones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cpu_alignment_profiles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "cpu_pin": { + Type: schema.TypeBool, + Computed: true, + }, + "cpus": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "custom_fields": { //NEED + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "devices": { //NEED + Type: schema.TypeString, + Computed: true, + }, + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hp_backed": { + Type: schema.TypeBool, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "flip_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + "listen_ssh": { + Type: schema.TypeBool, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_brust": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "libvirt_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "txmode": { + Type: schema.TypeString, + Computed: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Computed: true, + }, + "event_idx": { + Type: schema.TypeString, + Computed: true, + }, + "queues": { + Type: schema.TypeInt, + Computed: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "sdn_interface_id": { + Type: schema.TypeString, + Computed: true, + }, + "security_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "target": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "trunk_tags": { + Type: schema.TypeString, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "live_migration_job_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "migrationjob": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "need_reboot": { + Type: schema.TypeBool, + Computed: true, + }, + "nid": { + Type: schema.TypeInt, + Computed: true, + }, + "numa_affinity": { + Type: schema.TypeString, + Computed: true, + }, + "numa_node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "public_key": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "os_version": { + Type: schema.TypeString, + Computed: true, + }, + "pinned": { + Type: schema.TypeInt, + Computed: true, + }, + "preferred_cpu": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "qemu_guest": { + Type: schema.TypeList, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "enabled_agent_features": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "last_update": { + Type: schema.TypeInt, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "reserved_node_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "snap_sets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_name": { + Type: schema.TypeString, + Computed: true, + Description: "Find by node name.", + }, + "stateless_sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stateless_sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tags": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Computed: true, + }, + "val": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "total_disk_size": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_data": { + Type: schema.TypeString, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "read_only": { + Type: schema.TypeBool, + Computed: true, + Description: "Shows if compute is in read-only mode.", + }, + "vgpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "vins_connected": { + Type: schema.TypeInt, + Computed: true, + }, + "loader_type": { + Type: schema.TypeString, + Computed: true, + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceComputeListDeletedSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by AccountID", + }, + "rg_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by resgroup name", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by RGID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by tech status", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "Find by IP address", + }, + "extnet_name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by Extnet name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by Extnet ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "ignore_k8s": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If set to true, ignores any VMs associated with any k8s cluster", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_label": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "key": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + "topology": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "anti_affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "key": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + "topology": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "arch": { + Type: schema.TypeString, + Computed: true, + }, + "auto_start_w_node": { + Type: schema.TypeBool, + Computed: true, + }, + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "bootdisk_size": { + Type: schema.TypeInt, + Computed: true, + }, + "boot_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "chipset": { + Type: schema.TypeString, + Computed: true, + }, + "clock": { + Type: schema.TypeString, + Computed: true, + }, + "cd_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "clone_reference": { + Type: schema.TypeInt, + Computed: true, + }, + "clones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cpu_alignment_profiles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "cpu_pin": { + Type: schema.TypeBool, + Computed: true, + }, + "cpus": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "custom_fields": { //NEED + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "devices": { //NEED + Type: schema.TypeString, + Computed: true, + }, + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hp_backed": { + Type: schema.TypeBool, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "flip_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + "listen_ssh": { + Type: schema.TypeBool, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_brust": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "libvirt_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "txmode": { + Type: schema.TypeString, + Computed: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Computed: true, + }, + "event_idx": { + Type: schema.TypeString, + Computed: true, + }, + "queues": { + Type: schema.TypeInt, + Computed: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "sdn_interface_id": { + Type: schema.TypeString, + Computed: true, + }, + "security_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "target": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "trunk_tags": { + Type: schema.TypeString, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "migrationjob": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "need_reboot": { + Type: schema.TypeBool, + Computed: true, + }, + "numa_affinity": { + Type: schema.TypeString, + Computed: true, + }, + "numa_node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + }, + "public_key": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "os_version": { + Type: schema.TypeString, + Computed: true, + }, + "pinned": { + Type: schema.TypeInt, + Computed: true, + }, + "preferred_cpu": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "reserved_node_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "snap_sets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_name": { + Type: schema.TypeString, + Computed: true, + Description: "Find by node name.", + }, + "stateless_sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stateless_sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tags": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Computed: true, + }, + "val": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "total_disk_size": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_data": { + Type: schema.TypeString, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vgpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "vins_connected": { + Type: schema.TypeInt, + Computed: true, + }, + "loader_type": { + Type: schema.TypeString, + Computed: true, + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + }, + "network_interface_naming": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceComputeAuditsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "timestamp_at": { + Type: schema.TypeInt, + Optional: true, + }, + "timestamp_to": { + Type: schema.TypeInt, + Optional: true, + }, + "user": { + Type: schema.TypeString, + Optional: true, + }, + "call": { + Type: schema.TypeString, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "min_status_code": { + Type: schema.TypeInt, + Optional: true, + }, + "max_status_code": { + Type: schema.TypeInt, + Optional: true, + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "call": { + Type: schema.TypeString, + Computed: true, + }, + "responsetime": { + Type: schema.TypeFloat, + Computed: true, + }, + "statuscode": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceComputeGetAuditsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "epoch": { + Type: schema.TypeFloat, + Computed: true, + }, + "message": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } +} + +func dataSourceComputeGetConsoleUrlSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "console_url": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func dataSourceComputePfwListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pfw_id": { + Type: schema.TypeInt, + Computed: true, + }, + "local_ip": { + Type: schema.TypeString, + Computed: true, + }, + "local_port": { + Type: schema.TypeInt, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "public_port_end": { + Type: schema.TypeInt, + Computed: true, + }, + "public_port_start": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceComputeUserListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + + "account_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "compute_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "rg_acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } + + return res +} + +func dataSourceComputeSnapshotListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceComputeAffinityRelationsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + + "other_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "other_node_indirect": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "other_node_indirect_soft": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "other_node_soft": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "same_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "same_node_soft": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + } + return res +} + +func dataSourceComputeBootOrderGetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + } + return res +} + +func dataSourceComputeMigrateStorageInfoSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + + "migrate_storage_info": { + Type: schema.TypeString, + Computed: true, + }, + } + return res +} + +func dataSourceComputeSnapshotUsageSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "label": { + Type: schema.TypeString, + Optional: true, + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "count": { + Type: schema.TypeInt, + Computed: true, + }, + "stored": { + Type: schema.TypeFloat, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } +} + +func dataSourceComputePCIDeviceListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by RG id", + }, + "device_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by device id", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hwpath": { + Type: schema.TypeString, + Computed: true, + }, + "device_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "system_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceComputeVGPUListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "gpu_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by GPU id", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Find by type", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Find by status", + }, + "includedeleted": { + Type: schema.TypeBool, + Optional: true, + Description: "Include deleted computes. If using field 'status', then includedeleted will be ignored", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "vgpu_id": { + Type: schema.TypeInt, + Computed: true, + }, + "last_claimed_by": { + Type: schema.TypeInt, + Computed: true, + }, + "last_update_time": { + Type: schema.TypeInt, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "pgpuid": { + Type: schema.TypeInt, + Computed: true, + }, + "profile_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceComputeGetLogSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + }, + "path": { + Type: schema.TypeString, + Required: true, + }, + "log": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func resourceComputeSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "ID of the resource group where this compute should be deployed.", + }, + "cpu": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, constants.MAX_CPUS_PER_COMPUTE), + Description: "Number of CPUs to allocate to this compute instance.", + }, + "ram": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.All( + validation.IntAtLeast(constants.MIN_RAM_PER_COMPUTE), + validators.DivisibleBy(constants.RAM_DIVISIBILITY), + ), + Description: "Amount of RAM in MB to allocate to this compute instance.", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "Storage policy id of compute. The rules of the specified storage policy will be used.", + }, + "image_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the OS image to base this compute instance on.", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "chipset": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"Q35", "i440fx"}, false), // observe case while validating + Description: "Type of the emulated system.", + }, + "clock": { + Type: schema.TypeString, + Optional: true, + Default: "default", + ValidateFunc: validation.StringInSlice([]string{"default", "linux", "windows", "none"}, false), + Description: "Clock synchronization mode.", + }, + "without_boot_disk": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state.", + }, + "boot_disk_discard": { + Type: schema.TypeString, + Optional: true, + Default: "ignore", + ValidateFunc: validation.StringInSlice([]string{"unmap", "ignore"}, false), + }, + "create_blank": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If True, the compute is created via kvmx86/createBlank endpoint (without OS image). The image_id field is not required in this case.", + }, + "boot_disk_size": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.", + }, + "boot_disk_cache": { + Type: schema.TypeString, + Optional: true, + Default: "none", + ValidateFunc: validation.StringInSlice([]string{"none", "writethrough"}, false), + Description: "Setting the boot disk caching mode", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.", + }, + "pool": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.", + }, + "cloud_init": { + Type: schema.TypeString, + Optional: true, + Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Optional text description of this compute instance.", + }, + "started": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Is compute started.", + }, + "alt_boot_id": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: "ID of CD-ROM live image to boot", + }, + "node_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "ID of node to start compute", + }, + "custom_fields": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "network": { + Type: schema.TypeSet, + Optional: true, + MinItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS", "VFNIC", "DPDK", "SDN", "TRUNK"}, false), // observe case while validating + Description: "Type of the network for this connection", + }, + "net_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the network for this connection.", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: networkSubresIPAddreDiffSupperss, + Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.", + }, + "mac": { + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: networkSubresIPAddreDiffSupperss, + Description: "MAC address associated with this connection. MAC address is assigned automatically.", + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "weight the network if you need to sort network list, the smallest attach first. zero or null weight attach last", + }, + "mtu": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + //Default: 1500, + ValidateFunc: validation.IntBetween(1500, 9216), + Description: "Maximum transmission unit, used only for DPDK type, must be 1500-9216", + }, + "sdn_interface_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: networkSubresIPAddreDiffSupperss, + Description: "unique_identifier of LogicalPort on SDN side", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "network enable flag", + }, + "net_mask": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Subnet mask, used only for DPDK and VFNIC network types", + }, + }, + }, + Description: "Optional network connection(s) for this compute. You may specify several network blocks, one for each connection.", + }, + + "libvirt_settings": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"VINS", "VFNIC", "DPDK"}, false), // observe case while validating + Description: "Type of the network", + }, + "net_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the network", + }, + "txmode": { + Type: schema.TypeString, + Default: "", + Optional: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Default: "", + Optional: true, + }, + "event_idx": { + Type: schema.TypeString, + Default: "", + Optional: true, + }, + "queues": { + Type: schema.TypeInt, + Default: 0, + Optional: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Default: 0, + Optional: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Default: 0, + Optional: true, + }, + }, + }, + Description: "Configure libvirt virtio interface parameters. You can only delete values locally. Data on the platform cannot be deleted.", + }, + + "security_groups": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + StateFunc: statefuncs.StateFuncToUpper, + ValidateFunc: validation.StringInSlice([]string{"VINS", "EXTNET", "DPDK"}, false), // observe case while validating + Description: "Type of the network", + }, + "net_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the network", + }, + "security_groups": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + }, + }, + Description: "list of security group IDs to apply to this interface", + }, + + "affinity_label": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Set affinity label for compute", + }, + "cpu_alignment_profile": { + Type: schema.TypeString, + Optional: true, + Description: "CPU alignment profile name", + }, + "affinity_rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topology": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false), + Description: "compute or node, for whom rule applies", + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false), + Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule", + }, + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false), + Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'", + }, + "key": { + Type: schema.TypeString, + Required: true, + Description: "key that are taken into account when analyzing this rule will be identified", + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: "value that must match the key to be taken into account when analyzing this rule", + }, + }, + }, + }, + "delete_async_mode": { + Type: schema.TypeBool, + Computed: true, + Description: "async mode", + }, + "anti_affinity_rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topology": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false), + Description: "compute or node, for whom rule applies", + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false), + Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule", + }, + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false), + Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'", + }, + "key": { + Type: schema.TypeString, + Required: true, + Description: "key that are taken into account when analyzing this rule will be identified", + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: "value that must match the key to be taken into account when analyzing this rule", + }, + }, + }, + }, + "disks": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cache": { + Type: schema.TypeString, + Optional: true, + Default: "none", + ValidateFunc: validation.StringInSlice([]string{"none", "writethrough"}, false), + Description: "Setting the disk caching mode", + }, + "disk_name": { + Type: schema.TypeString, + Required: true, + Description: "Name for disk", + }, + "size": { + Type: schema.TypeInt, + Required: true, + Description: "Disk size in GiB", + }, + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + Description: "Storage policy id of disk. The rules of the specified storage policy will be used.", + }, + "discard": { + Type: schema.TypeString, + Optional: true, + Default: "ignore", + ValidateFunc: validation.StringInSlice([]string{"unmap", "ignore"}, false), + }, + "block_size": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Disk block size", + }, + "provision": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Storage endpoint provider ID; by default the same with boot disk", + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "PCI slot number of the disk", + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + Description: "Bus number of the disk on virtual bus (6 = boot disk)", + }, + "pool": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Pool name; by default will be chosen automatically", + }, + "node_ids": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Optional description", + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Specify image id for create disk from template", + }, + "independent": { + Type: schema.TypeBool, + Computed: true, + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Description: "Disk deletion status", + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Disk ID", + }, + "present_to": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "shareable": { + Type: schema.TypeBool, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeInt, + Computed: true, + }, + "to_clean": { + Type: schema.TypeBool, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "create_by": { + Type: schema.TypeString, + Computed: true, + }, + "create_time": { + Type: schema.TypeInt, + Computed: true, + }, + "delete_by": { + Type: schema.TypeString, + Computed: true, + }, + "delete_time": { + Type: schema.TypeInt, + Computed: true, + }, + "update_time": { + Type: schema.TypeInt, + Computed: true, + }, + "iotune": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "read_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "read_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "size_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "total_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_bytes_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_bytes_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_iops_sec": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "write_iops_sec_max": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "extra_disks": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.", + }, + "tags": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Required: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "port_forwarding": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "public_port_start": { + Type: schema.TypeInt, + Required: true, + }, + "public_port_end": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + }, + "local_port": { + Type: schema.TypeInt, + Optional: true, + }, + "proto": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false), + }, + "rule_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "user_access": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + }, + "access_type": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "snapshot": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "rollback": { + Type: schema.TypeSet, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "cd": { + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cdrom_id": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + "pin_to_node": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "auto_start_w_node": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "force_pin": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "If true - enable compute, else - disable", + }, + "pause": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "reset": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "force_stop": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Flag for redeploy compute", + }, + "force_resize": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Flag for resize compute", + }, + "detach_disks": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "numa_affinity": { + Type: schema.TypeString, + Optional: true, + Default: "none", + ValidateFunc: validation.StringInSlice([]string{"none", "strict", "loose"}, false), // observe case while validating + Description: "Rule for VM placement with NUMA affinity.", + }, + "cpu_pin": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node.", + }, + "hp_backed": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Use Huge Pages to allocate RAM of the virtual machine. The system must be pre-configured by allocating Huge Pages on the physical node.", + }, + "preferred_cpu": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Recommended isolated CPUs. Field is ignored if compute.cpupin=False or compute.pinned=False", + }, + "pci_devices": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "ID of the connected pci devices", + }, + "loader_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "unknown"}, false), + Description: "Type of image vm.", + }, + "boot_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, false), + Description: "Type of image upload.", + }, + "hot_resize": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Type of image vm.", + }, + "network_interface_naming": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, false), + Description: "Name of netfowrk interface.", + }, + "os_version": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "the OS version installed on the VM", + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "Priority weight of the compute. Higher value means higher priority and later migration.", + }, + // Computed properties + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the account this compute instance belongs to.", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account this compute instance belongs to.", + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "arch": { + Type: schema.TypeString, + Computed: true, + }, + "boot_order": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "boot_disk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "This compute instance boot disk ID.", + }, + "boot_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cd_image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "clone_reference": { + Type: schema.TypeInt, + Computed: true, + }, + "clones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computeci_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devices": { + Type: schema.TypeString, + Computed: true, + }, + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + }, + "def_gw": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "flip_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + "listen_ssh": { + Type: schema.TypeBool, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_brust": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "libvirt_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "txmode": { + Type: schema.TypeString, + Computed: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Computed: true, + }, + "event_idx": { + Type: schema.TypeString, + Computed: true, + }, + "queues": { + Type: schema.TypeInt, + Computed: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "sdn_interface_id": { + Type: schema.TypeString, + Computed: true, + }, + "security_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "target": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "trunk_tags": { + Type: schema.TypeString, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "image_name": { + Type: schema.TypeString, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "migrationjob": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "natable_vins_ip": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_name": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network": { + Type: schema.TypeString, + Computed: true, + }, + "natable_vins_network_name": { + Type: schema.TypeString, + Computed: true, + }, + "need_reboot": { + Type: schema.TypeBool, + Computed: true, + }, + "numa_node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "os_users": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "GUID of this guest OS user.", + }, + + "login": { + Type: schema.TypeString, + Computed: true, + Description: "Login name of this guest OS user.", + }, + + "password": { + Type: schema.TypeString, + Computed: true, + //Sensitive: true, + Description: "Password of this guest OS user.", + }, + + "public_key": { + Type: schema.TypeString, + Computed: true, + Description: "SSH public key of this guest OS user.", + }, + }, + }, + Description: "Guest OS users provisioned on this compute instance.", + }, + "pinned": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "reserved_node_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the resource group where this compute instance is located.", + }, + "snap_sets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "node_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the node, on which VM started", + }, + "stateless_sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stateless_sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "read_only": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Sets read-only mode for this compute. Only data operations allowed when enabled.", + }, + "vnc_password": { + Type: schema.TypeString, + Computed: true, + }, + "vgpus": { + Type: schema.TypeList, + Computed: true, + Description: "List of virtual GPUs", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "profile_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "last_update_time": { + Type: schema.TypeInt, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + "pgpuid": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "last_claimed_by": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "virtual_image_name": { + Type: schema.TypeString, + Computed: true, + }, + "loader_meta_iso": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "device_name": { + Type: schema.TypeString, + Computed: true, + }, + "path": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } +} diff --git a/internal/service/cloudbroker/kvmvm/state_upgraders.go b/internal/service/cloudbroker/kvmvm/state_upgraders.go new file mode 100644 index 00000000..a7f00066 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/state_upgraders.go @@ -0,0 +1,50 @@ +package kvmvm + +import ( + "context" + + log "github.com/sirupsen/logrus" +) + +func resourceCompueteStateUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceCompueteStateUpgradeV1: upgrading state") + if oldVal, ok := rawState["pinned"].(bool); ok { + if !oldVal { + rawState["pinned"] = -1 + } else { + rawState["pinned"] = 0 + } + } + + return rawState, nil +} + +func resourceComputeStateUpgradeV2(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceComputeStateUpgradeV2: upgrading state") + + if v, ok := rawState["boot_disk_blk_discard"].(bool); ok { + if v { + rawState["boot_disk_discard"] = "unmap" + } else { + rawState["boot_disk_discard"] = "ignore" + } + } + delete(rawState, "boot_disk_blk_discard") + + if disks, ok := rawState["disks"].([]interface{}); ok { + for _, d := range disks { + if disk, ok := d.(map[string]interface{}); ok { + if v, ok := disk["blk_discard"].(bool); ok { + if v { + disk["discard"] = "unmap" + } else { + disk["discard"] = "ignore" + } + } + delete(disk, "blk_discard") + } + } + } + + return rawState, nil +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute.go b/internal/service/cloudbroker/kvmvm/utility_compute.go new file mode 100644 index 00000000..4094d244 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute.go @@ -0,0 +1,2587 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "errors" + "fmt" + "regexp" + "sort" + "strconv" + "strings" + "time" + + "github.com/hashicorp/go-cty/cty" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityComputeEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + enabled := d.Get("enabled").(bool) + + if enabled { + req := compute.EnableRequest{ + ComputeID: computeId, + } + + if _, err := c.CloudBroker().Compute().Enable(ctx, req); err != nil { + return err + } + } else { + req := compute.DisableRequest{ + ComputeID: computeId, + } + + if _, err := c.CloudBroker().Compute().Disable(ctx, req); err != nil { + return err + } + } + log.Debugf("resourceComputeUpdate: enable=%v Compute ID %s after completing its resource configuration", enabled, d.Id()) + + return nil +} + +func utilityComputeStarted(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + if d.Get("started").(bool) { + req := compute.StartRequest{ + ComputeID: computeId, + } + if altBootId, ok := d.Get("alt_boot_id").(int); ok { + req.AltBootID = uint64(altBootId) + } + if nodeId, ok := d.Get("node_id").(int); ok { + req.NodeID = uint64(nodeId) + } + if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil { + return err + } + } else { + req := compute.StopRequest{ + ComputeID: computeId, + } + if force, ok := d.Get("force_stop").(bool); ok { + req.Force = force + } + if _, err := c.CloudBroker().Compute().Stop(ctx, req); err != nil { + return err + } + } + return nil +} + +func utilityComputeUpdateReadOnly(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, err := strconv.ParseUint(d.Id(), 10, 64) + if err != nil { + return err + } + + req := compute.ChangeReadOnlyRequest{ + ComputeID: computeId, + ReadOnly: d.Get("read_only").(bool), + } + + if _, err := c.CloudBroker().Compute().ChangeReadOnly(ctx, req); err != nil { + return err + } + + log.Debugf("resourceCompute: read_only=%t for Compute ID %d", req.ReadOnly, computeId) + + return nil +} + +func utilityComputeResize(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + var isStopRequired bool + + old, new := d.GetChange("cpu") + if d.Get("started").(bool) && (old.(int) > new.(int)) && d.Get("force_resize").(bool) { + isStopRequired = true + } + if isStopRequired { + stopReq := compute.StopRequest{ + ComputeID: computeId, + Force: false, + } + if _, err := c.CloudBroker().Compute().Stop(ctx, stopReq); err != nil { + return err + } + } + + resizeReq := compute.ResizeRequest{ + ComputeID: computeId, + } + forceResize, ok := d.GetOk("force_resize") + if ok { + resizeReq.Force = forceResize.(bool) + } + + doUpdate := false + + oldCpu, newCpu := d.GetChange("cpu") + if oldCpu.(int) > newCpu.(int) && !forceResize.(bool) { + return fmt.Errorf("сannot resize compute ID %d: enable 'force_resize' to reduce compute vCPUs", computeId) + } + if oldCpu.(int) != newCpu.(int) { + resizeReq.CPU = uint64(newCpu.(int)) + doUpdate = true + } else { + resizeReq.CPU = 0 + } + + if resizeReq.CPU != 0 { + if preferredCPU, ok := d.GetOk("preferred_cpu"); ok { + preferredList := preferredCPU.([]interface{}) + if len(preferredList) > 0 { + for _, v := range preferredList { + cpuNum := v.(int) + resizeReq.PreferredCPU = append(resizeReq.PreferredCPU, int64(cpuNum)) + } + } + } + oldPCPU, newPCPU := d.GetChange("preferred_cpu") + if len(oldPCPU.([]interface{})) != 0 && len(newPCPU.([]interface{})) == 0 { + resizeReq.PreferredCPU = []int64{-1} + } + } + + oldRam, newRam := d.GetChange("ram") + if oldRam.(int) != newRam.(int) { + resizeReq.RAM = uint64(newRam.(int)) + doUpdate = true + } else { + resizeReq.RAM = 0 + } + + if doUpdate { + log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d", + oldCpu.(int), newCpu.(int), + oldRam.(int), newRam.(int)) + _, err := c.CloudBroker().Compute().Resize(ctx, resizeReq) + if err != nil { + return err + } + } + + if isStopRequired { + req := compute.StartRequest{ComputeID: computeId} + if altBootID, ok := d.Get("alt_boot_id").(int); ok { + req.AltBootID = uint64(altBootID) + } + if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil { + return err + } + } + + return nil +} + +func utilityComputeBootDiskResize(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + oldSize, newSize := d.GetChange("boot_disk_size") + if oldSize.(int) < newSize.(int) { + req := compute.DiskResizeRequest{ComputeID: computeId, Size: uint64(newSize.(int))} + if diskId, ok := d.GetOk("boot_disk_id"); ok { + req.DiskID = uint64(diskId.(int)) + + } else { + bootDisk, err := utilityComputeBootDiskCheckPresence(ctx, d, m) + if err != nil { + return err + } + + req.DiskID = bootDisk.ID + } + + log.Debugf("resourceComputeUpdate: compute ID %s, boot disk ID %d resize %d -> %d", + d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int)) + + _, err := c.CloudBroker().Compute().DiskResize(ctx, req) + if err != nil { + return err + } + + } else if oldSize.(int) > newSize.(int) { + log.Warnf("resourceComputeUpdate: compute ID %s - shrinking boot disk is not allowed", d.Id()) + } + + return nil +} + +func utilityComputeUpdateDisks(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + deletedDisks := make([]interface{}, 0) + addedDisks := make([]interface{}, 0) + resizedDisks := make([]interface{}, 0) + renamedDisks := make([]interface{}, 0) + changeStoragePolicyDisks := make([]interface{}, 0) + cacheUpdatedDisks := make([]interface{}, 0) + discardUpdatedDisks := make([]interface{}, 0) + blockSizeUpdatedDisks := make([]interface{}, 0) + iotuneUpdatedDisks := make([]interface{}, 0) + migratedDisks := make([]interface{}, 0) + presentNewDisks := make([]interface{}, 0) + presentOldDisks := make([]interface{}, 0) + + chipset := d.Get("chipset").(string) + + oldDisks, newDisks := d.GetChange("disks") + oldConv := oldDisks.([]interface{}) + newConv := newDisks.([]interface{}) + + for _, el := range oldConv { + changeNodes, newEl := isChangeNodesDisk(newConv, el) + if changeNodes { + presentNewDisks = append(presentNewDisks, newEl) + presentOldDisks = append(presentOldDisks, el) + } + // !isRenameDisk(newConv, el) && !isResizeDisk(newConv, el) are required in case two or more disks are being created and their disk_id is the same (=0) + if !isContainsDisk(newConv, el) && !isRenameDisk(newConv, el) && !isResizeDisk(newConv, el) && !isChangeStoragePolicy(newConv, el) { + flag := false + extraDisks := d.Get("extra_disks").(*schema.Set).List() + delDisk := el.(map[string]interface{}) + delDiskId := delDisk["disk_id"].(int) + + for _, extraDiskId := range extraDisks { + if extraDiskId.(int) == delDiskId { + flag = true + break + } + } + + if !flag { + deletedDisks = append(deletedDisks, el) + } else { + log.Debugf("disk %d will not be deleted because it is present in the extra_disks block", delDiskId) + } + } + } + + for _, el := range newConv { + if !isContainsDisk(oldConv, el) { + addedDisks = append(addedDisks, el) + } + if isResizeDisk(oldConv, el) { + resizedDisks = append(resizedDisks, el) + } + if isRenameDisk(oldConv, el) { + renamedDisks = append(renamedDisks, el) + } + if isMigrateDisk(oldConv, el) { + migratedDisks = append(migratedDisks, el) + } else if isChangeStoragePolicy(oldConv, el) { + changeStoragePolicyDisks = append(changeStoragePolicyDisks, el) + } + if isChangeCacheDisk(oldConv, el) { + cacheUpdatedDisks = append(cacheUpdatedDisks, el) + } + + if isChangeDiscardDisk(oldConv, el) { + discardUpdatedDisks = append(discardUpdatedDisks, el) + } + + if isChangeBlockSizeDisk(oldConv, el) { + blockSizeUpdatedDisks = append(blockSizeUpdatedDisks, el) + } + + if isChangeIOTuneDisk(oldConv, el) { + iotuneUpdatedDisks = append(iotuneUpdatedDisks, el) + } + } + + if len(deletedDisks) > 0 { + for _, disk := range deletedDisks { + diskConv := disk.(map[string]interface{}) + if isBootDisk(diskConv, chipset) { + continue + } + + req := compute.DiskDelRequest{ + ComputeID: computeId, + DiskID: uint64(diskConv["disk_id"].(int)), + Permanently: diskConv["permanently"].(bool), + } + + _, err := c.CloudBroker().Compute().DiskDel(ctx, req) + if err != nil { + return err + } + } + } + + if len(addedDisks) > 0 { + for _, disk := range addedDisks { + diskConv := disk.(map[string]interface{}) + req := compute.DiskAddRequest{ + ComputeID: computeId, + DiskName: diskConv["disk_name"].(string), + Size: uint64(diskConv["size"].(int)), + StoragePolicyID: uint64(diskConv["storage_policy_id"].(int)), + } + if diskConv["sep_id"].(int) != 0 { + req.SepID = uint64(diskConv["sep_id"].(int)) + } + if diskConv["pool"].(string) != "" { + req.Pool = diskConv["pool"].(string) + } + if diskConv["desc"].(string) != "" { + req.Description = diskConv["desc"].(string) + } + if diskConv["image_id"].(int) != 0 { + req.ImageID = uint64(diskConv["image_id"].(int)) + } + if cacheVal, ok := diskConv["cache"].(string); ok { + req.Cache = cacheVal + } + diskID, err := c.CloudBroker().Compute().DiskAdd(ctx, req) + if err != nil { + return err + } + if blockSize, ok := diskConv["block_size"].(string); ok && blockSize != "" { + updateReq := disks.UpdateRequest{ + DiskID: diskID, + BlockSize: blockSize, + } + _, err := c.CloudBroker().Disks().Update(ctx, updateReq) + if err != nil { + return err + } + } + if nodeIDs, ok := diskConv["node_ids"]; ok { + presentIDs := nodeIDs.(*schema.Set).List() + if len(presentIDs) > 0 { + log.Debugf("resourceComputeUpdate: start presents new disk ID:%d to nodes", diskID) + } + for _, presentID := range presentIDs { + nodeID := uint64(presentID.(int)) + req := disks.PresentRequest{ + DiskID: diskID, + NodeID: nodeID, + } + _, err := c.CloudBroker().Disks().Present(ctx, req) + if err != nil { + return err + } + } + } + if iotuneRaw, ok := diskConv["iotune"].([]interface{}); ok && len(iotuneRaw) > 0 { + iotuneMap := iotuneRaw[0].(map[string]interface{}) + limitReq := disks.LimitIORequest{ + DiskID: diskID, + ReadBytesSec: uint64(iotuneMap["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotuneMap["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotuneMap["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotuneMap["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotuneMap["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotuneMap["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotuneMap["total_bytes_sec_max"].(int)), + TotalIOPSSec: uint64(iotuneMap["total_iops_sec"].(int)), + TotalIOPSSecMax: uint64(iotuneMap["total_iops_sec_max"].(int)), + WriteBytesSec: uint64(iotuneMap["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotuneMap["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotuneMap["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotuneMap["write_iops_sec_max"].(int)), + } + _, err := c.CloudBroker().Disks().LimitIO(ctx, limitReq) + if err != nil { + return err + } + } + if err != nil { + return err + } + } + } + + if len(resizedDisks) > 0 { + for _, disk := range resizedDisks { + diskConv := disk.(map[string]interface{}) + if isBootDisk(diskConv, chipset) { + continue + } + req := compute.DiskResizeRequest{ + ComputeID: computeId, + DiskID: uint64(diskConv["disk_id"].(int)), + Size: uint64(diskConv["size"].(int)), + } + + _, err := c.CloudBroker().Compute().DiskResize(ctx, req) + if err != nil { + return err + } + } + } + + if len(renamedDisks) > 0 { + for _, disk := range renamedDisks { + diskConv := disk.(map[string]interface{}) + + req := disks.RenameRequest{ + DiskID: uint64(diskConv["disk_id"].(int)), + Name: diskConv["disk_name"].(string), + } + + _, err := c.CloudBroker().Disks().Rename(ctx, req) + if err != nil { + return err + } + } + } + if len(changeStoragePolicyDisks) > 0 { + for _, disk := range changeStoragePolicyDisks { + diskConv := disk.(map[string]interface{}) + + req := disks.ChangeDiskStoragePolicyRequest{ + DiskID: uint64(diskConv["disk_id"].(int)), + StoragePolicyID: uint64(diskConv["storage_policy_id"].(int)), + } + + _, err := c.CloudBroker().Disks().ChangeDiskStoragePolicy(ctx, req) + if err != nil { + return err + } + } + } + + if len(cacheUpdatedDisks) > 0 { + for _, disk := range cacheUpdatedDisks { + diskConv := disk.(map[string]interface{}) + if isBootDisk(diskConv, chipset) { + continue + } + + diskID := uint64(diskConv["disk_id"].(int)) + if diskID == 0 { + continue + } + + req := disks.UpdateRequest{ + DiskID: diskID, + Cache: diskConv["cache"].(string), + } + _, err := c.CloudBroker().Disks().Update(ctx, req) + if err != nil { + return err + } + } + } + + if len(discardUpdatedDisks) > 0 { + for _, disk := range discardUpdatedDisks { + diskConv := disk.(map[string]interface{}) + if isBootDisk(diskConv, chipset) { + continue + } + + diskID := uint64(diskConv["disk_id"].(int)) + if diskID == 0 { + continue + } + + req := disks.UpdateRequest{ + DiskID: diskID, + Discard: diskConv["discard"].(string), + } + _, err := c.CloudBroker().Disks().Update(ctx, req) + if err != nil { + return err + } + } + } + + if len(blockSizeUpdatedDisks) > 0 { + for _, disk := range blockSizeUpdatedDisks { + diskConv := disk.(map[string]interface{}) + if isBootDisk(diskConv, chipset) { + continue + } + + diskID := uint64(diskConv["disk_id"].(int)) + if diskID == 0 { + continue + } + + req := disks.UpdateRequest{ + DiskID: diskID, + BlockSize: diskConv["block_size"].(string), + } + _, err := c.CloudBroker().Disks().Update(ctx, req) + if err != nil { + return err + } + } + } + + if len(iotuneUpdatedDisks) > 0 { + for _, disk := range iotuneUpdatedDisks { + diskConv := disk.(map[string]interface{}) + if isBootDisk(diskConv, chipset) { + continue + } + + diskID := uint64(diskConv["disk_id"].(int)) + if diskID == 0 { + continue + } + + iotuneRaw := diskConv["iotune"].([]interface{}) + if len(iotuneRaw) == 0 { + continue + } + iotuneMap := iotuneRaw[0].(map[string]interface{}) + req := disks.LimitIORequest{ + DiskID: diskID, + ReadBytesSec: uint64(iotuneMap["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotuneMap["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotuneMap["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotuneMap["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotuneMap["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotuneMap["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotuneMap["total_bytes_sec_max"].(int)), + TotalIOPSSec: uint64(iotuneMap["total_iops_sec"].(int)), + TotalIOPSSecMax: uint64(iotuneMap["total_iops_sec_max"].(int)), + WriteBytesSec: uint64(iotuneMap["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotuneMap["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotuneMap["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotuneMap["write_iops_sec_max"].(int)), + } + _, err := c.CloudBroker().Disks().LimitIO(ctx, req) + if err != nil { + return err + } + } + } + + if len(migratedDisks) > 0 { + if err := utilityComputeMigrateDisks(ctx, d, m, migratedDisks, oldConv); err != nil { + return err + } + } + + for i := range presentNewDisks { + newDisk := presentNewDisks[i].(map[string]interface{}) + oldDisk := presentOldDisks[i].(map[string]interface{}) + newArr := newDisk["node_ids"] + oldArr := oldDisk["node_ids"] + diskID := uint64(newDisk["disk_id"].(int)) + presentIDs := (newArr.(*schema.Set).Difference(oldArr.(*schema.Set))).List() + depresentIDs := (oldArr.(*schema.Set).Difference(newArr.(*schema.Set))).List() + for _, presentID := range presentIDs { + nodeID := uint64(presentID.(int)) + + req := disks.PresentRequest{ + DiskID: diskID, + NodeID: nodeID, + } + log.Debugf("resourceComputeUpdate: start presents disk ID:%d from nodes %d", req.DiskID, req.NodeID) + _, err := c.CloudBroker().Disks().Present(ctx, req) + if err != nil { + return err + } + } + + for _, depresentID := range depresentIDs { + nodeID := uint64(depresentID.(int)) + + req := disks.DepresentRequest{ + DiskID: diskID, + NodeID: nodeID, + } + log.Debugf("resourceComputeUpdate: start depresents disk ID:%d from nodes %d", req.DiskID, req.NodeID) + _, err := c.CloudBroker().Disks().Depresent(ctx, req) + if err != nil { + return err + } + } + } + + return nil +} + +func utilityComputeUpdateBootDiskCache(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + newCache := d.Get("boot_disk_cache").(string) + + var bootDiskID uint64 + if v, ok := d.GetOk("boot_disk_id"); ok { + if id, ok := v.(int); ok { + bootDiskID = uint64(id) + } + } + + if bootDiskID == 0 { + return fmt.Errorf("cannot update boot_disk_cache: boot disk ID is unknown for compute %s", d.Id()) + } + + req := disks.UpdateRequest{ + DiskID: bootDiskID, + Cache: newCache, + } + + _, err := c.CloudBroker().Disks().Update(ctx, req) + return err +} + +func utilityComputeUpdateBootDiskDiscard(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + newDiscard := d.Get("boot_disk_discard").(string) + + var bootDiskID uint64 + if v, ok := d.GetOk("boot_disk_id"); ok { + if id, ok := v.(int); ok { + bootDiskID = uint64(id) + } + } + + if bootDiskID == 0 { + return fmt.Errorf("cannot update boot_disk_discard: boot disk ID is unknown for compute %s", d.Id()) + } + + req := disks.UpdateRequest{ + DiskID: bootDiskID, + Discard: newDiscard, + } + + _, err := c.CloudBroker().Disks().Update(ctx, req) + return err +} + +func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool) error { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %t", d.Id(), do_delta) + + old_set, new_set := d.GetChange("extra_disks") + + apiErrCount := 0 + var lastSavedError error + + if !do_delta { + if new_set.(*schema.Set).Len() < 1 { + return nil + } + + for _, disk := range new_set.(*schema.Set).List() { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.DiskAttachRequest{ + ComputeID: computeId, + DiskID: uint64(disk.(int)), + } + + _, err := c.CloudBroker().Compute().DiskAttach(ctx, req) + if err != nil { + apiErrCount++ + lastSavedError = err + } + } + + if apiErrCount > 0 { + log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when attaching disks to Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) + return lastSavedError + } + + return nil + } + + detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set)) + log.Debugf("utilityComputeExtraDisksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id()) + + if detach_set.Len() > 0 { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + for _, diskId := range detach_set.List() { + req := compute.DiskDetachRequest{ + ComputeID: computeId, + DiskID: uint64(diskId.(int)), + } + _, err := c.CloudBroker().Compute().DiskDetach(ctx, req) + if err != nil { + log.Errorf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + } + + attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set)) + log.Debugf("utilityComputeExtraDisksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id()) + for _, diskId := range attach_set.List() { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.DiskAttachRequest{ + ComputeID: computeId, + DiskID: uint64(diskId.(int)), + } + + _, err := c.CloudBroker().Compute().DiskAttach(ctx, req) + if err != nil { + log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + if apiErrCount > 0 { + log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when managing disks of Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) + return lastSavedError + } + + return nil +} + +func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.RecordCompute, error) { + c := m.(*controller.ControllerCfg) + req := compute.GetRequest{} + + if d.Id() != "" { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.ComputeID = computeId + } else { + req.ComputeID = uint64(d.Get("compute_id").(int)) + } + + res, err := c.CloudBroker().Compute().Get(ctx, req) + if err != nil { + return nil, err + } + + return res, nil +} + +func utilityComputePCIDevicesList(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListPCIDevices, error) { + c := m.(*controller.ControllerCfg) + req := compute.ListPCIDeviceRequest{} + + if d.Id() != "" { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.ComputeID = computeId + } else { + req.ComputeID = uint64(d.Get("compute_id").(int)) + } + + res, err := c.CloudBroker().Compute().ListPCIDevice(ctx, req) + if err != nil { + return nil, err + } + + return res, nil +} + +func isBootDisk(diskConv map[string]interface{}, chipset string) bool { + if chipset == "i440fx" { + return diskConv["pci_slot"].(int) == 6 + } + return diskConv["bus_number"].(int) == 6 +} + +func findBootDisk(disks compute.ListDisks, chipset string) *compute.ItemDisk { + for _, disk := range disks { + if chipset == "i440fx" { + if disk.PCISlot == 6 { + return &disk + } + } else { + if disk.BusNumber == 6 { + return &disk + } + } + } + return &compute.ItemDisk{} +} + +func networkSubresIPAddreDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool { + if newVal != "" && newVal != oldVal { + log.Debugf("networkSubresIPAddreDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal) + return false + } + log.Debugf("networkSubresIPAddreDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal) + return true // suppress difference +} + +func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + oldSet, newSet := d.GetChange("network") + + oldList := oldSet.(*schema.Set).List() + newList := newSet.(*schema.Set).List() + + updateNetwork := differenceNetwork(oldList, newList) + apiErrCount := 0 + var lastSavedError error + + log.Debugf("utilityComputeNetworksConfigure: detach set has %d items for Compute ID %s", len(updateNetwork.DetachMap), d.Id()) + for _, netData := range updateNetwork.DetachMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.NetDetachRequest{ + ComputeID: computeId, + IPAddr: netData["ip_address"].(string), + MAC: netData["mac"].(string), + } + + _, err := c.CloudBroker().Compute().NetDetach(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s", + netData["net_id"].(int), netData["net_type"].(string), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + log.Debugf("utilityComputeNetworksConfigure: changeIp set has %d items for Compute ID %s", len(updateNetwork.ChangeIPMap), d.Id()) + for _, netData := range updateNetwork.ChangeIPMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.ChangeIPRequest{ + ComputeID: computeId, + NetType: netData["net_type"].(string), + NetID: uint64(netData["net_id"].(int)), + IPAddr: netData["ip_address"].(string), + } + + _, err := c.CloudBroker().Compute().ChangeIP(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to change net ID %d of type %s from Compute ID %s: %s", + netData["net_id"].(int), netData["net_type"].(string), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + needStart := false + + oldLibvirtSet, newLibvirtSet := d.GetChange("libvirt_settings") + addedLibvirtSettings := (newLibvirtSet.(*schema.Set).Difference(oldLibvirtSet.(*schema.Set))).List() + libvirtSettingsMap := addAttachedNetwork(addedLibvirtSettings, newLibvirtSet.(*schema.Set).List(), updateNetwork.AttachMap) + + if oldSet.(*schema.Set).Len() == len(updateNetwork.DetachMap) || oldSet.(*schema.Set).Len() == 0 || len(libvirtSettingsMap) > 0 || hasDPDKnetwork(updateNetwork.AttachMap) || len(updateNetwork.ChangeMacMap) > 0 { + if err := utilityComputeStop(ctx, d, m); err != nil { + apiErrCount++ + lastSavedError = err + } + if start := d.Get("started"); start.(bool) { + needStart = true + } + } + + log.Debugf("utilityComputeNetworksConfigure: changeMac set has %d items for Compute ID %s", len(updateNetwork.ChangeMacMap), d.Id()) + for _, netData := range updateNetwork.ChangeMacMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.ChangeMACRequest{ + ComputeID: computeId, + NewMAC: netData["mac"].(string), + СurrentMAC: netData["old_mac"].(string), + } + + _, err := c.CloudBroker().Compute().ChangeMAC(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to change mac %s to %s from Compute ID %s: %s", + req.СurrentMAC, req.NewMAC, d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + sort.Slice(updateNetwork.AttachMap, func(i, j int) bool { + weightI := updateNetwork.AttachMap[i]["weight"].(int) + weightJ := updateNetwork.AttachMap[j]["weight"].(int) + if weightI == 0 { + return false + } + if weightJ == 0 { + return true + } + return weightI < weightJ + }) + log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", len(updateNetwork.AttachMap), d.Id()) + for _, netData := range updateNetwork.AttachMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.NetAttachRequest{ + ComputeID: computeId, + NetType: netData["net_type"].(string), + NetID: uint64(netData["net_id"].(int)), + } + + if req.NetType == "DPDK" { + req.MTU = uint64(netData["mtu"].(int)) + } + + if netData["ip_address"].(string) != "" { + req.IPAddr = netData["ip_address"].(string) + } + + if netData["mac"].(string) != "" { + req.MACAddr = netData["mac"].(string) + } + + if req.NetType == "DPDK" || req.NetType == "EXTNET" { + req.MTU = uint64(netData["mtu"].(int)) + } + + if req.NetType == "DPDK" || req.NetType == "VFNIC" { + if netMask, ok := netData["net_mask"].(int); ok && netMask > 0 { + req.NetMask = uint64(netMask) + } + } + + if netData["sdn_interface_id"].(string) != "" { + req.SDNInterfaceID = netData["sdn_interface_id"].(string) + } + + _, err := c.CloudBroker().Compute().NetAttach(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s", + netData["net_id"].(int), netData["net_type"].(string), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + if len(libvirtSettingsMap) > 0 { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + computeRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to read information about compute with ID %s: %s", + d.Id(), err) + apiErrCount++ + lastSavedError = err + } + + if computeRec != nil { + log.Debugf("utilityComputeNetworksConfigure: libvirt virtio set has %d items for Compute ID %s", len(libvirtSettingsMap), d.Id()) + for _, libvirtSetting := range libvirtSettingsMap { + netType := libvirtSetting["net_type"].(string) + netId := uint64(libvirtSetting["net_id"].(int)) + var mac string + for _, iface := range computeRec.Interfaces { + if iface.NetID == netId && iface.NetType == netType { + mac = iface.MAC + break + } + } + log.Debugf("utilityComputeNetworksConfigure: Configure libvirt virtio interface parameters on Network with type %s and id %d", netType, netId) + req := compute.SetNetConfigRequest{ + ComputeID: computeId, + MAC: mac, + TXMode: libvirtSetting["txmode"].(string), + IOEventFD: libvirtSetting["ioeventfd"].(string), + EventIDx: libvirtSetting["event_idx"].(string), + Queues: uint64(libvirtSetting["queues"].(int)), + RXQueueSize: uint64(libvirtSetting["rx_queue_size"].(int)), + TXQueueSize: uint64(libvirtSetting["tx_queue_size"].(int)), + } + + _, err := c.CloudBroker().Compute().SetNetConfig(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to set net config to net ID %d of type %s to Compute ID %s: %s", + netId, netType, d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + } + } + + if needStart { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + var altBootID uint64 + if altBootIDRaw, ok := d.Get("alt_boot_id").(int); ok { + altBootID = uint64(altBootIDRaw) + } else { + altBootID = 0 + } + if numErr, err := utilityComputeStart(ctx, computeId, altBootID, m); err != nil { + apiErrCount += numErr + lastSavedError = err + } + } + + log.Debugf("utilityComputeNetworksConfigure: changeMTU set has %d items for Compute ID %s", len(updateNetwork.ChangeMTUMap), d.Id()) + for _, netData := range updateNetwork.ChangeMTUMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.ChangeMTURequest{ + ComputeID: computeId, + Interface: netData["mac"].(string), + MTU: uint64(netData["mtu"].(int)), + } + + _, err := c.CloudBroker().Compute().ChangeMTU(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to change MTU ID %d of type %s from Compute ID %s: %s", + netData["net_id"].(int), netData["net_type"].(string), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + log.Debugf("utilityComputeNetworksConfigure: enableMap set has %d items for Compute ID %s", len(updateNetwork.EnableMap), d.Id()) + for _, netData := range updateNetwork.EnableMap { + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.ChangeLinkStateRequest{ + ComputeID: computeId, + Interface: netData["mac"].(string), + State: "off", + } + + if netData["enabled"].(bool) { + req.State = "on" + } + + _, err := c.CloudBroker().Compute().ChangeLinkState(ctx, req) + if err != nil { + log.Errorf("utilityComputeNetworksConfigure: failed to change link state network ID %d of type %s from Compute ID %s: %s", + netData["net_id"].(int), netData["net_type"].(string), d.Id(), err) + apiErrCount++ + lastSavedError = err + } + } + + if apiErrCount > 0 { + log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) + return lastSavedError + } + + return nil +} + +func differenceNetwork(oldList, newList []interface{}) *updatedNetwork { + attachMap := make([]map[string]interface{}, 0) + changeIpMap := make([]map[string]interface{}, 0) + changeMacMap := make([]map[string]interface{}, 0) + changeMTUMap := make([]map[string]interface{}, 0) + detachMap := make([]map[string]interface{}, 0) + enableMap := make([]map[string]interface{}, 0) + for _, oldNetwork := range oldList { + oldMap := oldNetwork.(map[string]interface{}) + found := false + for _, newNetwork := range newList { + newMap := newNetwork.(map[string]interface{}) + if compareNetwork(newMap, oldMap) { + found = true + if (newMap["net_type"].(string) == "EXTNET" || newMap["net_type"].(string) == "VINS") && (newMap["ip_address"] != oldMap["ip_address"] && newMap["ip_address"].(string) != "") { + changeIpMap = append(changeIpMap, newMap) + } + if newMap["mac"] != oldMap["mac"] && newMap["mac"].(string) != "" { + newMap["old_mac"] = oldMap["mac"] + changeMacMap = append(changeMacMap, newMap) + } + if (newMap["net_type"].(string) == "EXTNET" || newMap["net_type"].(string) == "DPDK") && (newMap["mtu"] != oldMap["mtu"] && newMap["mtu"].(int) != 0) { + changeMTUMap = append(changeMTUMap, newMap) + } + if newMap["enabled"].(bool) != oldMap["enabled"].(bool) { + mac, _ := newMap["mac"].(string) + if mac == "" { + newMap["mac"] = oldMap["mac"] + } + enableMap = append(enableMap, newMap) + } + } + if found { + break + } + } + if found { + continue + } + detachMap = append(detachMap, oldMap) + } + + for _, newNetwork := range newList { + newMap := newNetwork.(map[string]interface{}) + found := false + for _, oldNetwork := range oldList { + oldMap := oldNetwork.(map[string]interface{}) + if compareNetwork(newMap, oldMap) { + found = true + break + } + } + if found { + continue + } + attachMap = append(attachMap, newMap) + } + + res := updatedNetwork{ + DetachMap: detachMap, + ChangeIPMap: changeIpMap, + ChangeMacMap: changeMacMap, + ChangeMTUMap: changeMTUMap, + AttachMap: attachMap, + EnableMap: enableMap, + } + + return &res +} + +func compareNetwork(newMap, oldMap map[string]interface{}) bool { + return newMap["net_type"] == oldMap["net_type"] && newMap["net_id"] == oldMap["net_id"] && newMap["sdn_interface_id"] == oldMap["sdn_interface_id"] && newMap["weight"] == oldMap["weight"] +} + +func hasDPDKnetwork(networkAttachMap []map[string]interface{}) bool { + for _, elem := range networkAttachMap { + if elem["net_type"].(string) == "DPDK" { + return true + } + } + return false +} + +// addAttachedNetwork adds libvirt_settings of attached networks to the libvirt_settings settings list +func addAttachedNetwork(addedLibvirtSettings []interface{}, newLibvirtSettings []interface{}, networkAttachMap []map[string]interface{}) (addedLibvirtSettingsMap []map[string]interface{}) { + addedLibvirtSettingsMap = make([]map[string]interface{}, 0) + + for _, attach := range networkAttachMap { + found := false + for _, elem := range addedLibvirtSettings { + addedLVSMap := elem.(map[string]interface{}) + if attach["net_id"] == addedLVSMap["net_id"] && attach["net_type"] == addedLVSMap["net_type"] { + found = true + break + } + } + if found { + continue + } + for _, elem := range newLibvirtSettings { + newVirtSettingMap := elem.(map[string]interface{}) + if attach["net_id"] == newVirtSettingMap["net_id"] && attach["net_type"] == newVirtSettingMap["net_type"] { + addedLibvirtSettingsMap = append(addedLibvirtSettingsMap, newVirtSettingMap) + found = true + break + } + } + } + + for _, elem := range addedLibvirtSettings { + addedLVSMap := elem.(map[string]interface{}) + addedLibvirtSettingsMap = append(addedLibvirtSettingsMap, addedLVSMap) + } + + return +} + +func utilityComputeSecGroupsConfigure(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + simpleCompRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + return err + } + + apiErrCount := 0 + var lastSavedError error + + oldSecGroups, newSecGroups := d.GetChange("security_groups") + updateSecGroups := (newSecGroups.(*schema.Set).Difference(oldSecGroups.(*schema.Set))).List() + + log.Debugf("utilityComputeSecGroupsConfigure: update security groups has %d items for Compute ID %s", len(updateSecGroups), d.Id()) + if len(updateSecGroups) > 0 { + for _, elem := range updateSecGroups { + secGroupsMap := elem.(map[string]interface{}) + + netType := secGroupsMap["net_type"].(string) + netId := uint64(secGroupsMap["net_id"].(int)) + var mac string + for _, iface := range simpleCompRec.Interfaces { + if iface.NetID == netId && iface.NetType == netType { + mac = iface.MAC + break + } + } + if mac == "" { + log.Errorf("utilityComputeSecGroupsConfigure: Network with type %s and id %d is not connected to the compute %s", + netType, netId, d.Id()) + apiErrCount++ + lastSavedError = errors.New(fmt.Sprintf("utilityComputeSecGroupsConfigure: Network with type %s and id %d is not connected to the compute %s", + netType, netId, d.Id())) + continue + } + secGroupsIDs := make([]uint64, 0) + for _, id := range secGroupsMap["security_groups"].(*schema.Set).List() { + secGroupsIDs = append(secGroupsIDs, uint64(id.(int))) + } + log.Debugf("utilityComputeSecGroupsConfigure: Configure security groups interface parameters on Network with type %s and id %d", netType, netId) + req := compute.ChangeSecGroupsRequest{ + ComputeID: computeId, + Interface: mac, + SecGroups: secGroupsIDs, + } + + if secGroupsMap["enable_secgroups"] != nil { + req.EnableSecGroups = secGroupsMap["enable_secgroups"].(bool) + } + + _, err := c.CloudBroker().Compute().ChangeSecGroups(ctx, req) + if err != nil { + apiErrCount++ + lastSavedError = err + } + } + } + + if apiErrCount > 0 { + log.Errorf("utilityComputeSecGroupsConfigure: there were %d error(s) when managing security groups of Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) + return lastSavedError + } + + return nil +} + +func utilityComputeUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + req := compute.UpdateRequest{ + ComputeID: computeId, + } + + if d.HasChange("name") { + req.Name = d.Get("name").(string) + } + if d.HasChange("description") { + req.Description = d.Get("description").(string) + } + if d.HasChange("numa_affinity") { + req.NumaAffinity = d.Get("numa_affinity").(string) + } + if d.HasChange("chipset") { + req.Chipset = d.Get("chipset").(string) + } + if d.HasChange("clock") { + req.Clock = d.Get("clock").(string) + } + + if d.HasChange("loader_type") { + req.LoaderType = d.Get("loader_type").(string) + } + + if d.HasChange("boot_type") { + req.BootType = d.Get("boot_type").(string) + } + + if d.HasChange("hot_resize") { + req.HotResize = d.Get("hot_resize").(bool) + } + + if d.HasChange("network_interface_naming") { + req.NetworkInterfaceNaming = d.Get("network_interface_naming").(string) + } + + if d.HasChange("os_version") { + req.OSVersion = d.Get("os_version").(string) + } + + if d.HasChange("weight") { + req.Weight = uint64(d.Get("weight").(int)) + } + + req.CPUPin = d.Get("cpu_pin").(bool) + req.HPBacked = d.Get("hp_backed").(bool) + req.AutoStart = d.Get("auto_start_w_node").(bool) + + if d.HasChange("preferred_cpu") { + if preferredCPU, ok := d.GetOk("preferred_cpu"); ok { + preferredList := preferredCPU.([]interface{}) + if len(preferredList) > 0 { + for _, v := range preferredList { + cpuNum := v.(int) + req.PreferredCPU = append(req.PreferredCPU, int64(cpuNum)) + } + } + } + oldPCPU, newPCPU := d.GetChange("preferred_cpu") + if len(oldPCPU.([]interface{})) != 0 && len(newPCPU.([]interface{})) == 0 { + req.PreferredCPU = []int64{-1} + } + } + + // Note bene: numa_affinity, cpu_pin and hp_backed are not allowed to be changed for compute in STARTED tech status. + // If STARTED, we need to stop it before update + var isStopRequired bool + if d.HasChanges("numa_affinity", "cpu_pin", "hp_backed", "chipset", "preferred_cpu", "hot_resize") && d.Get("started").(bool) { + isStopRequired = true + } + if isStopRequired { + stopReq := compute.StopRequest{ + ComputeID: computeId, + Force: false, + } + + if _, err := c.CloudBroker().Compute().Stop(ctx, stopReq); err != nil { + return err + } + } + + // perform update + if _, err := c.CloudBroker().Compute().Update(ctx, req); err != nil { + return err + } + + // If used to be STARTED, we need to start it after update + if isStopRequired { + req := compute.StartRequest{ComputeID: computeId} + if altBootID, ok := d.Get("alt_boot_id").(int); ok { + req.AltBootID = uint64(altBootID) + } + if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil { + return err + } + } + + return nil +} + +func utilityComputeUpdateAffinityLabel(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + affinityLabel := d.Get("affinity_label").(string) + if affinityLabel == "" { + req := compute.AffinityLabelRemoveRequest{ + ComputeIDs: []uint64{computeId}, + } + + _, err := c.CloudBroker().Compute().AffinityLabelRemove(ctx, req) + if err != nil { + return err + } + } + + req := compute.AffinityLabelSetRequest{ + ComputeIDs: []uint64{computeId}, + AffinityLabel: affinityLabel, + } + + _, err := c.CloudBroker().Compute().AffinityLabelSet(ctx, req) + if err != nil { + return err + } + + return nil +} + +func utilityComputeUpdateAffinityRules(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + deletedAR := make([]interface{}, 0) + addedAR := make([]interface{}, 0) + + oldAR, newAR := d.GetChange("affinity_rules") + oldConv := oldAR.([]interface{}) + newConv := newAR.([]interface{}) + + if len(newConv) == 0 { + req := compute.AffinityRulesClearRequest{ + ComputeIDs: []uint64{computeId}, + } + + _, err := c.CloudBroker().Compute().AffinityRulesClear(ctx, req) + if err != nil { + return err + } + } else { + for _, el := range oldConv { + if !isContainsAR(newConv, el) { + deletedAR = append(deletedAR, el) + } + } + for _, el := range newConv { + if !isContainsAR(oldConv, el) { + addedAR = append(addedAR, el) + } + } + + if len(deletedAR) > 0 { + for _, ar := range deletedAR { + arConv := ar.(map[string]interface{}) + req := compute.AffinityRuleRemoveRequest{ + ComputeIDs: []uint64{computeId}, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudBroker().Compute().AffinityRuleRemove(ctx, req) + if err != nil { + return err + } + } + } + if len(addedAR) > 0 { + for _, ar := range addedAR { + arConv := ar.(map[string]interface{}) + req := compute.AffinityRuleAddRequest{ + ComputeIDs: []uint64{computeId}, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudBroker().Compute().AffinityRuleAdd(ctx, req) + if err != nil { + return err + } + } + } + } + + return nil +} + +func utilityComputeUpdateAntiAffinityRules(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + deletedAR := make([]interface{}, 0) + addedAR := make([]interface{}, 0) + + oldAR, newAR := d.GetChange("anti_affinity_rules") + oldConv := oldAR.([]interface{}) + newConv := newAR.([]interface{}) + + if len(newConv) == 0 { + req := compute.AntiAffinityRulesClearRequest{ + ComputeIDs: []uint64{computeId}, + } + + _, err := c.CloudBroker().Compute().AntiAffinityRulesClear(ctx, req) + if err != nil { + return err + } + } else { + for _, el := range oldConv { + if !isContainsAR(newConv, el) { + deletedAR = append(deletedAR, el) + } + } + for _, el := range newConv { + if !isContainsAR(oldConv, el) { + addedAR = append(addedAR, el) + } + } + + if len(deletedAR) > 0 { + for _, ar := range deletedAR { + arConv := ar.(map[string]interface{}) + req := compute.AntiAffinityRuleRemoveRequest{ + ComputeIDs: []uint64{computeId}, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudBroker().Compute().AntiAffinityRuleRemove(ctx, req) + if err != nil { + return err + } + } + } + if len(addedAR) > 0 { + for _, ar := range addedAR { + arConv := ar.(map[string]interface{}) + req := compute.AntiAffinityRuleAddRequest{ + ComputeIDs: []uint64{computeId}, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudBroker().Compute().AntiAffinityRuleAdd(ctx, req) + if err != nil { + return err + } + } + } + } + + return nil +} + +func utilityComputeUpdatePciDevices(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + oldSet, newSet := d.GetChange("pci_devices") + deletedDevices := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedDevices) > 0 { + for _, ar := range deletedDevices { + arConv := ar.(int) + req := compute.DetachPCIDeviceRequest{ + ComputeID: computeId, + DeviceID: uint64(arConv), + } + _, err := c.CloudBroker().Compute().DetachPciDevice(ctx, req) + if err != nil { + return err + } + } + } + + added := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(added) > 0 { + for _, ar := range added { + arConv := ar.(int) + req := compute.AttachPCIDeviceRequest{ + ComputeID: computeId, + DeviceID: uint64(arConv), + } + + _, err := c.CloudBroker().Compute().AttachPCIDevice(ctx, req) + if err != nil { + return err + } + } + } + + return nil +} + +func utilityComputeUpdateTags(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + oldSet, newSet := d.GetChange("tags") + deletedTags := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedTags) > 0 { + for _, tagInterface := range deletedTags { + tagItem := tagInterface.(map[string]interface{}) + req := compute.TagRemoveRequest{ + ComputeIDs: []uint64{computeId}, + Key: tagItem["key"].(string), + } + + _, err := c.CloudBroker().Compute().TagRemove(ctx, req) + if err != nil { + return err + } + } + } + + addedTags := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedTags) > 0 { + for _, tagInterface := range addedTags { + tagItem := tagInterface.(map[string]interface{}) + req := compute.TagAddRequest{ + ComputeIDs: []uint64{computeId}, + Key: tagItem["key"].(string), + Value: tagItem["value"].(string), + } + + _, err := c.CloudBroker().Compute().TagAdd(ctx, req) + if err != nil { + return err + } + } + } + + return nil +} + +func utilityComputeUpdatePFW(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + oldSet, newSet := d.GetChange("port_forwarding") + deletedPfws := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedPfws) > 0 { + for _, pfwInterface := range deletedPfws { + pfwItem := pfwInterface.(map[string]interface{}) + req := compute.PFWDelRequest{ + ComputeID: computeId, + PublicPortStart: uint64(pfwItem["public_port_start"].(int)), + Proto: pfwItem["proto"].(string), + RuleID: uint64(pfwItem["rule_id"].(int)), + } + if pfwItem["local_port"].(int) != 0 { + req.LocalBasePort = uint64(pfwItem["local_port"].(int)) + } + if pfwItem["public_port_end"].(int) == -1 { + req.PublicPortEnd = req.PublicPortStart + } else { + req.PublicPortEnd = uint64(pfwItem["public_port_end"].(int)) + } + + _, err := c.CloudBroker().Compute().PFWDel(ctx, req) + if err != nil { + return err + } + } + } + + addedPfws := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedPfws) > 0 { + for _, pfwInterface := range addedPfws { + pfwItem := pfwInterface.(map[string]interface{}) + req := compute.PFWAddRequest{ + ComputeID: computeId, + PublicPortStart: uint64(pfwItem["public_port_start"].(int)), + PublicPortEnd: int64(pfwItem["public_port_end"].(int)), + Proto: pfwItem["proto"].(string), + } + if pfwItem["local_port"].(int) != 0 { + req.LocalBasePort = uint64(pfwItem["local_port"].(int)) + } + + pwfId, err := c.CloudBroker().Compute().PFWAdd(ctx, req) + if err != nil { + return err + } + d.Set("rule_id", pwfId) + } + } + + return nil +} + +func utilityComputeRestore(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + restoreReq := compute.RestoreRequest{ComputeID: computeId} + + _, err := c.CloudBroker().Compute().Restore(ctx, restoreReq) + if err != nil { + return err + } + + if _, ok := d.GetOk("enabled"); ok { + if err := utilityComputeEnabled(ctx, d, m); err != nil { + return err + } + } + + if _, ok := d.GetOk("started"); ok { + if err := utilityComputeStarted(ctx, d, m); err != nil { + return err + } + } + + return nil +} + +func utilityComputeUpdateUserAccess(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + oldSet, newSet := d.GetChange("user_access") + deletedUserAcess := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedUserAcess) > 0 { + for _, userAcessInterface := range deletedUserAcess { + userAccessItem := userAcessInterface.(map[string]interface{}) + req := compute.UserRevokeRequest{ + ComputeID: computeId, + Username: userAccessItem["username"].(string), + } + + _, err := c.CloudBroker().Compute().UserRevoke(ctx, req) + if err != nil { + return err + } + } + } + + addedUserAccess := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedUserAccess) > 0 { + for _, userAccessInterface := range addedUserAccess { + userAccessItem := userAccessInterface.(map[string]interface{}) + req := compute.UserGrantRequest{ + ComputeID: computeId, + Username: userAccessItem["username"].(string), + AccessType: userAccessItem["access_type"].(string), + } + + _, err := c.CloudBroker().Compute().UserGrant(ctx, req) + if err != nil { + return err + } + } + } + + return nil +} + +func utilityComputeUpdateSnapshot(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + oldSet, newSet := d.GetChange("snapshot") + deletedSnapshots := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedSnapshots) > 0 { + for _, snapshotInterface := range deletedSnapshots { + snapshotItem := snapshotInterface.(map[string]interface{}) + req := compute.SnapshotDeleteRequest{ + ComputeID: computeId, + Label: snapshotItem["label"].(string), + } + + asyncMode, ok := d.GetOk("snapshot_delete_async") + if ok && asyncMode.(bool) { + _, err := c.CloudBroker().Compute().SnapshotDeleteAsync(ctx, req) + if err != nil { + return err + } + } else { + _, err := c.CloudBroker().Compute().SnapshotDelete(ctx, req) + if err != nil { + return err + } + } + } + } + + addedSnapshots := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedSnapshots) > 0 { + for _, snapshotInterface := range addedSnapshots { + snapshotItem := snapshotInterface.(map[string]interface{}) + req := compute.SnapshotCreateRequest{ + ComputeID: computeId, + Label: snapshotItem["label"].(string), + } + + _, err := c.CloudBroker().Compute().SnapshotCreate(ctx, req) + if err != nil { + return err + } + } + } + + return nil +} + +func utilityComputeRollback(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + if rollback, ok := d.GetOk("rollback"); ok { + req := compute.StopRequest{ + ComputeID: computeId, + Force: false, + } + + _, err := c.CloudBroker().Compute().Stop(ctx, req) + if err != nil { + return err + } + + rollbackInterface := rollback.(*schema.Set).List()[0] + rollbackItem := rollbackInterface.(map[string]interface{}) + + rollbackReq := compute.SnapshotRollbackRequest{ + ComputeID: computeId, + Label: rollbackItem["label"].(string), + } + + _, err = c.CloudBroker().Compute().SnapshotRollback(ctx, rollbackReq) + if err != nil { + return err + } + + startReq := compute.StartRequest{ComputeID: computeId} + if altBootID, ok := d.Get("alt_boot_id").(int); ok { + startReq.AltBootID = uint64(altBootID) + } + + log.Debugf("utilityComputeRollback: starting compute %d", computeId) + + _, err = c.CloudBroker().Compute().Start(ctx, startReq) + if err != nil { + return err + } + } + + return nil +} + +func utilityComputeUpdateCD(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + oldSet, newSet := d.GetChange("cd") + deletedCd := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + if len(deletedCd) > 0 { + req := compute.CDEjectRequest{ + ComputeID: computeId, + } + + _, err := c.CloudBroker().Compute().CDEject(ctx, req) + if err != nil { + return err + } + } + + addedCd := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + if len(addedCd) > 0 { + cdItem := addedCd[0].(map[string]interface{}) + req := compute.CDInsertRequest{ + ComputeID: computeId, + CDROMID: uint64(cdItem["cdrom_id"].(int)), + } + + _, err := c.CloudBroker().Compute().CDInsert(ctx, req) + if err != nil { + return err + } + } + return nil +} + +func utilityComputePinToNode(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + oldPin, newPin := d.GetChange("pin_to_node") + if oldPin.(bool) && !newPin.(bool) { + req := compute.UnpinFromNodeRequest{ + ComputeID: computeId, + } + + _, err := c.CloudBroker().Compute().UnpinFromNode(ctx, req) + if err != nil { + return err + } + } + if !oldPin.(bool) && newPin.(bool) { + start, _ := d.GetOk("started") + _, nodeOk := d.GetOk("node_id") + + if !start.(bool) && !nodeOk { + return errors.New("cannot pin to node a VM, that is not started and node_id is not set") + } + + req := compute.PinToNodeRequest{ + ComputeID: computeId, + TargetNodeID: uint64(d.Get("node_id").(int)), + } + + if force, ok := d.Get("force_pin").(bool); ok { + req.Force = force + } + + if autoStart, ok := d.Get("auto_start_w_node").(bool); ok { + req.AutoStart = autoStart + } + + _, err := c.CloudBroker().Compute().PinToNode(ctx, req) + if err != nil { + return err + } + } + return nil +} + +func utilityComputePause(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + oldPause, newPause := d.GetChange("pause") + if oldPause.(bool) && !newPause.(bool) { + req := compute.ResumeRequest{ + ComputeID: computeId, + } + _, err := c.CloudBroker().Compute().Resume(ctx, req) + if err != nil { + return err + } + } + if !oldPause.(bool) && newPause.(bool) { + req := compute.PauseRequest{ + ComputeID: computeId, + } + + _, err := c.CloudBroker().Compute().Pause(ctx, req) + if err != nil { + return err + } + } + return nil +} + +func utilityComputeReset(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + oldReset, newReset := d.GetChange("reset") + if !oldReset.(bool) && newReset.(bool) { + req := compute.ResetRequest{ + ComputeID: computeId, + } + _, err := c.CloudBroker().Compute().Reset(ctx, req) + if err != nil { + return err + } + } + return nil +} + +func utilityComputeUpdateImage(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + oldImage, newImage := d.GetChange("image_id") + stopReq := compute.StopRequest{ + ComputeID: computeId, + Force: false, + } + if forceStop, ok := d.GetOk("force_stop"); ok { + stopReq.Force = forceStop.(bool) + } + + _, err := c.CloudBroker().Compute().Stop(ctx, stopReq) + if err != nil { + return err + } + + if oldImage.(int) != newImage.(int) { + req := compute.RedeployRequest{ + ComputeID: computeId, + ImageID: uint64(newImage.(int)), + DataDisks: "KEEP", + StoragePolicyID: uint64(d.Get("storage_policy_id").(int)), + } + + if diskSize, ok := d.GetOk("boot_disk_size"); ok { + req.DiskSize = uint64(diskSize.(int)) + } + if autoStart, ok := d.GetOk("started"); ok { + req.AutoStart = autoStart.(bool) + } + if forceStop, ok := d.GetOk("force_stop"); ok { + req.ForceStop = forceStop.(bool) + } + + if osVersion, ok := d.GetOk("os_version"); ok { + req.OSVersion = osVersion.(string) + } + + _, err := c.CloudBroker().Compute().Redeploy(ctx, req) + if err != nil { + return err + } + } + return nil +} + +func utilityComputeUpdateZoneID(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + req := compute.MigrateToZoneRequest{ + ComputeID: computeId, + } + + zoneID, ok := d.GetOk("zone_id") + if ok { + req.ZoneID = uint64(zoneID.(int)) + } + + _, err := c.CloudBroker().Compute().MigrateToZone(ctx, req) + if err != nil { + return err + } + + return nil +} + +func utilityComputeUpdateCustomFields(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + val := d.Get("custom_fields").(string) + val = strings.ReplaceAll(val, "\\", "") + val = strings.ReplaceAll(val, "\n", "") + val = strings.ReplaceAll(val, "\t", "") + val = strings.TrimSpace(val) + + if len(val) > 0 { + req := compute.SetCustomFieldsRequest{ + ComputeID: computeId, + CustomFields: val, + } + + _, err := c.CloudBroker().Compute().SetCustomFields(ctx, req) + if err != nil { + return err + } + } else { + req := compute.DeleteCustomFieldsRequest{ + ComputeID: computeId, + } + + _, err := c.CloudBroker().Compute().DeleteCustomFields(ctx, req) + if err != nil { + return err + } + } + return nil +} + +func utilityComputeStop(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + req := compute.StopRequest{ + Force: true, + } + req.ComputeID = uint64(d.Get("compute_id").(int)) + + log.Debugf("utilityComputeStop: stopping compute %d", req.ComputeID) + _, err := c.CloudBroker().Compute().Stop(ctx, req) + if err != nil { + return err + } + return nil +} + +func utilityComputeStart(ctx context.Context, computeID uint64, altBootID uint64, m interface{}) (int, error) { + c := m.(*controller.ControllerCfg) + startReq := compute.StartRequest{ComputeID: computeID} + + if altBootID != 0 { + startReq.AltBootID = altBootID + } + + log.Debugf("utilityComputeStart: starting compute %d", computeID) + _, err := c.CloudBroker().Compute().Start(ctx, startReq) + if err != nil { + return 1, err + } + return 0, nil +} + +func utilityComputeCreateBlockSize(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + diskList := d.Get("disks").([]interface{}) + + blockSizeArr := make([]string, 0, len(diskList)) + hasAny := false + for _, elem := range diskList { + diskVal := elem.(map[string]interface{}) + bs := diskVal["block_size"].(string) + blockSizeArr = append(blockSizeArr, bs) + if bs != "" { + hasAny = true + } + } + + if !hasAny { + return nil + } + + computeRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + return err + } + bootDisk := findBootDisk(computeRec.Disks, computeRec.Chipset) + computeDisksIDs := getComputeDiskIDs(computeRec.Disks, diskList, d.Get("extra_disks").(*schema.Set).List(), bootDisk.ID) + + for i, diskID := range computeDisksIDs { + if i >= len(blockSizeArr) || blockSizeArr[i] == "" { + continue + } + req := disks.UpdateRequest{ + DiskID: diskID.(uint64), + BlockSize: blockSizeArr[i], + } + _, err := c.CloudBroker().Disks().Update(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func utilityComputeCreateIOTune(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + diskList := d.Get("disks").([]interface{}) + + iotuneArr := make([]interface{}, 0, len(diskList)) + hasAny := false + for _, elem := range diskList { + diskVal := elem.(map[string]interface{}) + iotune := diskVal["iotune"].([]interface{}) + iotuneArr = append(iotuneArr, iotune) + if len(iotune) > 0 { + hasAny = true + } + } + + if !hasAny { + return nil + } + + computeRec, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + return err + } + bootDisk := findBootDisk(computeRec.Disks, computeRec.Chipset) + computeDisksIDs := getComputeDiskIDs(computeRec.Disks, diskList, d.Get("extra_disks").(*schema.Set).List(), bootDisk.ID) + + for i, diskID := range computeDisksIDs { + if i >= len(iotuneArr) { + continue + } + iotune, ok := iotuneArr[i].([]interface{}) + if !ok || len(iotune) == 0 { + continue + } + iotuneMap := iotune[0].(map[string]interface{}) + req := disks.LimitIORequest{ + DiskID: diskID.(uint64), + ReadBytesSec: uint64(iotuneMap["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotuneMap["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotuneMap["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotuneMap["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotuneMap["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotuneMap["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotuneMap["total_bytes_sec_max"].(int)), + TotalIOPSSec: uint64(iotuneMap["total_iops_sec"].(int)), + TotalIOPSSecMax: uint64(iotuneMap["total_iops_sec_max"].(int)), + WriteBytesSec: uint64(iotuneMap["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotuneMap["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotuneMap["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotuneMap["write_iops_sec_max"].(int)), + } + _, err := c.CloudBroker().Disks().LimitIO(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func utilityComputeCreatePresentDisk(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + var errs error + diskList := d.Get("disks") + presentArr := make([]interface{}, 0) + for _, elem := range diskList.([]interface{}) { + diskVal := elem.(map[string]interface{}) + presentArr = append(presentArr, diskVal["node_ids"]) + } + + computeRec, err := utilityComputeCheckPresence(ctx, d, m) + bootDisk := findBootDisk(computeRec.Disks, computeRec.Chipset) + if err != nil { + errs = errors.Join(err) + } + computeDisksIDs := getComputeDiskIDs(computeRec.Disks, d.Get("disks").([]interface{}), d.Get("extra_disks").(*schema.Set).List(), bootDisk.ID) + + for i, diskID := range computeDisksIDs { + if len(presentArr) <= i || presentArr[i] == nil { + continue + } + presentIDs := presentArr[i].(*schema.Set).List() + + if len(presentIDs) > 0 { + log.Debugf("resourceComputeCreate: start presents disk ID:%d to nodes", diskID) + } + + for _, presentID := range presentIDs { + nodeID := uint64(presentID.(int)) + + req := disks.PresentRequest{ + DiskID: diskID.(uint64), + NodeID: nodeID, + } + + _, err := c.CloudBroker().Disks().Present(ctx, req) + if err != nil { + errs = errors.Join(err) + } + } + } + + return errs +} + +func isResizeDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) && + elOldConv["size"].(int) != elConv["size"].(int) { + return true + } + } + return false +} + +func isRenameDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) && + elOldConv["disk_name"].(string) != elConv["disk_name"].(string) { + return true + } + } + return false +} + +func isChangeCacheDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) && + elOldConv["cache"].(string) != elConv["cache"].(string) { + return true + } + } + return false +} + +func isChangeDiscardDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) && + elOldConv["discard"].(string) != elConv["discard"].(string) { + return true + } + } + return false +} + +func isChangeBlockSizeDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) && + elOldConv["block_size"].(string) != elConv["block_size"].(string) { + return true + } + } + return false +} + +func isChangeIOTuneDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) != elConv["disk_id"].(int) { + continue + } + oldIOTune := elOldConv["iotune"].([]interface{}) + newIOTune := elConv["iotune"].([]interface{}) + if len(oldIOTune) == 0 && len(newIOTune) == 0 { + return false + } + if len(oldIOTune) == 0 || len(newIOTune) == 0 { + return true + } + oldMap := oldIOTune[0].(map[string]interface{}) + newMap := newIOTune[0].(map[string]interface{}) + return oldMap["read_bytes_sec"].(int) != newMap["read_bytes_sec"].(int) || + oldMap["read_bytes_sec_max"].(int) != newMap["read_bytes_sec_max"].(int) || + oldMap["read_iops_sec"].(int) != newMap["read_iops_sec"].(int) || + oldMap["read_iops_sec_max"].(int) != newMap["read_iops_sec_max"].(int) || + oldMap["size_iops_sec"].(int) != newMap["size_iops_sec"].(int) || + oldMap["total_bytes_sec"].(int) != newMap["total_bytes_sec"].(int) || + oldMap["total_bytes_sec_max"].(int) != newMap["total_bytes_sec_max"].(int) || + oldMap["total_iops_sec"].(int) != newMap["total_iops_sec"].(int) || + oldMap["total_iops_sec_max"].(int) != newMap["total_iops_sec_max"].(int) || + oldMap["write_bytes_sec"].(int) != newMap["write_bytes_sec"].(int) || + oldMap["write_bytes_sec_max"].(int) != newMap["write_bytes_sec_max"].(int) || + oldMap["write_iops_sec"].(int) != newMap["write_iops_sec"].(int) || + oldMap["write_iops_sec_max"].(int) != newMap["write_iops_sec_max"].(int) + } + return false +} + +func isChangeStoragePolicy(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) && + elOldConv["storage_policy_id"].(int) != elConv["storage_policy_id"].(int) { + return true + } + } + return false +} + +func isMigrateDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) && + elOldConv["disk_id"].(int) != 0 { + sepIDChanged := elOldConv["sep_id"].(int) != elConv["sep_id"].(int) + poolChanged := elOldConv["pool"].(string) != elConv["pool"].(string) + if sepIDChanged || poolChanged { + return true + } + } + } + return false +} + +func isContainsDisk(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) { + return true + } + } + return false +} + +// isChangeNodesDisk get slice of new disks values and current value disk, +// if need change nodes on disk returns true and new disk value, else return false and nil +func isChangeNodesDisk(els []interface{}, elOld interface{}) (bool, interface{}) { + for _, elNew := range els { + elNewConv := elNew.(map[string]interface{}) + elOldConv := elOld.(map[string]interface{}) + if elOldConv["disk_id"].(int) == elNewConv["disk_id"].(int) { + newArr := elNewConv["node_ids"] + oldArr := elOldConv["node_ids"] + presentID := (newArr.(*schema.Set).Difference(oldArr.(*schema.Set))).List() + depresentID := (oldArr.(*schema.Set).Difference(newArr.(*schema.Set))).List() + if len(presentID) > 0 || len(depresentID) > 0 { + return true, elNew + } + return false, nil + } + } + return false, nil +} + +func utilityComputeMigrateDisks(ctx context.Context, d *schema.ResourceData, m interface{}, migratedDisks, oldDisks []interface{}) error { + c := m.(*controller.ControllerCfg) + + for _, disk := range migratedDisks { + diskConv := disk.(map[string]interface{}) + + oldDiskID := uint64(diskConv["disk_id"].(int)) + if oldDiskID == 0 { + log.Debugf("utilityComputeMigrateDisks: skipping disk with id=0") + continue + } + + newSepID := uint64(diskConv["sep_id"].(int)) + newPool := diskConv["pool"].(string) + storagePolicyID := uint64(diskConv["storage_policy_id"].(int)) + + log.Debugf("utilityComputeMigrateDisks: migrating disk_id=%d to sep_id=%d, pool=%s", oldDiskID, newSepID, newPool) + + migrateReq := disks.MigrateRequest{ + DiskID: oldDiskID, + SEPID: newSepID, + PoolName: newPool, + StoragePolicyID: storagePolicyID, + } + + taskID, err := c.CloudBroker().Disks().Migrate(ctx, migrateReq) + if err != nil { + return fmt.Errorf("failed to start disk migration for disk_id=%d: %w", oldDiskID, err) + } + + log.Debugf("utilityComputeMigrateDisks: disk migration started, taskID=%s", taskID) + + newDiskID, err := utilityComputeWaitForMigrationTask(ctx, c, taskID, oldDiskID) + if err != nil { + return fmt.Errorf("disk migration task failed for disk_id=%d: %w", oldDiskID, err) + } + + log.Debugf("utilityComputeMigrateDisks: disk migration completed, old_disk_id=%d, new_disk_id=%d", oldDiskID, newDiskID) + + } + + return nil +} + +func utilityComputeWaitForMigrationTask(ctx context.Context, c *controller.ControllerCfg, taskID string, oldDiskID uint64) (uint64, error) { + + for { + + time.Sleep(15 * time.Second) + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(taskID, `"`), + } + + taskInfo, err := c.CloudBroker().Tasks().Get(ctx, taskReq) + if err != nil { + return 0, fmt.Errorf("failed to get task status: %w", err) + } + + log.Debugf("utilityComputeWaitForMigrationTask: taskID=%s, completed=%t, status=%s", taskID, taskInfo.Completed, taskInfo.Status) + + if taskInfo.Completed { + if taskInfo.Error != "" { + return 0, fmt.Errorf("migration task failed with error: %s", taskInfo.Error) + } + + resultStr, err := taskInfo.Result.ToString() + if err != nil { + return 0, fmt.Errorf("failed to get task result: %w", err) + } + + log.Debugf("utilityComputeWaitForMigrationTask: migration result: %s", resultStr) + + newDiskID, err := extractNewDiskIDFromResult(resultStr) + if err != nil { + return 0, fmt.Errorf("failed to parse migration result: %w", err) + } + + return newDiskID, nil + } + } + +} + +func extractNewDiskIDFromResult(result string) (uint64, error) { + re := regexp.MustCompile(`Disk ID \d+ successfully migrated to Disk ID (\d+)`) + matches := re.FindStringSubmatch(result) + + if len(matches) < 2 { + return 0, fmt.Errorf("could not extract new disk ID from result: %s", result) + } + + newDiskID, err := strconv.ParseUint(matches[1], 10, 64) + if err != nil { + return 0, fmt.Errorf("failed to parse new disk ID: %w", err) + } + + return newDiskID, nil +} + +func isContainsAR(els []interface{}, el interface{}) bool { + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + elConv := el.(map[string]interface{}) + if elOldConv["key"].(string) == elConv["key"].(string) && + elOldConv["value"].(string) == elConv["value"].(string) && + elOldConv["mode"].(string) == elConv["mode"].(string) && + elOldConv["topology"].(string) == elConv["topology"].(string) && + elOldConv["policy"].(string) == elConv["policy"].(string) { + return true + } + } + return false +} + +func getComputeDiskIDs(disksList compute.ListDisks, disksBlocks, extraDisks []interface{}, bootDiskId uint64) []interface{} { + res := make([]interface{}, 0) + + if len(disksBlocks) == 0 { + return res + } + + sort.Slice(disksList, func(i, j int) bool { + return disksList[i].ID < disksList[j].ID + }) + + for _, disk := range disksList { + if disk.ID == bootDiskId || findInExtraDisks(uint(disk.ID), extraDisks) { //skip main bootdisk and extraDisks + continue + } + + res = append(res, disk.ID) + } + + return res +} + +func enabledNetwork(rawNetworkConfig cty.Value, netID uint64, netType string) bool { + for _, netConfigVal := range rawNetworkConfig.AsValueSlice() { + if netConfigVal.IsNull() { + continue + } + + netConfig := netConfigVal.AsValueMap() + + tempID, _ := netConfig["net_id"].AsBigFloat().Int64() + configNetID := uint64(tempID) + + configNetType := netConfig["net_type"].AsString() + + if configNetID == netID && configNetType == netType { + enabledVal := netConfig["enabled"] + return !enabledVal.IsNull() + } + } + + return false +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_affinity_relations.go b/internal/service/cloudbroker/kvmvm/utility_compute_affinity_relations.go new file mode 100644 index 00000000..93e3f5f6 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_affinity_relations.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeAffinityRelationsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.RecordAffinityRelations, error) { + c := m.(*controller.ControllerCfg) + req := compute.AffinityRelationsRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + affinityRelations, err := c.CloudBroker().Compute().AffinityRelations(ctx, req) + if err != nil { + return nil, err + } + + return affinityRelations, nil +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_audits.go b/internal/service/cloudbroker/kvmvm/utility_compute_audits.go new file mode 100644 index 00000000..b2ccfdfa --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_audits.go @@ -0,0 +1,80 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListDetailedAudits, error) { + c := m.(*controller.ControllerCfg) + req := compute.AuditsRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + if timestampAt, ok := d.GetOk("timestamp_at"); ok { + req.TimestampAT = uint64(timestampAt.(int)) + } + if timestampTo, ok := d.GetOk("timestamp_to"); ok { + req.TimestampTO = uint64(timestampTo.(int)) + } + if user, ok := d.GetOk("user"); ok { + req.User = user.(string) + } + if call, ok := d.GetOk("call"); ok { + req.Call = call.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if minStatusCode, ok := d.GetOk("min_status_code"); ok { + req.MinStatusCode = uint64(minStatusCode.(int)) + } + if maxStatusCode, ok := d.GetOk("max_status_code"); ok { + req.MaxStatusCode = uint64(maxStatusCode.(int)) + } + computeAudits, err := c.CloudBroker().Compute().Audits(ctx, req) + if err != nil { + return compute.ListDetailedAudits{}, err + } + return *computeAudits, nil +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_boot_disk.go b/internal/service/cloudbroker/kvmvm/utility_compute_boot_disk.go new file mode 100644 index 00000000..999db72e --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_boot_disk.go @@ -0,0 +1,57 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, +Nikita Sorokin, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" +) + +func utilityComputeBootDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemDisk, error) { + computeRecord, err := utilityComputeCheckPresence(ctx, d, m) + if err != nil { + return nil, err + } + + bootDisk := &compute.ItemDisk{} + for _, disk := range computeRecord.Disks { + if disk.Name == "bootdisk" { + *bootDisk = disk + break + } + } + return bootDisk, nil +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_boot_order_get.go b/internal/service/cloudbroker/kvmvm/utility_compute_boot_order_get.go new file mode 100644 index 00000000..e314d104 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_boot_order_get.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeBootOrderGetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]string, error) { + c := m.(*controller.ControllerCfg) + + req := compute.BootOrderGetRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + result, err := c.CloudBroker().Compute().BootOrderGet(ctx, req) + if err != nil { + return nil, err + } + + return result, nil +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_cpu_alignment_profile.go b/internal/service/cloudbroker/kvmvm/utility_compute_cpu_alignment_profile.go new file mode 100644 index 00000000..01aa11b2 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_cpu_alignment_profile.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeUpdateCPUAlignmentProfile(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + + profileName := d.Get("cpu_alignment_profile").(string) + if profileName == "" { + req := compute.DeleteCPUAlignmentProfileRequest{ + ComputeIDs: []uint64{computeId}, + } + _, err := c.CloudBroker().Compute().DeleteCPUAlignmentProfile(ctx, req) + return err + } + + req := compute.SetCPUAlignmentProfileRequest{ + ComputeIDs: []int64{int64(computeId)}, + CPUAlignmentProfile: profileName, + } + _, err := c.CloudBroker().Compute().SetCPUAlignmentProfile(ctx, req) + return err +} + +func utilityComputeGetCPUAlignmentProfile(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.CPUAlignmentProfile, error) { + c := m.(*controller.ControllerCfg) + req := compute.GetCPUAlignmentProfileRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + return c.CloudBroker().Compute().GetCPUAlignmentProfile(ctx, req) +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_get_audits.go b/internal/service/cloudbroker/kvmvm/utility_compute_get_audits.go new file mode 100644 index 00000000..4fe73ef2 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_get_audits.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeGetAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListAudits, error) { + c := m.(*controller.ControllerCfg) + req := compute.GetAuditsRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + computeAudits, err := c.CloudBroker().Compute().GetAudits(ctx, req) + if err != nil { + return nil, err + } + + return computeAudits, nil +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_get_console_url.go b/internal/service/cloudbroker/kvmvm/utility_compute_get_console_url.go new file mode 100644 index 00000000..d9287d34 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_get_console_url.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeGetConsoleUrlCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + + req := compute.GetConsoleURLRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + computeConsoleUrl, err := c.CloudBroker().Compute().GetConsoleURL(ctx, req) + if err != nil { + return "", err + } + + return computeConsoleUrl, nil +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_get_log.go b/internal/service/cloudbroker/kvmvm/utility_compute_get_log.go new file mode 100644 index 00000000..3e9ff2a7 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_get_log.go @@ -0,0 +1,56 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeGetLogCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + req := compute.GetLogRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + Path: d.Get("path").(string), + } + + computeGetLog, err := c.CloudBroker().Compute().GetLog(ctx, req) + if err != nil { + return "", err + } + + return computeGetLog, nil +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_list.go b/internal/service/cloudbroker/kvmvm/utility_compute_list.go new file mode 100644 index 00000000..26ca50ea --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_list.go @@ -0,0 +1,119 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "regexp" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDataComputeListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListComputes, error) { + c := m.(*controller.ControllerCfg) + req := compute.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if rgName, ok := d.GetOk("rg_name"); ok { + req.RGName = rgName.(string) + } + if rgId, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgId.(int)) + } + if techStatus, ok := d.GetOk("tech_status"); ok { + req.TechStatus = techStatus.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if ipAddress, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ipAddress.(string) + } + if nodeID, ok := d.GetOk("node_id"); ok { + req.NodeID = nodeID.(uint64) + } + if nodeName, ok := d.GetOk("node_name"); ok { + req.NodeName = nodeName.(string) + } + if cdImageID, ok := d.GetOk("cd_image_id"); ok { + req.CDImageID = cdImageID.(uint64) + } + if extNetName, ok := d.GetOk("extnet_name"); ok { + req.ExtNetName = extNetName.(string) + } + if extnetId, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnetId.(int)) + } + if includeDeleted, ok := d.GetOk("includedeleted"); ok { + req.IncludeDeleted = includeDeleted.(bool) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + listComputes, err := c.CloudBroker().Compute().List(ctx, req) + if err != nil { + return nil, err + } + + return listComputes, nil +} + +func matchComputes(computeList *compute.ListComputes) *compute.ListComputes { + matched, _ := regexp.Compile(`[a-zA-Z]+\\d+-[a-zA-Z]+\\d+-[a-zA-Z]+\\d+`) + result := computeList.FilterFunc(func(ic compute.ItemCompute) bool { + res := matched.Match([]byte(ic.Name)) + return !res + }) + + return &result +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_list_deleted.go b/internal/service/cloudbroker/kvmvm/utility_compute_list_deleted.go new file mode 100644 index 00000000..859dfac0 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_list_deleted.go @@ -0,0 +1,100 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + "regexp" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDataComputeListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListDeletedComputes, error) { + c := m.(*controller.ControllerCfg) + req := compute.ListDeletedRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if rgName, ok := d.GetOk("rg_name"); ok { + req.RGName = rgName.(string) + } + if rgId, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgId.(int)) + } + if techStatus, ok := d.GetOk("tech_status"); ok { + req.TechStatus = techStatus.(string) + } + if ipAddress, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ipAddress.(string) + } + if extNetName, ok := d.GetOk("extnet_name"); ok { + req.ExtNetName = extNetName.(string) + } + if extnetId, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnetId.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listComputes, err := c.CloudBroker().Compute().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return listComputes, nil +} +func matchDeletedComputes(computeList *compute.ListDeletedComputes) *compute.ListDeletedComputes { + matched, _ := regexp.Compile(`[a-zA-Z]+\\d+-[a-zA-Z]+\\d+-[a-zA-Z]+\\d+`) + result := computeList.FilterFunc(func(ic compute.ItemDeletedCompute) bool { + res := matched.Match([]byte(ic.Name)) + return !res + }) + + return &result +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_migrate_storage_info.go b/internal/service/cloudbroker/kvmvm/utility_compute_migrate_storage_info.go new file mode 100644 index 00000000..2023d826 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_migrate_storage_info.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeMigrateStorageInfoCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + + req := compute.MigrateStorageInfoRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + result, err := c.CloudBroker().Compute().MigrateStorageInfo(ctx, req) + if err != nil { + return "", err + } + + return result, nil +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_pci_device_list.go b/internal/service/cloudbroker/kvmvm/utility_compute_pci_device_list.go new file mode 100644 index 00000000..521809a2 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_pci_device_list.go @@ -0,0 +1,76 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputePCIDeviceListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListPCIDevices, error) { + c := m.(*controller.ControllerCfg) + req := compute.ListPCIDeviceRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + if rgId, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgId.(int)) + } + if devId, ok := d.GetOk("device_id"); ok { + req.DevID = uint64(devId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listPCIDevice, err := c.CloudBroker().Compute().ListPCIDevice(ctx, req) + if err != nil { + return nil, err + } + + return listPCIDevice, err +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_pfw_list.go b/internal/service/cloudbroker/kvmvm/utility_compute_pfw_list.go new file mode 100644 index 00000000..0579a256 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_pfw_list.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputePfwListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListPFW, error) { + c := m.(*controller.ControllerCfg) + req := compute.PFWListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + listPFWs, err := c.CloudBroker().Compute().PFWList(ctx, req) + if err != nil { + return nil, err + } + + return listPFWs, err +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_shapshot_usage.go b/internal/service/cloudbroker/kvmvm/utility_compute_shapshot_usage.go new file mode 100644 index 00000000..ecaffbd6 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_shapshot_usage.go @@ -0,0 +1,59 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeSnapshotUsageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListSnapshotUsage, error) { + c := m.(*controller.ControllerCfg) + req := compute.SnapshotUsageRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + if label, ok := d.GetOk("label"); ok { + req.Label = label.(string) + } + + computeSnapshotUsage, err := c.CloudBroker().Compute().SnapshotUsage(ctx, req) + if err != nil { + return nil, err + } + + return &computeSnapshotUsage, err +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_snapshot_list.go b/internal/service/cloudbroker/kvmvm/utility_compute_snapshot_list.go new file mode 100644 index 00000000..62ab5ee9 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_snapshot_list.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeSnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListSnapShot, error) { + c := m.(*controller.ControllerCfg) + req := compute.SnapshotListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + listSnapshots, err := c.CloudBroker().Compute().SnapshotList(ctx, req) + if err != nil { + return nil, err + } + + return listSnapshots, err +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_user_list.go b/internal/service/cloudbroker/kvmvm/utility_compute_user_list.go new file mode 100644 index 00000000..e59830b7 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_user_list.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeUserListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListUsers, error) { + c := m.(*controller.ControllerCfg) + req := compute.UserListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + + computeUserList, err := c.CloudBroker().Compute().UserList(ctx, req) + if err != nil { + return computeUserList, err + } + + return computeUserList, err +} diff --git a/internal/service/cloudbroker/kvmvm/utility_compute_vgpu_list.go b/internal/service/cloudbroker/kvmvm/utility_compute_vgpu_list.go new file mode 100644 index 00000000..6474eeb1 --- /dev/null +++ b/internal/service/cloudbroker/kvmvm/utility_compute_vgpu_list.go @@ -0,0 +1,76 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package kvmvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityComputeVGPUListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ListVGPUs, error) { + c := m.(*controller.ControllerCfg) + req := compute.ListVGPURequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + if GPUID, ok := d.GetOk("gpu_id"); ok { + req.GPUID = uint64(GPUID.(int)) + } + if typeVGPU, ok := d.GetOk("type"); ok { + req.Type = typeVGPU.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if includeDeleted, ok := d.GetOk("includedeleted"); ok { + req.IncludeDeleted = includeDeleted.(bool) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listVGPU, err := c.CloudBroker().Compute().ListVGPU(ctx, req) + if err != nil { + return nil, err + } + + return listVGPU, err +} diff --git a/internal/service/cloudbroker/lb/data_source_lb.go b/internal/service/cloudbroker/lb/data_source_lb.go new file mode 100644 index 00000000..85b9b075 --- /dev/null +++ b/internal/service/cloudbroker/lb/data_source_lb.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + lb, err := utilityLBCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(lb.ID, 10)) + flattenLB(d, lb) + + return nil +} + +func DataSourceLB() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLBRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dsLBSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/lb/data_source_lb_list.go b/internal/service/cloudbroker/lb/data_source_lb_list.go new file mode 100644 index 00000000..cd6a44eb --- /dev/null +++ b/internal/service/cloudbroker/lb/data_source_lb_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceLBListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + lbList, err := utilityLBListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenLBList(lbList)) + d.Set("entry_count", lbList.EntryCount) + + return nil +} + +func DataSourceLBList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLBListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dsLBListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/lb/data_source_lb_list_deleted.go b/internal/service/cloudbroker/lb/data_source_lb_list_deleted.go new file mode 100644 index 00000000..a3169b49 --- /dev/null +++ b/internal/service/cloudbroker/lb/data_source_lb_list_deleted.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceLBListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + lbList, err := utilityLBListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenLBList(lbList)) + d.Set("entry_count", lbList.EntryCount) + + return nil +} + +func DataSourceLBListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLBListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dsLBListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/lb/flattens.go b/internal/service/cloudbroker/lb/flattens.go new file mode 100644 index 00000000..40a26e56 --- /dev/null +++ b/internal/service/cloudbroker/lb/flattens.go @@ -0,0 +1,280 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenLBFrontendBind(d *schema.ResourceData, b *lb.ItemBinding, lbId int64, frontendName string) { + d.Set("lb_id", lbId) + d.Set("frontend_name", frontendName) + d.Set("name", b.Name) + d.Set("address", b.Address) + d.Set("guid", b.GUID) + d.Set("port", b.Port) +} + +func flattenLBFrontend(d *schema.ResourceData, f *lb.ItemFrontend, lbId int64) { + d.Set("lb_id", lbId) + d.Set("backend_name", f.Backend) + d.Set("name", f.Name) + d.Set("guid", f.GUID) + d.Set("bindings", flattendBindings(f.Bindings)) +} + +func flattenResourceLBBackendServer(d *schema.ResourceData, s *lb.ItemServer, lbId int64, backendName string) { + d.Set("lb_id", lbId) + d.Set("backend_name", backendName) + d.Set("name", s.Name) + d.Set("port", s.Port) + d.Set("address", s.Address) + d.Set("check", s.Check) + d.Set("guid", s.GUID) + d.Set("downinter", s.ServerSettings.DownInter) + d.Set("fall", s.ServerSettings.Fall) + d.Set("inter", s.ServerSettings.Inter) + d.Set("maxconn", s.ServerSettings.MaxConn) + d.Set("maxqueue", s.ServerSettings.MaxQueue) + d.Set("rise", s.ServerSettings.Rise) + d.Set("slowstart", s.ServerSettings.SlowStart) + d.Set("weight", s.ServerSettings.Weight) + +} + +func flattenResourceLBBackend(d *schema.ResourceData, b *lb.ItemBackend, lbId int64) { + d.Set("lb_id", lbId) + d.Set("name", b.Name) + d.Set("algorithm", b.Algorithm) + d.Set("guid", b.GUID) + d.Set("downinter", b.ServerDefaultSettings.DownInter) + d.Set("fall", b.ServerDefaultSettings.Fall) + d.Set("inter", b.ServerDefaultSettings.Inter) + d.Set("maxconn", b.ServerDefaultSettings.MaxConn) + d.Set("maxqueue", b.ServerDefaultSettings.MaxQueue) + d.Set("rise", b.ServerDefaultSettings.Rise) + d.Set("slowstart", b.ServerDefaultSettings.SlowStart) + d.Set("weight", b.ServerDefaultSettings.Weight) + d.Set("servers", flattenServers(b.Servers)) +} + +func flattenLB(d *schema.ResourceData, lb *lb.RecordLB) { + d.Set("account_id", lb.AccountID) + d.Set("ha_mode", lb.HAMode) + d.Set("ckey", lb.CKey) + d.Set("meta", flattens.FlattenMeta(lb.Meta)) + d.Set("acl", flattenACl(lb.ACL)) + d.Set("backend_haip", lb.BackendHAIP) + d.Set("backends", flattenLBBackends(lb.Backends)) + d.Set("desc", lb.Description) + d.Set("dp_api_user", lb.DPAPIUser) + d.Set("dp_api_password", lb.DPAPIPassword) + d.Set("extnet_id", lb.ExtNetID) + d.Set("frontend_haip", lb.FrontendHAIP) + d.Set("frontends", flattenFrontends(lb.Frontends)) + d.Set("gid", lb.GID) + d.Set("guid", lb.GUID) + d.Set("lb_id", lb.ID) + d.Set("manager_id", lb.ManagerId) + d.Set("manager_type", lb.ManagerType) + d.Set("image_id", lb.ImageID) + d.Set("milestones", lb.Milestones) + d.Set("name", lb.Name) + d.Set("part_k8s", lb.PartK8s) + d.Set("primary_node", flattenNode(lb.PrimaryNode)) + d.Set("rg_id", lb.RGID) + d.Set("secondary_node", flattenNode(lb.SecondaryNode)) + d.Set("status", lb.Status) + d.Set("tech_status", lb.TechStatus) + d.Set("user_managed", lb.UserManaged) + d.Set("vins_id", lb.VINSID) + d.Set("zone_id", lb.ZoneID) +} + +func flattenNode(node lb.Node) []map[string]interface{} { + temp := make([]map[string]interface{}, 0) + n := map[string]interface{}{ + "backend_ip": node.BackendIP, + "compute_id": node.ComputeID, + "frontend_ip": node.FrontendIP, + "guid": node.GUID, + "mgmt_ip": node.MGMTIP, + "network_id": node.NetworkID, + } + + temp = append(temp, n) + + return temp +} + +func flattendBindings(bs []lb.ItemBinding) []map[string]interface{} { + temp := make([]map[string]interface{}, 0, len(bs)) + for _, b := range bs { + t := map[string]interface{}{ + "address": b.Address, + "guid": b.GUID, + "name": b.Name, + "port": b.Port, + } + temp = append(temp, t) + } + return temp +} + +func flattenFrontends(fs []lb.ItemFrontend) []map[string]interface{} { + temp := make([]map[string]interface{}, 0, len(fs)) + for _, f := range fs { + t := map[string]interface{}{ + "backend": f.Backend, + "bindings": flattendBindings(f.Bindings), + "guid": f.GUID, + "name": f.Name, + } + temp = append(temp, t) + } + + return temp +} + +func flattenServers(servers []lb.ItemServer) []map[string]interface{} { + temp := make([]map[string]interface{}, 0, len(servers)) + for _, server := range servers { + t := map[string]interface{}{ + "address": server.Address, + "check": server.Check, + "guid": server.GUID, + "name": server.Name, + "port": server.Port, + "server_settings": flattenServerSettings(server.ServerSettings), + } + + temp = append(temp, t) + } + return temp +} + +func flattenServerSettings(defSet lb.ServerSettings) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "downinter": defSet.DownInter, + "fall": defSet.Fall, + "guid": defSet.GUID, + "inter": defSet.Inter, + "maxconn": defSet.MaxConn, + "maxqueue": defSet.MaxQueue, + "rise": defSet.Rise, + "slowstart": defSet.SlowStart, + "weight": defSet.Weight, + } + res = append(res, temp) + return res +} + +func flattenLBBackends(backends []lb.ItemBackend) []map[string]interface{} { + temp := make([]map[string]interface{}, 0, len(backends)) + for _, item := range backends { + t := map[string]interface{}{ + "algorithm": item.Algorithm, + "guid": item.GUID, + "name": item.Name, + "server_default_settings": flattenServerSettings(item.ServerDefaultSettings), + "servers": flattenServers(item.Servers), + } + temp = append(temp, t) + } + return temp +} + +func flattenLBList(lbl *lb.ListLB) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(lbl.Data)) + for _, lb := range lbl.Data { + temp := map[string]interface{}{ + "ha_mode": lb.HAMode, + "acl": flattenACl(lb.ACL), + "backend_haip": lb.BackendHAIP, + "backends": flattenLBBackends(lb.Backends), + "created_by": lb.CreatedBy, + "created_time": lb.CreatedTime, + "deleted_by": lb.DeletedBy, + "deleted_time": lb.DeletedTime, + "desc": lb.Description, + "dp_api_user": lb.DPAPIUser, + "dp_api_password": lb.DPAPIPassword, + "extnet_id": lb.ExtNetID, + "frontend_haip": lb.FrontendHAIP, + "frontends": flattenFrontends(lb.Frontends), + "gid": lb.GID, + "guid": lb.GUID, + "lb_id": lb.ID, + "manager_id": lb.ManagerId, + "manager_type": lb.ManagerType, + "milestones": lb.Milestones, + "name": lb.Name, + "part_k8s": lb.PartK8s, + "primary_node": flattenNode(lb.PrimaryNode), + "rg_id": lb.RGID, + "rg_name": lb.RGName, + "secondary_node": flattenNode(lb.SecondaryNode), + "status": lb.Status, + "tech_status": lb.TechStatus, + "updated_by": lb.UpdatedBy, + "updated_time": lb.UpdatedTime, + "user_managed": lb.UserManaged, + "vins_id": lb.VINSID, + "zone_id": lb.ZoneID, + } + res = append(res, temp) + } + return res +} + +func flattenACl(m interface{}) string { + + switch d := m.(type) { + case string: + return d + case int: + return strconv.Itoa(d) + case int64: + return strconv.FormatInt(d, 10) + case float64: + return strconv.FormatInt(int64(d), 10) + default: + return "" + } + +} diff --git a/internal/service/cloudbroker/lb/resource_check_input_values.go b/internal/service/cloudbroker/lb/resource_check_input_values.go new file mode 100644 index 00000000..e2949832 --- /dev/null +++ b/internal/service/cloudbroker/lb/resource_check_input_values.go @@ -0,0 +1,34 @@ +package lb + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" +) + +func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + errs := []error{} + + if err := ic.ExistRG(ctx, uint64(d.Get("rg_id").(int)), c); err != nil { + errs = append(errs, err) + } + + if err := ic.ExistExtNetInLb(ctx, uint64(d.Get("extnet_id").(int)), c); err != nil { + errs = append(errs, err) + } + + if err := ic.ExistVinsInLb(ctx, uint64(d.Get("vins_id").(int)), c); err != nil { + errs = append(errs, err) + } + + return dc.ErrorsToDiagnostics(errs) +} + +func checkParamsExistenceLb(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + err := ic.ExistLB(ctx, uint64(d.Get("lb_id").(int)), c) + return diag.FromErr(err) +} diff --git a/internal/service/cloudbroker/lb/resource_lb.go b/internal/service/cloudbroker/lb/resource_lb.go new file mode 100644 index 00000000..4838ddda --- /dev/null +++ b/internal/service/cloudbroker/lb/resource_lb.go @@ -0,0 +1,600 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBCreate called with name: %s", d.Get("name").(string)) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + req := lb.CreateRequest{ + Name: d.Get("name").(string), + RGID: uint64(d.Get("rg_id").(int)), + ExtNetID: int64(d.Get("extnet_id").(int)), + VINSID: uint64(d.Get("vins_id").(int)), + } + if start, ok := d.GetOk("start"); ok { + req.Start = start.(bool) + } + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + if haMode, ok := d.GetOk("ha_mode"); ok { + req.HighlyAvailable = haMode.(bool) + } + if sysctlParams, ok := d.GetOk("sysctl_params"); ok { + syscrlSliceMaps := sysctlParams.([]interface{}) + res := make([]map[string]interface{}, 0, len(syscrlSliceMaps)) + for _, syscrlMap := range syscrlSliceMaps { + tempMap := make(map[string]interface{}) + for k, v := range syscrlMap.(map[string]interface{}) { + if intVal, err := strconv.Atoi(v.(string)); err == nil { + tempMap[k] = intVal + continue + } + tempMap[k] = v.(string) + } + res = append(res, tempMap) + } + req.SysctlParams = res + } + + lbId, err := c.CloudBroker().LB().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(lbId, 10)) + d.Set("lb_id", lbId) + + var warnings dc.Warnings + + if enable, ok := d.GetOk("enable"); ok { + if enable.(bool) { + if err := resourceLbEnable(ctx, lbId, m); err != nil { + warnings.Add(err) + } + } else { + if err := resourceLbDisable(ctx, lbId, m); err != nil { + warnings.Add(err) + } + } + } + + return append(warnings.Get(), resourceLBRead(ctx, d, m)...) +} + +func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBRead called for lb_id %s", d.Id()) + + // c := m.(*controller.ControllerCfg) + + lbRec, err := utilityLBCheckPresence(ctx, d, m) + if lbRec == nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch lbRec.Status { + case status.Modeled: + return diag.Errorf("The LB is in status: %s, please, contact support for more information", lbRec.Status) + case status.Creating: + case status.Created: + case status.Deleting: + case status.Deleted: + // lbId, _ := strconv.ParseUint(d.Id(), 10, 64) + // restoreReq := lb.RestoreRequest{LBID: lbId} + + // _, err := c.CloudBroker().LB().Restore(ctx, restoreReq) + // if err != nil { + // return diag.FromErr(err) + // } + + // if enable := d.Get("enable"); enable.(bool) { + // req := lb.EnableRequest{ + // LBID: lbId, + // } + // _, err := c.CloudBroker().LB().Enable(ctx, req) + // if err != nil { + // return diag.FromErr(err) + // } + // } + // if start := d.Get("start"); start.(bool) { + // if enable := d.Get("enable"); enable.(bool) { + // req := lb.StartRequest{ + // LBID: lbId, + // } + // _, err := c.CloudBroker().LB().Start(ctx, req) + // if err != nil { + // return diag.FromErr(err) + // } + // } else { + // return diag.Errorf("To start the LB, please, enable LB first.") + // } + // } + + // hasChanged = true + case status.Destroying: + return diag.Errorf("The LB is in progress with status: %s", lbRec.Status) + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be read because it has been destroyed") + // return resourceLBCreate(ctx, d, m) + case status.Enabled: + case status.Enabling: + case status.Disabling: + case status.Disabled: + log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lbRec.Status) + case status.Restoring: + } + + if hasChanged { + lbRec, err = utilityLBCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + flattenLB(d, lbRec) + + return nil +} + +func resourceLBDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBDelete called with lb id: %v", d.Get("lb_id").(int)) + + _, err := utilityLBCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := lb.DeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + + if permanently, ok := d.GetOk("permanently"); ok { + req.Permanently = permanently.(bool) + } + + _, err = c.CloudBroker().LB().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBUpdate called for lb_id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + lbRec, err := utilityLBCheckPresence(ctx, d, m) + if lbRec == nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch lbRec.Status { + case status.Modeled: + return diag.Errorf("The LB is in status: %s, please, contact support for more information", lbRec.Status) + case status.Creating: + case status.Created: + case status.Deleting: + case status.Deleted: + restore, ok := d.GetOk("restore") + if ok && restore.(bool) { + if err := resourceLbRestore(ctx, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } + + enable, ok := d.GetOk("enable") + if ok && enable.(bool) { + if err := resourceLbEnable(ctx, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } + + start, ok := d.GetOk("start") + if ok && start.(bool) { + if enable.(bool) { + if err := resourceLbStart(ctx, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } else { + return diag.Errorf("to start the LB, please, enable LB first.") + } + } + + hasChanged = true + case status.Destroying: + return diag.Errorf("The LB is in progress with status: %s", lbRec.Status) + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceLBCreate(ctx, d, m) + case status.Enabled: + case status.Enabling: + case status.Disabling: + case status.Disabled: + log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lbRec.Status) + case status.Restoring: + } + + if hasChanged { + _, err = utilityLBCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChange("enable") { + if err := resourceLbChangeEnable(ctx, d, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("ha_mode") { + if err := resourceLbChangeHaMode(ctx, d, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("zone_id") { + if err := resourceLbChangeZoneID(ctx, d, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("sysctl_params") { + if err := resourceLbChangeSysctlParams(ctx, d, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("start") { + if err := resourceLbChangeStart(ctx, d, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("desc") { + if err := resourceLbChangeDesc(ctx, d, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("restart") { + if err := resourceLbChangeRestart(ctx, d, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("config_reset") { + if err := resourceLbChangeConfigReset(ctx, d, lbRec.ID, m); err != nil { + return diag.FromErr(err) + } + } + + return resourceLBRead(ctx, d, m) +} + +func resourceLbEnable(ctx context.Context, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + req := lb.EnableRequest{ + LBID: lbId, + } + _, err := c.CloudBroker().LB().Enable(ctx, req) + return err +} + +func resourceLbChangeSysctlParams(ctx context.Context, d *schema.ResourceData, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + syscrlSliceMaps := d.Get("sysctl_params").([]interface{}) + res := make([]map[string]interface{}, 0, len(syscrlSliceMaps)) + for _, syscrlMap := range syscrlSliceMaps { + tempMap := make(map[string]interface{}) + for k, v := range syscrlMap.(map[string]interface{}) { + if intVal, err := strconv.Atoi(v.(string)); err == nil { + tempMap[k] = intVal + continue + } + tempMap[k] = v.(string) + } + res = append(res, tempMap) + } + if len(res) > 0 { + req := lb.UpdateSysctParamsRequest{ + LBID: lbId, + SysctlParams: res, + } + _, err := c.CloudBroker().LB().UpdateSysctlParams(ctx, req) + return err + } + return nil +} + +func resourceLbDisable(ctx context.Context, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + req := lb.DisableRequest{ + LBID: lbId, + } + _, err := c.CloudBroker().LB().Disable(ctx, req) + return err +} + +func resourceLbRestore(ctx context.Context, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + restoreReq := lb.RestoreRequest{ + LBID: lbId, + } + _, err := c.CloudBroker().LB().Restore(ctx, restoreReq) + return err +} + +func resourceLbStart(ctx context.Context, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + req := lb.StartRequest{ + LBID: lbId, + } + _, err := c.CloudBroker().LB().Start(ctx, req) + return err +} + +func resourceLbChangeEnable(ctx context.Context, d *schema.ResourceData, lbId uint64, m interface{}) error { + enable := d.Get("enable").(bool) + + if enable { + if err := resourceLbEnable(ctx, lbId, m); err != nil { + return err + } + } else { + if err := resourceLbDisable(ctx, lbId, m); err != nil { + return err + } + } + + return nil +} + +func resourceLbChangeHaMode(ctx context.Context, d *schema.ResourceData, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + haModeOn := d.Get("ha_mode").(bool) + + if haModeOn { + req := lb.HighlyAvailableRequest{ + LBID: lbId, + } + + if _, err := c.CloudBroker().LB().HighlyAvailable(ctx, req); err != nil { + return err + } + } + + return nil +} + +func resourceLbChangeZoneID(ctx context.Context, d *schema.ResourceData, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + start := d.Get("start").(bool) + + if start { + reqStop := lb.StopRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + + _, err := c.CloudBroker().LB().Stop(ctx, reqStop) + if err != nil { + return err + } + } + + req := lb.MigrateToZoneRequest{ + LBID: uint64(d.Get("lb_id").(int)), + ZoneID: uint64(d.Get("zone_id").(int)), + } + + _, err := c.CloudBroker().LB().MigrateToZone(ctx, req) + if err != nil { + return err + } + + if start { + reqStart := lb.StartRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + + _, err = c.CloudBroker().LB().Start(ctx, reqStart) + if err != nil { + return err + } + } + + return nil +} + +func resourceLbChangeStart(ctx context.Context, d *schema.ResourceData, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + start := d.Get("start").(bool) + + if start { + req := lb.StartRequest{LBID: lbId} + if _, err := c.CloudBroker().LB().Start(ctx, req); err != nil { + return err + } + } else { + req := lb.StopRequest{LBID: lbId} + if _, err := c.CloudBroker().LB().Stop(ctx, req); err != nil { + return err + } + } + + return nil +} + +func resourceLbChangeDesc(ctx context.Context, d *schema.ResourceData, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + desc := d.Get("desc").(string) + + req := lb.UpdateRequest{ + LBID: lbId, + Description: desc, + } + + if _, err := c.CloudBroker().LB().Update(ctx, req); err != nil { + return err + } + + return nil +} + +func resourceLbChangeRestart(ctx context.Context, d *schema.ResourceData, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + restart := d.Get("restart").(bool) + if restart { + req := lb.RestartRequest{ + LBID: lbId, + } + if safe, ok := d.GetOk("safe"); ok { + req.Safe = safe.(bool) + } + + if _, err := c.CloudBroker().LB().Restart(ctx, req); err != nil { + return err + } + } + + return nil +} + +func resourceLbChangeRestore(ctx context.Context, d *schema.ResourceData, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + restore := d.Get("restore").(bool) + if restore { + req := lb.RestoreRequest{ + LBID: lbId, + } + + if _, err := c.CloudBroker().LB().Restore(ctx, req); err != nil { + return err + } + } + + return nil +} + +func resourceLbChangeConfigReset(ctx context.Context, d *schema.ResourceData, lbId uint64, m interface{}) error { + c := m.(*controller.ControllerCfg) + + cfgReset := d.Get("config_reset").(bool) + if cfgReset { + req := lb.ConfigResetRequest{ + LBID: lbId, + } + + if _, err := c.CloudBroker().LB().ConfigReset(ctx, req); err != nil { + return err + } + } + + return nil +} + +func ResourceLB() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLBCreate, + ReadContext: resourceLBRead, + UpdateContext: resourceLBUpdate, + DeleteContext: resourceLBDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: lbResourceSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/lb/resource_lb_backend.go b/internal/service/cloudbroker/lb/resource_lb_backend.go new file mode 100644 index 00000000..6dbb3796 --- /dev/null +++ b/internal/service/cloudbroker/lb/resource_lb_backend.go @@ -0,0 +1,212 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceLBBackendCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendCreate: call for lb_backend id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistenceLb(ctx, d, c); diags != nil { + return diags + } + + req := lb.BackendCreateRequest{ + LBID: uint64(d.Get("lb_id").(int)), + BackendName: d.Get("name").(string), + } + + if algorithm, ok := d.GetOk("algorithm"); ok { + req.Algorithm = algorithm.(string) + } + if inter, ok := d.GetOk("inter"); ok { + req.Inter = uint64(inter.(int)) + } + if downinter, ok := d.GetOk("downinter"); ok { + req.DownInter = uint64(downinter.(int)) + } + if rise, ok := d.GetOk("rise"); ok { + req.Rise = uint64(rise.(int)) + } + if fall, ok := d.GetOk("fall"); ok { + req.Fall = uint64(fall.(int)) + } + if slowstart, ok := d.GetOk("slowstart"); ok { + req.SlowStart = uint64(slowstart.(int)) + } + if maxconn, ok := d.GetOk("maxconn"); ok { + req.MaxConn = uint64(maxconn.(int)) + } + if maxqueue, ok := d.GetOk("maxqueue"); ok { + req.MaxQueue = uint64(maxqueue.(int)) + } + if weight, ok := d.GetOk("weight"); ok { + req.Weight = uint64(weight.(int)) + } + + _, err := c.CloudBroker().LB().BackendCreate(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("name").(string)) + + return resourceLBBackendRead(ctx, d, m) +} + +func resourceLBBackendRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendRead: call for lb_backend id %s", d.Id()) + + b, err := utilityLBBackendCheckPresence(ctx, d, m) + if b == nil { + d.SetId("") + return diag.FromErr(err) + } + + lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) + + flattenResourceLBBackend(d, b, lbId) + + return nil +} + +func resourceLBBackendDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendDelete: call for lb_backend id %s", d.Id()) + + _, err := utilityLBBackendCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := lb.BackendDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + BackendName: d.Get("name").(string), + } + + _, err = c.CloudBroker().LB().BackendDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceLBBackendUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendUpdate: call for lb_backend id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistenceLb(ctx, d, c); diags != nil { + return diags + } + + req := lb.BackendUpdateRequest{ + LBID: uint64(d.Get("lb_id").(int)), + BackendName: d.Get("name").(string), + } + + if algorithm, ok := d.GetOk("algorithm"); ok { + req.Algorithm = algorithm.(string) + } + if inter, ok := d.GetOk("inter"); ok { + req.Inter = uint64(inter.(int)) + } + if downinter, ok := d.GetOk("downinter"); ok { + req.DownInter = uint64(downinter.(int)) + } + if rise, ok := d.GetOk("rise"); ok { + req.Rise = uint64(rise.(int)) + } + if fall, ok := d.GetOk("fall"); ok { + req.Fall = uint64(fall.(int)) + } + if slowstart, ok := d.GetOk("slowstart"); ok { + req.SlowStart = uint64(slowstart.(int)) + } + if maxconn, ok := d.GetOk("maxconn"); ok { + req.MaxConn = uint64(maxconn.(int)) + } + if maxqueue, ok := d.GetOk("maxqueue"); ok { + req.MaxQueue = uint64(maxqueue.(int)) + } + if weight, ok := d.GetOk("weight"); ok { + req.Weight = uint64(weight.(int)) + } + + _, err := c.CloudBroker().LB().BackendUpdate(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + return resourceLBBackendRead(ctx, d, m) +} + +func ResourceLBBackend() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLBBackendCreate, + ReadContext: resourceLBBackendRead, + UpdateContext: resourceLBBackendUpdate, + DeleteContext: resourceLBBackendDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceLbBackendSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/lb/resource_lb_backend_server.go b/internal/service/cloudbroker/lb/resource_lb_backend_server.go new file mode 100644 index 00000000..bb449519 --- /dev/null +++ b/internal/service/cloudbroker/lb/resource_lb_backend_server.go @@ -0,0 +1,223 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceLBBackendServerCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendServerCreate: call for lb_id %d, backend_name %s, server_name %s", + d.Get("lb_id").(int), + d.Get("backend_name").(string), + d.Get("name").(string)) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistenceLb(ctx, d, c); diags != nil { + return diags + } + + req := lb.BackendServerAddRequest{ + BackendName: d.Get("backend_name").(string), + ServerName: d.Get("name").(string), + Address: d.Get("address").(string), + LBID: uint64(d.Get("lb_id").(int)), + Port: uint64(d.Get("port").(int)), + } + + if check, ok := d.GetOk("check"); ok { + req.Check = check.(string) + } + if inter, ok := d.GetOk("inter"); ok { + req.Inter = uint64(inter.(int)) + } + if downinter, ok := d.GetOk("downinter"); ok { + req.DownInter = uint64(downinter.(int)) + } + if rise, ok := d.GetOk("rise"); ok { + req.Rise = uint64(rise.(int)) + } + if fall, ok := d.GetOk("fall"); ok { + req.Fall = uint64(fall.(int)) + } + if slowstart, ok := d.GetOk("slowstart"); ok { + req.SlowStart = uint64(slowstart.(int)) + } + if maxconn, ok := d.GetOk("maxconn"); ok { + req.MaxConn = uint64(maxconn.(int)) + } + if maxqueue, ok := d.GetOk("maxqueue"); ok { + req.MaxQueue = uint64(maxqueue.(int)) + } + if weight, ok := d.GetOk("weight"); ok { + req.Weight = uint64(weight.(int)) + } + + _, err := c.CloudBroker().LB().BackendServerAdd(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("backend_name").(string) + "#" + d.Get("name").(string)) + + return resourceLBBackendServerRead(ctx, d, m) +} + +func resourceLBBackendServerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendServerRead: call for id %s", d.Id()) + + s, err := utilityLBBackendServerCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) + backendName := strings.Split(d.Id(), "#")[1] + + flattenResourceLBBackendServer(d, s, lbId, backendName) + + return nil +} + +func resourceLBBackendServerDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendServerDelete: call for id %s", d.Id()) + + _, err := utilityLBBackendServerCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := lb.BackendServerDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + BackendName: d.Get("backend_name").(string), + ServerName: d.Get("name").(string), + } + + _, err = c.CloudBroker().LB().BackendServerDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + d.SetId("") + + return nil +} + +func resourceLBBackendServerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBBackendServerEdit: call for id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistenceLb(ctx, d, c); diags != nil { + return diags + } + + req := lb.BackendServerUpdateRequest{ + BackendName: d.Get("backend_name").(string), + LBID: uint64(d.Get("lb_id").(int)), + ServerName: d.Get("name").(string), + Address: d.Get("address").(string), + Port: uint64(d.Get("port").(int)), + } + + if check, ok := d.GetOk("check"); ok { + req.Check = check.(string) + } + if inter, ok := d.GetOk("inter"); ok { + req.Inter = uint64(inter.(int)) + } + if downinter, ok := d.GetOk("downinter"); ok { + req.DownInter = uint64(downinter.(int)) + } + if rise, ok := d.GetOk("rise"); ok { + req.Rise = uint64(rise.(int)) + } + if fall, ok := d.GetOk("fall"); ok { + req.Fall = uint64(fall.(int)) + } + if slowstart, ok := d.GetOk("slowstart"); ok { + req.SlowStart = uint64(slowstart.(int)) + } + if maxconn, ok := d.GetOk("maxconn"); ok { + req.MaxConn = uint64(maxconn.(int)) + } + if maxqueue, ok := d.GetOk("maxqueue"); ok { + req.MaxQueue = uint64(maxqueue.(int)) + } + if weight, ok := d.GetOk("weight"); ok { + req.Weight = uint64(weight.(int)) + } + + _, err := c.CloudBroker().LB().BackendServerUpdate(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + return resourceLBBackendServerRead(ctx, d, m) +} + +func ResourceLBBackendServer() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLBBackendServerCreate, + ReadContext: resourceLBBackendServerRead, + UpdateContext: resourceLBBackendServerUpdate, + DeleteContext: resourceLBBackendServerDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceLbBackendServerSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/lb/resource_lb_frontend.go b/internal/service/cloudbroker/lb/resource_lb_frontend.go new file mode 100644 index 00000000..962bdf7a --- /dev/null +++ b/internal/service/cloudbroker/lb/resource_lb_frontend.go @@ -0,0 +1,145 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceLBFrontendCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendCreate: call for lb_id %d, backend %s to create frontend %s", + d.Get("lb_id").(int), + d.Get("backend_name").(string), + d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistenceLb(ctx, d, c); diags != nil { + return diags + } + + req := lb.FrontendCreateRequest{ + BackendName: d.Get("backend_name").(string), + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("name").(string), + } + + _, err := c.CloudBroker().LB().FrontendCreate(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("name").(string)) + + return resourceLBFrontendRead(ctx, d, m) +} + +func resourceLBFrontendRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendRead: call for id %s", d.Id()) + + f, err := utilityLBFrontendCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) + + flattenLBFrontend(d, f, lbId) + + return nil +} + +func resourceLBFrontendDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendDelete: call for id %s", d.Id()) + + _, err := utilityLBFrontendCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := lb.FrontendDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("name").(string), + } + + _, err = c.CloudBroker().LB().FrontendDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceLBFrontendEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + return nil +} + +func ResourceLBFrontend() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLBFrontendCreate, + ReadContext: resourceLBFrontendRead, + UpdateContext: resourceLBFrontendEdit, + DeleteContext: resourceLBFrontendDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceLbFrontendSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/lb/resource_lb_frontend_bind.go b/internal/service/cloudbroker/lb/resource_lb_frontend_bind.go new file mode 100644 index 00000000..9cc5b9f5 --- /dev/null +++ b/internal/service/cloudbroker/lb/resource_lb_frontend_bind.go @@ -0,0 +1,171 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceLBFrontendBindCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendBindCreate: call for lb_id %d, frontend %s to create bind %s", + d.Get("lb_id").(int), + d.Get("frontend_name").(string), + d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistenceLb(ctx, d, c); diags != nil { + return diags + } + + req := lb.FrontendBindRequest{ + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("frontend_name").(string), + BindingName: d.Get("name").(string), + BindingAddress: d.Get("address").(string), + BindingPort: uint64(d.Get("port").(int)), + } + + _, err := c.CloudBroker().LB().FrontendBind(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("frontend_name").(string) + "#" + d.Get("name").(string)) + + return resourceLBFrontendBindRead(ctx, d, m) +} + +func resourceLBFrontendBindRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendBindRead: call for %s", d.Id()) + + b, err := utilityLBFrontendBindCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) + frontendName := strings.Split(d.Id(), "#")[1] + + flattenLBFrontendBind(d, b, lbId, frontendName) + + return nil +} + +func resourceLBFrontendBindDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendBindDelete: call for %s", d.Id()) + + _, err := utilityLBFrontendBindCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := lb.FrontendBindDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("frontend_name").(string), + BindingName: d.Get("name").(string), + } + + _, err = c.CloudBroker().LB().FrontendBindDelete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceLBFrontendBindUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLBFrontendBindEdit: call for %s", d.Id()) + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistenceLb(ctx, d, c); diags != nil { + return diags + } + + req := lb.FrontendBindUpdateRequest{ + FrontendName: d.Get("frontend_name").(string), + BindingName: d.Get("name").(string), + LBID: uint64(d.Get("lb_id").(int)), + } + + if d.HasChange("address") || d.HasChange("port") { + req.BindingAddress = d.Get("address").(string) + req.BindingPort = uint64(d.Get("port").(int)) + } + + _, err := c.CloudBroker().LB().FrontendBindUpdate(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + return resourceLBFrontendBindRead(ctx, d, m) +} + +func ResourceLBFrontendBind() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLBFrontendBindCreate, + ReadContext: resourceLBFrontendBindRead, + UpdateContext: resourceLBFrontendBindUpdate, + DeleteContext: resourceLBFrontendBindDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceLbFrontendBindSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/lb/schema.go b/internal/service/cloudbroker/lb/schema.go new file mode 100644 index 00000000..89efc98a --- /dev/null +++ b/internal/service/cloudbroker/lb/schema.go @@ -0,0 +1,1980 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dsLBSchemaMake() map[string]*schema.Schema { + sch := map[string]*schema.Schema{ + "lb_id": { + Type: schema.TypeInt, + Required: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ha_mode": { + Type: schema.TypeBool, + Computed: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "backend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "backends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "algorithm": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "server_default_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "servers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "check": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + "server_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dp_api_password": { + Type: schema.TypeString, + Computed: true, + }, + "dp_api_user": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "frontends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend": { + Type: schema.TypeString, + Computed: true, + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "part_k8s": { + Type: schema.TypeBool, + Computed: true, + }, + "primary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "secondary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return sch +} + +func dsLBListDeletedSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by Account ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by TechStatus", + }, + "front_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by FrontIP", + }, + "back_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by BackIP", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ha_mode": { + Type: schema.TypeBool, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "backend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "backends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "algorithm": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "server_default_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "servers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "check": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + "server_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dp_api_user": { + Type: schema.TypeString, + Computed: true, + }, + "dp_api_password": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "frontends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend": { + Type: schema.TypeString, + Computed: true, + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "part_k8s": { + Type: schema.TypeBool, + Computed: true, + }, + "primary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dsLBListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by Account ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by RG ID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by TechStatus", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by Status", + }, + "front_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by FrontIP", + }, + "back_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by BackIP", + }, + "includedeleted": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ha_mode": { + Type: schema.TypeBool, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "backend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "backends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "algorithm": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "server_default_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "servers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "check": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + "server_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dp_api_user": { + Type: schema.TypeString, + Computed: true, + }, + "dp_api_password": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "frontends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend": { + Type: schema.TypeString, + Computed: true, + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "part_k8s": { + Type: schema.TypeBool, + Computed: true, + }, + "primary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func lbResourceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "ha_mode": { + Type: schema.TypeBool, + Optional: true, + }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "desc": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + }, + "restart": { + Type: schema.TypeBool, + Optional: true, + }, + "safe": { + Type: schema.TypeBool, + Default: true, + Optional: true, + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + }, + "config_reset": { + Type: schema.TypeBool, + Optional: true, + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + }, + "sysctl_params": { + Type: schema.TypeList, + Optional: true, + Description: "Custom sysctl values for Load Balancer instance. Applied on boot", + Elem: &schema.Schema{ + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "backend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "backends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "algorithm": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "server_default_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "servers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "check": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + "server_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "dp_api_user": { + Type: schema.TypeString, + Computed: true, + }, + "dp_api_password": { + Type: schema.TypeString, + Computed: true, + }, + "frontend_haip": { + Type: schema.TypeString, + Computed: true, + }, + "frontends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend": { + Type: schema.TypeString, + Computed: true, + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "lb_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "part_k8s": { + Type: schema.TypeBool, + Computed: true, + }, + "primary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "secondary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + } +} + +func resourceLbBackendSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "lb_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the LB instance to backendCreate", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Must be unique among all backends of this LB - name of the new backend to create", + }, + "algorithm": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"roundrobin", "static-rr", "leastconn"}, false), + }, + "inter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "downinter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "servers": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "check": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "server_settings": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "downinter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "inter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + } +} + +func resourceLbBackendServerSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "lb_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the LB instance to backendCreate", + }, + "backend_name": { + Type: schema.TypeString, + Required: true, + Description: "Must be unique among all backends of this LB - name of the new backend to create", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Must be unique among all servers defined for this backend - name of the server definition to add.", + }, + "address": { + Type: schema.TypeString, + Required: true, + Description: "IP address of the server.", + }, + "port": { + Type: schema.TypeInt, + Required: true, + Description: "Port number on the server", + }, + "check": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"disabled", "enabled"}, false), + Description: "set to disabled if this server should be used regardless of its state.", + }, + "inter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "downinter": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "slowstart": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxconn": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "maxqueue": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + + "guid": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func resourceLbFrontendSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "lb_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the LB instance to backendCreate", + }, + "backend_name": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func resourceLbFrontendBindSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "lb_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the LB instance to backendCreate", + }, + "frontend_name": { + Type: schema.TypeString, + Required: true, + Description: "Must be unique among all backends of this LB - name of the new backend to create", + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "address": { + Type: schema.TypeString, + Required: true, + }, + "port": { + Type: schema.TypeInt, + Required: true, + }, + + "guid": { + Type: schema.TypeString, + Computed: true, + }, + } +} diff --git a/internal/service/cloudbroker/lb/utility_lb.go b/internal/service/cloudbroker/lb/utility_lb.go new file mode 100644 index 00000000..0e131325 --- /dev/null +++ b/internal/service/cloudbroker/lb/utility_lb.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLBCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.RecordLB, error) { + c := m.(*controller.ControllerCfg) + req := lb.GetRequest{} + + if d.Id() != "" { + rgId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.LBID = rgId + } else { + req.LBID = uint64(d.Get("lb_id").(int)) + } + + lb, err := c.CloudBroker().LB().Get(ctx, req) + if err != nil { + return nil, err + } + + return lb, nil +} diff --git a/internal/service/cloudbroker/lb/utility_lb_backend.go b/internal/service/cloudbroker/lb/utility_lb_backend.go new file mode 100644 index 00000000..9798de4b --- /dev/null +++ b/internal/service/cloudbroker/lb/utility_lb_backend.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLBBackendCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemBackend, error) { + c := m.(*controller.ControllerCfg) + req := lb.GetRequest{} + bName := d.Get("name").(string) + + if d.Id() != "" { + parameters := strings.Split(d.Id(), "#") + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + req.LBID = lbId + bName = parameters[1] + } else { + req.LBID = uint64(d.Get("lb_id").(int)) + } + + lbRec, err := c.CloudBroker().LB().Get(ctx, req) + if err != nil { + return nil, err + } + + backends := lbRec.Backends + for _, b := range backends { + if b.Name == bName { + return &b, nil + } + } + + return nil, fmt.Errorf("can not find backend with name: %s for lb: %d", bName, lbRec.ID) +} diff --git a/internal/service/cloudbroker/lb/utility_lb_backend_server.go b/internal/service/cloudbroker/lb/utility_lb_backend_server.go new file mode 100644 index 00000000..cdbecb2a --- /dev/null +++ b/internal/service/cloudbroker/lb/utility_lb_backend_server.go @@ -0,0 +1,88 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLBBackendServerCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemServer, error) { + c := m.(*controller.ControllerCfg) + req := lb.GetRequest{} + + bName := d.Get("backend_name").(string) + sName := d.Get("name").(string) + + if d.Id() != "" { + parameters := strings.Split(d.Id(), "#") + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + req.LBID = lbId + bName = parameters[1] + sName = parameters[2] + } else { + req.LBID = uint64(d.Get("lb_id").(int)) + } + + foundLB, err := c.CloudBroker().LB().Get(ctx, req) + if err != nil { + return nil, err + } + + backend := &lb.ItemBackend{} + backends := foundLB.Backends + for i, b := range backends { + if b.Name == bName { + backend = &backends[i] + break + } + } + + if backend.Name == "" { + return nil, fmt.Errorf("can not find backend with name: %s for lb: %d", bName, foundLB.ID) + } + + for _, s := range backend.Servers { + if s.Name == sName { + return &s, nil + } + } + + return nil, fmt.Errorf("can not find server with name: %s for backend: %s for lb: %d", sName, bName, foundLB.ID) +} diff --git a/internal/service/cloudbroker/lb/utility_lb_frontend.go b/internal/service/cloudbroker/lb/utility_lb_frontend.go new file mode 100644 index 00000000..18d4c904 --- /dev/null +++ b/internal/service/cloudbroker/lb/utility_lb_frontend.go @@ -0,0 +1,74 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLBFrontendCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemFrontend, error) { + c := m.(*controller.ControllerCfg) + req := lb.GetRequest{} + + fName := d.Get("name").(string) + + if d.Id() != "" { + parameters := strings.Split(d.Id(), "#") + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + req.LBID = lbId + fName = parameters[1] + } else { + req.LBID = uint64(d.Get("lb_id").(int)) + } + + foundLB, err := c.CloudBroker().LB().Get(ctx, req) + if err != nil { + return nil, err + } + + frontends := foundLB.Frontends + for _, f := range frontends { + if f.Name == fName { + return &f, nil + } + } + + return nil, fmt.Errorf("can not find frontend with name: %s for lb: %d", fName, foundLB.ID) +} diff --git a/internal/service/cloudbroker/lb/utility_lb_frontend_bind.go b/internal/service/cloudbroker/lb/utility_lb_frontend_bind.go new file mode 100644 index 00000000..adfb5c4a --- /dev/null +++ b/internal/service/cloudbroker/lb/utility_lb_frontend_bind.go @@ -0,0 +1,87 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLBFrontendBindCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemBinding, error) { + c := m.(*controller.ControllerCfg) + req := lb.GetRequest{} + + fName := d.Get("frontend_name").(string) + bName := d.Get("name").(string) + + if d.Id() != "" { + parameters := strings.Split(d.Id(), "#") + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + req.LBID = lbId + fName = parameters[1] + bName = parameters[2] + } else { + req.LBID = uint64(d.Get("lb_id").(int)) + } + + foundLB, err := c.CloudBroker().LB().Get(ctx, req) + if err != nil { + return nil, err + } + + frontend := &lb.ItemFrontend{} + frontends := foundLB.Frontends + for i, f := range frontends { + if f.Name == fName { + frontend = &frontends[i] + break + } + } + if frontend.Name == "" { + return nil, fmt.Errorf("can not find frontend with name: %s for lb: %d", fName, foundLB.ID) + } + + for _, b := range frontend.Bindings { + if b.Name == bName { + return &b, nil + } + } + + return nil, fmt.Errorf("can not find bind with name: %s for frontend: %s for lb: %d", bName, fName, foundLB.ID) +} diff --git a/internal/service/cloudbroker/lb/utility_lb_list.go b/internal/service/cloudbroker/lb/utility_lb_list.go new file mode 100644 index 00000000..75a3b91f --- /dev/null +++ b/internal/service/cloudbroker/lb/utility_lb_list.go @@ -0,0 +1,108 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityLBListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ListLB, error) { + c := m.(*controller.ControllerCfg) + req := lb.ListRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if front_ip, ok := d.GetOk("front_ip"); ok { + req.FrontIP = front_ip.(string) + } + + if back_ip, ok := d.GetOk("back_ip"); ok { + req.BackIP = back_ip.(string) + } + + if includedeleted, ok := d.GetOk("includedeleted"); ok { + req.IncludeDeleted = includedeleted.(bool) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + log.Debugf("utilityLBListCheckPresence: load lb list") + lbList, err := c.CloudBroker().LB().List(ctx, req) + if err != nil { + return nil, err + } + + return lbList, nil +} diff --git a/internal/service/cloudbroker/lb/utility_lb_list_deleted.go b/internal/service/cloudbroker/lb/utility_lb_list_deleted.go new file mode 100644 index 00000000..283ad14c --- /dev/null +++ b/internal/service/cloudbroker/lb/utility_lb_list_deleted.go @@ -0,0 +1,96 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package lb + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityLBListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ListLB, error) { + c := m.(*controller.ControllerCfg) + req := lb.ListDeletedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if front_ip, ok := d.GetOk("front_ip"); ok { + req.FrontIP = front_ip.(string) + } + + if back_ip, ok := d.GetOk("back_ip"); ok { + req.BackIP = back_ip.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityLBListDeletedCheckPresence: load lb list") + lbList, err := c.CloudBroker().LB().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return lbList, nil +} diff --git a/internal/service/cloudbroker/node/data_source_node.go b/internal/service/cloudbroker/node/data_source_node.go new file mode 100644 index 00000000..87a8104a --- /dev/null +++ b/internal/service/cloudbroker/node/data_source_node.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package node + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceNodeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + nodeRec, err := utilityNodeCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + flattenNode(d, nodeRec) + d.SetId(strconv.Itoa(d.Get("node_id").(int))) + + return nil +} + +func DataSourceNode() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceNodeRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceNodeSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/node/data_source_node_list.go b/internal/service/cloudbroker/node/data_source_node_list.go new file mode 100644 index 00000000..940a48df --- /dev/null +++ b/internal/service/cloudbroker/node/data_source_node_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package node + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceNodeListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + nodeList, err := utilityNodeListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenNodeList(nodeList)) + d.Set("entry_count", nodeList.EntryCount) + + return nil +} + +func DataSourceNodeList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceNodeListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceNodeListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/node/data_source_node_network_info.go b/internal/service/cloudbroker/node/data_source_node_network_info.go new file mode 100644 index 00000000..e3ac0a7a --- /dev/null +++ b/internal/service/cloudbroker/node/data_source_node_network_info.go @@ -0,0 +1,355 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package node + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/node" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func dataSourceNodeNetworkInfoRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + req := node.GetNetworkInfoRequest{ + NodeID: uint64(d.Get("node_id").(int)), + } + + info, err := c.CloudBroker().Node().GetNetworkInfo(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("system_networks_info", flattenSystemNetworksInfo(info.SystemNetworksInfo)) + d.Set("ovs_networks_info", flattenOVSNetworksInfo(info.OVSNetworksInfo)) + d.Set("libvirt_networks_info", flattenLibvirtNetworksInfo(info.LibvirtNetworksInfo)) + d.Set("topology", flattenNetworkTopology(info.Topology)) + + return nil +} + +func dataSourceNodeNetworkInfoSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "node_id": { + Type: schema.TypeInt, + Required: true, + Description: "Node ID", + }, + "system_networks_info": { + Type: schema.TypeList, + Computed: true, + Description: "System-level information about all network interfaces on the node", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Interface name", + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + Description: "MTU value", + }, + "speed": { + Type: schema.TypeInt, + Computed: true, + Description: "Interface link speed", + }, + "bridge_id": { + Type: schema.TypeString, + Computed: true, + Description: "Linux bridge ID", + }, + "bport_id": { + Type: schema.TypeString, + Computed: true, + Description: "Bridge port ID", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address", + }, + }, + }, + }, + "ovs_networks_info": { + Type: schema.TypeList, + Computed: true, + Description: "Raw OVS ports data", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bridge_name": { + Type: schema.TypeString, + Computed: true, + Description: "Bridge name", + }, + "bridge_tag": { + Type: schema.TypeString, + Computed: true, + Description: "Bridge tag", + }, + "interface_uuid": { + Type: schema.TypeString, + Computed: true, + Description: "Interface UUID", + }, + "interface_type": { + Type: schema.TypeString, + Computed: true, + Description: "Interface type", + }, + "interface_name": { + Type: schema.TypeString, + Computed: true, + Description: "Interface name", + }, + "interface_mtu": { + Type: schema.TypeInt, + Computed: true, + Description: "Interface MTU value", + }, + "interface_ip": { + Type: schema.TypeString, + Computed: true, + Description: "Interface IP address", + }, + "interface_mac": { + Type: schema.TypeString, + Computed: true, + Description: "Interface MAC address", + }, + "interface_peer": { + Type: schema.TypeString, + Computed: true, + Description: "Interface peer name", + }, + }, + }, + }, + "libvirt_networks_info": { + Type: schema.TypeList, + Computed: true, + Description: "VM network interface connections", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vm_name": { + Type: schema.TypeString, + Computed: true, + Description: "VM name", + }, + "interface": { + Type: schema.TypeString, + Computed: true, + Description: "Host-side interface name used by the VM", + }, + "interface_type": { + Type: schema.TypeString, + Computed: true, + Description: "Interface type", + }, + "interface_source": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the bridge the VM interface is attached to", + }, + }, + }, + }, + "topology": { + Type: schema.TypeList, + Computed: true, + Description: "Assembled network topology of the node", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "interfaces": { + Type: schema.TypeList, + Computed: true, + Description: "Network interfaces and their topology details", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Interface name", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "Interface type", + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + Description: "Interface MTU value", + }, + "speed": { + Type: schema.TypeInt, + Computed: true, + Description: "Interface link speed", + }, + "vlans": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: "VLANs associated with the interface", + }, + "bridge_id": { + Type: schema.TypeString, + Computed: true, + Description: "Linux bridge ID", + }, + "peer": { + Type: schema.TypeString, + Computed: true, + Description: "Peer interface name", + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + Description: "OVS UUID", + }, + "connected_interfaces": { + Type: schema.TypeList, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, + Description: "Names of interfaces attached to this bridge as ports", + }, + "connections": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vms": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": {Type: schema.TypeString, Computed: true}, + "vm_interface": {Type: schema.TypeString, Computed: true}, + "vm_interface_type": {Type: schema.TypeString, Computed: true}, + "connection_type": {Type: schema.TypeString, Computed: true}, + "via_bridge": {Type: schema.TypeString, Computed: true}, + }, + }, + }, + "bridges": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": {Type: schema.TypeString, Computed: true}, + "type": {Type: schema.TypeString, Computed: true}, + "via": {Type: schema.TypeString, Computed: true}, + "bport_id": {Type: schema.TypeString, Computed: true}, + "port_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": {Type: schema.TypeString, Computed: true}, + "type": {Type: schema.TypeString, Computed: true}, + "mtu": {Type: schema.TypeInt, Computed: true}, + "vlan": {Type: schema.TypeString, Computed: true}, + "uuid": {Type: schema.TypeString, Computed: true}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "bridge_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": {Type: schema.TypeString, Computed: true}, + "ports": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": {Type: schema.TypeString, Computed: true}, + "type": {Type: schema.TypeString, Computed: true}, + "mtu": {Type: schema.TypeInt, Computed: true}, + "vlan": {Type: schema.TypeString, Computed: true}, + "uuid": {Type: schema.TypeString, Computed: true}, + "ip": {Type: schema.TypeString, Computed: true}, + "mac": {Type: schema.TypeString, Computed: true}, + }, + }, + }, + }, + }, + }, + "bridge_connections": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": {Type: schema.TypeString, Computed: true}, + "via": {Type: schema.TypeString, Computed: true}, + "vlan": {Type: schema.TypeString, Computed: true}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func DataSourceNodeNetworkInfo() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + ReadContext: dataSourceNodeNetworkInfoRead, + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: dataSourceNodeNetworkInfoSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/node/data_source_node_pci_devices.go b/internal/service/cloudbroker/node/data_source_node_pci_devices.go new file mode 100644 index 00000000..f9034694 --- /dev/null +++ b/internal/service/cloudbroker/node/data_source_node_pci_devices.go @@ -0,0 +1,172 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package node + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + sdknode "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/node" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func dataSourceNodePCIDevicesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + req := sdknode.GetPCIDevicesRequest{ + NodeID: uint64(d.Get("node_id").(int)), + } + if v, ok := d.GetOk("search"); ok { + req.Search = v.(string) + } + if v, ok := d.GetOk("sort_by"); ok { + req.SortBy = v.(string) + } + if v, ok := d.GetOk("page"); ok { + req.Page = uint64(v.(int)) + } + if v, ok := d.GetOk("size"); ok { + req.Size = uint64(v.(int)) + } + + list, err := c.CloudBroker().Node().GetPCIDevices(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenNodePCIDevices(list.Data)) + d.Set("entry_count", list.EntryCount) + + return nil +} + +func dataSourceNodePCIDevicesSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "node_id": { + Type: schema.TypeInt, + Required: true, + Description: "Node ID", + }, + "search": { + Type: schema.TypeString, + Optional: true, + Description: "Search string", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "Sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "Total number of PCI devices", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "List of PCI devices", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "hw_path": { + Type: schema.TypeString, + Computed: true, + Description: "Hardware path", + }, + "current_driver": { + Type: schema.TypeString, + Computed: true, + Description: "Current driver", + }, + "numa_node": { + Type: schema.TypeInt, + Computed: true, + Description: "NUMA node", + }, + "product_id": { + Type: schema.TypeString, + Computed: true, + Description: "Product ID", + }, + "product_name": { + Type: schema.TypeString, + Computed: true, + Description: "Product name", + }, + "vendor_id": { + Type: schema.TypeString, + Computed: true, + Description: "Vendor ID", + }, + "vendor_name": { + Type: schema.TypeString, + Computed: true, + Description: "Vendor name", + }, + "iommu_group": { + Type: schema.TypeInt, + Computed: true, + Description: "IOMMU group", + }, + }, + }, + }, + } +} + +func DataSourceNodePCIDevices() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + ReadContext: dataSourceNodePCIDevicesRead, + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: dataSourceNodePCIDevicesSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/node/flattens.go b/internal/service/cloudbroker/node/flattens.go new file mode 100644 index 00000000..b491fb82 --- /dev/null +++ b/internal/service/cloudbroker/node/flattens.go @@ -0,0 +1,526 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package node + +import ( + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/node" +) + +func flattenNode(d *schema.ResourceData, item *node.RecordNode) { + log.Debugf("flattenNode: decoded node id %d", d.Get("node_id").(int)) + + d.Set("auto_start", item.AutoStart) + d.Set("auto_start_count", item.AutoStartCount) + d.Set("consumption", flattenConsumption(item.Consumption)) + d.Set("cpu_info", flattenCpuInfo(item.CpuInfo)) + d.Set("cpu_allocation_ratio", item.CPUAllocationRatio) + d.Set("mem_allocation_ratio", item.MemAllocationRatio) + d.Set("description", item.Description) + d.Set("dpdk", flattenDPDKItem(item.DPDK)) + d.Set("gid", item.GID) + d.Set("ipaddr", item.IPAddr) + d.Set("isolated_cpus", flattenNodeItem(item.IsolatedCpus)) + d.Set("name", item.Name) + d.Set("need_reboot", item.NeedReboot) + d.Set("net_addr", flattenGetNetAddr(item.NetAddr)) + d.Set("network_mode", item.NetworkMode) + d.Set("openvswitch_bridges", item.OpenvSwitchBridges) + d.Set("nic_info", flattenNicInfo(item.NicInfo)) + d.Set("numa_topology", flattenNumaTopology(item.NumaTopology)) + d.Set("reserved_cpus", flattenNodeItem(item.ReservedCPUs)) + d.Set("roles", item.Roles) + d.Set("sdn_hypervisor_name", item.SDNHypervisorName) + d.Set("sriov_enabled", item.SriovEnabled) + d.Set("node_id", item.ID) + d.Set("status", item.Status) + d.Set("to_active", flattenRole(item.ToActive)) + d.Set("to_installing", flattenRole(item.ToInstalling)) + d.Set("to_maintenance", flattenRole(item.ToMaintenance)) + d.Set("to_restricted", flattenRole(item.ToRestricted)) + d.Set("version", item.Version) + d.Set("zone_id", item.ZoneID) + d.Set("usable_cpus", item.UsableCPUs) +} + +func flattenConsumption(info node.ConsumptionInfo) []map[string]interface{} { + res := make([]map[string]interface{}, 1) + tempRes := map[string]interface{}{ + "hostname": info.Hostname, + } + + tempConsumed := map[string]interface{}{ + "ram": info.Consumed.RAM, + "computes": info.Consumed.Computes, + "routers": info.Consumed.Routers, + "vcpu": info.Consumed.VCPU, + } + tempRes["consumed"] = []map[string]interface{}{ + tempConsumed, + } + + tempFree := map[string]interface{}{ + "ram": info.Free.RAM, + "vcpu": info.Free.VCPU, + } + tempRes["free"] = []map[string]interface{}{ + tempFree, + } + + tempReserved := map[string]interface{}{ + "ram": info.Reserved.RAM, + } + tempRes["reserved"] = []map[string]interface{}{ + tempReserved, + } + + tempTotal := map[string]interface{}{ + "ram": info.Total.RAM, + } + tempRes["total"] = []map[string]interface{}{ + tempTotal, + } + + res[0] = tempRes + return res +} + +func flattenNodeList(nodes *node.ListNodes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(nodes.Data)) + for _, item := range nodes.Data { + temp := map[string]interface{}{ + "additional_pkgs": flattenNodeItem(item.AdditionalPkgs), + "auto_start": item.AutoStart, + "auto_start_count": item.AutoStartCount, + "cpu_info": flattenCpuInfo(item.CpuInfo), + "description": item.Description, + "dpdk": flattenDPDKItem(item.DPDK), + "gid": item.GID, + "guid": item.GUID, + "hostkey": item.HostKey, + "node_id": item.ID, + "ipaddr": item.IPAddr, + "isolated_cpus": flattenNodeItem(item.IsolatedCpus), + "lastcheck": item.LastCheck, + "machine_guid": item.MachineGUID, + "mainboard_sn": item.MainboardSN, + "memory": item.Memory, + "milestones": item.Milestones, + "model": item.Model, + "name": item.Name, + "need_reboot": item.NeedReboot, + "net_addr": flattenNetAddr(item.NetAddr), + "network_mode": item.NetworkMode, + "nic_info": flattenNicInfo(item.NicInfo), + "node_uuid": item.NodeUUID, + "numa_topology": flattenNumaTopology(item.NumaTopology), + "peer_backup": item.PeerBackup, + "peer_log": item.PeerLog, + "peer_stats": item.PeerStats, + "pgpus": item.Pgpus, + "public_keys": item.PublicKeys, + "release": item.Release, + "reserved_cpus": flattenNodeItem(item.ReservedCPUs), + "roles": item.Roles, + "sdn_hypervisor_name": item.SDNHypervisorName, + "seps": item.Seps, + "serial_num": item.SerialNum, + "sriov_enabled": item.SriovEnabled, + "status": item.Status, + "tags": item.Tags, + "type": item.Type, + "uefi_firmware_file": item.UEFIFirmwareFile, + "usable_cpus": item.UsableCPUs, + "version": item.Version, + "zone_id": item.ZoneID, + "openvswitch_bridges": item.OpenvSwitchBridges, + "api_url": item.APIUrl, + "drivers": item.Drivers, + "old_compat_lvm_id": item.OldCompatLVMID, + "cpu_allocation_ratio": item.CPUAllocationRatio, + "mem_allocation_ratio": item.MemAllocationRatio, + "packages": flattenPackages(item.Packages), + "pci_devices": flattenNodePCIDevices(item.PCIDevices), + } + res = append(res, temp) + } + return res +} + +func flattenNumaTopology(info node.NumaTopologyInfo) []map[string]interface{} { + res := make([]map[string]interface{}, 1) + tempRes := map[string]interface{}{ + "node_num": info.NodeNum, + } + resNodes := make([]map[string]interface{}, 0, len(info.Nodes)) + for _, item := range info.Nodes { + memoryTemp := []map[string]interface{}{ + { + "one_g": item.Memory.OneG, + "one_g_free": item.Memory.OneGFree, + "one_g_reserved": item.Memory.OneGReserved, + "one_g_available": item.Memory.OneGAvailable, + "one_g_used": item.Memory.OneGUsed, + "one_g_dpdk_reserved": item.Memory.OneGDPDKReserved, + "two_m": item.Memory.TwoM, + "two_m_free": item.Memory.TwoMFree, + "two_m_reserved": item.Memory.TwoMReserved, + "two_m_available": item.Memory.TwoMAvailable, + "two_m_used": item.Memory.TwoMUsed, + "total": item.Memory.Total, + }, + } + temp := map[string]interface{}{ + "cpu_list": item.CPUList, + "memory": memoryTemp, + } + resNodes = append(resNodes, temp) + } + tempRes["nodes"] = resNodes + res[0] = tempRes + return res +} + +func flattenNicInfo(infos node.ListNicInfo) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(infos)) + for _, item := range infos { + temp := map[string]interface{}{ + "driver": item.Driver, + "max_vfs": item.MaxVFS, + "numa_node": item.NumaNode, + "num_vfs": item.NumVFS, + "os_name": item.OSName, + "pci_slot": item.PCISlot, + "vf_list": flattenVFList(item.VFList), + } + res = append(res, temp) + } + return res +} + +func flattenVFList(vfList []interface{}) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vfList)) + for _, v := range vfList { + vConv := v.(map[string]interface{}) + temp := map[string]interface{}{ + "fn_id": vConv["fnId"], + "pci_slot": vConv["pciSlot"], + } + res = append(res, temp) + } + return res +} + +func flattenNetAddr(addresses node.ListNetAddr) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(addresses)) + for _, item := range addresses { + temp := map[string]interface{}{ + "cidr": item.CIDR, + "index": item.Index, + "ip": item.IP, + "mac": item.Mac, + "mtu": item.MTU, + "name": item.Name, + } + res = append(res, temp) + } + return res +} + +func flattenGetNetAddr(address node.NetAddr) []map[string]interface{} { + res := make([]map[string]interface{}, 1) + temp := map[string]interface{}{ + "ip": address.IP, + "name": address.Name, + } + res[0] = temp + return res +} + +func flattenCpuInfo(info node.CpuInfo) []map[string]interface{} { + res := make([]map[string]interface{}, 1) + temp := map[string]interface{}{ + "clock_speed": info.ClockSpeed, + "core_count": info.CoreCount, + "phys_count": info.PhysCount, + "flags": info.Flags, + "model_name": info.ModelName, + "thread_count": info.ThreadCount, + } + res[0] = temp + return res +} + +func flattenNodeItem(m []interface{}) []string { + output := []string{} + for _, item := range m { + switch d := item.(type) { + case string: + output = append(output, d) + case int: + output = append(output, strconv.Itoa(d)) + case int64: + output = append(output, strconv.FormatInt(d, 10)) + case float64: + output = append(output, strconv.FormatInt(int64(d), 10)) + default: + output = append(output, "") + } + } + return output +} + +func flattenPackages(pkgs map[string]node.PackageInfo) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(pkgs)) + + for _, p := range pkgs { + temp := map[string]interface{}{ + "ver": p.Ver, + "size": p.InstalledSize, + } + res = append(res, temp) + } + + return res +} + +func flattenDPDKItem(dpdk node.DPDK) []map[string]interface{} { + res := make([]map[string]interface{}, 1) + bridges := make([]map[string]interface{}, 1) + backplane := make([]map[string]interface{}, 1) + backplane[0] = map[string]interface{}{ + "interfaces": dpdk.Bridges.Backplane1.Interfaces, + "numa_node": dpdk.Bridges.Backplane1.NumaNode, + } + + bridges[0] = map[string]interface{}{ + "backplane1": backplane, + } + + res[0] = map[string]interface{}{ + "bridges": bridges, + "hp_memory": dpdk.HPMemory, + "pmd_cpu": dpdk.PMDCPU, + } + + return res +} + +func flattenRole(role node.Role) []map[string]interface{} { + res := make([]map[string]interface{}, 1) + temp := map[string]interface{}{ + "actor": role.Actor, + "reason": role.Reason, + "time": role.Time, + } + res[0] = temp + return res +} + +func flattenSystemNetworksInfo(m map[string]node.SystemNetworkInfo) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(m)) + for name, info := range m { + res = append(res, map[string]interface{}{ + "name": name, + "mtu": info.MTU, + "speed": info.Speed, + "bridge_id": info.BridgeID, + "bport_id": info.BPortID, + "mac": info.MAC, + }) + } + return res +} + +func flattenOVSNetworksInfo(items []node.OVSNetworkInfo) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(items)) + for _, item := range items { + res = append(res, map[string]interface{}{ + "bridge_name": item.BridgeName, + "bridge_tag": item.BridgeTag, + "interface_uuid": item.InterfaceUUID, + "interface_type": item.InterfaceType, + "interface_name": item.InterfaceName, + "interface_mtu": item.InterfaceMTU, + "interface_ip": item.InterfaceIP, + "interface_mac": item.InterfaceMAC, + "interface_peer": item.InterfacePeer, + }) + } + return res +} + +func flattenLibvirtNetworksInfo(items []node.LibvirtNetworkInfo) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(items)) + for _, item := range items { + res = append(res, map[string]interface{}{ + "vm_name": item.VMName, + "interface": item.Interface, + "interface_type": item.InterfaceType, + "interface_source": item.InterfaceSource, + }) + } + return res +} + +func flattenNetworkTopology(t node.NetworkTopology) []map[string]interface{} { + return []map[string]interface{}{ + { + "interfaces": flattenTopologyInterfaces(t.Interfaces), + }, + } +} + +func flattenTopologyInterfaces(m map[string]node.TopologyInterface) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(m)) + for name, iface := range m { + res = append(res, map[string]interface{}{ + "name": name, + "type": iface.Type, + "mtu": iface.MTU, + "speed": iface.Speed, + "vlans": iface.VLANs, + "bridge_id": iface.BridgeID, + "peer": iface.Peer, + "uuid": iface.UUID, + "connected_interfaces": iface.ConnectedInterfaces, + "connections": flattenTopologyConnections(iface.Connections), + "bridge_info": flattenTopologyBridgeInfo(iface.BridgeInfo), + "bridge_connections": flattenTopologyBridgeRefs(iface.BridgeConnections), + }) + } + return res +} + +func flattenTopologyConnections(c node.TopologyInterfaceConnections) []map[string]interface{} { + vms := make([]map[string]interface{}, 0, len(c.VMs)) + for _, vm := range c.VMs { + vms = append(vms, map[string]interface{}{ + "name": vm.Name, + "vm_interface": vm.VMInterface, + "vm_interface_type": vm.VMInterfaceType, + "connection_type": vm.ConnectionType, + "via_bridge": vm.ViaBridge, + }) + } + + bridges := make([]map[string]interface{}, 0, len(c.Bridges)) + for _, b := range c.Bridges { + portInfo := flattenTopologyPortInfo(b.PortInfo) + bridges = append(bridges, map[string]interface{}{ + "name": b.Name, + "type": b.Type, + "via": b.Via, + "bport_id": b.BPortID, + "port_info": portInfo, + }) + } + + return []map[string]interface{}{ + { + "vms": vms, + "bridges": bridges, + }, + } +} + +func flattenTopologyPortInfo(p *node.TopologyPortInfo) []map[string]interface{} { + if p == nil { + return nil + } + return []map[string]interface{}{ + { + "name": p.Name, + "type": p.Type, + "mtu": p.MTU, + "vlan": p.VLAN, + "uuid": p.UUID, + }, + } +} + +func flattenTopologyBridgeInfo(b *node.TopologyBridgeInfo) []map[string]interface{} { + if b == nil { + return nil + } + ports := make([]map[string]interface{}, 0, len(b.Ports)) + for _, p := range b.Ports { + ports = append(ports, map[string]interface{}{ + "name": p.Name, + "type": p.Type, + "mtu": p.MTU, + "vlan": p.VLAN, + "uuid": p.UUID, + "ip": p.IP, + "mac": p.MAC, + }) + } + return []map[string]interface{}{ + { + "type": b.Type, + "ports": ports, + }, + } +} + +func flattenTopologyBridgeRefs(refs []node.TopologyBridgeRef) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(refs)) + for _, r := range refs { + res = append(res, map[string]interface{}{ + "name": r.Name, + "via": r.Via, + "vlan": r.VLAN, + }) + } + return res +} + +func flattenNodePCIDevices(items []node.ItemPCIDevice) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(items)) + for _, item := range items { + res = append(res, map[string]interface{}{ + "hw_path": item.HWPath, + "current_driver": item.CurrentDriver, + "numa_node": item.NUMANode, + "product_id": item.ProductID, + "product_name": item.ProductName, + "vendor_id": item.VendorID, + "vendor_name": item.VendorName, + "iommu_group": item.IOMMUGroup, + }) + } + return res +} diff --git a/internal/service/cloudbroker/node/schema.go b/internal/service/cloudbroker/node/schema.go new file mode 100644 index 00000000..7ac4657b --- /dev/null +++ b/internal/service/cloudbroker/node/schema.go @@ -0,0 +1,1102 @@ +package node + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func dataSourceNodeSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "node_id": { + Type: schema.TypeInt, + Required: true, + Description: "node id", + }, + "auto_start": { + Type: schema.TypeBool, + Computed: true, + }, + "auto_start_count": { + Type: schema.TypeInt, + Computed: true, + }, + "consumption": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "computes": { + Type: schema.TypeInt, + Computed: true, + }, + "routers": { + Type: schema.TypeInt, + Computed: true, + }, + "vcpu": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "free": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vcpu": { + Type: schema.TypeFloat, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "total": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "cpu_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "clock_speed": { + Type: schema.TypeInt, + Computed: true, + }, + "core_count": { + Type: schema.TypeInt, + Computed: true, + }, + "phys_count": { + Type: schema.TypeInt, + Computed: true, + }, + "flags": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "model_name": { + Type: schema.TypeString, + Computed: true, + }, + "thread_count": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "mem_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "dpdk": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bridges": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backplane1": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "numa_node": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "hp_memory": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "pmd_cpu": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "ipaddr": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "isolated_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "need_reboot": { + Type: schema.TypeBool, + Computed: true, + }, + "net_addr": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "usable_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "network_mode": { + Type: schema.TypeString, + Computed: true, + }, + "openvswitch_bridges": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "nic_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "max_vfs": { + Type: schema.TypeInt, + Computed: true, + }, + "numa_node": { + Type: schema.TypeInt, + Computed: true, + }, + "num_vfs": { + Type: schema.TypeInt, + Computed: true, + }, + "os_name": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeString, + Computed: true, + }, + + "vf_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "fn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "numa_topology": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_num": { + Type: schema.TypeInt, + Computed: true, + }, + "nodes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "memory": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "one_g": { + Type: schema.TypeInt, + Computed: true, + }, + "one_g_free": { + Type: schema.TypeInt, + Computed: true, + }, + "one_g_reserved": { + Type: schema.TypeInt, + Computed: true, + }, + "one_g_available": { + Type: schema.TypeInt, + Computed: true, + }, + "one_g_used": { + Type: schema.TypeInt, + Computed: true, + }, + "one_g_dpdk_reserved": { + Type: schema.TypeInt, + Computed: true, + }, + "two_m": { + Type: schema.TypeInt, + Computed: true, + }, + "two_m_free": { + Type: schema.TypeInt, + Computed: true, + }, + "two_m_reserved": { + Type: schema.TypeInt, + Computed: true, + }, + "two_m_available": { + Type: schema.TypeInt, + Computed: true, + }, + "two_m_used": { + Type: schema.TypeInt, + Computed: true, + }, + "total": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "reserved_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "roles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sdn_hypervisor_name": { + Type: schema.TypeString, + Computed: true, + }, + "sriov_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "to_active": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "actor": { + Type: schema.TypeString, + Computed: true, + }, + "reason": { + Type: schema.TypeString, + Computed: true, + }, + "time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "to_installing": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "actor": { + Type: schema.TypeString, + Computed: true, + }, + "reason": { + Type: schema.TypeString, + Computed: true, + }, + "time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "to_maintenance": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "actor": { + Type: schema.TypeString, + Computed: true, + }, + "reason": { + Type: schema.TypeString, + Computed: true, + }, + "time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "to_restricted": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "actor": { + Type: schema.TypeString, + Computed: true, + }, + "reason": { + Type: schema.TypeString, + Computed: true, + }, + "time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceNodeListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "find node by id", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "find node by name", + }, + "version": { + Type: schema.TypeString, + Optional: true, + Description: "find node by version", + }, + "release": { + Type: schema.TypeString, + Optional: true, + Description: "find node by release", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Description: "find node by sepId", + }, + "role": { + Type: schema.TypeString, + Optional: true, + Description: "find node by role", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "find node by status", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "find node by zone id", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "additional_pkgs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "api_url": { + Type: schema.TypeString, + Computed: true, + }, + "auto_start": { + Type: schema.TypeBool, + Computed: true, + }, + "auto_start_count": { + Type: schema.TypeInt, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "cpu_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "clock_speed": { + Type: schema.TypeFloat, + Computed: true, + }, + "core_count": { + Type: schema.TypeInt, + Computed: true, + }, + "phys_count": { + Type: schema.TypeInt, + Computed: true, + }, + "flags": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "model_name": { + Type: schema.TypeString, + Computed: true, + }, + "thread_count": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "dpdk": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bridges": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backplane1": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "interfaces": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "numa_node": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "hp_memory": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "pmd_cpu": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "hostkey": { + Type: schema.TypeString, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ipaddr": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "isolated_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "lastcheck": { + Type: schema.TypeInt, + Computed: true, + }, + "machine_guid": { + Type: schema.TypeString, + Computed: true, + }, + "mainboard_sn": { + Type: schema.TypeString, + Computed: true, + }, + "mem_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "memory": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "need_reboot": { + Type: schema.TypeBool, + Computed: true, + }, + "net_addr": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cidr": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "index": { + Type: schema.TypeInt, + Computed: true, + }, + "ip": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "network_mode": { + Type: schema.TypeString, + Computed: true, + }, + "old_compat_lvm_id": { + Type: schema.TypeInt, + Computed: true, + }, + "openvswitch_bridges": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "nic_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "driver": { + Type: schema.TypeString, + Computed: true, + }, + "max_vfs": { + Type: schema.TypeInt, + Computed: true, + }, + "numa_node": { + Type: schema.TypeInt, + Computed: true, + }, + "num_vfs": { + Type: schema.TypeInt, + Computed: true, + }, + "os_name": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeString, + Computed: true, + }, + + "vf_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "fn_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "node_uuid": { + Type: schema.TypeString, + Computed: true, + }, + "numa_topology": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_num": { + Type: schema.TypeInt, + Computed: true, + }, + "nodes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "memory": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "one_g": { + Type: schema.TypeInt, + Computed: true, + }, + "one_g_free": { + Type: schema.TypeInt, + Computed: true, + }, + "one_g_reserved": { + Type: schema.TypeInt, + Computed: true, + }, + "one_g_available": { + Type: schema.TypeInt, + Computed: true, + }, + "one_g_used": { + Type: schema.TypeInt, + Computed: true, + }, + "one_g_dpdk_reserved": { + Type: schema.TypeInt, + Computed: true, + }, + "two_m": { + Type: schema.TypeInt, + Computed: true, + }, + "two_m_free": { + Type: schema.TypeInt, + Computed: true, + }, + "two_m_reserved": { + Type: schema.TypeInt, + Computed: true, + }, + "two_m_available": { + Type: schema.TypeInt, + Computed: true, + }, + "two_m_used": { + Type: schema.TypeInt, + Computed: true, + }, + "total": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "packages": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ver": { + Type: schema.TypeString, + Computed: true, + }, + "size": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "peer_backup": { + Type: schema.TypeInt, + Computed: true, + }, + "peer_log": { + Type: schema.TypeInt, + Computed: true, + }, + "peer_stats": { + Type: schema.TypeInt, + Computed: true, + }, + "pgpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "public_keys": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "release": { + Type: schema.TypeString, + Computed: true, + }, + "reserved_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "roles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sdn_hypervisor_name": { + Type: schema.TypeString, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "serial_num": { + Type: schema.TypeString, + Computed: true, + }, + "sriov_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tags": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "uefi_firmware_file": { + Type: schema.TypeString, + Computed: true, + }, + "usable_cpus": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_devices": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "hw_path": { + Type: schema.TypeString, + Computed: true, + }, + "current_driver": { + Type: schema.TypeString, + Computed: true, + }, + "numa_node": { + Type: schema.TypeInt, + Computed: true, + }, + "product_id": { + Type: schema.TypeString, + Computed: true, + }, + "product_name": { + Type: schema.TypeString, + Computed: true, + }, + "vendor_id": { + Type: schema.TypeString, + Computed: true, + }, + "vendor_name": { + Type: schema.TypeString, + Computed: true, + }, + "iommu_group": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry count", + }, + } +} diff --git a/internal/service/cloudbroker/node/utility_node.go b/internal/service/cloudbroker/node/utility_node.go new file mode 100644 index 00000000..3598b6fb --- /dev/null +++ b/internal/service/cloudbroker/node/utility_node.go @@ -0,0 +1,56 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package node + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/node" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityNodeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*node.RecordNode, error) { + c := m.(*controller.ControllerCfg) + req := node.GetRequest{NID: uint64(d.Get("node_id").(int))} + + log.Debugf("utilityNodeCheckPresence: load node") + nodeInfo, err := c.CloudBroker().Node().Get(ctx, req) + if err != nil { + return nil, err + } + + return nodeInfo, nil +} diff --git a/internal/service/cloudbroker/node/utility_node_list.go b/internal/service/cloudbroker/node/utility_node_list.go new file mode 100644 index 00000000..bac49b25 --- /dev/null +++ b/internal/service/cloudbroker/node/utility_node_list.go @@ -0,0 +1,90 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package node + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/node" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityNodeListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*node.ListNodes, error) { + c := m.(*controller.ControllerCfg) + req := node.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if version, ok := d.GetOk("version"); ok { + req.Version = version.(string) + } + if release, ok := d.GetOk("release"); ok { + req.Release = release.(string) + } + if sepId, ok := d.GetOk("sep_id"); ok { + req.SepID = uint64(sepId.(int)) + } + if role, ok := d.GetOk("role"); ok { + req.Role = role.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if Page, ok := d.GetOk("page"); ok { + req.Page = uint64(Page.(int)) + } + if Size, ok := d.GetOk("size"); ok { + req.Size = uint64(Size.(int)) + } + if zoneId, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneId.(int)) + } + + log.Debugf("utilityNodeListCheckPresence: load node list") + nodeList, err := c.CloudBroker().Node().List(ctx, req) + if err != nil { + return nil, err + } + + return nodeList, nil +} diff --git a/internal/service/cloudbroker/pcidevice/data_source_pcidevice.go b/internal/service/cloudbroker/pcidevice/data_source_pcidevice.go new file mode 100644 index 00000000..dfc1f05e --- /dev/null +++ b/internal/service/cloudbroker/pcidevice/data_source_pcidevice.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package pcidevice + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourcePcideviceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + pcidevice, err := utilityPcideviceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenPcidevice(d, pcidevice) + d.SetId(strconv.Itoa(d.Get("device_id").(int))) + + return nil +} + +func DataSourcePcidevice() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourcePcideviceRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourcePcideviceSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/pcidevice/data_source_pcidevice_list.go b/internal/service/cloudbroker/pcidevice/data_source_pcidevice_list.go new file mode 100644 index 00000000..b661a2f7 --- /dev/null +++ b/internal/service/cloudbroker/pcidevice/data_source_pcidevice_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package pcidevice + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourcePcideviceListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + pcideviceList, err := utilityPcideviceListCheckPresence(ctx, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.Set("items", flattenPcideviceList(pcideviceList)) + d.Set("entry_count", pcideviceList.EntryCount) + + id := uuid.New() + d.SetId(id.String()) + + return nil +} + +func DataSourcePcideviceList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourcePcideviceListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourcePcideviceListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/pcidevice/flattens.go b/internal/service/cloudbroker/pcidevice/flattens.go new file mode 100644 index 00000000..b5694484 --- /dev/null +++ b/internal/service/cloudbroker/pcidevice/flattens.go @@ -0,0 +1,44 @@ +package pcidevice + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice" +) + +func flattenPcidevice(d *schema.ResourceData, pd *pcidevice.ItemPCIDevice) { + log.Debugf("flattenPCIDevice: ID %d", pd.ID) + + d.Set("compute_id", pd.ComputeID) + d.Set("description", pd.Description) + d.Set("guid", pd.GUID) + d.Set("hw_path", pd.HwPath) + d.Set("device_id", pd.ID) + d.Set("name", pd.Name) + d.Set("rg_id", pd.RGID) + d.Set("node_id", pd.NodeID) + d.Set("status", pd.Status) + d.Set("system_name", pd.SystemName) +} + +func flattenPcideviceList(pl *pcidevice.ListPCIDevices) []map[string]interface{} { + log.Debug("flattenPCIDeviceList") + + res := make([]map[string]interface{}, 0, len(pl.Data)) + for _, item := range pl.Data { + temp := map[string]interface{}{ + "compute_id": item.ComputeID, + "description": item.Description, + "guid": item.GUID, + "hw_path": item.HwPath, + "device_id": item.ID, + "rg_id": item.RGID, + "name": item.Name, + "node_id": item.NodeID, + "status": item.Status, + "system_name": item.SystemName, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudbroker/pcidevice/resource_check_input_vales.go b/internal/service/cloudbroker/pcidevice/resource_check_input_vales.go new file mode 100644 index 00000000..692ef65d --- /dev/null +++ b/internal/service/cloudbroker/pcidevice/resource_check_input_vales.go @@ -0,0 +1,59 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package pcidevice + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" +) + +func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + nodeId := uint64(d.Get("node_id").(int)) + rgId := uint64(d.Get("rg_id").(int)) + + if err := ic.ExistRG(ctx, rgId, c); err != nil { + errs = append(errs, err) + } + + if err := ic.ExistNode(ctx, nodeId, c); err != nil { + errs = append(errs, err) + } + + return dc.ErrorsToDiagnostics(errs) +} diff --git a/internal/service/cloudbroker/pcidevice/resource_pcidevice.go b/internal/service/cloudbroker/pcidevice/resource_pcidevice.go new file mode 100644 index 00000000..7b6e6dae --- /dev/null +++ b/internal/service/cloudbroker/pcidevice/resource_pcidevice.go @@ -0,0 +1,230 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package pcidevice + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" +) + +func resourcePcideviceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourcePcideviceCreate: called for pcidevice %s", d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + createReq := pcidevice.CreateRequest{} + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + createReq.NodeID = uint64(d.Get("node_id").(int)) + createReq.RGID = uint64(d.Get("rg_id").(int)) + createReq.Name = d.Get("name").(string) + createReq.HWPath = d.Get("hw_path").(string) + + if description, ok := d.GetOk("description"); ok { + createReq.Description = description.(string) + } + + pcideviceId, err := c.CloudBroker().PCIDevice().Create(ctx, createReq) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(pcideviceId, 10)) + d.Set("device_id", pcideviceId) + + warnings := dc.Warnings{} + + if enable, ok := d.GetOk("enable"); ok { + log.Debugf("resourcePcideviceCreate: enable=%t device_id %d after completing its resource configuration", enable, pcideviceId) + + if enable.(bool) { + req := pcidevice.EnableRequest{DeviceID: pcideviceId} + if _, err := c.CloudBroker().PCIDevice().Enable(ctx, req); err != nil { + warnings.Add(err) + } + + } else { + req := pcidevice.DisableRequest{ + DeviceID: pcideviceId, + } + if force, ok := d.GetOk("force_disable"); ok { + req.Force = force.(bool) + log.Debugf("force_disable=%v", force) + } + if _, err := c.CloudBroker().PCIDevice().Disable(ctx, req); err != nil { + warnings.Add(err) + } + } + } + + return append(resourcePcideviceRead(ctx, d, m), warnings.Get()...) +} + +func resourcePcideviceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourcePcideviceRead: called for pci_device id %d, name %s", + d.Id(), d.Get("name").(string)) + + pcideviceRec, err := utilityPcideviceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenPcidevice(d, pcideviceRec) + + log.Debugf("resourcePcideviceRead: after flattenPcidevice: device_id %s, name %s", + d.Id(), d.Get("name").(string)) + + return nil +} + +func resourcePcideviceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourcePcideviceUpdate: called for pcidevice id %s, name %s", d.Id(), d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + if d.HasChange("enable") { + err := resourcePcideviceChangeEnable(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return resourcePcideviceRead(ctx, d, m) +} + +func resourcePcideviceDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourcePcideviceDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + c := m.(*controller.ControllerCfg) + + pciDevice, err := utilityPcideviceCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + if pciDevice.Status == status.Destroyed || pciDevice.Status == status.Purged { + return nil + } + + req := pcidevice.DeleteRequest{ + DeviceID: pciDevice.ID, + } + if force, ok := d.GetOk("force_delete"); ok { + req.Force = force.(bool) + } + + if _, err = c.CloudBroker().PCIDevice().Delete(ctx, req); err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourcePcidevice() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourcePcideviceCreate, + ReadContext: resourcePcideviceRead, + UpdateContext: resourcePcideviceUpdate, + DeleteContext: resourcePcideviceDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout900s, + Read: &constants.Timeout300s, + Update: &constants.Timeout300s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourcePcideviceSchemaMake(), + } +} + +func resourcePcideviceChangeEnable(ctx context.Context, d *schema.ResourceData, m interface{}) error { + enable := d.Get("enable").(bool) + log.Debugf("resourcePcideviceChangeEnable: enable=%t device_id %s after completing its resource configuration", enable, d.Id()) + + pcideviceRec, err := utilityPcideviceCheckPresence(ctx, d, m) + if err != nil { + return err + } + c := m.(*controller.ControllerCfg) + + if enable { + req := pcidevice.EnableRequest{ + DeviceID: pcideviceRec.ID, + } + + if _, err := c.CloudBroker().PCIDevice().Enable(ctx, req); err != nil { + return err + } + } else { + req := pcidevice.DisableRequest{ + DeviceID: pcideviceRec.ID, + } + if force, ok := d.GetOk("force_disable"); ok { + req.Force = force.(bool) + } + + if _, err := c.CloudBroker().PCIDevice().Disable(ctx, req); err != nil { + return err + } + } + + return nil +} diff --git a/internal/service/cloudbroker/pcidevice/schema.go b/internal/service/cloudbroker/pcidevice/schema.go new file mode 100644 index 00000000..8dc82e8a --- /dev/null +++ b/internal/service/cloudbroker/pcidevice/schema.go @@ -0,0 +1,230 @@ +package pcidevice + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourcePcideviceSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "device_id": { + Type: schema.TypeInt, + Required: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hw_path": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "system_name": { + Type: schema.TypeString, + Computed: true, + }, + } + return rets +} + +func dataSourcePcideviceListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "by_id", + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + Description: "compute_id", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "name", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "rg_id", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "status", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "pcidevice list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "device_id": { + Type: schema.TypeInt, + Required: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hw_path": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "system_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry count", + }, + } + return rets +} + +func resourcePcideviceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "node_id": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "Node ID", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "Resource GROUP", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of Device", + }, + "hw_path": { + Type: schema.TypeString, + Required: true, + Description: "PCI address of the device", + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "description, just for information", + }, + "device_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Enable pci device", + }, + "force_delete": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Force delete", + }, + "force_disable": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Force disable", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "system_name": { + Type: schema.TypeString, + Computed: true, + }, + } +} diff --git a/internal/service/cloudbroker/pcidevice/utility_pcidevice.go b/internal/service/cloudbroker/pcidevice/utility_pcidevice.go new file mode 100644 index 00000000..3949c1b3 --- /dev/null +++ b/internal/service/cloudbroker/pcidevice/utility_pcidevice.go @@ -0,0 +1,65 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package pcidevice + +import ( + "context" + "fmt" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice" +) + +func utilityPcideviceCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*pcidevice.ItemPCIDevice, error) { + pcideviceList, err := utilityPcideviceListCheckPresence(ctx, m) + if err != nil { + return nil, err + } + + var pcideviceId uint64 + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + pcideviceId = id + } else { + pcideviceId = uint64(d.Get("device_id").(int)) + } + + for _, pd := range pcideviceList.Data { + if pd.ID == pcideviceId { + return &pd, nil + } + } + + return nil, fmt.Errorf("dataPcideviceRead: can't find Pcidevice because Device_id %d is not allowed or does not exist", d.Get("device_id").(int)) +} diff --git a/internal/service/cloudbroker/pcidevice/utility_pcidevice_list.go b/internal/service/cloudbroker/pcidevice/utility_pcidevice_list.go new file mode 100644 index 00000000..2be8d96f --- /dev/null +++ b/internal/service/cloudbroker/pcidevice/utility_pcidevice_list.go @@ -0,0 +1,52 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package pcidevice + +import ( + "context" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityPcideviceListCheckPresence(ctx context.Context, m interface{}) (*pcidevice.ListPCIDevices, error) { + c := m.(*controller.ControllerCfg) + + req := pcidevice.ListRequest{} + + pcideviceList, err := c.CloudBroker().PCIDevice().List(ctx, req) + if err != nil { + return nil, err + } + + return pcideviceList, nil +} diff --git a/internal/service/cloudbroker/rg/data_source_rg.go b/internal/service/cloudbroker/rg/data_source_rg.go new file mode 100644 index 00000000..d439389c --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "fmt" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rg, err := utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + // if empty string is returned from utilityResgroupCheckPresence then there is no + // such resource group and err tells so - just return it to the calling party + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + d.SetId(fmt.Sprintf("%d", rg.ID)) + flattenResgroup(d, rg) + + return nil +} + +func DataSourceResgroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceResgroupRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_affinity_group_computes.go b/internal/service/cloudbroker/rg/data_source_rg_affinity_group_computes.go new file mode 100644 index 00000000..f5977a36 --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_affinity_group_computes.go @@ -0,0 +1,37 @@ +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgAffinityGroupComputesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgComputes, err := utilityRgAffinityGroupComputesCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("items", flattenRgAffinityGroupComputes(rgComputes)) + return nil +} + +func DataSourceRgAffinityGroupComputes() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgAffinityGroupComputesRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgAffinityGroupComputesSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_affinity_groups_get.go b/internal/service/cloudbroker/rg/data_source_rg_affinity_groups_get.go new file mode 100644 index 00000000..f119e54b --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_affinity_groups_get.go @@ -0,0 +1,36 @@ +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgAffinityGroupsGetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + computes, err := utilityRgAffinityGroupsGetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("ids", computes) + return nil +} + +func DataSourceRgAffinityGroupsGet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgAffinityGroupsGetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgAffinityGroupsGetSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_affinity_groups_list.go b/internal/service/cloudbroker/rg/data_source_rg_affinity_groups_list.go new file mode 100644 index 00000000..6f7d17f9 --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_affinity_groups_list.go @@ -0,0 +1,38 @@ +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgAffinityGroupsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + list, err := utilityRgAffinityGroupsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("affinity_groups", flattenRgListGroups(list)) + d.Set("entry_count", list.EntryCount) + return nil +} + +func DataSourceRgAffinityGroupsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgAffinityGroupsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgAffinityGroupsListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_audits.go b/internal/service/cloudbroker/rg/data_source_rg_audits.go new file mode 100644 index 00000000..8cd285dc --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_audits.go @@ -0,0 +1,37 @@ +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgAudits, err := utilityRgAuditsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("items", flattenRgAudits(rgAudits)) + return nil +} + +func DataSourceRgAudits() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgAuditsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgAuditsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_get_resource_consumption.go b/internal/service/cloudbroker/rg/data_source_rg_get_resource_consumption.go new file mode 100644 index 00000000..b09ddf58 --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_get_resource_consumption.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRGResourceConsumptionGetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + RGResourceConsumptionRec, err := utilityRGResourceConsumptionGetCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenRGResourceConsumption(d, RGResourceConsumptionRec) + return nil +} + +func DataSourceRGResourceConsumptionGet() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRGResourceConsumptionGetRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRGResourceConsumptionGetSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_list.go b/internal/service/cloudbroker/rg/data_source_rg_list.go new file mode 100644 index 00000000..5800bac2 --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgList, err := utilityRgListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenRgList(rgList)) + d.Set("entry_count", rgList.EntryCount) + + return nil +} + +func DataSourceRgList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_list_computes.go b/internal/service/cloudbroker/rg/data_source_rg_list_computes.go new file mode 100644 index 00000000..cc0dd94e --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_list_computes.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListComputesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + listComputes, err := utilityRgListComputesCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenRgListComputes(listComputes)) + d.Set("entry_count", listComputes.EntryCount) + + return nil +} + +func DataSourceRgListComputes() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListComputesRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListComputesSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_list_deleted.go b/internal/service/cloudbroker/rg/data_source_rg_list_deleted.go new file mode 100644 index 00000000..b4470b2d --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_list_deleted.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgList, err := utilityRgListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenRgList(rgList)) + d.Set("entry_count", rgList.EntryCount) + + return nil +} + +func DataSourceRgListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_list_lb.go b/internal/service/cloudbroker/rg/data_source_rg_list_lb.go new file mode 100644 index 00000000..a4521fec --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_list_lb.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListLbRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + listLb, err := utilityRgListLbCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("items", flattenRgListLb(listLb)) + d.Set("entry_count", listLb.EntryCount) + + return nil +} + +func DataSourceRgListLb() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListLbRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListLbSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_list_pfw.go b/internal/service/cloudbroker/rg/data_source_rg_list_pfw.go new file mode 100644 index 00000000..3e3a3729 --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_list_pfw.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListPfwRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + listPfw, err := utilityRgListPfwCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("items", flattenRgListPfw(listPfw)) + d.Set("entry_count", listPfw.EntryCount) + + return nil +} + +func DataSourceRgListPfw() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListPfwRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListPfwSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_list_vins.go b/internal/service/cloudbroker/rg/data_source_rg_list_vins.go new file mode 100644 index 00000000..4a5ae091 --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_list_vins.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgListVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + listVins, err := utilityRgListVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + d.Set("items", flattenRgListVins(listVins)) + d.Set("entry_count", listVins.EntryCount) + + return nil +} + +func DataSourceRgListVins() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgListVinsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgListVinsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_resource_consumption_list.go b/internal/service/cloudbroker/rg/data_source_rg_resource_consumption_list.go new file mode 100644 index 00000000..74ea889d --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_resource_consumption_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRGResourceConsumptionListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rgResourceConsumptionList, err := utilityRGResourceConsumptionListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenRGResourceConsumptionList(rgResourceConsumptionList)) + d.Set("entry_count", rgResourceConsumptionList.EntryCount) + return nil +} + +func DataSourceRGResourceConsumptionList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRGResourceConsumptionListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRGResourceConsumptionListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/data_source_rg_usage.go b/internal/service/cloudbroker/rg/data_source_rg_usage.go new file mode 100644 index 00000000..94f8f199 --- /dev/null +++ b/internal/service/cloudbroker/rg/data_source_rg_usage.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceRgUsageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + usage, err := utilityDataRgUsageCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(d.Get("rg_id").(int))) + flattenRgUsageResource(d, *usage) + return nil +} + +func DataSourceRgUsage() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceRgUsageRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceRgUsageSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/flattens.go b/internal/service/cloudbroker/rg/flattens.go new file mode 100644 index 00000000..af5a91f3 --- /dev/null +++ b/internal/service/cloudbroker/rg/flattens.go @@ -0,0 +1,518 @@ +package rg + +import ( + log "github.com/sirupsen/logrus" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" +) + +func flattenResgroup(d *schema.ResourceData, rgData *rg.RecordRG) { + log.Debugf("flattenResgroup: decoded RG name %q / ID %d, account ID %d", + rgData.Name, rgData.ID, rgData.AccountID) + + d.Set("account_id", rgData.AccountID) + d.Set("account_name", rgData.AccountName) + d.Set("acl", flattenRgAcl(rgData.ACL)) + d.Set("compute_features", rgData.ComputeFeatures) + d.Set("cpu_allocation_parameter", rgData.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", rgData.CPUAllocationRatio) + d.Set("created_by", rgData.CreatedBy) + d.Set("created_time", rgData.CreatedTime) + d.Set("def_net_id", rgData.DefNetID) + d.Set("def_net_type", rgData.DefNetType) + d.Set("deleted_by", rgData.DeletedBy) + d.Set("deleted_time", rgData.DeletedTime) + d.Set("desc", rgData.Description) + d.Set("dirty", rgData.Dirty) + d.Set("gid", rgData.GID) + d.Set("guid", rgData.GUID) + d.Set("rg_id", rgData.ID) + d.Set("lock_status", rgData.LockStatus) + d.Set("milestones", rgData.Milestones) + d.Set("name", rgData.Name) + d.Set("resource_limits", flattenRgResourceLimits(rgData.ResourceLimits)) + d.Set("resource_types", rgData.ResTypes) + d.Set("secret", rgData.Secret) + d.Set("status", rgData.Status) + d.Set("uniq_pools", rgData.UniqPools) + d.Set("updated_by", rgData.UpdatedBy) + d.Set("updated_time", rgData.UpdatedTime) + d.Set("vins", rgData.VINS) + d.Set("computes", rgData.VMs) + d.Set("sdn_access_group_id", rgData.SDNAccessGroupID) + d.Set("storage_policy_ids", rgData.StoragePolicyIDs) +} + +func flattenRgAcl(rgACLs rg.ListACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rgACLs)) + for _, acl := range rgACLs { + temp := map[string]interface{}{ + "email": acl.Email, + "explicit": acl.Explicit, + "guid": acl.GUID, + "right": acl.Right, + "status": acl.Status, + "type": acl.Type, + "user_group_id": acl.UserGroupID, + } + + res = append(res, temp) + } + + return res +} + +func flattenRgResourceLimits(rl rg.ResourceLimits) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cu_c": rl.CUC, + "cu_d": rl.CuD, + "cu_dm": rl.CUDM, + "cu_i": rl.CUI, + "cu_m": rl.CUM, + "gpu_units": rl.GPUUnits, + "storage_policy": flattenRgStoragePolicy(rl.StoragePolicies), + } + res = append(res, temp) + + return res + +} + +func flattenRgAudits(rgAudits rg.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rgAudits)) + for _, rgAudit := range rgAudits { + temp := map[string]interface{}{ + "call": rgAudit.Call, + "responsetime": rgAudit.ResponseTime, + "statuscode": rgAudit.StatusCode, + "timestamp": rgAudit.Timestamp, + "user": rgAudit.User, + } + + res = append(res, temp) + } + + return res +} + +func flattenRgListGroups(list *rg.ListAffinityGroup) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list.Data)) + for _, item := range list.Data { + for key, vals := range item { + for _, v := range vals { + temp := map[string]interface{}{ + "label": key, + "id": v.ID, + "node_id": v.NodeID, + } + res = append(res, temp) + } + } + } + + return res +} + +func flattenRgAffinityGroupComputes(list rg.ListAffinityGroupCompute) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + + for _, item := range list { + temp := map[string]interface{}{ + "compute_id": item.ComputeID, + "other_node": item.OtherNode, + "other_node_indirect": item.OtherNodeIndirect, + "other_node_indirect_soft": item.OtherNodeIndirectSoft, + "other_node_soft": item.OtherNodeSoft, + "same_node": item.SameNode, + "same_node_soft": item.SameNodeSoft, + } + res = append(res, temp) + } + + return res +} + +func flattenRGResourceConsumption(d *schema.ResourceData, rg *rg.ItemResourceConsumption) { + d.Set("consumed", flattenResource(rg.Consumed)) + d.Set("reserved", flattenResource(rg.Reserved)) + d.Set("resource_limits", flattenRgResourceLimits(rg.ResourceLimits)) + d.Set("rg_id", rg.RGID) +} + +func flattenRGResourceConsumptionList(rg *rg.ListResourceConsumption) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rg.Data)) + for _, rc := range rg.Data { + temp := map[string]interface{}{ + "consumed": flattenResource(rc.Consumed), + "reserved": flattenResource(rc.Reserved), + "resource_limits": flattenRgResourceLimits(rc.ResourceLimits), + "rg_id": rc.RGID, + } + res = append(res, temp) + } + return res +} + +func flattenRgUsageResource(d *schema.ResourceData, usage rg.Reservation) { + d.Set("cpu", usage.CPU) + d.Set("disk_size", usage.DiskSize) + d.Set("disk_size_max", usage.DiskSizeMax) + d.Set("extips", usage.ExtIPs) + d.Set("gpu", usage.GPU) + d.Set("ram", usage.RAM) + d.Set("seps", flattenRGSeps(usage.SEPs)) +} + +func flattenResource(resource rg.Reservation) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": resource.CPU, + "disk_size": resource.DiskSize, + "disk_size_max": resource.DiskSizeMax, + "extips": resource.ExtIPs, + "gpu": resource.GPU, + "ram": resource.RAM, + "seps": flattenRGSeps(resource.SEPs), + } + + res = append(res, temp) + + return res +} + +func flattenRGSeps(seps map[string]map[string]rg.DiskUsage) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for sepKey, sepVal := range seps { + for dataKey, dataVal := range sepVal { + temp := map[string]interface{}{ + "sep_id": sepKey, + "data_name": dataKey, + "disk_size": dataVal.DiskSize, + "disk_size_max": dataVal.DiskSizeMax, + } + res = append(res, temp) + } + } + + return res +} + +func flattenRgListComputes(lc *rg.ListComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(lc.Data)) + for _, compute := range lc.Data { + temp := map[string]interface{}{ + "account_id": compute.AccountID, + "account_name": compute.AccountName, + "affinity_label": compute.AffinityLabel, + "affinity_rules": flattenRules(compute.AffinityRules), + "affinity_weight": compute.AffinityWeight, + "antiaffinity_rules": flattenRules(compute.AntiAffinityRules), + "cpus": compute.CPUs, + "created_by": compute.CreatedBy, + "created_time": compute.CreatedTime, + "deleted_by": compute.DeletedBy, + "deleted_time": compute.DeletedTime, + "id": compute.ID, + "name": compute.Name, + "ram": compute.RAM, + "registered": compute.Registered, + "rg_id": compute.RGID, + "rg_name": compute.RGName, + "status": compute.Status, + "tech_status": compute.TechStatus, + "total_disks_size": compute.TotalDisksSize, + "updated_by": compute.UpdatedBy, + "updated_time": compute.UpdatedTime, + "user_managed": compute.UserManaged, + "vins_connected": compute.VINSConnected, + } + + res = append(res, temp) + } + + return res +} + +func flattenRules(list rg.ListRules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + for _, rule := range list { + temp := map[string]interface{}{ + "guid": rule.GUID, + "key": rule.Key, + "mode": rule.Mode, + "policy": rule.Policy, + "topology": rule.Topology, + "value": rule.Value, + } + + res = append(res, temp) + } + + return res +} + +func flattenRgListLb(listLb *rg.ListLB) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(listLb.Data)) + for _, lb := range listLb.Data { + temp := map[string]interface{}{ + "ha_mode": lb.HAMode, + "acl": lb.ACL, + "backends": flattenBackends(lb.Backends), + "created_by": lb.CreatedBy, + "created_time": lb.CreatedTime, + "deleted_by": lb.DeletedBy, + "deleted_time": lb.DeletedTime, + "desc": lb.Description, + "dp_api_user": lb.DPAPIUser, + "extnet_id": lb.ExtNetID, + "frontends": flattenFrontends(lb.Frontends), + "gid": lb.GID, + "guid": lb.GUID, + "id": lb.ID, + "image_id": lb.ImageID, + "milestones": lb.Milestones, + "name": lb.Name, + "primary_node": flattenNode(lb.PrimaryNode), + "rg_name": lb.RGName, + "secondary_node": flattenNode(lb.SecondaryNode), + "status": lb.Status, + "tech_status": lb.TechStatus, + "updated_by": lb.UpdatedBy, + "updated_time": lb.UpdatedTime, + "vins_id": lb.VINSID, + } + res = append(res, temp) + } + return res +} + +func flattenNode(node rg.RecordNode) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "backend_ip": node.BackendIP, + "compute_id": node.ComputeID, + "frontend_ip": node.FrontendIP, + "guid": node.GUID, + "mgmt_ip": node.MGMTIP, + "network_id": node.NetworkID, + } + res = append(res, temp) + return res +} + +func flattenFrontends(list rg.ListFrontends) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + for _, front := range list { + temp := map[string]interface{}{ + "backend": front.Backend, + "bindings": flattenBindings(front.Bindings), + "guid": front.GUID, + "name": front.Name, + } + res = append(res, temp) + } + + return res +} + +func flattenBindings(list rg.ListBindings) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + for _, bind := range list { + temp := map[string]interface{}{ + "address": bind.Address, + "guid": bind.GUID, + "name": bind.Name, + "port": bind.Port, + } + res = append(res, temp) + } + + return res +} + +func flattenBackends(b rg.ListBackends) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(b)) + for _, item := range b { + temp := map[string]interface{}{ + "algorithm": item.Algorithm, + "guid": item.GUID, + "name": item.Name, + "server_default_settings": flattenServerSettings(item.ServerDefaultSettings), + "servers": flattenListServers(item.Servers), + } + res = append(res, temp) + } + return res +} + +func flattenListServers(list rg.ListServers) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list)) + for _, serv := range list { + temp := map[string]interface{}{ + "address": serv.Address, + "check": serv.Check, + "guid": serv.GUID, + "name": serv.Name, + "port": serv.Port, + "server_settings": flattenServerSettings(serv.ServerSettings), + } + res = append(res, temp) + } + + return res +} + +func flattenServerSettings(settings rg.ServerSettings) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "inter": settings.Inter, + "guid": settings.GUID, + "down_inter": settings.DownInter, + "rise": settings.Rise, + "fall": settings.Fall, + "slow_start": settings.SlowStart, + "max_conn": settings.MaxConn, + "max_queue": settings.MaxQueue, + "weight": settings.Weight, + } + res = append(res, temp) + return res +} + +func flattenRgList(rgl *rg.ListRG) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rgl.Data)) + for _, rg := range rgl.Data { + temp := map[string]interface{}{ + "account_id": rg.AccountID, + "account_name": rg.AccountName, + "acl": flattenRgAcl(rg.ACL), + "compute_features": rg.ComputeFeatures, + "cpu_allocation_parameter": rg.CPUAllocationParameter, + "cpu_allocation_ratio": rg.CPUAllocationRatio, + "created_by": rg.CreatedBy, + "created_time": rg.CreatedTime, + "def_net_id": rg.DefNetID, + "def_net_type": rg.DefNetType, + "deleted_by": rg.DeletedBy, + "deleted_time": rg.DeletedTime, + "desc": rg.Description, + "dirty": rg.Dirty, + "gid": rg.GID, + "guid": rg.GUID, + "rg_id": rg.ID, + "lock_status": rg.LockStatus, + "milestones": rg.Milestones, + "name": rg.Name, + "resource_limits": flattenRgResourceLimits(rg.ResourceLimits), + "secret": rg.Secret, + "status": rg.Status, + "updated_by": rg.UpdatedBy, + "updated_time": rg.UpdatedTime, + "vins": rg.VINS, + "vms": rg.VMs, + "sdn_access_group_id": rg.SDNAccessGroupID, + "storage_policy_ids": rg.StoragePolicyIDs, + } + res = append(res, temp) + } + return res + +} + +func flattenRgListVins(lv *rg.ListVINS) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(lv.Data)) + for _, vins := range lv.Data { + temp := map[string]interface{}{ + "account_id": vins.AccountID, + "account_name": vins.AccountName, + "computes": vins.Computes, + "created_by": vins.CreatedBy, + "created_time": vins.CreatedTime, + "deleted_by": vins.DeletedBy, + "deleted_time": vins.DeletedTime, + "external_ip": vins.ExternalIP, + "extnet_id": vins.ExtnetId, + "free_ips": vins.FreeIPs, + "id": vins.ID, + "name": vins.Name, + "network": vins.Network, + "pri_vnf_dev_id": vins.PriVNFDevID, + "rg_id": vins.RGID, + "rg_name": vins.RGName, + "status": vins.Status, + "updated_by": vins.UpdatedBy, + "updated_time": vins.UpdatedTime, + } + + res = append(res, temp) + } + + return res +} + +func flattenRgListPfw(listPfw *rg.ListPFW) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(listPfw.Data)) + for _, pfw := range listPfw.Data { + temp := map[string]interface{}{ + "public_port_end": pfw.PublicPortEnd, + "public_port_start": pfw.PublicPortStart, + "vm_id": pfw.VMID, + "vm_ip": pfw.VMIP, + "vm_name": pfw.VMName, + "vm_port": pfw.VMPort, + "vins_id": pfw.VINSID, + "vins_name": pfw.VINSName, + } + res = append(res, temp) + } + + return res +} + +func flattenResourceRG(d *schema.ResourceData, rgData *rg.RecordRG) { + d.Set("account_id", rgData.AccountID) + d.Set("gid", rgData.GID) + d.Set("rg_name", rgData.Name) + d.Set("resource_limits", flattenRgResourceLimits(rgData.ResourceLimits)) + d.Set("storage_policy", flattenRgStoragePolicy(rgData.ResourceLimits.StoragePolicies)) + d.Set("description", rgData.Description) + d.Set("uniq_pools", rgData.UniqPools) + d.Set("cpu_allocation_parameter", rgData.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", rgData.CPUAllocationRatio) + d.Set("acl", flattenRgAcl(rgData.ACL)) + d.Set("account_name", rgData.AccountName) + d.Set("created_by", rgData.CreatedBy) + d.Set("created_time", rgData.CreatedTime) + d.Set("def_net_id", rgData.DefNetID) + d.Set("deleted_by", rgData.DeletedBy) + d.Set("deleted_time", rgData.DeletedTime) + d.Set("guid", rgData.GUID) + d.Set("rg_id", rgData.ID) + d.Set("lock_status", rgData.LockStatus) + d.Set("milestones", rgData.Milestones) + d.Set("resource_types", rgData.ResTypes) + d.Set("secret", rgData.Secret) + d.Set("status", rgData.Status) + d.Set("updated_by", rgData.UpdatedBy) + d.Set("updated_time", rgData.UpdatedTime) + d.Set("vins", rgData.VINS) + d.Set("vms", rgData.VMs) + d.Set("sdn_access_group_id", rgData.SDNAccessGroupID) + d.Set("storage_policy_ids", rgData.StoragePolicyIDs) +} + +func flattenRgStoragePolicy(spList []rg.StoragePolicy) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(spList)) + for _, sp := range spList { + temp := map[string]interface{}{ + "id": sp.ID, + "limit": sp.Limit, + } + + res = append(res, temp) + } + + return res +} diff --git a/internal/service/cloudbroker/rg/models.go b/internal/service/cloudbroker/rg/models.go new file mode 100644 index 00000000..7b3841ae --- /dev/null +++ b/internal/service/cloudbroker/rg/models.go @@ -0,0 +1,144 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +type ResourceLimits struct { + CUC float64 `json:"CU_C"` + CUD float64 `json:"CU_D"` + CUI float64 `json:"CU_I"` + CUM float64 `json:"CU_M"` + GpuUnits float64 `json:"gpu_units"` +} + +type ResgroupRecord struct { + ACLs []AccountAclRecord `json:"acl"` + AccountID int `json:"accountId"` + AccountName string `json:"accountName"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DefaultNetID int `json:"def_net_id"` + DefaultNetType string `json:"def_net_type"` + DeletedBy string `json:"deletedBy"` + DeletedTime int `json:"deletedTime"` + Decsription string `json:"desc"` + GridID int `json:"gid"` + GUID int `json:"guid"` + ID uint `json:"id"` + LockStatus string `json:"lockStatus"` + Milestones int `json:"milestones"` + Name string `json:"name"` + ResourceLimits ResourceLimits `json:"resourceLimits"` + Secret string `json:"secret"` + Status string `json:"status"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + Vins []int `json:"vins"` + Computes []int `json:"vms"` +} + +type ResgroupListResp []ResgroupRecord + +type ResgroupUpdateParam struct { + RgId int `json:"rgId"` + Name string `json:"name"` + Desc string `json:"decs"` + Ram int `json:"maxMemoryCapacity"` + Disk int `json:"maxVDiskCapacity"` + Cpu int `json:"maxCPUCapacity"` + NetTraffic int `json:"maxNetworkPeerTransfer"` +} + +type AccountAclRecord struct { + IsExplicit bool `json:"explicit"` + Guid string `json:"guid"` + Rights string `json:"right"` + Status string `json:"status"` + Type string `json:"type"` + UgroupID string `json:"userGroupId"` + CanBeDeleted bool `json:"canBeDeleted"` +} + +type ResgroupGetResp struct { + ACLs []UserAclRecord `json:"ACLs"` + Usage UsageRecord `json:"Resources"` + AccountID int `json:"accountId"` + AccountName string `json:"accountName"` + GridID int `json:"gid"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DefaultNetID int `json:"def_net_id"` + DefaultNetType string `json:"def_net_type"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + Desc string `json:"desc"` + ID uint `json:"id"` + LockStatus string `json:"lockStatus"` + Name string `json:"name"` + Quota QuotaRecord `json:"resourceLimits"` + Status string `json:"status"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + Vins []int `json:"vins"` + Computes []int `json:"vms"` + + Ignored map[string]interface{} `json:"-"` +} + +type UserAclRecord struct { + IsExplicit bool `json:"explicit"` + Rights string `json:"right"` + Status string `json:"status"` + Type string `json:"type"` + UgroupID string `json:"userGroupId"` + // CanBeDeleted bool `json:"canBeDeleted"` +} + +type QuotaRecord struct { // this is how quota is reported by /api/.../rg/get + Cpu float64 `json:"CU_C"` // CPU count in pcs + Ram float64 `json:"CU_M"` // RAM volume in MB, it is STILL reported as FLOAT + Disk float64 `json:"CU_D"` // Disk capacity in GB + ExtIPs float64 `json:"CU_I"` // Ext IPs count + GpuUnits float64 `json:"gpu_units"` // GPU count +} + +type ResourceRecord struct { // this is how actual usage is reported by /api/.../rg/get + Cpu int `json:"cpu"` + Disk int `json:"disksize"` + ExtIPs int `json:"extips"` + Gpu int `json:"gpu"` + Ram int `json:"ram"` +} + +type UsageRecord struct { + Current ResourceRecord `json:"Current"` + Reserved ResourceRecord `json:"Reserved"` +} diff --git a/internal/service/cloudbroker/rg/quota_subresource.go b/internal/service/cloudbroker/rg/quota_subresource.go new file mode 100644 index 00000000..946208fb --- /dev/null +++ b/internal/service/cloudbroker/rg/quota_subresource.go @@ -0,0 +1,132 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" +) + +func makeQuotaRecord(arg_list []interface{}) QuotaRecord { + quota := QuotaRecord{ + Cpu: -1, + Ram: -1., // this is float64, but may change in the future + Disk: -1, + ExtIPs: -1, + GpuUnits: -1, + } + subres_data := arg_list[0].(map[string]interface{}) + + if subres_data["cpu"].(int) > 0 { + quota.Cpu = subres_data["cpu"].(float64) + } + + if subres_data["disk"].(int) > 0 { + quota.Disk = subres_data["disk"].(float64) + } + + if subres_data["ram"].(float64) > 0 { + quota.Ram = subres_data["ram"].(float64) + } + + if subres_data["ext_ips"].(int) > 0 { + quota.ExtIPs = subres_data["ext_ips"].(float64) + } + + if subres_data["gpu_units"].(int) > 0 { + quota.GpuUnits = subres_data["gpu_units"].(float64) + } + + return quota +} + +func parseQuota(quota rg.ResourceLimits) []interface{} { + quota_map := make(map[string]interface{}) + + quota_map["cpu"] = quota.CUC + quota_map["ram"] = quota.CUM + quota_map["disk"] = quota.CuD + quota_map["ext_ips"] = quota.CUI + quota_map["gpu_units"] = quota.GPUUnits + + result := make([]interface{}, 1) + result[0] = quota_map + + return result // this result will be used to d.Set("quota,") of dataSourceResgroup schema +} + +func quotaRgSubresourceSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeFloat, + Optional: true, + Default: -1, + Description: "Limit on the total number of CPUs in this resource group.", + }, + + "ram": { + Type: schema.TypeFloat, // NB: API expects and returns this as float in units of MB! This may be changed in the future. + Optional: true, + Default: -1., + Description: "Limit on the total amount of RAM in this resource group, specified in MB.", + }, + + "disk": { + Type: schema.TypeFloat, + Optional: true, + Default: -1, + Description: "Limit on the total volume of storage resources in this resource group, specified in GB.", + }, + + "ext_traffic": { + Type: schema.TypeFloat, + Optional: true, + Default: -1, + Description: "Limit on the total ingress network traffic for this resource group, specified in GB.", + }, + + "ext_ips": { + Type: schema.TypeFloat, + Optional: true, + Default: -1, + Description: "Limit on the total number of external IP addresses this resource group can use.", + }, + + "gpu_units": { + Type: schema.TypeFloat, + Optional: true, + Default: -1, + Description: "Limit on the total number of virtual GPUs this resource group can use.", + }, + } + return rets +} diff --git a/internal/service/cloudbroker/rg/resource_check_input_values.go b/internal/service/cloudbroker/rg/resource_check_input_values.go new file mode 100644 index 00000000..951740ce --- /dev/null +++ b/internal/service/cloudbroker/rg/resource_check_input_values.go @@ -0,0 +1,32 @@ +package rg + +import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, accountId, gid uint64) diag.Diagnostics { + var errs []error + + if err := ic.ExistAccount(ctx, accountId, c); err != nil { + errs = append(errs, err) + } + + if err := ic.ExistGID(ctx, gid, c); err != nil { + errs = append(errs, err) + } + + extNetId, ok := d.GetOk("ext_net_id") + if ok { + if err := ic.ExistExtNetInRG(ctx, uint64(extNetId.(int)), accountId, c); err != nil { + errs = append(errs, err) + } + } + return dc.ErrorsToDiagnostics(errs) +} diff --git a/internal/service/cloudbroker/rg/resource_rg.go b/internal/service/cloudbroker/rg/resource_rg.go new file mode 100644 index 00000000..2facc009 --- /dev/null +++ b/internal/service/cloudbroker/rg/resource_rg.go @@ -0,0 +1,815 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "fmt" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d", + d.Get("rg_name").(string), d.Get("account_id").(int)) + c := m.(*controller.ControllerCfg) + + accountId := uint64(d.Get("account_id").(int)) + gid := uint64(d.Get("gid").(int)) + req := rg.CreateRequest{ + AccountID: accountId, + GID: gid, + Name: d.Get("rg_name").(string), + } + + if diags := checkParamsExistence(ctx, d, c, accountId, gid); diags != nil { + return diags + } + + if resLimits, ok := d.GetOk("resource_limits"); ok { + resLimits := resLimits.([]interface{})[0] + resLimitsConv := resLimits.(map[string]interface{}) + if resLimitsConv["cu_m"] != nil { + maxMemCap := int64(resLimitsConv["cu_m"].(float64)) + if maxMemCap == 0 { + req.MaxMemoryCapacity = -1 + } else { + req.MaxMemoryCapacity = maxMemCap + } + } + if resLimitsConv["cu_dm"] != nil { + maxDiskCap := int64(resLimitsConv["cu_dm"].(float64)) + if maxDiskCap == 0 { + req.MaxVDiskCapacity = -1 + } else { + req.MaxVDiskCapacity = maxDiskCap + } + } + if resLimitsConv["cu_c"] != nil { + maxCPUCap := int64(resLimitsConv["cu_c"].(float64)) + if maxCPUCap == 0 { + req.MaxCPUCapacity = -1 + } else { + req.MaxCPUCapacity = maxCPUCap + } + } + if resLimitsConv["cu_i"] != nil { + maxNumPublicIP := int64(resLimitsConv["cu_i"].(float64)) + if maxNumPublicIP == 0 { + req.MaxNumPublicIP = -1 + } else { + req.MaxNumPublicIP = maxNumPublicIP + } + } + } + + if owner, ok := d.GetOk("owner"); ok { + req.Owner = owner.(string) + } + + if _, ok := d.GetOk("def_net"); !ok { + if defNetType, ok := d.GetOk("def_net_type"); ok { + if defNetType.(string) == "PRIVATE" { + return diag.Errorf("resourceResgroupCreate: cannot create RG with def_net_type=\"PRIVATE\": no ViNSes exist in a newly created RG. Use def_net_type=\"PRIVATE\" only when updating an existing RG that already contains a ViNS") + } + req.DefNet = defNetType.(string) + } + } else { + req.DefNet = "NONE" + } + + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + + if extNetId, ok := d.GetOk("ext_net_id"); ok { + req.ExtNetID = uint64(extNetId.(int)) + } + + if extIp, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = extIp.(string) + } + + if uniqPools, ok := d.GetOk("uniq_pools"); ok { + uniqPools := uniqPools.([]interface{}) + + for _, pool := range uniqPools { + req.UniqPools = append(req.UniqPools, pool.(string)) + } + } + + if sdnAccessGroupID, ok := d.GetOk("sdn_access_group_id"); ok { + req.SDNAccessGroupID = sdnAccessGroupID.(string) + } + + if storagePolicies, ok := d.GetOk("storage_policy"); ok { + var id uint64 + var limit int + + if storagePolicies.(*schema.Set).Len() > 0 { + spList := storagePolicies.(*schema.Set).List() + for _, spInterface := range spList { + sps := spInterface.(map[string]interface{}) + id = uint64(sps["id"].(int)) + limit = sps["limit"].(int) + + spModel := rg.StoragePolicy{ + ID: id, + Limit: limit, + } + + req.StoragePolicies = append(req.StoragePolicies, spModel) + } + } + } + + rgID, err := c.CloudBroker().RG().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(rgID, 10)) + d.Set("rg_id", rgID) + + w := dc.Warnings{} + + // compute_features is not set up during create request and is updated after create on purpose: + // 1. to support configuration as final state in resource group, + // 2. not to support compute_features inheritance from account. + // other implementation may result in inconsistency between user configuration and state after rg creation. + // note that call for compute features updated required even if compute_features is null in configuration, in order not ot inherit from account. + if err := resourceRGChangeComputeFeatures(ctx, d, m); err != nil { + w.Add(err) + } + + if _, ok := d.GetOk("access"); ok { + if errs := resourceRGAccessGrant(ctx, d, m); len(errs) != 0 { + for _, err := range errs { + w.Add(err) + } + } + } + + if defNet, ok := d.GetOk("def_net"); ok { + if defNet.(*schema.Set).Len() > 0 { + defNetList := defNet.(*schema.Set).List() + defNetItem := defNetList[0].(map[string]interface{}) + if defNetItem["net_type"].(string) == "PRIVATE" { + return diag.Errorf("resourceResgroupCreate: cannot create RG with def_net net_type=\"PRIVATE\": no ViNSes exist in a newly created RG. Use net_type=\"PRIVATE\" in def_net block only when updating an existing RG that already contains a ViNS") + } + } + if err := resourceRGSetDefNet(ctx, d, m); err != nil { + w.Add(err) + } + } + + if _, ok := d.GetOk("cpu_allocation_parameter"); ok { + if err := resourceRGSetCPUAllocationParameter(ctx, d, m); err != nil { + w.Add(err) + } + } + + if _, ok := d.GetOk("cpu_allocation_ratio"); ok { + if err := resourceRGSetCPUAllocationRatio(ctx, d, m); err != nil { + w.Add(err) + } + } + + enable, ok := d.GetOk("enable") + if ok && !enable.(bool) { + _, err := c.CloudBroker().RG().Disable(ctx, rg.DisableRequest{RGID: rgID}) + if err != nil { + w.Add(err) + } + } + + return append(resourceResgroupRead(ctx, d, m), w.Get()...) +} + +func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceResgroupRead: called for RG name %s, account ID %d", + d.Get("rg_name").(string), d.Get("account_id").(int)) + + //c := m.(*controller.ControllerCfg) + rgData, err := utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty + return diag.FromErr(err) + } + + hasChanged := false + + switch rgData.Status { + case status.Modeled: + return diag.Errorf("The resource group is in status: %s, please, contact support for more information", rgData.Status) + case status.Created: + case status.Enabled: + case status.Deleted: + //restoreReq := rg.RestoreRequest{ + // RGID: rgData.ID, + // Reason: "automatic restore of resource by terraform", + //} + //enableReq := rg.EnableRequest{ + // RGID: rgData.ID, + // Reason: "automatic enable of resource by terraform", + //} + // + //log.Debugf("restoring RG") + //_, err := c.CloudBroker().RG().Restore(ctx, restoreReq) + //if err != nil { + // return diag.FromErr(err) + //} + // + //log.Debugf("enabling RG") + //_, err = c.CloudBroker().RG().Enable(context.Background(), enableReq) + //if err != nil { + // return diag.FromErr(err) + //} + // + //hasChanged = true + case status.Deleting: + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be read because it has been destroyed") + //return resourceResgroupCreate(ctx, d, m) + case status.Destroying: + case status.Disabled: + case status.Disabling: + case status.Enabled: + case status.Enabling: + } + + if hasChanged { + rgData, err = utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + flattenResourceRG(d, rgData) + + return nil +} + +func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceResgroupUpdate: called for RG name %s, account ID %d", + d.Get("rg_name").(string), d.Get("account_id").(int)) + + c := m.(*controller.ControllerCfg) + accountId := uint64(d.Get("account_id").(int)) + gid := uint64(d.Get("gid").(int)) + + if diags := checkParamsExistence(ctx, d, c, accountId, gid); diags != nil { + return diags + } + + rgData, err := utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + hasChanged := false + + switch rgData.Status { + case status.Modeled: + case status.Created: + case status.Enabled: + case status.Deleted: + restore, ok := d.GetOk("restore") + if ok && restore.(bool) { + restoreReq := rg.RestoreRequest{ + RGID: rgData.ID, + } + + _, err := c.CloudBroker().RG().Restore(ctx, restoreReq) + if err != nil { + return diag.FromErr(err) + } + + hasChanged = true + } + + enable, ok := d.GetOk("enable") + if ok && enable.(bool) { + enableReq := rg.EnableRequest{ + RGID: rgData.ID, + } + + _, err = c.CloudBroker().RG().Enable(ctx, enableReq) + if err != nil { + return diag.FromErr(err) + } + + hasChanged = true + } + case status.Deleting: + case status.Destroyed: + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + //return resourceResgroupCreate(ctx, d, m) + case status.Destroying: + case status.Disabled: + case status.Disabling: + case status.Enabled: + case status.Enabling: + } + + if hasChanged { + rgData, err = utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + /* NOTE: we do not allow changing the following attributes of an existing RG via terraform: + - def_net_type + - ext_net_id + - ext_ip + + The following code fragment checks if any of these have been changed and generates error. + */ + for _, attr := range []string{"def_net_type", "ext_ip"} { + attrNew, attrOld := d.GetChange(attr) + if attrNew.(string) != attrOld.(string) { + return diag.FromErr(fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing %s for existing RG is not allowed", d.Id(), attr)) + } + } + + attrNew, attrOld := d.GetChange("ext_net_id") + if attrNew.(int) != attrOld.(int) { + return diag.FromErr(fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing ext_net_id for existing RG is not allowed", d.Id())) + } + + doGeneralUpdate := false + + req := rg.UpdateRequest{ + RGID: rgData.ID, + } + + if d.HasChange("rg_name") { + req.Name = d.Get("rg_name").(string) + doGeneralUpdate = true + } + + if d.HasChange("resource_limits") { + if _, ok := d.GetOk("resource_limits"); ok { + resLimits := d.Get("resource_limits").([]interface{})[0] + resLimitsConv := resLimits.(map[string]interface{}) + if resLimitsConv["cu_m"] != nil { + maxMemCap := int64(resLimitsConv["cu_m"].(float64)) + if maxMemCap == 0 { + req.MaxMemoryCapacity = -1 + } else { + req.MaxMemoryCapacity = maxMemCap + } + } + if resLimitsConv["cu_dm"] != nil { + maxDiskCap := int64(resLimitsConv["cu_dm"].(float64)) + if maxDiskCap == 0 { + req.MaxVDiskCapacity = -1 + } else { + req.MaxVDiskCapacity = maxDiskCap + } + } + if resLimitsConv["cu_c"] != nil { + maxCPUCap := int64(resLimitsConv["cu_c"].(float64)) + if maxCPUCap == 0 { + req.MaxCPUCapacity = -1 + } else { + req.MaxCPUCapacity = maxCPUCap + } + } + if resLimitsConv["cu_i"] != nil { + maxNumPublicIP := int64(resLimitsConv["cu_i"].(float64)) + if maxNumPublicIP == 0 { + req.MaxNumPublicIP = -1 + } else { + req.MaxNumPublicIP = maxNumPublicIP + } + } + + doGeneralUpdate = true + } + } + + if d.HasChange("description") { + req.Description = d.Get("description").(string) + doGeneralUpdate = true + } + + if d.HasChange("storage_policy") { + needUpdate, updateEl, err := utilityRGUpdateStPolicy(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + if needUpdate { + // spList := storagePolicies.(*schema.Set).List() + var id uint64 + var limit int + for _, spInterface := range updateEl { + // sps := spInterface.(map[string]interface{}) + id = uint64(spInterface["id"].(int)) + limit = spInterface["limit"].(int) + + spModel := rg.StoragePolicy{ + ID: id, + Limit: limit, + } + + req.StoragePolicies = append(req.StoragePolicies, spModel) + } + doGeneralUpdate = needUpdate + } + } + + if d.HasChange("uniq_pools") { + uniqPools := d.Get("uniq_pools").([]interface{}) + if len(uniqPools) == 0 { + req.ClearUniqPools = true + } + for _, pool := range uniqPools { + req.UniqPools = append(req.UniqPools, pool.(string)) + } + + doGeneralUpdate = true + } + + if doGeneralUpdate { + log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG") + _, err := c.CloudBroker().RG().Update(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + log.Debugf("resourceResgroupUpdate: no difference between old and new state - no update on the RG will be done") + } + + if d.HasChange("access") { + if err := resourceRGChangeAccess(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("def_net") { + oldDefNet, newDefNet := d.GetChange("def_net") + if newDefNet.(*schema.Set).Len() > 0 { + defNetList := newDefNet.(*schema.Set).List() + defNetItem := defNetList[0].(map[string]interface{}) + netType := defNetItem["net_type"].(string) + netID := uint64(defNetItem["net_id"].(int)) + + if netType == "PRIVATE" { + if netID == 0 { + if len(rgData.VINS) == 0 { + return diag.Errorf("resourceResgroupUpdate: cannot set def_net net_type=\"PRIVATE\" for RG ID %d: no ViNSes exist in this RG", rgData.ID) + } + } else { + found := false + for _, vinsID := range rgData.VINS { + if vinsID == netID { + found = true + break + } + } + if !found { + return diag.Errorf("resourceResgroupUpdate: cannot set def_net net_type=\"PRIVATE\" for RG ID %d: ViNS ID %d is not found in this RG", rgData.ID, netID) + } + } + } + } + if oldDefNet.(*schema.Set).Len() > 0 { + _, err := c.CloudBroker().RG().RemoveDefNet(ctx, rg.RemoveDefNetRequest{RGID: rgData.ID}) + if err != nil { + return diag.FromErr(err) + } + } + if err := resourceRGSetDefNet(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("cpu_allocation_parameter") { + if err := resourceRGSetCPUAllocationParameter(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("cpu_allocation_ratio") { + if err := resourceRGSetCPUAllocationRatio(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("enable") { + if err := resourceRGChangeEnable(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("compute_features") { + if err := resourceRGChangeComputeFeatures(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + return resourceResgroupRead(ctx, d, m) +} + +func resourceResgroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %d", + d.Get("rg_name").(string), d.Get("account_id").(int)) + + rg_facts, err := utilityResgroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + req := rg.DeleteRequest{ + RGID: rg_facts.ID, + } + + if force, ok := d.GetOk("force"); ok { + req.Force = force.(bool) + } + if permanently, ok := d.GetOk("permanently"); ok { + req.Permanently = permanently.(bool) + } + + c := m.(*controller.ControllerCfg) + _, err = c.CloudBroker().RG().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceRGAccessGrant(ctx context.Context, d *schema.ResourceData, m interface{}) []error { + var errs []error + + access := d.Get("access") + rgId := uint64(d.Get("rg_id").(int)) + log.Debugf("resourceRGAccessGrant: access %v for rg id %d", access, rgId) + + c := m.(*controller.ControllerCfg) + + var user, right string + + if access.(*schema.Set).Len() > 0 { + accessList := access.(*schema.Set).List() + for _, accessIface := range accessList { + access := accessIface.(map[string]interface{}) + user = access["user"].(string) + right = access["right"].(string) + + req := rg.AccessGrantRequest{ + RGID: rgId, + User: user, + Right: right, + } + + if _, err := c.CloudBroker().RG().AccessGrant(ctx, req); err != nil { + errs = append(errs, err) + } + } + } + + return errs +} + +func resourceRGSetDefNet(ctx context.Context, d *schema.ResourceData, m interface{}) error { + defNet := d.Get("def_net") + rgId := uint64(d.Get("rg_id").(int)) + log.Debugf("resourceRGSetDefNet: def_net %v for rg id %d", defNet, rgId) + + c := m.(*controller.ControllerCfg) + + if defNet.(*schema.Set).Len() > 0 { + defNetList := defNet.(*schema.Set).List() + defNetItem := defNetList[0].(map[string]interface{}) + + netType := defNetItem["net_type"].(string) + + req := rg.SetDefNetRequest{ + RGID: rgId, + NetType: netType, + } + + if netID, ok := defNetItem["net_id"]; ok { + req.NetID = uint64(netID.(int)) + } + + _, err := c.CloudBroker().RG().SetDefNet(ctx, req) + return err + } + + return nil +} + +func resourceRGSetCPUAllocationParameter(ctx context.Context, d *schema.ResourceData, m interface{}) error { + cpuAllocationParameter := d.Get("cpu_allocation_parameter").(string) + log.Debugf("resourceRGSetCPUAllocationParameter: cpuAllocationParameter %s for rg id %d", cpuAllocationParameter, uint64(d.Get("rg_id").(int))) + + c := m.(*controller.ControllerCfg) + + req := rg.SetCPUAllocationParameterRequest{ + RGID: uint64(d.Get("rg_id").(int)), + StrictLoose: cpuAllocationParameter, + } + + _, err := c.CloudBroker().RG().SetCPUAllocationParameter(ctx, req) + return err +} + +func resourceRGSetCPUAllocationRatio(ctx context.Context, d *schema.ResourceData, m interface{}) error { + // log.Debugf("resourceRGSetCPUAllocationRatio: cpuAllocationRatio %s for rg id %d", cpuAllocationRatio, uint64(d.Get("rg_id").(int))) + + c := m.(*controller.ControllerCfg) + + req := rg.SetCPUAllocationRatioRequest{ + RGID: uint64(d.Get("rg_id").(int)), + Ratio: uint64(d.Get("cpu_allocation_ratio").(int)), + } + + _, err := c.CloudBroker().RG().SetCPUAllocationRatio(ctx, req) + return err +} + +func resourceRGChangeAccess(ctx context.Context, d *schema.ResourceData, m interface{}) error { + rgId := uint64(d.Get("rg_id").(int)) + log.Debugf("resourceRGChangeAccess: for rg id %d", rgId) + + c := m.(*controller.ControllerCfg) + oldSet, newSet := d.GetChange("access") + + deletedAccess := oldSet.(*schema.Set).Difference(newSet.(*schema.Set)).List() + for _, deletedIface := range deletedAccess { + deleteItem := deletedIface.(map[string]interface{}) + user := deleteItem["user"].(string) + + reqRevoke := rg.AccessRevokeRequest{ + RGID: rgId, + User: user, + } + + _, err := c.CloudBroker().RG().AccessRevoke(ctx, reqRevoke) + if err != nil { + return err + } + } + + addedAccess := newSet.(*schema.Set).Difference(oldSet.(*schema.Set)).List() + for _, addedIface := range addedAccess { + addedItem := addedIface.(map[string]interface{}) + user := addedItem["user"].(string) + right := addedItem["right"].(string) + + reqGrant := rg.AccessGrantRequest{ + RGID: rgId, + User: user, + Right: right, + } + + _, err := c.CloudBroker().RG().AccessGrant(ctx, reqGrant) + if err != nil { + return err + } + } + + return nil +} + +func resourceRGChangeEnable(ctx context.Context, d *schema.ResourceData, m interface{}) error { + rgId := uint64(d.Get("rg_id").(int)) + rgStatus := d.Get("status").(string) + enable := d.Get("enable").(bool) + log.Debugf("resourceRGChangeEnable: enable %t for rg id %d with status %s", enable, rgId, rgStatus) + + c := m.(*controller.ControllerCfg) + + if enable && rgStatus == status.Disabled { + if _, err := c.CloudBroker().RG().Enable(ctx, rg.EnableRequest{RGID: rgId}); err != nil { + return err + } + + } else if !enable && (rgStatus == status.Enabled || rgStatus == status.Created) { + req := rg.DisableRequest{RGID: rgId} + + if _, err := c.CloudBroker().RG().Disable(ctx, req); err != nil { + return err + } + } + + return nil +} + +func resourceRGChangeComputeFeatures(ctx context.Context, d *schema.ResourceData, m interface{}) error { + rgId := uint64(d.Get("rg_id").(int)) + compFeaturesInterface := d.Get("compute_features").(*schema.Set).List() + + compFeatures := make([]string, 0, len(compFeaturesInterface)) + for _, item := range compFeaturesInterface { + compFeatures = append(compFeatures, item.(string)) + } + + log.Debugf("resourceRGChangeComputeFeatures: compute_features %v for rg id %d", compFeatures, rgId) + + c := m.(*controller.ControllerCfg) + + req := rg.UpdateComputeFeaturesRequest{ + RGID: rgId, + ComputeFeatures: compFeatures, + } + + _, err := c.CloudBroker().RG().UpdateComputeFeatures(ctx, req) + if err != nil { + return err + } + + return nil +} + +func ResourceResgroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceResgroupCreate, + ReadContext: resourceResgroupRead, + UpdateContext: resourceResgroupUpdate, + DeleteContext: resourceResgroupDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error { + if diff.HasChange("def_net") { + diff.SetNewComputed("def_net_id") + } + if diff.HasChange("storage_policy") { + diff.SetNewComputed("storage_policy_ids") + diff.SetNewComputed("resource_limits") + } + if diff.HasChanges() { + diff.SetNewComputed("updated_by") + diff.SetNewComputed("updated_time") + } + return nil + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout900s, + Default: &constants.Timeout300s, + }, + + Schema: resourceRgSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/rg/schema.go b/internal/service/cloudbroker/rg/schema.go new file mode 100644 index 00000000..a9a1b27c --- /dev/null +++ b/internal/service/cloudbroker/rg/schema.go @@ -0,0 +1,2595 @@ +package rg + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceRgSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + }, + + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "email": { + Type: schema.TypeString, + Computed: true, + }, + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_type": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dirty": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "resource_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "computes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "sdn_access_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } +} + +func dataSourceRgAuditsSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "call": { + Type: schema.TypeString, + Computed: true, + }, + "responsetime": { + Type: schema.TypeFloat, + Computed: true, + }, + "statuscode": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } +} + +func dataSourceRgAffinityGroupsListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + + "affinity_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func dataSourceRgAffinityGroupsGetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "affinity_group": { + Type: schema.TypeString, + Required: true, + Description: "Affinity group label", + }, + + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } + + return res +} + +func dataSourceRgAffinityGroupComputesSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "affinity_group": { + Type: schema.TypeString, + Required: true, + Description: "Affinity group label", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "other_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "other_node_indirect": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "other_node_indirect_soft": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "other_node_soft": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "same_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "same_node_soft": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + } + + return res +} + +func dataSourceRGResourceConsumptionGetSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + }, + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + } + + return res +} + +func dataSourceRGResourceConsumptionListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "consumed": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "reserved": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceRgUsageSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + }, + + "cpu": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "extips": { + Type: schema.TypeInt, + Computed: true, + }, + "gpu": { + Type: schema.TypeInt, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "seps": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeString, + Computed: true, + }, + "data_name": { + Type: schema.TypeString, + Computed: true, + }, + "disk_size": { + Type: schema.TypeFloat, + Computed: true, + }, + "disk_size_max": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + } + + return res +} + +func dataSourceRgListComputesSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by compute ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by account ID", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by tech. status", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "FIlter by IP address", + }, + "extnet_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by extnet name", + }, + "extnet_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by extnet ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_label": { + Type: schema.TypeString, + Computed: true, + }, + "affinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "key": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + "topology": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "affinity_weight": { + Type: schema.TypeInt, + Computed: true, + }, + "antiaffinity_rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "key": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, + "topology": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "cpus": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + }, + "registered": { + Type: schema.TypeBool, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "total_disks_size": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vins_connected": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func dataSourceRgListLbSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by tech. status", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "front_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by frontend IP", + }, + "back_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by backend IP", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ha_mode": { + Type: schema.TypeBool, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "backends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "algorithm": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "server_default_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "down_inter": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "slow_start": { + Type: schema.TypeInt, + Computed: true, + }, + "max_conn": { + Type: schema.TypeInt, + Computed: true, + }, + "max_queue": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "servers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "check": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + "server_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "inter": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "down_inter": { + Type: schema.TypeInt, + Computed: true, + }, + "rise": { + Type: schema.TypeInt, + Computed: true, + }, + "fall": { + Type: schema.TypeInt, + Computed: true, + }, + "slow_start": { + Type: schema.TypeInt, + Computed: true, + }, + "max_conn": { + Type: schema.TypeInt, + Computed: true, + }, + "max_queue": { + Type: schema.TypeInt, + Computed: true, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dp_api_user": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontends": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend": { + Type: schema.TypeString, + Computed: true, + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "primary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_node": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "frontend_ip": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "mgmt_ip": { + Type: schema.TypeString, + Computed: true, + }, + "network_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func dataSourceRgListDeletedSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by account ID", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by account name", + }, + "created_after": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter RGs created after certain point in time (unix timestamp)", + }, + "created_before": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter RGs created before certain point in time (unix timestamp)", + }, + "lock_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by lock status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_type": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dirty": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Required: true, + }, + "limit": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + }, + }, + }, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "vms": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "resource_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sdn_access_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceRgListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by account ID", + }, + "account_name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by account name", + }, + "created_after": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter RGs created after certain point in time (unix timestamp)", + }, + "created_before": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter RGs created before certain point in time (unix timestamp)", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by status", + }, + "lock_status": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by lock status", + }, + "includedeleted": { + Type: schema.TypeBool, + Optional: true, + Description: "Include deleted", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "compute_features": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "def_net_type": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "dirty": { + Type: schema.TypeBool, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_limits": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_i": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_m": { + Type: schema.TypeFloat, + Computed: true, + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Required: true, + }, + "limit": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + }, + }, + }, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "vms": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "resource_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sdn_access_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func dataSourceRgListVinsSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by account ID", + }, + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by external IP", + }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ViNS ID", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "computes": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "pri_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func dataSourceRgListPfwSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of the RG", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "public_port_end": { + Type: schema.TypeInt, + Computed: true, + }, + "public_port_start": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_ip": { + Type: schema.TypeString, + Computed: true, + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + }, + "vm_port": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func resourceRgSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + Description: "Unique ID of the account, which this resource group belongs to.", + }, + + "gid": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the grid, where this resource group is deployed.", + }, + + "rg_name": { + Type: schema.TypeString, + Required: true, + Description: "Name of this resource group. Names are case sensitive and unique within the context of a account.", + }, + + "resource_limits": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cu_c": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + Description: "MaxCPUCapacity", + }, + "cu_d": { + Type: schema.TypeFloat, + Computed: true, + }, + "cu_dm": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + Description: "MaxVDiskCapacity", + }, + "cu_i": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + Description: "MaxNumPublicIP", + }, + "cu_m": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + Description: "MaxMemoryCapacity", + }, + "gpu_units": { + Type: schema.TypeFloat, + Computed: true, + }, + "storage_policy": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + + "owner": { + Type: schema.TypeString, + Optional: true, + Description: "username - owner of this RG. Leave blank to set current user as owner", + }, + + "def_net_type": { + Type: schema.TypeString, + Optional: true, + // Default: "PRIVATE", + ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC", "NONE"}, false), + Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.", + }, + + "ipcidr": { + Type: schema.TypeString, + Optional: true, + Description: "Address of the netowrk inside the private network segment (aka ViNS) if def_net_type=PRIVATE", + }, + + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "User-defined text description of this resource group.", + }, + + "ext_net_id": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: "ID of the external network for default ViNS. Pass 0 if def_net_type=PUBLIC or no external connection required for the defult ViNS when def_net_type=PRIVATE", + }, + + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "IP address on the external netowrk to request when def_net_type=PRIVATE and ext_net_id is not 0", + }, + + "uniq_pools": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "access": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "user": { + Type: schema.TypeString, + Required: true, + Description: "User or group name to grant access", + }, + "right": { + Type: schema.TypeString, + Required: true, + Description: "Access rights to set, one of 'R', 'RCX' or 'ARCXDU'", + }, + }, + }, + }, + + "def_net": { + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC"}, false), + Description: "Network type to set. Must be on of 'PRIVATE' or 'PUBLIC'.", + }, + "net_id": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: "Network segment ID. If netType is PUBLIC and netId is 0 then default external network segment will be selected. If netType is PRIVATE and netId=0, the first ViNS defined for this RG will be selected. Otherwise, netId identifies either existing external network segment or ViNS.", + }, + }, + }, + }, + + "cpu_allocation_parameter": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "set cpu allocation parameter", + }, + + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + Description: "set cpu allocation ratio", + }, + + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "enable/disable rg", + }, + "restore": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "restore deleted rg", + }, + + "force": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "flag to force deleting resource group", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "flag to permanently delete resource group", + }, + + "compute_features": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"hugepages", "numa", "cpupin", "vfnic", "dpdk", "changemac", "trunk"}, true), + }, + }, + "sdn_access_group_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "ID of the SDN access group", + }, + "storage_policy": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Required: true, + }, + "limit": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + }, + }, + }, + }, + + "acl": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "email": { + Type: schema.TypeString, + Computed: true, + }, + "explicit": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "right": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "user_group_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the account, which this resource group belongs to.", + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + + "def_net_id": { + Type: schema.TypeInt, + Computed: true, + Description: "ID of the default network for this resource group (if any).", + }, + + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "resource_types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Current status of this resource group.", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of VINs deployed in this resource group.", + }, + "vms": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of VM ids in this resource group.", + }, + + "storage_policy_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } + + return res +} diff --git a/internal/service/cloudbroker/rg/utility_rg.go b/internal/service/cloudbroker/rg/utility_rg.go new file mode 100644 index 00000000..af8f71cf --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg.go @@ -0,0 +1,150 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.RecordRG, error) { + c := m.(*controller.ControllerCfg) + req := rg.GetRequest{} + + if d.Id() != "" { + rgId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.RGID = rgId + } else { + req.RGID = uint64(d.Get("rg_id").(int)) + } + + rgData, err := c.CloudBroker().RG().Get(ctx, req) + if err != nil { + return nil, err + } + + return rgData, nil +} + +func utilityRGUpdateStPolicy(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, []map[string]interface{}, error) { + c := m.(*controller.ControllerCfg) + + rgId, _ := strconv.ParseUint(d.Id(), 10, 64) + + addSP, delSP, updateSP := utilityGetStoragePolicyUpdate(ctx, d, m) + needUpdate := len(updateSP) > 0 + + if len(addSP) > 0 { + for _, spMap := range addSP { + req := rg.AddStoragePolicyRequest{ + RGID: rgId, + StoragePolicyID: uint64(spMap["id"].(int)), + Limit: spMap["limit"].(int), + } + log.Debugf("utilityRGUpdateStPolicy: starting to add storage policy ID:%d for rg %d", req.StoragePolicyID, req.RGID) + _, err := c.CloudBroker().RG().AddStoragePolicy(ctx, req) + if err != nil { + return needUpdate, updateSP, err + } + } + } + + if len(delSP) > 0 { + for _, spMap := range delSP { + req := rg.DelStoragePolicyRequest{ + RGID: rgId, + StoragePolicyID: uint64(spMap["id"].(int)), + } + log.Debugf("utilityRGUpdateStPolicy: starting to delete storage policy ID:%d from rg %d", req.StoragePolicyID, req.RGID) + _, err := c.CloudBroker().RG().DelStoragePolicy(ctx, req) + if err != nil { + return needUpdate, updateSP, err + } + } + } + + return needUpdate, updateSP, nil +} + +func utilityGetStoragePolicyUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) (added, deleted, updated []map[string]interface{}) { + added = make([]map[string]interface{}, 0) + deleted = make([]map[string]interface{}, 0) + updated = make([]map[string]interface{}, 0) + oldSet, newSet := d.GetChange("storage_policy") + oldList := oldSet.(*schema.Set).List() + newList := newSet.(*schema.Set).List() + + for _, oldSP := range oldList { + oldMap := oldSP.(map[string]interface{}) + found := false + for _, newSP := range newList { + newMap := newSP.(map[string]interface{}) + if oldMap["id"] == newMap["id"] { + found = true + if oldMap["limit"] != newMap["limit"] { + updated = append(added, newMap) + } + break + } + if found { + break + } + } + if found { + continue + } + deleted = append(deleted, oldMap) + } + + for _, newSP := range newList { + newMap := newSP.(map[string]interface{}) + found := false + for _, oldSP := range oldList { + oldMap := oldSP.(map[string]interface{}) + if oldMap["id"] == newMap["id"] { + found = true + break + } + } + if found { + continue + } + added = append(added, newMap) + } + + return +} diff --git a/internal/service/cloudbroker/rg/utility_rg_affinity_group_computes.go b/internal/service/cloudbroker/rg/utility_rg_affinity_group_computes.go new file mode 100644 index 00000000..f47bc63f --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_affinity_group_computes.go @@ -0,0 +1,27 @@ +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgAffinityGroupComputesCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListAffinityGroupCompute, error) { + c := m.(*controller.ControllerCfg) + req := rg.AffinityGroupComputesRequest{ + RGID: uint64(d.Get("rg_id").(int)), + AffinityGroup: d.Get("affinity_group").(string), + } + + log.Debugf("utilityRgAffinityGroupComputesCheckPresence: load affinity group computes") + res, err := c.CloudBroker().RG().AffinityGroupComputes(ctx, req) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_affinity_groups_get.go b/internal/service/cloudbroker/rg/utility_rg_affinity_groups_get.go new file mode 100644 index 00000000..6e3cb0dd --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_affinity_groups_get.go @@ -0,0 +1,26 @@ +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgAffinityGroupsGetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]uint64, error) { + c := m.(*controller.ControllerCfg) + req := rg.AffinityGroupsGetRequest{ + RGID: uint64(d.Get("rg_id").(int)), + AffinityGroup: d.Get("affinity_group").(string), + } + + log.Debugf("utilityRgAffinityGroupsGetCheckPresence: load computes in the specified affinity group") + computes, err := c.CloudBroker().RG().AffinityGroupsGet(ctx, req) + if err != nil { + return nil, err + } + + return computes, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_affinity_groups_list.go b/internal/service/cloudbroker/rg/utility_rg_affinity_groups_list.go new file mode 100644 index 00000000..2f54bea4 --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_affinity_groups_list.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgAffinityGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListAffinityGroup, error) { + c := m.(*controller.ControllerCfg) + req := rg.AffinityGroupsListRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + groups, err := c.CloudBroker().RG().AffinityGroupsList(ctx, req) + if err != nil { + return nil, err + } + + return groups, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_audits.go b/internal/service/cloudbroker/rg/utility_rg_audits.go new file mode 100644 index 00000000..531dc11e --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_audits.go @@ -0,0 +1,25 @@ +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListAudits, error) { + c := m.(*controller.ControllerCfg) + req := rg.AuditsRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + log.Debugf("utilityRgAuditsCheckPresence: load rg audits") + rgAudits, err := c.CloudBroker().RG().Audits(ctx, req) + if err != nil { + return nil, err + } + + return rgAudits, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_get_resource_consumption.go b/internal/service/cloudbroker/rg/utility_rg_get_resource_consumption.go new file mode 100644 index 00000000..f133ea55 --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_get_resource_consumption.go @@ -0,0 +1,58 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityRGResourceConsumptionGetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ItemResourceConsumption, error) { + c := m.(*controller.ControllerCfg) + req := rg.GetResourceConsumptionRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + log.Debugf("utilityRGResourceConsumptionGetCheckPresence: load") + accountResourceConsumptionRec, err := c.CloudBroker().RG().GetResourceConsumption(ctx, req) + if err != nil { + return nil, err + } + + return accountResourceConsumptionRec, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_list.go b/internal/service/cloudbroker/rg/utility_rg_list.go new file mode 100644 index 00000000..b2c981ba --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_list.go @@ -0,0 +1,94 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityRgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListRG, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if accountName, ok := d.GetOk("account_name"); ok { + req.AccountName = accountName.(string) + } + + if createdAfter, ok := d.GetOk("created_after"); ok { + req.CreatedAfter = uint64(createdAfter.(int)) + } + if createdBefore, ok := d.GetOk("created_before"); ok { + req.CreatedBefore = uint64(createdBefore.(int)) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if includedeleted, ok := d.GetOk("includedeleted"); ok { + req.IncludeDeleted = includedeleted.(bool) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + log.Debugf("utilityRgListCheckPresence: load rg list") + rgList, err := c.CloudBroker().RG().List(ctx, req) + if err != nil { + return nil, err + } + + return rgList, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_list_computes.go b/internal/service/cloudbroker/rg/utility_rg_list_computes.go new file mode 100644 index 00000000..d74a17e2 --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_list_computes.go @@ -0,0 +1,99 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgListComputesCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListComputes, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListComputesRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + if compute_id, ok := d.GetOk("compute_id"); ok { + req.ComputeID = uint64(compute_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if ip_address, ok := d.GetOk("ip_address"); ok { + req.IPAddress = ip_address.(string) + } + + if extnet_name, ok := d.GetOk("extnet_name"); ok { + req.ExtNetName = extnet_name.(string) + } + + if extnet_id, ok := d.GetOk("extnet_id"); ok { + req.ExtNetID = uint64(extnet_id.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listComputes, err := c.CloudBroker().RG().ListComputes(ctx, req) + if err != nil { + return nil, err + } + + return listComputes, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_list_deleted.go b/internal/service/cloudbroker/rg/utility_rg_list_deleted.go new file mode 100644 index 00000000..49f61b02 --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_list_deleted.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListRG, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListDeletedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if account_name, ok := d.GetOk("account_name"); ok { + req.AccountName = account_name.(string) + } + + if created_after, ok := d.GetOk("created_after"); ok { + req.CreatedAfter = uint64(created_after.(int)) + } + + if created_before, ok := d.GetOk("created_before"); ok { + req.CreatedBefore = uint64(created_before.(int)) + } + + if lock_status, ok := d.GetOk("lock_status"); ok { + req.LockStatus = lock_status.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + rgList, err := c.CloudBroker().RG().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return rgList, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_list_lb.go b/internal/service/cloudbroker/rg/utility_rg_list_lb.go new file mode 100644 index 00000000..cd961721 --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_list_lb.go @@ -0,0 +1,91 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgListLbCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListLB, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListLBRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if front_ip, ok := d.GetOk("front_ip"); ok { + req.FrontIP = front_ip.(string) + } + + if back_ip, ok := d.GetOk("back_ip"); ok { + req.BackIP = back_ip.(string) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listLb, err := c.CloudBroker().RG().ListLB(ctx, req) + if err != nil { + return nil, err + } + + return listLb, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_list_pfw.go b/internal/service/cloudbroker/rg/utility_rg_list_pfw.go new file mode 100644 index 00000000..f82d7c5f --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_list_pfw.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgListPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListPFW, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListPFWRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + listPfw, err := c.CloudBroker().RG().ListPFW(ctx, req) + if err != nil { + return nil, err + } + + return listPfw, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_list_vins.go b/internal/service/cloudbroker/rg/utility_rg_list_vins.go new file mode 100644 index 00000000..8445f3fc --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_list_vins.go @@ -0,0 +1,83 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityRgListVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListVINS, error) { + c := m.(*controller.ControllerCfg) + req := rg.ListVINSRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + + if ext_ip, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = ext_ip.(string) + } + + if vins_id, ok := d.GetOk("vins_id"); ok { + req.VINSID = uint64(vins_id.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + listVins, err := c.CloudBroker().RG().ListVINS(ctx, req) + if err != nil { + return nil, err + } + + return listVins, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_resource_consumption_list.go b/internal/service/cloudbroker/rg/utility_rg_resource_consumption_list.go new file mode 100644 index 00000000..8d827f5b --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_resource_consumption_list.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityRGResourceConsumptionListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.ListResourceConsumption, error) { + c := m.(*controller.ControllerCfg) + + log.Debugf("utilityRGResourceConsumptionListCheckPresence: load") + rgResourceConsumptionList, err := c.CloudBroker().RG().ListResourceConsumption(ctx) + if err != nil { + return nil, err + } + + return rgResourceConsumptionList, nil +} diff --git a/internal/service/cloudbroker/rg/utility_rg_usage.go b/internal/service/cloudbroker/rg/utility_rg_usage.go new file mode 100644 index 00000000..8d7abdc8 --- /dev/null +++ b/internal/service/cloudbroker/rg/utility_rg_usage.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package rg + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDataRgUsageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.Reservation, error) { + c := m.(*controller.ControllerCfg) + req := rg.UsageRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } + + usage, err := c.CloudBroker().RG().Usage(ctx, req) + if err != nil { + return nil, err + } + + return usage, nil +} diff --git a/internal/service/cloudbroker/secgroup/data_source_security_group.go b/internal/service/cloudbroker/secgroup/data_source_security_group.go new file mode 100644 index 00000000..d5ba7ebd --- /dev/null +++ b/internal/service/cloudbroker/secgroup/data_source_security_group.go @@ -0,0 +1,38 @@ +package secgroup + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSecurityGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + securityGroup, err := utilitySecurityGroupCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenSecurityGroup(d, securityGroup) + + return nil +} + +func DataSourceSecurityGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSecurityGroupRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSecurityGroupSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/secgroup/data_source_security_group_list.go b/internal/service/cloudbroker/secgroup/data_source_security_group_list.go new file mode 100644 index 00000000..a2bf3e1a --- /dev/null +++ b/internal/service/cloudbroker/secgroup/data_source_security_group_list.go @@ -0,0 +1,40 @@ +package secgroup + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSecurityGroupListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + storagePolicyList, err := utilitySecurityGroupListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenSecurityGroupList(storagePolicyList)) + d.Set("entry_count", storagePolicyList.EntryCount) + + return nil +} + +func DataSourceSecurityGroupList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSecurityGroupListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSecurityGroupListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/secgroup/flattens.go b/internal/service/cloudbroker/secgroup/flattens.go new file mode 100644 index 00000000..e32297e0 --- /dev/null +++ b/internal/service/cloudbroker/secgroup/flattens.go @@ -0,0 +1,68 @@ +package secgroup + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/secgroup" +) + +func flattenSecurityGroupResource(d *schema.ResourceData, securityGroup *secgroup.RecordSecurityGroup) { + d.Set("security_group_id", securityGroup.ID) + d.Set("account_id", securityGroup.AccountID) + d.Set("name", securityGroup.Name) + d.Set("description", securityGroup.Description) + d.Set("rules", flattenRules(securityGroup.Rules)) + d.Set("created_at", securityGroup.CreatedAt) + d.Set("created_by", securityGroup.CreatedBy) + d.Set("updated_at", securityGroup.UpdatedAt) + d.Set("updated_by", securityGroup.UpdatedBy) +} + +func flattenSecurityGroupList(securityGroupList *secgroup.ListSecurityGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(securityGroupList.Data)) + for _, v := range securityGroupList.Data { + temp := map[string]interface{}{ + "account_id": v.AccountID, + "name": v.Name, + "description": v.Description, + "rules": flattenRules(v.Rules), + "created_at": v.CreatedAt, + "created_by": v.CreatedBy, + "security_group_id": v.ID, + "updated_at": v.UpdatedAt, + "updated_by": v.UpdatedBy, + } + + res = append(res, temp) + } + + return res +} + +func flattenSecurityGroup(d *schema.ResourceData, securityGroup *secgroup.RecordSecurityGroup) { + d.Set("security_group_id", securityGroup.ID) + d.Set("account_id", securityGroup.AccountID) + d.Set("name", securityGroup.Name) + d.Set("description", securityGroup.Description) + d.Set("rules", flattenRules(securityGroup.Rules)) + d.Set("created_at", securityGroup.CreatedAt) + d.Set("created_by", securityGroup.CreatedBy) + d.Set("updated_at", securityGroup.UpdatedAt) + d.Set("updated_by", securityGroup.UpdatedBy) +} + +func flattenRules(rules secgroup.Rules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rules)) + for _, rule := range rules { + temp := map[string]interface{}{ + "id": rule.ID, + "direction": rule.Direction, + "ethertype": rule.Ethertype, + "protocol": rule.Protocol, + "port_range_min": rule.PortRangeMin, + "port_range_max": rule.PortRangeMax, + "remote_ip_prefix": rule.RemoteIPPrefix, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudbroker/secgroup/resource_security_group.go b/internal/service/cloudbroker/secgroup/resource_security_group.go new file mode 100644 index 00000000..1983336c --- /dev/null +++ b/internal/service/cloudbroker/secgroup/resource_security_group.go @@ -0,0 +1,146 @@ +package secgroup + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/secgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func resourceSecurityGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSecurityGroupCreate: called with account ID %d, name %s", uint64(d.Get("account_id").(int)), d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + warnings := dc.Warnings{} + + accountID := uint64(d.Get("account_id").(int)) + name := d.Get("name").(string) + + req := secgroup.CreateRequest{ + AccountID: accountID, + Name: name, + } + + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + + securityGroupID, err := c.CloudBroker().SecurityGroup().Create(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(securityGroupID, 10)) + d.Set("security_group_id", securityGroupID) + + return append(warnings.Get(), resourceSecurityGroupRead(ctx, d, m)...) +} + +func resourceSecurityGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSecurityGroupRead: called with with account ID %d", uint64(d.Get("account_id").(int))) + + w := dc.Warnings{} + + securityGroupItem, err := utilitySecurityGroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenSecurityGroupResource(d, securityGroupItem) + + return w.Get() +} + +func resourceSecurityGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + securityGroupID, _ := strconv.ParseUint(d.Id(), 10, 64) + + log.Debugf("resourceSecurityGroupUpdate: called security group with id %d", securityGroupID) + + c := m.(*controller.ControllerCfg) + + _, err := utilitySecurityGroupCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + + return diag.FromErr(err) + } + + _, err = strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + + d.SetId("") + + return diag.FromErr(err) + } + + if d.HasChanges("name", "description") { + + if err := utilitySecurityGroupHandleHasChanges(ctx, d, c, securityGroupID); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("rules") { + if err := utilitySecurityGroupUpdateRules(ctx, d, c, securityGroupID); err != nil { + return diag.FromErr(err) + } + } + + return resourceSecurityGroupRead(ctx, d, m) +} + +func resourceSecurityGroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSecurityGroupDelete: called with id %s", d.Id()) + + securityGroupItem, err := utilitySecurityGroupCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := secgroup.DeleteRequest{ + SecurityGroupID: securityGroupItem.ID, + } + if _, err := c.CloudBroker().SecurityGroup().Delete(ctx, req); err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceSecurityGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceSecurityGroupCreate, + ReadContext: resourceSecurityGroupRead, + UpdateContext: resourceSecurityGroupUpdate, + DeleteContext: resourceSecurityGroupDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout600s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceSecurityGroupSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/secgroup/schema.go b/internal/service/cloudbroker/secgroup/schema.go new file mode 100644 index 00000000..9e1a49fd --- /dev/null +++ b/internal/service/cloudbroker/secgroup/schema.go @@ -0,0 +1,288 @@ +package secgroup + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceSecurityGroupSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "rules": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "direction": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"inbound", "outbound"}, true), + }, + "ethertype": { + Type: schema.TypeString, + Optional: true, + Default: "IPv4", + ValidateFunc: validation.StringInSlice([]string{"IPv4", "IPv6"}, true), + }, + "protocol": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"icmp", "tcp", "udp"}, true), + }, + "port_range_min": { + Type: schema.TypeInt, + Optional: true, + }, + "port_range_max": { + Type: schema.TypeInt, + Optional: true, + }, + "remote_ip_prefix": { + Type: schema.TypeString, + Optional: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "security_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + } + return res +} + +func dataSourceSecurityGroupSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "security_group_id": { + Type: schema.TypeInt, + Required: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "direction": { + Type: schema.TypeString, + Computed: true, + }, + "ethertype": { + Type: schema.TypeString, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "port_range_min": { + Type: schema.TypeInt, + Computed: true, + }, + "port_range_max": { + Type: schema.TypeInt, + Computed: true, + }, + "remote_ip_prefix": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + } + return res +} + +func dataSourceSecurityGroupListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + }, + "desc": { + Type: schema.TypeString, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + }, + "created_min": { + Type: schema.TypeInt, + Optional: true, + }, + "created_max": { + Type: schema.TypeInt, + Optional: true, + }, + "updated_min": { + Type: schema.TypeInt, + Optional: true, + }, + "updated_max": { + Type: schema.TypeInt, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "security_group_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "rules": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "direction": { + Type: schema.TypeString, + Computed: true, + }, + "ethertype": { + Type: schema.TypeString, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "port_range_min": { + Type: schema.TypeInt, + Computed: true, + }, + "port_range_max": { + Type: schema.TypeInt, + Computed: true, + }, + "remote_ip_prefix": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} diff --git a/internal/service/cloudbroker/secgroup/utility_security_group.go b/internal/service/cloudbroker/secgroup/utility_security_group.go new file mode 100644 index 00000000..2a1a5c6f --- /dev/null +++ b/internal/service/cloudbroker/secgroup/utility_security_group.go @@ -0,0 +1,95 @@ +package secgroup + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/secgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilitySecurityGroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*secgroup.RecordSecurityGroup, error) { + c := m.(*controller.ControllerCfg) + req := secgroup.GetRequest{} + if d.Id() != "" { + securityGroupID, _ := strconv.ParseUint(d.Id(), 10, 64) + req.SecurityGroupID = securityGroupID + } else { + req.SecurityGroupID = uint64(d.Get("security_group_id").(int)) + } + + log.Debugf("utilitySecurityGroupCheckPresence: load security group") + securityGroup, err := c.CloudBroker().SecurityGroup().Get(ctx, req) + if err != nil { + return nil, err + } + + return securityGroup, nil +} + +func utilitySecurityGroupHandleHasChanges(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, securityGroupID uint64) error { + req := secgroup.UpdateRequest{ + SecurityGroupID: securityGroupID, + } + + if d.HasChange("name") { + name := d.Get("name").(string) + req.Name = name + } + + if d.HasChange("description") { + description := d.Get("description").(string) + req.Description = description + } + + if _, err := c.CloudBroker().SecurityGroup().Update(ctx, req); err != nil { + return err + } + + return nil +} + +func utilitySecurityGroupUpdateRules(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, securityGroupID uint64) error { + oldSet, newSet := d.GetChange("rules") + deletedRules := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + for _, deletedInterface := range deletedRules { + deletedItem := deletedInterface.(map[string]interface{}) + ruleID := uint64(deletedItem["id"].(int)) + req := secgroup.DeleteRuleRequest{ + SecurityGroupID: securityGroupID, + RuleID: ruleID, + } + if _, err := c.CloudBroker().SecurityGroup().DeleteRule(ctx, req); err != nil { + return err + } + + } + + addedRules := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + for _, addedInterface := range addedRules { + addedItem := addedInterface.(map[string]interface{}) + direction := addedItem["direction"].(string) + ethertype := addedItem["ethertype"].(string) + protocol := addedItem["protocol"].(string) + portRangeMin := uint64(addedItem["port_range_min"].(int)) + portRangeMax := uint64(addedItem["port_range_max"].(int)) + remoteIPPrefix := addedItem["remote_ip_prefix"].(string) + req := secgroup.CreateRuleRequest{ + SecurityGroupID: securityGroupID, + Direction: direction, + Ethertype: ethertype, + Protocol: protocol, + PortRangeMin: portRangeMin, + PortRangeMax: portRangeMax, + RemoteIPPrefix: remoteIPPrefix, + } + + if _, err := c.CloudBroker().SecurityGroup().CreateRule(ctx, req); err != nil { + return err + } + } + + return nil +} diff --git a/internal/service/cloudbroker/secgroup/utility_security_group_list.go b/internal/service/cloudbroker/secgroup/utility_security_group_list.go new file mode 100644 index 00000000..7853c53e --- /dev/null +++ b/internal/service/cloudbroker/secgroup/utility_security_group_list.go @@ -0,0 +1,60 @@ +package secgroup + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/secgroup" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilitySecurityGroupListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*secgroup.ListSecurityGroups, error) { + c := m.(*controller.ControllerCfg) + + req := secgroup.ListRequest{} + + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if byID, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byID.(int)) + } + if accountID, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountID.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if createdMin, ok := d.GetOk("created_min"); ok { + req.CreatedMin = uint64(createdMin.(int)) + } + if createdMax, ok := d.GetOk("created_max"); ok { + req.CreatedMax = uint64(createdMax.(int)) + } + if updatedMin, ok := d.GetOk("updated_min"); ok { + req.UpdatedMin = uint64(updatedMin.(int)) + } + if updatedMax, ok := d.GetOk("updated_max"); ok { + req.UpdatedMax = uint64(updatedMax.(int)) + } + + log.Debugf("utilitySecurityGroupListCheckPresence: load storage policy list") + + securityGroupList, err := c.CloudBroker().SecurityGroup().List(ctx, req) + if err != nil { + return nil, err + } + + return securityGroupList, nil + +} diff --git a/internal/service/cloudbroker/sep/data_available_sep_and_pools_list.go b/internal/service/cloudbroker/sep/data_available_sep_and_pools_list.go new file mode 100644 index 00000000..f67355d7 --- /dev/null +++ b/internal/service/cloudbroker/sep/data_available_sep_and_pools_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func DataSourceAvailableSEPAndPoolsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + sepList, err := utilityAvailableSEPAndPoolsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + flattenAvailableSEPList(d, sepList) + + return nil +} + +func DataSourceAvailableSEPAndPoolsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: DataSourceAvailableSEPAndPoolsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAvailableSEPListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/sep/data_source_sep.go b/internal/service/cloudbroker/sep/data_source_sep.go new file mode 100644 index 00000000..c9036795 --- /dev/null +++ b/internal/service/cloudbroker/sep/data_source_sep.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSepRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + desSep, err := utilitySepCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenSep(d, desSep) + d.SetId(strconv.Itoa(d.Get("sep_id").(int))) + + return nil +} + +func DataSourceSep() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSepRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSepCSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/sep/data_source_sep_config.go b/internal/service/cloudbroker/sep/data_source_sep_config.go new file mode 100644 index 00000000..f3c57083 --- /dev/null +++ b/internal/service/cloudbroker/sep/data_source_sep_config.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + "encoding/json" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSepConfigRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + sepConfig, err := utilitySepConfigCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + data, _ := json.Marshal(sepConfig) + d.Set("config", string(data)) + + return nil +} + +func DataSourceSepConfig() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSepConfigRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSepConfigSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/sep/data_source_sep_consumption.go b/internal/service/cloudbroker/sep/data_source_sep_consumption.go new file mode 100644 index 00000000..a6978930 --- /dev/null +++ b/internal/service/cloudbroker/sep/data_source_sep_consumption.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSepConsumptionRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + sepCons, err := utilitySepConsumptionCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + + flattenSepConsumption(d, sepCons) + + return nil +} + +func DataSourceSepConsumption() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSepConsumptionRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSepConsumptionSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/sep/data_source_sep_disk_list.go b/internal/service/cloudbroker/sep/data_source_sep_disk_list.go new file mode 100644 index 00000000..7165be72 --- /dev/null +++ b/internal/service/cloudbroker/sep/data_source_sep_disk_list.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSepDiskListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + sepDiskList, err := utilitySepDiskListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", sepDiskList) + + return nil +} + +func DataSourceSepDiskList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSepDiskListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSepDiskListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/sep/data_source_sep_list.go b/internal/service/cloudbroker/sep/data_source_sep_list.go new file mode 100644 index 00000000..82ce8354 --- /dev/null +++ b/internal/service/cloudbroker/sep/data_source_sep_list.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSepListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + sepList, err := utilitySepListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + d.Set("items", flattenSepListItems(sepList)) + d.Set("entry_count", sepList.EntryCount) + + return nil +} + +func DataSourceSepList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSepListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSepListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/sep/data_source_sep_pool.go b/internal/service/cloudbroker/sep/data_source_sep_pool.go new file mode 100644 index 00000000..2e567984 --- /dev/null +++ b/internal/service/cloudbroker/sep/data_source_sep_pool.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSepPoolRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + sepPool, err := utilitySepPoolCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("pool", flattenSepPool(sepPool)) + + return nil +} + +func DataSourceSepPool() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSepPoolRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSepPoolSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/sep/data_source_sep_template.go b/internal/service/cloudbroker/sep/data_source_sep_template.go new file mode 100644 index 00000000..375a1520 --- /dev/null +++ b/internal/service/cloudbroker/sep/data_source_sep_template.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSepTemplateRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + sepTemplate, err := utilitySepTemplateCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + d.Set("sep_template", sepTemplate) + + return nil +} + +func DataSourceSepTemplate() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSepTemplateRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSepTemplateSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/sep/flattens.go b/internal/service/cloudbroker/sep/flattens.go new file mode 100644 index 00000000..9eb44785 --- /dev/null +++ b/internal/service/cloudbroker/sep/flattens.go @@ -0,0 +1,185 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "encoding/json" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" +) + +func flattenSep(d *schema.ResourceData, desSep *sep.RecordSEP) { + d.Set("consumed_by", desSep.ConsumedBy) + d.Set("desc", desSep.Description) + d.Set("gid", desSep.GID) + d.Set("guid", desSep.GUID) + d.Set("sep_id", desSep.ID) + d.Set("milestones", desSep.Milestones) + d.Set("multipath_num", desSep.MultipathNum) + d.Set("name", desSep.Name) + d.Set("obj_status", desSep.ObjStatus) + d.Set("provided_by", desSep.ProvidedBy) + d.Set("shared_with", desSep.SharedWith) + d.Set("tech_status", desSep.TechStatus) + d.Set("type", desSep.Type) + data, _ := json.Marshal(desSep.Config) + d.Set("config", string(data)) +} + +func flattenSepListItems(sl *sep.ListSEP) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, item := range sl.Data { + data, _ := json.Marshal(item.Config) + temp := map[string]interface{}{ + "consumed_by": item.ConsumedBy, + "desc": item.Description, + "gid": item.GID, + "guid": item.GUID, + "sep_id": item.ID, + "milestones": item.Milestones, + "name": item.Name, + "multipath_num": item.MultipathNum, + "obj_status": item.ObjStatus, + "provided_by": item.ProvidedBy, + "shared_with": item.SharedWith, + "tech_status": item.TechStatus, + "type": item.Type, + "config": string(data), + } + res = append(res, temp) + } + return res +} + +func flattenSepPool(rp *sep.RecordPool) []map[string]interface{} { + sh := make([]map[string]interface{}, 0) + res := map[string]interface{}{ + "access_account_ids": rp.AccessAccountIDs, + "access_res_group_ids": rp.AccessResGroupIDs, + "name": rp.Name, + "pagecache_ratio": rp.PageCacheRatio, + "reference_id": rp.ReferenceID, + "types": rp.Types, + "uris": flattenSepPoolUris(rp), + "usage_limit": rp.UsageLimit, + } + sh = append(sh, res) + return sh +} + +func flattenSepPoolUris(rp *sep.RecordPool) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, ur := range rp.URIs { + temp := map[string]interface{}{ + "ip": ur.IP, + "port": ur.Port, + } + res = append(res, temp) + } + return res +} + +func flattenSepConsumption(d *schema.ResourceData, sepCons *sep.RecordConsumption) { + d.Set("type", sepCons.Type) + d.Set("total", flattenSepConsumptionTotal(sepCons.Total)) + d.Set("by_pool", flattenSepConsumptionPools(sepCons)) +} + +func flattenSepConsumptionTotal(sc sep.Total) []map[string]interface{} { + sh := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "capacity_limit": sc.CapacityLimit, + "disk_count": sc.DiskCount, + "disk_usage": sc.DiskUsage, + "snapshot_count": sc.SnapshotCount, + "snapshot_usage": sc.SnapshotUsage, + "usage": sc.Usage, + "usage_limit": sc.UsageLimit, + } + sh = append(sh, temp) + return sh +} + +func flattenSepConsumptionPools(bp *sep.RecordConsumption) []map[string]interface{} { + sh := make([]map[string]interface{}, 0) + for key, value := range bp.ByPool { + temp := map[string]interface{}{ + "name": key, + "disk_count": value.DiskCount, + "disk_usage": value.DiskUsage, + "snapshot_count": value.SnapshotCount, + "snapshot_usage": value.SnapshotUsage, + "usage": value.Usage, + "usage_limit": value.UsageLimit, + } + sh = append(sh, temp) + } + return sh +} + +func flattenAvailableSEPList(d *schema.ResourceData, sepList *sep.ListAvailableSEP) { + d.Set("items", flattenSEPDataList(sepList.Data)) + d.Set("entry_count", sepList.EntryCount) +} + +func flattenSEPDataList(sepDataList []sep.SEPData) []map[string]interface{} { + sh := make([]map[string]interface{}, 0) + + for _, sepData := range sepDataList { + temp := map[string]interface{}{ + "sep_id": sepData.SEPID, + "sep_name": sepData.SEPName, + "sep_type": sepData.SEPType, + "pools": flattenPoolList(sepData.Pools), + } + sh = append(sh, temp) + } + + return sh +} + +func flattenPoolList(pools []sep.Pool) []map[string]interface{} { + sh := make([]map[string]interface{}, 0) + + for _, pool := range pools { + temp := map[string]interface{}{ + "name": pool.Name, + "types": pool.Types, + "system": pool.System, + } + sh = append(sh, temp) + } + + return sh +} diff --git a/internal/service/cloudbroker/sep/resource_check_input_values.go b/internal/service/cloudbroker/sep/resource_check_input_values.go new file mode 100644 index 00000000..0a5de37b --- /dev/null +++ b/internal/service/cloudbroker/sep/resource_check_input_values.go @@ -0,0 +1,55 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + gid := uint64(d.Get("gid").(int)) + + if err := ic.ExistGID(ctx, gid, c); err != nil { + errs = append(errs, err) + } + + return dc.ErrorsToDiagnostics(errs) +} diff --git a/internal/service/cloudbroker/sep/resource_sep.go b/internal/service/cloudbroker/sep/resource_sep.go new file mode 100644 index 00000000..9cf40276 --- /dev/null +++ b/internal/service/cloudbroker/sep/resource_sep.go @@ -0,0 +1,571 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + "encoding/json" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func resourceSepCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSepCreate: called for sep %s", d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistence(ctx, d, c); diags != nil { + return diags + } + + req := sep.CreateRequest{ + GID: uint64(d.Get("gid").(int)), + Name: d.Get("name").(string), + SEPType: d.Get("type").(string), + Config: d.Get("config").(string), + } + + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } + if enable, ok := d.GetOk("enable"); ok { + req.Enable = enable.(bool) + } + + sepId, err := c.CloudBroker().SEP().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(sepId, 10)) + d.Set("sep_id", sepId) + + warnings := dc.Warnings{} + + if enable, ok := d.GetOk("enable"); ok { + log.Debugf("resourceSepCreate, Enable: enable=%t sep_id %d after completing its resource configuration", enable, sepId) + err := resourceSepChangeEnabled(ctx, d, m) + if err != nil { + warnings.Add(err) + } + } + + if accountIds, ok := d.GetOk("account_ids"); ok { + log.Debugf("resourceSepCreate, accessGrant: accountIds=%v sep_id %d after completing its resource configuration", accountIds, sepId) + err := resourceSepChangeAccess(ctx, d, m) + if err != nil { + warnings.Add(err) + } + } + + if accessToPool, ok := d.GetOk("access_to_pool"); ok { + log.Debugf("resourceSepCreate, accessToPool: accessToPool=%v sep_id %d after completing its resource configuration", accessToPool, sepId) + err := resourceSepChangeAccessToPool(ctx, d, m) + if err != nil { + warnings.Add(err) + } + } + + if pools, ok := d.GetOk("pools"); ok { + log.Debugf("resourceSepCreate, pools: pools=%v sep_id %d after completing its resource configuration", pools, sepId) + err := resourceSepChangePools(ctx, d, m) + if err != nil { + warnings.Add(err) + } + } + + if consumedBy, ok := d.GetOk("consumed_by"); ok && consumedBy.(*schema.Set).Len() > 0 { + log.Debugf("resourceSepCreate, consumed_by: consumed_by=%v sep_id %d after completing its resource configuration", consumedBy, sepId) + err := resourceSepAddConsumerNodes(ctx, d, m) + if err != nil { + warnings.Add(err) + } + } + + if providedBy, ok := d.GetOk("provided_by"); ok && len(providedBy.([]interface{})) > 0 { + log.Debugf("resourceSepCreate, provided_by: provided_by=%v sep_id %d after completing its resource configuration", providedBy, sepId) + err := resourceSepAddProviderNodes(ctx, d, m) + if err != nil { + warnings.Add(err) + } + } + + return append(resourceSepRead(ctx, d, m), warnings.Get()...) +} + +func resourceSepRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSepRead: called for %s id: %d", d.Get("name").(string), d.Get("sep_id").(int)) + + sepRec, err := utilitySepCheckPresence(ctx, d, m) + if sepRec == nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenSep(d, sepRec) + + log.Debugf("resourceSepRead: after flattenSep: %s id: %d", d.Get("name").(string), d.Get("sep_id").(int)) + + return nil +} + +func resourceSepDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSepDelete: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) + + sepDes, err := utilitySepCheckPresence(ctx, d, m) + if sepDes == nil { + d.SetId("") + if err != nil { + return diag.FromErr(err) + } + return nil + } + + c := m.(*controller.ControllerCfg) + req := sep.DeleteRequest{ + SEPID: sepDes.ID, + } + + _, err = c.CloudBroker().SEP().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceSepUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + return diag.Errorf( + "SEP upgrade is not possible via terraform") + +} + +func resourceSepChangeAccess(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceSepChangeAccess: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) + c := m.(*controller.ControllerCfg) + + oldSet, newSet := d.GetChange("account_ids") + + deletedAccounts := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + var accountDelIds []uint64 + for _, deletedInterface := range deletedAccounts { + deletedItem := deletedInterface.(int) + accountDelIds = append(accountDelIds, uint64(deletedItem)) + } + if len(accountDelIds) != 0 { + for _, acc := range accountDelIds { + reqDel := sep.AccessRevokeRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + AccountID: acc, + } + _, err := c.CloudBroker().SEP().AccessRevoke(ctx, reqDel) + if err != nil { + return err + } + } + } + + addedAccounts := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + var accountAddIds []uint64 + for _, addedInterface := range addedAccounts { + addedItem := addedInterface.(int) + accountAddIds = append(accountAddIds, uint64(addedItem)) + } + if len(accountAddIds) != 0 { + for _, acc := range accountAddIds { + reqDel := sep.AccessGrantRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + AccountID: acc, + } + _, err := c.CloudBroker().SEP().AccessGrant(ctx, reqDel) + if err != nil { + return err + } + } + } + + return nil +} + +func resourceSepChangeAccessToPool(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceSepChangeAccessToPool: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) + c := m.(*controller.ControllerCfg) + + oldAccessToPool, newAccessToPool := d.GetChange("access_to_pool") + + oldAccess := oldAccessToPool.([]interface{})[0].(map[string]interface{}) + if oldAccess["pool_name"] != "" { + revokeReq := sep.AccessRevokeToPoolRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + PoolName: oldAccess["pool_name"].(string), + } + + if oldAccId, ok := oldAccess["account_id_pool"]; ok { + revokeReq.AccountID = uint64(oldAccId.(int)) + } + + if oldRgId, ok := oldAccess["rg_id"]; ok { + revokeReq.RGID = uint64(oldRgId.(int)) + } + + _, err := c.CloudBroker().SEP().AccessRevokeToPool(ctx, revokeReq) + if err != nil { + return err + } + } + + newAccess := newAccessToPool.([]interface{})[0].(map[string]interface{}) + if newAccess["pool_name"] != "" { + grantReq := sep.AccessGrantToPoolRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + PoolName: newAccess["pool_name"].(string), + } + + if newAccId, ok := newAccess["account_id_pool"]; ok { + grantReq.AccountID = uint64(newAccId.(int)) + } + + if newRgId, ok := newAccess["rg_id"]; ok { + grantReq.RGID = uint64(newRgId.(int)) + } + + _, err := c.CloudBroker().SEP().AccessGrantToPool(ctx, grantReq) + if err != nil { + return err + } + } + + return nil +} + +func resourceSepChangePools(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceSepChangePools: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) + c := m.(*controller.ControllerCfg) + + oldPoolsInterface, newPoolsInterface := d.GetChange("pools") + + oldPoolsList := oldPoolsInterface.(*schema.Set).Difference(newPoolsInterface.(*schema.Set)).List() + for _, pool := range oldPoolsList { + delPoolReq := sep.DelPoolRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + PoolName: pool.(string), + } + + _, err := c.CloudBroker().SEP().DelPool(ctx, delPoolReq) + if err != nil { + return err + } + } + + newPoolsList := newPoolsInterface.(*schema.Set).Difference(oldPoolsInterface.(*schema.Set)).List() + for _, pool := range newPoolsList { + poolItem := pool.(map[string]interface{}) + + accessAccountIDs := []uint64{} + + for _, v := range poolItem["access_account_ids"].([]interface{}) { + accessAccountIDs = append(accessAccountIDs, uint64(v.(int))) + } + accessResGroupIDs := []uint64{} + for _, v := range poolItem["access_res_group_ids"].([]interface{}) { + accessResGroupIDs = append(accessResGroupIDs, uint64(v.(int))) + } + + types := []string{} + for _, v := range poolItem["types"].([]interface{}) { + types = append(types, v.(string)) + } + + uris := []UrisModel{} + list := poolItem["uris"].(*schema.Set).List() + for _, v := range list { + if m, ok := v.(map[string]interface{}); ok { + uris = append(uris, UrisModel{IP: m["ip"].(string), + Port: uint64(m["port"].(int)), + }) + } + } + + poolValue := PoolModel{ + AccessAccountIDs: accessAccountIDs, + AccessResGroupIDs: accessResGroupIDs, + Name: poolItem["name"].(string), + Types: types, + Uris: uris, + UsageLimit: uint64(poolItem["usage_limit"].(int)), + } + marshalPool, _ := json.Marshal(poolValue) + log.Debugf(string(marshalPool)) + addPoolReq := sep.AddPoolRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + Pool: string(marshalPool), + } + + _, err := c.CloudBroker().SEP().AddPool(ctx, addPoolReq) + if err != nil { + return err + } + } + + return nil +} + +func resourceSepUpdateConfig(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + validateReq := sep.ConfigValidateRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + Config: d.Get("config").(string), + } + _, err := c.CloudBroker().SEP().ConfigValidate(ctx, validateReq) + if err != nil { + return err + } + + insertReq := sep.ConfigInsertRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + Config: d.Get("config").(string), + } + _, err = c.CloudBroker().SEP().ConfigInsert(ctx, insertReq) + if err != nil { + return err + } + + return nil +} + +func resourceSepFieldEdit(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + fieldConfig := d.Get("field_edit").([]interface{}) + field := fieldConfig[0].(map[string]interface{}) + req := sep.ConfigFieldEditRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + FieldName: field["field_name"].(string), + FieldValue: field["field_value"].(string), + FieldType: field["field_type"].(string), + } + + _, err := c.CloudBroker().SEP().ConfigFieldEdit(ctx, req) + if err != nil { + return err + } + + return nil +} + +func resourceSepChangeEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + sepID := uint64(d.Get("sep_id").(int)) + + if d.Get("enable").(bool) { + req := sep.EnableRequest{ + SEPID: sepID, + } + + _, err := c.CloudBroker().SEP().Enable(ctx, req) + if err != nil { + return err + } + } else { + req := sep.DisableRequest{ + SEPID: sepID, + } + + _, err := c.CloudBroker().SEP().Disable(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func resourceSepUpdateNodes(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceSepUpdateNodes: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) + c := m.(*controller.ControllerCfg) + + oldSet, newSet := d.GetChange("consumed_by") + + deletedConsumed := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + var consumerDelIds []uint64 + for _, deletedInterface := range deletedConsumed { + deletedItem := deletedInterface.(int) + consumerDelIds = append(consumerDelIds, uint64(deletedItem)) + } + if len(consumerDelIds) != 0 { + reqDel := sep.DelConsumerNodesRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + ConsumerNIDs: consumerDelIds, + } + _, err := c.CloudBroker().SEP().DelConsumerNodes(ctx, reqDel) + if err != nil { + return err + } + } + + addedConsumed := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + var consumerAddIds []uint64 + for _, addedInterface := range addedConsumed { + AddedItem := addedInterface.(int) + consumerAddIds = append(consumerAddIds, uint64(AddedItem)) + } + if len(consumerAddIds) != 0 { + reqAdd := sep.AddConsumerNodesRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + ConsumerNIDs: consumerAddIds, + } + _, err := c.CloudBroker().SEP().AddConsumerNodes(ctx, reqAdd) + if err != nil { + return err + } + } + return nil +} + +func resourceSepUpdateProviders(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceSepUpdateProviders: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) + c := m.(*controller.ControllerCfg) + req := sep.AddProviderNodesRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + } + + var providerNIDs []uint64 + for _, item := range d.Get("provided_by").([]interface{}) { + providerNIDs = append(providerNIDs, uint64(item.(int))) + } + req.ProviderNIDs = providerNIDs + + _, err := c.CloudBroker().SEP().AddProviderNodes(ctx, req) + if err != nil { + return err + } + + return nil +} + +func resourceSepAddConsumerNodes(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceSepAddConsumerNodes: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) + c := m.(*controller.ControllerCfg) + + var consumerNIDs []uint64 + for _, item := range d.Get("consumed_by").(*schema.Set).List() { + consumerNIDs = append(consumerNIDs, uint64(item.(int))) + } + + if len(consumerNIDs) > 0 { + reqAdd := sep.AddConsumerNodesRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + ConsumerNIDs: consumerNIDs, + } + _, err := c.CloudBroker().SEP().AddConsumerNodes(ctx, reqAdd) + if err != nil { + return err + } + } + + return nil +} + +func resourceSepAddProviderNodes(ctx context.Context, d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceSepAddProviderNodes: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) + c := m.(*controller.ControllerCfg) + + var providerNIDs []uint64 + for _, item := range d.Get("provided_by").([]interface{}) { + providerNIDs = append(providerNIDs, uint64(item.(int))) + } + + if len(providerNIDs) > 0 { + reqAdd := sep.AddProviderNodesRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + ProviderNIDs: providerNIDs, + } + _, err := c.CloudBroker().SEP().AddProviderNodes(ctx, reqAdd) + if err != nil { + return err + } + } + + return nil +} + +func ResourceSep() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceSepCreate, + ReadContext: resourceSepRead, + UpdateContext: resourceSepUpdate, + DeleteContext: resourceSepDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceSepSchemaMake(), + } +} + +type PoolModel struct { + AccessAccountIDs []uint64 `json:"accessAccountIds"` + AccessResGroupIDs []uint64 `json:"accessResGroupIds"` + Name string `json:"name"` + Types []string `json:"types"` + Uris []UrisModel `json:"uris"` + UsageLimit uint64 `json:"usage_limit"` +} + +type UrisModel struct { + IP string `json:"ip"` + + Port uint64 `json:"port"` +} diff --git a/internal/service/cloudbroker/sep/resource_sep_config.go b/internal/service/cloudbroker/sep/resource_sep_config.go new file mode 100644 index 00000000..ab5e34dc --- /dev/null +++ b/internal/service/cloudbroker/sep/resource_sep_config.go @@ -0,0 +1,127 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + "encoding/json" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func resourceSepConfigCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSepConfigCreate: called for sep id %d", d.Get("sep_id").(int)) + + if _, ok := d.GetOk("sep_id"); ok { + sepConfig, err := utilitySepConfigCheckPresence(ctx, d, m) + + if err != nil { + return diag.FromErr(err) + } + + if sepConfig == nil { + return diag.Errorf("provided sep id config does not exist") + } + + id := uuid.New() + d.SetId(id.String()) + } + + return resourceSepConfigRead(ctx, d, m) +} + +func resourceSepConfigRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSepConfigRead: called for sep id: %d", d.Get("sep_id").(int)) + + sepConfig, err := utilitySepConfigCheckPresence(ctx, d, m) + if sepConfig == nil { + d.SetId("") + return diag.FromErr(err) + } + data, _ := json.Marshal(sepConfig) + d.Set("config", string(data)) + return nil +} + +func resourceSepConfigDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + d.SetId("") + return nil +} + +func resourceSepConfigUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSepConfigEdit: called for sep id: %d", d.Get("sep_id").(int)) + + if d.HasChange("config") { + err := resourceSepUpdateConfig(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("field_edit") { + err := resourceSepFieldEdit(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + return resourceSepConfigRead(ctx, d, m) +} + +func ResourceSepConfig() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceSepConfigCreate, + ReadContext: resourceSepConfigRead, + UpdateContext: resourceSepConfigUpdate, + DeleteContext: resourceSepConfigDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceSepConfigSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/sep/schema.go b/internal/service/cloudbroker/sep/schema.go new file mode 100644 index 00000000..7bc4d83d --- /dev/null +++ b/internal/service/cloudbroker/sep/schema.go @@ -0,0 +1,804 @@ +package sep + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceSepCSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Required: true, + Description: "sep type des id", + }, + "config": { + Type: schema.TypeString, + Computed: true, + Description: "config", + }, + "consumed_by": { + Type: schema.TypeSet, + Computed: true, + Description: "consumed by", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "multipath_num": { + Type: schema.TypeInt, + Computed: true, + Description: "multipath_num", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "name", + }, + "obj_status": { + Type: schema.TypeString, + Computed: true, + Description: "object status", + }, + "provided_by": { + Type: schema.TypeList, + Computed: true, + Description: "provided by", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Description: "shared with", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + } +} + +func dataSourceSepConfigSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Required: true, + Description: "storage endpoint provider ID", + }, + "config": { + Type: schema.TypeString, + Computed: true, + Description: "sep config json string", + }, + } +} + +func dataSourceSepTemplateSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "sep_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"des", "hitachi", "dorado", "tatlin", "shared", "local", "ustor"}, false), + Description: "type of sep", + }, + "lang": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"ru", "en"}, false), + Description: "language", + }, + "sep_template": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func dataSourceSepConsumptionSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Required: true, + Description: "sep id", + }, + "by_pool": { + Type: schema.TypeList, + Computed: true, + Description: "consumption divided by pool", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "pool name", + }, + "disk_count": { + Type: schema.TypeInt, + Computed: true, + Description: "number of disks", + }, + "disk_usage": { + Type: schema.TypeInt, + Computed: true, + Description: "disk usage", + }, + "snapshot_count": { + Type: schema.TypeInt, + Computed: true, + Description: "number of snapshots", + }, + "snapshot_usage": { + Type: schema.TypeInt, + Computed: true, + Description: "snapshot usage", + }, + "usage": { + Type: schema.TypeInt, + Computed: true, + Description: "usage", + }, + "usage_limit": { + Type: schema.TypeInt, + Computed: true, + Description: "usage limit", + }, + }, + }, + }, + "total": { + Type: schema.TypeList, + Computed: true, + Description: "total consumption", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "capacity_limit": { + Type: schema.TypeInt, + Computed: true, + Description: "capacity limit", + }, + "disk_count": { + Type: schema.TypeInt, + Computed: true, + Description: "number of disks", + }, + "disk_usage": { + Type: schema.TypeInt, + Computed: true, + Description: "disk usage", + }, + "snapshot_count": { + Type: schema.TypeInt, + Computed: true, + Description: "number of snapshots", + }, + "snapshot_usage": { + Type: schema.TypeInt, + Computed: true, + Description: "snapshot usage", + }, + "usage": { + Type: schema.TypeInt, + Computed: true, + Description: "usage", + }, + "usage_limit": { + Type: schema.TypeInt, + Computed: true, + Description: "usage limit", + }, + }, + }, + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "sep type", + }, + } +} + +func dataSourceSepDiskListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Required: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + Description: "pool name", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "sep disk list", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } + + return rets +} + +func dataSourceSepListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "find by id", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "find by name", + }, + "gid": { + Type: schema.TypeInt, + Optional: true, + Description: "find by gid", + }, + "type": { + Type: schema.TypeString, + Optional: true, + Description: "find by sep type", + }, + "provided_by": { + Type: schema.TypeInt, + Optional: true, + Description: "find by provided physical node id", + }, + "tech_status": { + Type: schema.TypeString, + Optional: true, + Description: "find by techStatus", + }, + "consumed_by": { + Type: schema.TypeInt, + Optional: true, + Description: "find by consumed physical node id", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "sep_ids": { + Type: schema.TypeList, + Optional: true, + Description: "sort by list of SEP identifiers", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "sep list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "config": { + Description: "config", + Type: schema.TypeString, + Computed: true, + }, + "consumed_by": { + Type: schema.TypeSet, + Computed: true, + Description: "consumed by", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "sep id", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "multipath_num": { + Type: schema.TypeInt, + Computed: true, + Description: "multipath_num", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "name", + }, + "obj_status": { + Type: schema.TypeString, + Computed: true, + Description: "object status", + }, + "provided_by": { + Type: schema.TypeList, + Computed: true, + Description: "provided by", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "shared_with": { + Type: schema.TypeList, + Computed: true, + Description: "shared with", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entryCount", + }, + } + + return rets +} + +func dataSourceSepPoolSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Required: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Required: true, + Description: "pool name", + }, + "pool": { + Type: schema.TypeList, + Computed: true, + Description: "pool", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_account_ids": { + Type: schema.TypeList, + Computed: true, + Description: "access account ids", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "access_res_group_ids": { + Type: schema.TypeList, + Computed: true, + Description: "access res group ids", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "name", + }, + "pagecache_ratio": { + Type: schema.TypeInt, + Computed: true, + Description: "pagecache_ratio", + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + Description: "reference_id", + }, + "types": { + Type: schema.TypeList, + Computed: true, + Description: "types", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "uris": { + Type: schema.TypeSet, + Computed: true, + Description: "uris", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Computed: true, + Description: "ip", + }, + "port": { + Type: schema.TypeInt, + Computed: true, + Description: "port", + }, + }, + }, + }, + "usage_limit": { + Type: schema.TypeInt, + Computed: true, + Description: "usage limit", + }, + }, + }, + }, + } +} + +func resourceSepSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "gid": { + Type: schema.TypeInt, + Required: true, + Description: "grid (platform) ID", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "SEP name", + }, + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"des", "hitachi", "dorado", "tatlin", "shared", "local", "ustor"}, false), + Description: "type of storage", + }, + "access_to_pool": { + Type: schema.TypeSet, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "grant or revoke access to pool", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pool_name": { + Type: schema.TypeString, + Required: true, + Description: "pool name", + }, + "account_id_pool": { + Type: schema.TypeInt, + Optional: true, + Description: "account id to grant/revoke access to the specified pool sep", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "resource group id to grant/revoke access to the specified pool sep", + }, + }, + }, + }, + "account_ids": { + Type: schema.TypeSet, + Optional: true, + Description: "lift of account ids to have access to sep", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "enable SEP after creation", + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "sep type des id", + }, + "pools": { + Type: schema.TypeSet, + Optional: true, + Description: "add/delete pools to/from sep", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_account_ids": { + Type: schema.TypeList, + Required: true, + Description: "access account ids", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "access_res_group_ids": { + Type: schema.TypeList, + Required: true, + Description: "access res group ids", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "name", + }, + "types": { + Type: schema.TypeList, + Optional: true, + Description: "types", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "uris": { + Type: schema.TypeSet, + Optional: true, + Description: "uris", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Required: true, + Description: "ip", + }, + "port": { + Type: schema.TypeInt, + Required: true, + Description: "port", + }, + }, + }, + }, + "usage_limit": { + Type: schema.TypeInt, + Required: true, + Description: "usage limit", + }, + }, + }, + }, + "config": { + Type: schema.TypeString, + Required: true, + Description: "sep config string", + DiffSuppressFunc: resourceSepDiffSupperss, + }, + "consumed_by": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "list of consumer nodes IDs", + }, + "desc": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "sep description", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "multipath_num": { + Type: schema.TypeInt, + Computed: true, + Description: "multipath_num", + }, + "obj_status": { + Type: schema.TypeString, + Computed: true, + Description: "object status", + }, + "provided_by": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "list of provider nodes IDs", + }, + "shared_with": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "list of shared with ids", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + } +} + +func resourceSepConfigSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Required: true, + Description: "sep id", + }, + "config": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "config json string", + }, + "field_edit": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "field_name": { + Type: schema.TypeString, + Required: true, + Description: "field name", + }, + "field_value": { + Type: schema.TypeString, + Required: true, + Description: "field value", + }, + "field_type": { + Type: schema.TypeString, + Required: true, + Description: "field type", + }, + }, + }, + }, + } +} + +func dataSourceAvailableSEPListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Required: true, + Description: "Account ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Resource group ID", + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of available SEP entries", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "List of available SEPs", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "SEP ID", + }, + "sep_name": { + Type: schema.TypeString, + Computed: true, + Description: "SEP name", + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + Description: "SEP type", + }, + "pools": { + Type: schema.TypeList, + Computed: true, + Description: "List of pools in the SEP", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Pool name", + }, + "types": { + Type: schema.TypeList, + Computed: true, + Description: "List of pool types", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "system": { + Type: schema.TypeBool, + Computed: true, + Description: "Is system pool", + }, + }, + }, + }, + }, + }, + }, + } +} diff --git a/internal/service/cloudbroker/sep/utility_available_sep_and_pools_list.go b/internal/service/cloudbroker/sep/utility_available_sep_and_pools_list.go new file mode 100644 index 00000000..438bcb70 --- /dev/null +++ b/internal/service/cloudbroker/sep/utility_available_sep_and_pools_list.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityAvailableSEPAndPoolsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.ListAvailableSEP, error) { + c := m.(*controller.ControllerCfg) + req := sep.ListAvailableSEPAndPoolsRequest{} + + if AccountID, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(AccountID.(int)) + } + if RGID, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(RGID.(int)) + } + + log.Debugf("utilityAvailableSEPAndPoolsListCheckPresence: load sep and pools list") + sepList, err := c.CloudBroker().SEP().ListAvailableSEPAndPools(ctx, req) + if err != nil { + return nil, err + } + + return sepList, nil +} diff --git a/internal/service/cloudbroker/sep/utility_sep.go b/internal/service/cloudbroker/sep/utility_sep.go new file mode 100644 index 00000000..e456c48f --- /dev/null +++ b/internal/service/cloudbroker/sep/utility_sep.go @@ -0,0 +1,83 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + "encoding/json" + "reflect" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilitySepCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.RecordSEP, error) { + c := m.(*controller.ControllerCfg) + req := sep.GetRequest{} + + if d.Get("sep_id") != nil { + if d.Get("sep_id").(int) == 0 { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.SEPID = id + } else { + req.SEPID = uint64(d.Get("sep_id").(int)) + } + } else { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.SEPID = id + } + + log.Debugf("utilitySepCheckPresence: load sep") + sep, err := c.CloudBroker().SEP().Get(ctx, req) + if err != nil { + return nil, err + } + + return sep, nil +} + +func resourceSepDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool { + var v1, v2 interface{} + json.Unmarshal([]byte(newVal), &v1) + json.Unmarshal([]byte(oldVal), &v2) + if reflect.DeepEqual(v1, v2) { + log.Debugf("resourceSepDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal) + return true + } + log.Debugf("resourceSepDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal) + return false +} diff --git a/internal/service/cloudbroker/sep/utility_sep_config.go b/internal/service/cloudbroker/sep/utility_sep_config.go new file mode 100644 index 00000000..2e3a91e1 --- /dev/null +++ b/internal/service/cloudbroker/sep/utility_sep_config.go @@ -0,0 +1,57 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilitySepConfigCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.SEPConfig, error) { + c := m.(*controller.ControllerCfg) + req := sep.GetConfigRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + } + + log.Debugf("utilitySepConfigCheckPresence: load sep config") + sepConfig, err := c.CloudBroker().SEP().GetConfig(ctx, req) + if err != nil { + return nil, err + } + + return sepConfig, nil +} diff --git a/internal/service/cloudbroker/sep/utility_sep_consumption.go b/internal/service/cloudbroker/sep/utility_sep_consumption.go new file mode 100644 index 00000000..47f61612 --- /dev/null +++ b/internal/service/cloudbroker/sep/utility_sep_consumption.go @@ -0,0 +1,53 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" +) + +func utilitySepConsumptionCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.RecordConsumption, error) { + // c := m.(*controller.ControllerCfg) + // req := sep.ConsumptionRequest{ + // SEPID: uint64(d.Get("sep_id").(int)), + // } + + // nil, err := c.CloudBroker().SEP().Consumption(ctx, req) + // if err != nil { + // return nil, err + // } + + return nil, nil +} diff --git a/internal/service/cloudbroker/sep/utility_sep_disk_list.go b/internal/service/cloudbroker/sep/utility_sep_disk_list.go new file mode 100644 index 00000000..9f5446ae --- /dev/null +++ b/internal/service/cloudbroker/sep/utility_sep_disk_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilitySepDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]uint64, error) { + c := m.(*controller.ControllerCfg) + req := sep.DiskListRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + } + + if poolName, ok := d.GetOk("pool_name"); ok { + req.PoolName = poolName.(string) + } + + log.Debugf("utilitySepDiskListCheckPresence: load sep") + sepDiskList, err := c.CloudBroker().SEP().DiskList(ctx, req) + if err != nil { + return nil, err + } + + return sepDiskList, nil +} diff --git a/internal/service/cloudbroker/sep/utility_sep_list.go b/internal/service/cloudbroker/sep/utility_sep_list.go new file mode 100644 index 00000000..24b3a461 --- /dev/null +++ b/internal/service/cloudbroker/sep/utility_sep_list.go @@ -0,0 +1,93 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilitySepListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.ListSEP, error) { + c := m.(*controller.ControllerCfg) + req := sep.ListRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if gid, ok := d.GetOk("gid"); ok { + req.GID = uint64(gid.(int)) + } + if type_, ok := d.GetOk("type"); ok { + req.Type = type_.(string) + } + if provided_by, ok := d.GetOk("provided_by"); ok { + req.ProvidedBy = uint64(provided_by.(int)) + } + if tech_status, ok := d.GetOk("tech_status"); ok { + req.TechStatus = tech_status.(string) + } + if consumed_by, ok := d.GetOk("consumed_by"); ok { + req.ConsumedBy = uint64(consumed_by.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if sepIds, ok := d.GetOk("sep_ids"); ok { + ids := sepIds.([]interface{}) + for _, id := range ids { + req.SepIDs = append(req.SepIDs, uint64(id.(int))) + } + } + + log.Debugf("utilitySepListCheckPresence: load image list") + sepList, err := c.CloudBroker().SEP().List(ctx, req) + if err != nil { + return nil, err + } + + return sepList, nil +} diff --git a/internal/service/cloudbroker/sep/utility_sep_pool.go b/internal/service/cloudbroker/sep/utility_sep_pool.go new file mode 100644 index 00000000..c61937ad --- /dev/null +++ b/internal/service/cloudbroker/sep/utility_sep_pool.go @@ -0,0 +1,58 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilitySepPoolCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.RecordPool, error) { + c := m.(*controller.ControllerCfg) + req := sep.GetPoolRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + PoolName: d.Get("pool_name").(string), + } + + log.Debugf("utilitySepDesPoolCheckPresence: load pool") + sepPool, err := c.CloudBroker().SEP().GetPool(ctx, req) + if err != nil { + return nil, err + } + + return sepPool, nil +} diff --git a/internal/service/cloudbroker/sep/utility_sep_template.go b/internal/service/cloudbroker/sep/utility_sep_template.go new file mode 100644 index 00000000..e8b3b2b9 --- /dev/null +++ b/internal/service/cloudbroker/sep/utility_sep_template.go @@ -0,0 +1,59 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package sep + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilitySepTemplateCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { + c := m.(*controller.ControllerCfg) + req := sep.GetTemplateRequest{ + SepType: d.Get("sep_type").(string), + Language: d.Get("lang").(string), + } + + log.Debugf("utilitySepTemplateCheckPresence: load sep template") + sepTemplate, err := c.CloudBroker().SEP().GetTemplate(ctx, req) + + if err != nil { + return "", err + } + + return sepTemplate, nil +} diff --git a/internal/service/cloudbroker/stpolicy/data_source_storage_policy.go b/internal/service/cloudbroker/stpolicy/data_source_storage_policy.go new file mode 100644 index 00000000..90ba6b94 --- /dev/null +++ b/internal/service/cloudbroker/stpolicy/data_source_storage_policy.go @@ -0,0 +1,37 @@ +package stpolicy + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceStoragePolicyRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + storagePolicy, err := utilityStoragePolicyCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenStoragePolicyData(d, storagePolicy) + return nil +} + +func DataSourceStoragePolicy() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceStoragePolicyRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceStoragePolicySchemaMake(), + } +} diff --git a/internal/service/cloudbroker/stpolicy/data_source_storage_policy_list.go b/internal/service/cloudbroker/stpolicy/data_source_storage_policy_list.go new file mode 100644 index 00000000..73565f97 --- /dev/null +++ b/internal/service/cloudbroker/stpolicy/data_source_storage_policy_list.go @@ -0,0 +1,40 @@ +package stpolicy + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceStoragePolicyListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + storagePolicyList, err := utilityStoragePolicyListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenStoragePolicyList(storagePolicyList)) + d.Set("entry_count", storagePolicyList.EntryCount) + + return nil +} + +func DataSourceStoragePolicyList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceStoragePolicyListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceStoragePolicyListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/stpolicy/flattens.go b/internal/service/cloudbroker/stpolicy/flattens.go new file mode 100644 index 00000000..e11a9733 --- /dev/null +++ b/internal/service/cloudbroker/stpolicy/flattens.go @@ -0,0 +1,88 @@ +package stpolicy + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/stpolicy" +) + +func flattenStoragePolicyData(d *schema.ResourceData, storagePolicy *stpolicy.InfoStoragePolicy) { + d.Set("description", storagePolicy.Description) + d.Set("guid", storagePolicy.GUID) + d.Set("limit_iops", storagePolicy.LimitIOPS) + d.Set("name", storagePolicy.Name) + d.Set("status", storagePolicy.Status) + d.Set("access_seps_pools", flattenAccessSEPPools(storagePolicy.AccessSEPPools)) + d.Set("usage", flattenUsage(storagePolicy.Usage)) +} + +func flattenAccessSEPPools(accessSEPPools stpolicy.ListAccessSEPPools) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(accessSEPPools)) + for _, asp := range accessSEPPools { + temp := map[string]interface{}{ + "sep_id": asp.SEPID, + "sep_name": asp.Name, + "pool_names": asp.PoolNames, + "sep_tech_status": asp.SepTechStatus, + } + + res = append(res, temp) + } + + return res +} + +func flattenUsage(usage stpolicy.Usage) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + + temp := map[string]interface{}{ + "accounts": usage.Accounts, + "resgroups": usage.Resgroups, + } + + res = append(res, temp) + return res +} + +func flattenStoragePolicyList(storagePolicyList *stpolicy.ListStoragePolicies) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(storagePolicyList.Data)) + for _, v := range storagePolicyList.Data { + temp := map[string]interface{}{ + "storage_policy_id": v.ID, + "description": v.Description, + "guid": v.GUID, + "limit_iops": v.LimitIOPS, + "name": v.Name, + "status": v.Status, + "access_seps_pools": flattenAccessSEPPools(v.AccessSEPPools), + "usage": flattenUsage(v.Usage), + } + res = append(res, temp) + } + return res +} + +func flattenAccessSEPPoolsResource(accessSEPPools stpolicy.ListAccessSEPPools) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, asp := range accessSEPPools { + for _, poolName := range asp.PoolNames { + temp := map[string]interface{}{ + "sep_id": asp.SEPID, + "sep_name": asp.Name, + "pool_name": poolName, + "sep_tech_status": asp.SepTechStatus, + } + res = append(res, temp) + } + } + return res +} + +func flattenStoragePolicyResource(d *schema.ResourceData, storagePolicy *stpolicy.InfoStoragePolicy) { + d.Set("description", storagePolicy.Description) + d.Set("guid", storagePolicy.GUID) + d.Set("limit_iops", storagePolicy.LimitIOPS) + d.Set("name", storagePolicy.Name) + d.Set("status", storagePolicy.Status) + d.Set("access_seps_pools", flattenAccessSEPPoolsResource(storagePolicy.AccessSEPPools)) + d.Set("usage", flattenUsage(storagePolicy.Usage)) +} diff --git a/internal/service/cloudbroker/stpolicy/resource_storage_policy.go b/internal/service/cloudbroker/stpolicy/resource_storage_policy.go new file mode 100644 index 00000000..2751d1a4 --- /dev/null +++ b/internal/service/cloudbroker/stpolicy/resource_storage_policy.go @@ -0,0 +1,181 @@ +package stpolicy + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/stpolicy" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func resourceStoragePolicyCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceTrunkCreate: called with name %s", d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + warnings := dc.Warnings{} + + name := d.Get("name").(string) + aspRaw := d.Get("access_seps_pools") + aspFromMan := aspRaw.(*schema.Set).List() + aspArray := make([]stpolicy.AccessSEPsPool, 0, len(aspFromMan)) + aspMap := make(map[uint64][]string) + for _, aspfm := range aspFromMan { + temp := aspfm.(map[string]interface{}) + sepID := uint64(temp["sep_id"].(int)) + _, ok := aspMap[sepID] + poolName := temp["pool_name"].(string) + if !ok { + aspMap[sepID] = []string{} + } + aspMap[sepID] = append(aspMap[sepID], poolName) + } + + for key, value := range aspMap { + asp := stpolicy.AccessSEPsPool{} + asp.SEPID = key + asp.PoolNames = value + aspArray = append(aspArray, asp) + } + + req := stpolicy.CreateRequest{ + Name: name, + AccessSEPsPools: aspArray, + } + + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + + if limitIOPS, ok := d.GetOk("limit_iops"); ok { + req.LimitIOPS = uint64(limitIOPS.(int)) + } + + storagePolicyID, err := c.CloudBroker().StPolicy().Create(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(storagePolicyID, 10)) + + if enabled, ok := d.GetOk("enabled"); ok { + isToEnable := enabled.(bool) + if err := handleStoragePolicyEnabling(ctx, d, c, storagePolicyID, isToEnable); err != nil { + warnings.Add(err) + } + } + + return append(warnings.Get(), resourceStoragePolicyRead(ctx, d, m)...) +} + +func resourceStoragePolicyRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceStoragePolicyRead: called with name %s", d.Get("name").(string)) + + w := dc.Warnings{} + storagePolicyItem, err := utilityStoragePolicyCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenStoragePolicyResource(d, storagePolicyItem) + + return w.Get() +} + +func resourceStoragePolicyUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + storagePolicyID, _ := strconv.ParseUint(d.Id(), 10, 64) + + log.Debugf("resourceStoragePolicyUpdate: called storage policy with id %d", storagePolicyID) + + c := m.(*controller.ControllerCfg) + + _, err := utilityStoragePolicyCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + + return diag.FromErr(err) + } + + _, err = strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + + d.SetId("") + + return diag.FromErr(err) + } + + if d.HasChanges("name", "limit_iops", "description") { + if err := utilityStoragePolicyHandleHasChanges(ctx, d, c, storagePolicyID); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("enabled") { + enabled := d.Get("enabled") + isToEnable := enabled.(bool) + if err := handleStoragePolicyEnabling(ctx, d, c, storagePolicyID, isToEnable); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("access_seps_pools") { + if err := utilityStoragePolicyUpdateAccessSEPsPools(ctx, d, c, storagePolicyID); err != nil { + return diag.FromErr(err) + } + } + return resourceStoragePolicyRead(ctx, d, m) +} + +func resourceStoragePolicyDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceStoragePolicyDelete: called with id %s", d.Id()) + + storagePolicyItem, err := utilityStoragePolicyCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + req := stpolicy.DeleteRequest{ + StoragePolicyID: storagePolicyItem.ID, + } + if _, err := c.CloudBroker().StPolicy().Delete(ctx, req); err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceStoragePolicy() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceStoragePolicyCreate, + ReadContext: resourceStoragePolicyRead, + UpdateContext: resourceStoragePolicyUpdate, + DeleteContext: resourceStoragePolicyDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout600s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceStoragePolicySchemaMake(), + } +} diff --git a/internal/service/cloudbroker/stpolicy/schema.go b/internal/service/cloudbroker/stpolicy/schema.go new file mode 100644 index 00000000..4b1d802c --- /dev/null +++ b/internal/service/cloudbroker/stpolicy/schema.go @@ -0,0 +1,309 @@ +package stpolicy + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceStoragePolicySchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "access_seps_pools": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pool_name": { + Type: schema.TypeString, + Required: true, + }, + "sep_name": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Required: true, + }, + "sep_tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "limit_iops": { + Type: schema.TypeInt, + Optional: true, + }, + "enabled": { + Type: schema.TypeBool, + Default: true, + Optional: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "usage": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "accounts": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "resgroups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + } + + return res +} + +func dataSourceStoragePolicySchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "limit_iops": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "access_seps_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pool_names": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sep_name": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "usage": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "accounts": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "resgroups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + } + + return res +} + +func dataSourceStoragePolicyListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Optional: true, + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "size": { + Type: schema.TypeInt, + Optional: true, + }, + "by_id": { + Type: schema.TypeInt, + Optional: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + }, + "status": { + Type: schema.TypeString, + Optional: true, + }, + "desc": { + Type: schema.TypeString, + Optional: true, + }, + "limit_iops": { + Type: schema.TypeInt, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + }, + "resgroup_id": { + Type: schema.TypeInt, + Optional: true, + }, + "sep_id": { + Type: schema.TypeInt, + Optional: true, + }, + "sep_tech_status": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"ENABLED", "DISABLED"}, true), + }, + "pool_name": { + Type: schema.TypeString, + Optional: true, + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "storage_policy_id": { + Type: schema.TypeInt, + Required: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "limit_iops": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "access_seps_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pool_names": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "sep_name": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "usage": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "accounts": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "resgroups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} diff --git a/internal/service/cloudbroker/stpolicy/utility_storage_policy.go b/internal/service/cloudbroker/stpolicy/utility_storage_policy.go new file mode 100644 index 00000000..77147ec0 --- /dev/null +++ b/internal/service/cloudbroker/stpolicy/utility_storage_policy.go @@ -0,0 +1,115 @@ +package stpolicy + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/stpolicy" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityStoragePolicyCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*stpolicy.InfoStoragePolicy, error) { + c := m.(*controller.ControllerCfg) + req := stpolicy.GetRequest{} + + if d.Id() != "" { + storagePolicyID, _ := strconv.ParseUint(d.Id(), 10, 64) + req.StoragePolicyID = storagePolicyID + } else { + req.StoragePolicyID = uint64(d.Get("storage_policy_id").(int)) + } + + storagePolicyData, err := c.CloudBroker().StPolicy().Get(ctx, req) + if err != nil { + return nil, err + } + + return storagePolicyData, nil +} + +func handleStoragePolicyEnabling(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, storagePolicyID uint64, enable bool) error { + if enable { + req := stpolicy.EnableRequest{ + StoragePolicyID: storagePolicyID, + } + + _, err := c.CloudBroker().StPolicy().Enable(ctx, req) + if err != nil { + return err + } + } else { + req := stpolicy.DisableRequest{ + StoragePolicyID: storagePolicyID, + } + + _, err := c.CloudBroker().StPolicy().Disable(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func utilityStoragePolicyHandleHasChanges(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, storagePolicyID uint64) error { + req := stpolicy.UpdateRequest{ + StoragePolicyID: storagePolicyID, + } + + if d.HasChange("name") { + name := d.Get("name").(string) + req.Name = name + } + + if d.HasChange("limit_iops") { + limitIOPS := uint64(d.Get("limit_iops").(int)) + req.LimitIOPS = limitIOPS + } + + if d.HasChange("description") { + description := d.Get("description").(string) + req.Description = description + } + + if _, err := c.CloudBroker().StPolicy().Update(ctx, req); err != nil { + return err + } + + return nil +} + +func utilityStoragePolicyUpdateAccessSEPsPools(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, storagePolicyID uint64) error { + oldSet, newSet := d.GetChange("access_seps_pools") + deletedASP := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() + for _, deletedInterface := range deletedASP { + deletedItem := deletedInterface.(map[string]interface{}) + SEPID := uint64(deletedItem["sep_id"].(int)) + poolName := deletedItem["pool_name"].(string) + req := stpolicy.DeletePoolRequest{ + StoragePolicyID: storagePolicyID, + SEPID: SEPID, + PoolName: poolName, + } + if _, err := c.CloudBroker().StPolicy().DeletePool(ctx, req); err != nil { + return err + } + } + + addedASP := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() + for _, addedInterface := range addedASP { + addedItem := addedInterface.(map[string]interface{}) + SEPID := uint64(addedItem["sep_id"].(int)) + poolName := addedItem["pool_name"].(string) + req := stpolicy.AddPoolRequest{ + StoragePolicyID: storagePolicyID, + SEPID: SEPID, + PoolName: poolName, + } + if _, err := c.CloudBroker().StPolicy().AddPool(ctx, req); err != nil { + return err + } + } + + return nil +} diff --git a/internal/service/cloudbroker/stpolicy/utility_storage_policy_list.go b/internal/service/cloudbroker/stpolicy/utility_storage_policy_list.go new file mode 100644 index 00000000..fac2517e --- /dev/null +++ b/internal/service/cloudbroker/stpolicy/utility_storage_policy_list.go @@ -0,0 +1,74 @@ +package stpolicy + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/stpolicy" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityStoragePolicyListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*stpolicy.ListStoragePolicies, error) { + c := m.(*controller.ControllerCfg) + req := stpolicy.ListRequest{} + + if accountID, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountID.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if byID, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byID.(int)) + } + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + + if desc, ok := d.GetOk("desc"); ok { + req.Desc = desc.(string) + } + + if limitIOPS, ok := d.GetOk("limit_iops"); ok { + req.LimitIOPS = uint64(limitIOPS.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if resgroupID, ok := d.GetOk("resgroup_id"); ok { + req.ResgroupID = uint64(resgroupID.(int)) + } + + if SEPID, ok := d.GetOk("sep_id"); ok { + req.SepID = uint64(SEPID.(int)) + } + + if SEPtechstatus, ok := d.GetOk("sep_tech_status"); ok { + req.SepTechStatus = SEPtechstatus.(string) + } + + if poolName, ok := d.GetOk("pool_name"); ok { + req.PoolName = poolName.(string) + } + + log.Debugf("utilityStoragePolicyListCheckPresence: load storage policy list") + + storagePolicyList, err := c.CloudBroker().StPolicy().List(ctx, req) + if err != nil { + return nil, err + } + + return storagePolicyList, nil +} diff --git a/internal/service/cloudbroker/trunk/data_source_trunk.go b/internal/service/cloudbroker/trunk/data_source_trunk.go new file mode 100644 index 00000000..3fc924ad --- /dev/null +++ b/internal/service/cloudbroker/trunk/data_source_trunk.go @@ -0,0 +1,45 @@ +package trunk + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func dataSourceTrunkRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("dataSourceTrunkRead: called with name %s", d.Get("name").(string)) + + w := dc.Warnings{} + trunkItem, err := utilityTrunkCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + flattenTrunk(d, trunkItem) + + return w.Get() +} + +func DataSourceTrunk() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceTrunkRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceTrunkSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/trunk/data_source_trunk_list.go b/internal/service/cloudbroker/trunk/data_source_trunk_list.go new file mode 100644 index 00000000..76ea5eeb --- /dev/null +++ b/internal/service/cloudbroker/trunk/data_source_trunk_list.go @@ -0,0 +1,43 @@ +package trunk + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func dataSourceTrunkListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + w := dc.Warnings{} + trunkList, err := utilityTrunkListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + + d.Set("items", flattenTrunkList(trunkList)) + d.Set("entry_count", trunkList.EntryCount) + + return w.Get() +} + +func DataSourceTrunkList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceTrunkListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceTrunkListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/trunk/flattens.go b/internal/service/cloudbroker/trunk/flattens.go new file mode 100644 index 00000000..a8c467e7 --- /dev/null +++ b/internal/service/cloudbroker/trunk/flattens.go @@ -0,0 +1,80 @@ +package trunk + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/trunk" +) + +func flattenTrunkResource(d *schema.ResourceData, details *trunk.ItemTrunk) { + log.Debugf("flattenTrunk: decoded Trunk ID %s", + details.ID) + + d.Set("trunk_id", details.ID) + d.Set("guid", details.GUID) + d.Set("name", details.Name) + d.Set("mac", details.MAC) + d.Set("description", details.Description) + d.Set("account_ids", details.AccountIDs) + d.Set("ovs_bridge", details.OVSBridge) + d.Set("native_vlan_id", details.NativeVLANID) + d.Set("status", details.Status) + d.Set("trunk_tags", details.TrunkTags) + d.Set("created_at", details.CreatedAt) + d.Set("created_by", details.CreatedBy) + d.Set("updated_at", details.UpdatedAt) + d.Set("updated_by", details.UpdatedBy) + d.Set("deleted_at", details.DeletedAt) + d.Set("deleted_by", details.DeletedBy) +} + +func flattenTrunk(d *schema.ResourceData, trunkItem *trunk.ItemTrunk) { + log.Debugf("flattenTrunk: decoded Trunk ID %d", + trunkItem.ID) + + d.Set("trunk_id", trunkItem.ID) + d.Set("guid", trunkItem.GUID) + d.Set("name", trunkItem.Name) + d.Set("mac", trunkItem.MAC) + d.Set("description", trunkItem.Description) + d.Set("account_ids", trunkItem.AccountIDs) + d.Set("ovs_bridge", trunkItem.OVSBridge) + d.Set("native_vlan_id", trunkItem.NativeVLANID) + d.Set("mtu", trunkItem.MTU) + d.Set("status", trunkItem.Status) + d.Set("trunk_tags", trunkItem.TrunkTags) + d.Set("created_at", trunkItem.CreatedAt) + d.Set("created_by", trunkItem.CreatedBy) + d.Set("updated_at", trunkItem.UpdatedAt) + d.Set("updated_by", trunkItem.UpdatedBy) + d.Set("deleted_at", trunkItem.DeletedAt) + d.Set("deleted_by", trunkItem.DeletedBy) +} + +func flattenTrunkList(trunkList *trunk.ListTrunks) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(trunkList.Data)) + for _, trunkItem := range trunkList.Data { + temp := map[string]interface{}{ + "account_ids": trunkItem.AccountIDs, + "created_at": trunkItem.CreatedAt, + "created_by": trunkItem.CreatedBy, + "deleted_at": trunkItem.DeletedAt, + "deleted_by": trunkItem.DeletedBy, + "description": trunkItem.Description, + "guid": trunkItem.GUID, + "id": trunkItem.ID, + "mac": trunkItem.MAC, + "name": trunkItem.Name, + "native_vlan_id": trunkItem.NativeVLANID, + "ovs_bridge": trunkItem.OVSBridge, + "mtu": trunkItem.MTU, + "status": trunkItem.Status, + "trunk_tags": trunkItem.TrunkTags, + "updated_at": trunkItem.UpdatedAt, + "updated_by": trunkItem.UpdatedBy, + } + res = append(res, temp) + } + + return res +} diff --git a/internal/service/cloudbroker/trunk/resource_trunk.go b/internal/service/cloudbroker/trunk/resource_trunk.go new file mode 100644 index 00000000..5e4eff96 --- /dev/null +++ b/internal/service/cloudbroker/trunk/resource_trunk.go @@ -0,0 +1,228 @@ +package trunk + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/trunk" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func resourceTrunkCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("resourceTrunkCreate: called with name %s, trunk_tags %s, ovs_bridge %s", d.Get("name").(string), d.Get("trunk_tags").(string), d.Get("ovs_bridge").(string)) + + c := m.(*controller.ControllerCfg) + + warnings := dc.Warnings{} + + name := d.Get("name").(string) + + trunkTags := d.Get("trunk_tags").(string) + + ovsBridge := d.Get("ovs_bridge").(string) + + createReq := trunk.CreateRequest{ + Name: name, + TrunkTags: trunkTags, + OVSBridge: ovsBridge, + } + + if description, ok := d.GetOk("description"); ok { + createReq.Description = description.(string) + } + + if mtu, ok := d.GetOk("mtu"); ok { + createReq.MTU = uint64(mtu.(int)) + } + + accountIDs := make([]uint64, 0) + + if accountAccess, ok := d.GetOk("account_ids"); ok { + IDs := accountAccess.(*schema.Set).List() + + for _, ID := range IDs { + accountIDs = append(accountIDs, uint64(ID.(int))) + } + createReq.AccountIDs = accountIDs + } + + if nativeVLANID, ok := d.GetOk("native_vlan_id"); ok { + createReq.NativeVLANID = uint64(nativeVLANID.(int)) + } + + trunkID, err := c.CloudBroker().Trunk().Create(ctx, createReq) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(trunkID, 10)) + d.Set("trunk_id", trunkID) + + if _, ok := d.GetOk("enable"); ok { + if err := handleTrunkEnabling(ctx, d, c, trunkID); err != nil { + warnings.Add(err) + } + } + + return append(warnings.Get(), resourceTrunkRead(ctx, d, m)...) +} + +func resourceTrunkRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("resourceTrunkRead: called with name %s", d.Get("name").(string)) + + w := dc.Warnings{} + + trunkItem, err := utilityTrunkCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + + return diag.FromErr(err) + } + flattenTrunkResource(d, trunkItem) + + return w.Get() +} + +func resourceTrunkUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("resourceTrunkUpdate: called with id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + trunkItem, err := utilityTrunkCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + + return diag.FromErr(err) + } + + id, err := strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + + d.SetId("") + + return diag.FromErr(err) + } + + if d.HasChanges("name", "trunk_tags", "description", "native_vlan_id", "mtu") { + req := trunk.UpdateRequest{ + TrunkID: uint64(id), + } + + if d.HasChange("name") { + name := d.Get("name").(string) + req.Name = name + } + + if d.HasChange("trunk_tags") { + trunkTags := d.Get("trunk_tags").(string) + req.TrunkTags = trunkTags + } + + if d.HasChange("description") { + description := d.Get("description").(string) + req.Description = description + } + + if d.HasChange("native_vlan_id") { + nativeVLANID := uint64(d.Get("native_vlan_id").(int)) + req.NativeVLANID = nativeVLANID + } + + if d.HasChange("mtu") { + mtu := d.Get("mtu").(int) + req.MTU = uint64(mtu) + } + + if _, err := c.CloudBroker().Trunk().Update(ctx, req); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("enable") { + if err := handleTrunkEnabling(ctx, d, c, uint64(id)); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("account_ids") { + if err := handleAccountAccessUpdate(ctx, d, c, trunkItem); err != nil { + return diag.FromErr(err) + } + } + + return resourceTrunkRead(ctx, d, m) +} + +func resourceTrunkDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("resourceTrunkDelete: called with id %s", d.Id()) + + trunkItem, err := utilityTrunkCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + + req := trunk.DestroyRequest{ + TrunkID: trunkItem.ID, + } + + _, err = c.CloudBroker().Trunk().Destroy(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceTrunk() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error { + if diff.HasChanges() || diff.HasChanges("name", "trunk_tags", "description", "native_vlan_id", "account_ids") { + diff.SetNewComputed("updated_time") + diff.SetNewComputed("updated_by") + } + if diff.HasChanges("enable") { + diff.SetNewComputed("status") + diff.SetNewComputed("updated_time") + diff.SetNewComputed("updated_by") + } + return nil + }, + + CreateContext: resourceTrunkCreate, + ReadContext: resourceTrunkRead, + UpdateContext: resourceTrunkUpdate, + DeleteContext: resourceTrunkDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout600s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceTrunkSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/trunk/schema.go b/internal/service/cloudbroker/trunk/schema.go new file mode 100644 index 00000000..a23264ce --- /dev/null +++ b/internal/service/cloudbroker/trunk/schema.go @@ -0,0 +1,352 @@ +package trunk + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" +) + +func resourceTrunkSchemaMake() map[string]*schema.Schema { + log.Debugf("resourceTrunkSchemaMake: invoked") + return map[string]*schema.Schema{ + "trunk_id": { + Type: schema.TypeInt, + Computed: true, + Description: "trunk id", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the trunk", + }, + "trunk_tags": { + Type: schema.TypeString, + Required: true, + Description: "List of trunk tags (values between 1-4095)", + }, + "ovs_bridge": { + Type: schema.TypeString, + Required: true, + Description: "OVS bridge name", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Description of the trunk", + }, + "account_ids": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of account IDs with access to this trunk", + }, + "native_vlan_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Native VLAN ID", + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Whether the trunk should be enabled", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "GUID", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address", + }, + "mtu": { + Type: schema.TypeInt, + Optional: true, + Default: 1500, + Description: "Maximum Transmission Unit", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "if the trunk is enabled", + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was created", + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + Description: "who created the trunk", + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was updated", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + Description: "who updated the trunk", + }, + "deleted_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was updated", + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + Description: "who updated the trunk", + }, + } +} + +func dataSourceTrunkSchemaMake() map[string]*schema.Schema { + log.Debugf("dataSourceTrunkSchemaMake: invoked") + + res := map[string]*schema.Schema{ + "trunk_id": { + Type: schema.TypeInt, + Required: true, + Description: "trunk id", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "GUID", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the trunk", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of the trunk", + }, + "account_ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of account IDs with access to this trunk", + }, + "ovs_bridge": { + Type: schema.TypeString, + Computed: true, + Description: "OVS bridge name", + }, + "native_vlan_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Native VLAN ID", + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum Transmission Unit", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "if the trunk is enabled", + }, + "trunk_tags": { + Type: schema.TypeString, + Computed: true, + Description: "List of trunk tags (values between 1-4095)", + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was created", + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + Description: "who created the trunk", + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was updated", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + Description: "who updated the trunk", + }, + "deleted_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was updated", + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + Description: "who updated the trunk", + }, + } + + return res +} + +func dataSourceTrunkListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "trunk_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "ID of the trunk(s) to filter by", + }, + "account_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "Account access ID(s) to filter by", + }, + "trunk_tags": { + Type: schema.TypeString, + Optional: true, + Description: "Trunk tags to filter by (value between 1-4095)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number.", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size.", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "find by status", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "Sort by one of supported fields, format ±", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of account IDs with access to this trunk", + }, + "created_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was created", + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + Description: "who created the trunk", + }, + "deleted_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was updated", + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + Description: "who updated the trunk", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of the trunk", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "GUID", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "Trunk ID", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the trunk", + }, + "native_vlan_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Native VLAN ID", + }, + "ovs_bridge": { + Type: schema.TypeString, + Computed: true, + Description: "OVS bridge name", + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + Description: "Maximum Transmission Unit", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "if the trunk is enabled", + }, + "trunk_tags": { + Type: schema.TypeString, + Computed: true, + Description: "List of trunk tags (values between 1-4095)", + }, + "updated_at": { + Type: schema.TypeInt, + Computed: true, + Description: "when the trunk was updated", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + Description: "who updated the trunk", + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} diff --git a/internal/service/cloudbroker/trunk/utility_trunk.go b/internal/service/cloudbroker/trunk/utility_trunk.go new file mode 100644 index 00000000..2960d839 --- /dev/null +++ b/internal/service/cloudbroker/trunk/utility_trunk.go @@ -0,0 +1,104 @@ +package trunk + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/trunk" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityTrunkCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*trunk.ItemTrunk, error) { + c := m.(*controller.ControllerCfg) + req := trunk.GetRequest{} + + if d.Id() != "" { + id, err := strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + return nil, err + } + + req.TrunkID = uint64(id) + } else { + req.TrunkID = uint64(d.Get("trunk_id").(int)) + } + + trunkInfo, err := c.CloudBroker().Trunk().Get(ctx, req) + if err != nil { + return nil, err + } + + return trunkInfo, nil +} + +func handleAccountAccessUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, trnk *trunk.ItemTrunk) error { + oldSet, newSet := d.GetChange("account_ids") + + revokeSet := oldSet.(*schema.Set).Difference(newSet.(*schema.Set)) + if revokeSet.Len() > 0 { + accountIDs := make([]uint64, 0) + for _, revokeAccountID := range revokeSet.List() { + accountIDs = append(accountIDs, uint64(revokeAccountID.(int))) + } + + log.Debugf("cloudbroker: revoking access from %d account IDs", revokeSet.Len()) + + req := trunk.AccessRevokeRequest{ + TrunkID: trnk.ID, + AccountIDs: accountIDs, + } + + _, err := c.CloudBroker().Trunk().AccessRevoke(ctx, req) + if err != nil { + return err + } + } + + grantSet := newSet.(*schema.Set).Difference(oldSet.(*schema.Set)) + if grantSet.Len() > 0 { + accountIDs := make([]uint64, 0) + for _, grantAccountID := range grantSet.List() { + accountIDs = append(accountIDs, uint64(grantAccountID.(int))) + } + + log.Debugf("cloudbroker: granting access to %d account IDs", grantSet.Len()) + + req := trunk.AccessGrantRequest{ + TrunkID: trnk.ID, + AccountIDs: accountIDs, + } + + _, err := c.CloudBroker().Trunk().AccessGrant(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func handleTrunkEnabling(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, trunkID uint64) error { + if d.Get("enable").(bool) { + req := trunk.EnableRequest{ + TrunkID: trunkID, + } + + _, err := c.CloudBroker().Trunk().Enable(ctx, req) + if err != nil { + return err + } + } else { + req := trunk.DisableRequest{ + TrunkID: trunkID, + } + + _, err := c.CloudBroker().Trunk().Disable(ctx, req) + if err != nil { + return err + } + } + + return nil +} diff --git a/internal/service/cloudbroker/trunk/utility_trunk_list.go b/internal/service/cloudbroker/trunk/utility_trunk_list.go new file mode 100644 index 00000000..ddcdace8 --- /dev/null +++ b/internal/service/cloudbroker/trunk/utility_trunk_list.go @@ -0,0 +1,51 @@ +package trunk + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/trunk" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityTrunkListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*trunk.ListTrunks, error) { + c := m.(*controller.ControllerCfg) + req := trunk.ListRequest{} + + if trunkIDs, ok := d.GetOk("trunk_ids"); ok { + IDs := trunkIDs.([]interface{}) + for _, id := range IDs { + req.IDs = append(req.IDs, uint64(id.(int))) + } + } + if accountIDs, ok := d.GetOk("account_ids"); ok { + IDs := accountIDs.([]interface{}) + for _, id := range IDs { + req.AccountIDs = append(req.AccountIDs, uint64(id.(int))) + } + } + if trunkTags, ok := d.GetOk("trunk_tags"); ok { + req.TrunkTags = trunkTags.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + + log.Debugf("utilityTrunkListCheckPresence: load trunk network list") + trunkList, err := c.CloudBroker().Trunk().List(ctx, req) + if err != nil { + return nil, err + } + + return trunkList, nil +} diff --git a/internal/service/cloudbroker/user/data_source_user.go b/internal/service/cloudbroker/user/data_source_user.go new file mode 100644 index 00000000..14be07b5 --- /dev/null +++ b/internal/service/cloudbroker/user/data_source_user.go @@ -0,0 +1,68 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package user + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceUserRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + user, err := utilityUserCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + flattenUserDataSource(d, user) + d.SetId(d.Get("user_id").(string)) + + return nil +} + +func DataSourceUser() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceUserRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceUserSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/user/data_source_user_get_audit.go b/internal/service/cloudbroker/user/data_source_user_get_audit.go new file mode 100644 index 00000000..96b2ebbc --- /dev/null +++ b/internal/service/cloudbroker/user/data_source_user_get_audit.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package user + +import ( + "context" + "github.com/google/uuid" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceUserGetAuditRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + audits, err := utilityUserGetAuditCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenUserGetAudits(audits)) + d.Set("entry_count", audits.EntryCount) + + return nil +} + +func DataSourceUserGetAudit() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceUserGetAuditRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceUserGetAuditSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/user/data_source_user_list.go b/internal/service/cloudbroker/user/data_source_user_list.go new file mode 100644 index 00000000..9d5ab987 --- /dev/null +++ b/internal/service/cloudbroker/user/data_source_user_list.go @@ -0,0 +1,74 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package user + +import ( + "context" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceUserListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + users, err := utilityUserListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + err = d.Set("items", flattenUserList(users)) + log.Debug("err:", err) + d.Set("entry_count", users.EntryCount) + + return nil +} + +func DataSourceUserList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceUserListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceUserListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/user/flattens.go b/internal/service/cloudbroker/user/flattens.go new file mode 100644 index 00000000..b0a9b30e --- /dev/null +++ b/internal/service/cloudbroker/user/flattens.go @@ -0,0 +1,186 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package user + +import ( + "strconv" + + log "github.com/sirupsen/logrus" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/user" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenUserDataSource(d *schema.ResourceData, details *user.ItemUser) { + log.Debugf("flattenUser: decoded User ID %s", + details.ID) + + d.Set("user_id", details.ID) + d.Set("ckey", details.CKey) + d.Set("meta", flattens.FlattenMeta(details.Meta)) + d.Set("api_access", details.APIAccess) + d.Set("active", details.Active) + d.Set("authkey", details.AuthKey) + d.Set("auth_keys", flattenItemUser(details.AuthKeys)) + d.Set("blocked", details.Blocked) + d.Set("data", details.Data) + d.Set("description", details.Description) + d.Set("domain", details.Domain) + d.Set("emails", details.Emails) + d.Set("gid", details.GID) + d.Set("groups", details.Groups) + d.Set("guid", details.GUID) + d.Set("last_check", details.LastCheck) + d.Set("mobile", flattenItemUser(details.Mobile)) + d.Set("protected", details.Protected) + d.Set("roles", flattenItemUser(details.Roles)) + d.Set("service_account", details.ServiceAccount) + d.Set("xmpp", flattenItemUser(details.XMPP)) +} + +func flattenUserResource(d *schema.ResourceData, details *user.ItemUser) { + log.Debugf("flattenUser: decoded User ID %s", + details.ID) + + d.Set("username", details.ID) + d.Set("ckey", details.CKey) + d.Set("meta", flattens.FlattenMeta(details.Meta)) + d.Set("apiaccess", flattenAPIAcess(details.APIAccess)) + d.Set("active", details.Active) + d.Set("authkey", details.AuthKey) + d.Set("auth_keys", flattenItemUser(details.AuthKeys)) + d.Set("blocked", details.Blocked) + d.Set("data", details.Data) + d.Set("description", details.Description) + d.Set("domain", details.Domain) + d.Set("emailaddress", details.Emails[0]) + d.Set("gid", details.GID) + d.Set("groups", details.Groups) + d.Set("guid", details.GUID) + d.Set("last_check", details.LastCheck) + d.Set("mobile", flattenItemUser(details.Mobile)) + d.Set("protected", details.Protected) + d.Set("roles", flattenItemUser(details.Roles)) + d.Set("service_account", details.ServiceAccount) + d.Set("xmpp", flattenItemUser(details.XMPP)) +} + +func flattenItemUser(m []interface{}) []string { + output := []string{} + for _, item := range m { + switch d := item.(type) { + case string: + output = append(output, d) + case int: + output = append(output, strconv.Itoa(d)) + case int64: + output = append(output, strconv.FormatInt(d, 10)) + case float64: + output = append(output, strconv.FormatInt(int64(d), 10)) + default: + output = append(output, "") + } + } + return output +} + +func flattenUserGetAudits(audits *user.ListAudits) []map[string]interface{} { + log.Debug("flattenUserGetAudits") + + res := make([]map[string]interface{}, 0, len(audits.Data)) + for _, item := range audits.Data { + temp := map[string]interface{}{ + "call": item.Call, + "response_time": item.ResponseTime, + "status_code": item.StatusCode, + "time": item.Time, + "guid": item.GUID, + } + res = append(res, temp) + } + + return res +} + +func flattenUserList(users *user.ListUsers) []map[string]interface{} { + log.Debug("flattenUserList") + + res := make([]map[string]interface{}, 0, len(users.Data)) + for _, item := range users.Data { + temp := map[string]interface{}{ + "ckey": item.CKey, + "meta": flattens.FlattenMeta(item.Meta), + "apiaccess": item.APIAccess, + "active": item.Active, + "authkey": item.AuthKey, + "authkeys": flattenItemUser(item.AuthKeys), + "blocked": item.Blocked, + "data": item.Data, + "description": item.Description, + "domain": item.Domain, + "emails": item.Emails, + "gid": item.GID, + "groups": item.Groups, + "guid": item.GUID, + "user_id": item.ID, + "last_check": item.LastCheck, + "mobile": flattenItemUser(item.Mobile), + "protected": item.Protected, + "roles": flattenItemUser(item.Roles), + "service_account": item.ServiceAccount, + "xmpp": flattenItemUser(item.XMPP), + } + res = append(res, temp) + } + + return res +} + +func flattenAPIAcess(in map[string]string) []int { + + res := make([]int, 0, len(in)) + + for i := range in { + num, err := strconv.Atoi(i) + if err != nil { + + log.Errorf("flattenAPIAcess: unable to convert %s to digit %v", i, err) + + return nil + } + res = append(res, num) + } + return res + +} diff --git a/internal/service/cloudbroker/user/old_schemas.go b/internal/service/cloudbroker/user/old_schemas.go new file mode 100644 index 00000000..59d31e7e --- /dev/null +++ b/internal/service/cloudbroker/user/old_schemas.go @@ -0,0 +1,156 @@ +package user + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceUserV1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + Description: "ID of user", + }, + "emailaddress": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "Email address of the user", + }, + "password": { + Type: schema.TypeString, + Default: "strongpassword", + Optional: true, + Description: "password of user", + }, + "provider_name": { + Type: schema.TypeString, + Optional: true, + Description: "provider", + ValidateFunc: validation.StringInSlice([]string{"bvs", "decs3o"}, false), + }, + "groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "list of groups this user belongs to", + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "meta", + }, + "active": { + Type: schema.TypeBool, + Computed: true, + Description: "active", + }, + "apiaccess": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "list of apiaccess groups this user belongs to", + }, + "blocked": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "is the user blocked", + }, + "authkey": { + Type: schema.TypeString, + Computed: true, + Description: "authkey", + }, + "auth_keys": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "authkeys", + }, + "data": { + Type: schema.TypeString, + Computed: true, + Description: "data", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "domain": { + Type: schema.TypeString, + Computed: true, + Description: "domain", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid", + }, + "last_check": { + Type: schema.TypeInt, + Computed: true, + Description: "last_check", + }, + "mobile": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "mobile", + }, + "protected": { + Type: schema.TypeBool, + Computed: true, + Description: "protected", + }, + "roles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "roles", + }, + "service_account": { + Type: schema.TypeBool, + Computed: true, + Description: "service_account", + }, + "xmpp": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "xmpp", + }, + }, + } +} diff --git a/internal/service/cloudbroker/user/resource_user.go b/internal/service/cloudbroker/user/resource_user.go new file mode 100644 index 00000000..8f314fb5 --- /dev/null +++ b/internal/service/cloudbroker/user/resource_user.go @@ -0,0 +1,166 @@ +package user + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/user" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceUserCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("resourceUserCreate: called with username %s, emailaddress %v", d.Get("username").(string), d.Get("emailaddress").([]interface{})) + + c := m.(*controller.ControllerCfg) + + username := d.Get("username").(string) + + email := d.Get("emailaddress").(string) + + createReq := user.CreateRequest{ + Username: username, + EmailAddress: email, + } + + createReq.Password = d.Get("password").(string) + + if provider, ok := d.GetOk("provider_name"); ok { + createReq.Provider = provider.(string) + } + + if aa, ok := d.GetOk("apiaccess"); ok { + + apiaccess := aa.(*schema.Set) + + for _, v := range apiaccess.List() { + + createReq.APIAccess = append(createReq.APIAccess, uint64(v.(int))) + } + } + + _, err := c.CloudBroker().User().Create(ctx, createReq) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(username) + + return resourceUserRead(ctx, d, m) +} + +func resourceUserRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("resourceUserRead: called with username %s", d.Get("username").(string)) + + user, err := utilityUserCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + + return diag.FromErr(err) + } + flattenUserResource(d, user) + + return nil +} + +func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("resourceUserUpdate: called with username %s", d.Get("username").(string)) + + if d.HasChange("apiaccess") { + + err := utilityUserAPIAccessGroupsConfigure(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + } + + c := m.(*controller.ControllerCfg) + + if d.HasChange("blocked") { + blocked := d.Get("blocked").(bool) + if blocked { + req := user.BlockRequest{ + UserID: d.Id(), + } + + if _, err := c.CloudBroker().User().Block(ctx, req); err != nil { + return diag.FromErr(err) + } + } else { + req := user.UnblockRequest{ + UserID: d.Id(), + } + + if _, err := c.CloudBroker().User().Unblock(ctx, req); err != nil { + return diag.FromErr(err) + } + } + } + + return resourceUserRead(ctx, d, m) +} + +func resourceUserDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + + log.Debugf("resourceUserDelete: called with username %s", d.Get("username").(string)) + + usr, err := utilityUserCheckPresence(ctx, d, m) + if err != nil { + + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + + req := user.DeleteRequest{ + Username: usr.ID, + } + + _, err = c.CloudBroker().User().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + return nil +} + +func ResourceUser() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 2, + + CreateContext: resourceUserCreate, + ReadContext: resourceUserRead, + UpdateContext: resourceUserUpdate, + DeleteContext: resourceUserDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout600s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + StateUpgraders: []schema.StateUpgrader{ + { + Version: 1, + Type: resourceUserV1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceUserUpgradeV1, + }, + }, + + Schema: resourceUserSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/user/schema.go b/internal/service/cloudbroker/user/schema.go new file mode 100644 index 00000000..4b9e5ae4 --- /dev/null +++ b/internal/service/cloudbroker/user/schema.go @@ -0,0 +1,549 @@ +package user + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" +) + +func dataSourceUserSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "user_id": { + Type: schema.TypeString, + Required: true, + Description: "user_id", + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "meta", + }, + "active": { + Type: schema.TypeBool, + Computed: true, + Description: "active", + }, + "api_access": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "api_access", + }, + "authkey": { + Type: schema.TypeString, + Computed: true, + Description: "authkey", + }, + "authkeys": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "authkeys", + }, + "blocked": { + Type: schema.TypeBool, + Computed: true, + Description: "is the user blocked", + }, + "data": { + Type: schema.TypeString, + Computed: true, + Description: "data", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "domain": { + Type: schema.TypeString, + Computed: true, + Description: "domain", + }, + "emails": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "emails", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "groups", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid", + }, + "last_check": { + Type: schema.TypeInt, + Computed: true, + Description: "last_check", + }, + "mobile": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "mobile", + }, + "protected": { + Type: schema.TypeBool, + Computed: true, + Description: "protected", + }, + "roles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "roles", + }, + "service_account": { + Type: schema.TypeBool, + Computed: true, + Description: "service_account", + }, + "xmpp": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "xmpp", + }, + } +} + +func dataSourceUserGetAuditSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Optional: true, + Description: "name of user (get audits for current user if set to empty)", + }, + "call": { + Type: schema.TypeString, + Optional: true, + Description: "find by api call", + }, + "status_code": { + Type: schema.TypeInt, + Optional: true, + Description: "find by status code", + }, + "timestamp_at": { + Type: schema.TypeInt, + Optional: true, + Description: "find all audits after point in time (unixtime)", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format ±", + }, + "timestamp_to": { + Type: schema.TypeInt, + Optional: true, + Description: "find all audits before point in time (unixtime)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "call": { + Type: schema.TypeString, + Computed: true, + }, + "response_time": { + Type: schema.TypeFloat, + Computed: true, + }, + "status_code": { + Type: schema.TypeInt, + Computed: true, + }, + "time": { + Type: schema.TypeFloat, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry_count", + }, + } +} + +func dataSourceUserListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeString, + Optional: true, + Description: "find by id", + }, + "active": { + Type: schema.TypeBool, + Optional: true, + Description: "find by active. True or False", + }, + "email": { + Type: schema.TypeString, + Optional: true, + Description: "find by email", + }, + "service_account": { + Type: schema.TypeBool, + Optional: true, + Description: "find by service account. True or False", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "meta", + }, + "active": { + Type: schema.TypeBool, + Computed: true, + Description: "active", + }, + "apiaccess": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "apiaccess", + }, + "authkey": { + Type: schema.TypeString, + Computed: true, + Description: "authkey", + }, + "authkeys": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "authkeys", + }, + "blocked": { + Type: schema.TypeBool, + Computed: true, + Description: "is the user blocked", + }, + "data": { + Type: schema.TypeString, + Computed: true, + Description: "data", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "domain": { + Type: schema.TypeString, + Computed: true, + Description: "domain", + }, + "emails": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "emails", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "groups", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid", + }, + "user_id": { + Type: schema.TypeString, + Computed: true, + Description: "user id", + }, + "last_check": { + Type: schema.TypeInt, + Computed: true, + Description: "last_check", + }, + "mobile": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "mobile", + }, + "protected": { + Type: schema.TypeBool, + Computed: true, + Description: "protected", + }, + "roles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "roles", + }, + "service_account": { + Type: schema.TypeBool, + Computed: true, + Description: "service_account", + }, + "xmpp": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "xmpp", + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry_count", + }, + } +} + +func resourceUserSchemaMake() map[string]*schema.Schema { + log.Debugf("resourceUserSchemaMake: invoked") + return map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + Description: "ID of user", + }, + "emailaddress": { + Type: schema.TypeString, + Required: true, + Description: "email address of the user", + }, + "password": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + Description: "password of user", + }, + "provider_name": { + Type: schema.TypeString, + Optional: true, + Description: "provider", + ValidateFunc: validation.StringInSlice([]string{"bvs", "decs3o"}, false), + }, + "groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "list of groups this user belongs to", + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "meta", + }, + "active": { + Type: schema.TypeBool, + Computed: true, + Description: "active", + }, + "apiaccess": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "list of apiaccess groups this user belongs to", + }, + "blocked": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "is the user blocked", + }, + "authkey": { + Type: schema.TypeString, + Computed: true, + Description: "authkey", + }, + "auth_keys": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "authkeys", + }, + "data": { + Type: schema.TypeString, + Computed: true, + Description: "data", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "domain": { + Type: schema.TypeString, + Computed: true, + Description: "domain", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid", + }, + "last_check": { + Type: schema.TypeInt, + Computed: true, + Description: "last_check", + }, + "mobile": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "mobile", + }, + "protected": { + Type: schema.TypeBool, + Computed: true, + Description: "protected", + }, + "roles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "roles", + }, + "service_account": { + Type: schema.TypeBool, + Computed: true, + Description: "service_account", + }, + "xmpp": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "xmpp", + }, + } +} diff --git a/internal/service/cloudbroker/user/state_upgrader.go b/internal/service/cloudbroker/user/state_upgrader.go new file mode 100644 index 00000000..35021d33 --- /dev/null +++ b/internal/service/cloudbroker/user/state_upgrader.go @@ -0,0 +1,20 @@ +package user + +import ( + "context" + + log "github.com/sirupsen/logrus" +) + +func resourceUserUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { + log.Debug("resourceUserUpgradeV1: upgrading state from list to string") + + if oldVal, ok := rawState["emailaddress"].([]interface{}); ok && len(oldVal) > 0 { + if firstEmail, ok := oldVal[0].(string); ok { + rawState["emailaddress"] = firstEmail + log.Debugf("resourceUserUpgradeV1: converted emailaddress from list to string: %s", firstEmail) + } + } + + return rawState, nil +} diff --git a/internal/service/cloudbroker/user/utility_user.go b/internal/service/cloudbroker/user/utility_user.go new file mode 100644 index 00000000..0e754ae0 --- /dev/null +++ b/internal/service/cloudbroker/user/utility_user.go @@ -0,0 +1,108 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package user + +import ( + "context" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/user" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" +) + +func utilityUserCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*user.ItemUser, error) { + c := m.(*controller.ControllerCfg) + req := user.GetRequest{} + + if d.Id() != "" { + req.UserID = d.Id() + } else { + req.UserID = d.Get("user_id").(string) + } + + userInfo, err := c.CloudBroker().User().Get(ctx, req) + if err != nil { + return nil, err + } + + return userInfo, nil +} + +func utilityUserAPIAccessGroupsConfigure(ctx context.Context, d *schema.ResourceData, m interface{}) error { + + c := m.(*controller.ControllerCfg) + + old_set, new_set := d.GetChange("apiaccess") + + leave_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set)) + + log.Debugf("utilityUserAPIAccessGroupsConfigure: leave set has %d items for Username %s", leave_set.Len(), d.Id()) + + if leave_set.Len() > 0 { + + for _, v := range leave_set.List() { + + leaveReq := user.APIAccessLeaveRequest{ + UserID: d.Id(), + APIAccessID: uint64(v.(int)), + } + _, err := c.CloudBroker().User().APIAccessLeave(ctx, leaveReq) + if err != nil { + return err + } + } + } + + join_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set)) + + log.Debugf("utilityUserAPIAccessGroupsConfigure: join set has %d items for Username %s", join_set.Len(), d.Id()) + + if join_set.Len() > 0 { + + for _, v := range join_set.List() { + + joinReq := user.APIAccessJoinRequest{ + UserID: d.Id(), + APIAccessID: uint64(v.(int)), + } + _, err := c.CloudBroker().User().APIAccessJoin(ctx, joinReq) + if err != nil { + return err + } + } + } + + return nil +} diff --git a/internal/service/cloudbroker/user/utility_user_get_audit.go b/internal/service/cloudbroker/user/utility_user_get_audit.go new file mode 100644 index 00000000..709c49d8 --- /dev/null +++ b/internal/service/cloudbroker/user/utility_user_get_audit.go @@ -0,0 +1,80 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package user + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/user" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityUserGetAuditCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*user.ListAudits, error) { + c := m.(*controller.ControllerCfg) + req := user.GetAuditRequest{} + + if username, ok := d.GetOk("username"); ok { + req.Username = username.(string) + } + if call, ok := d.GetOk("call"); ok { + req.Call = call.(string) + } + if statusCode, ok := d.GetOk("status_code"); ok { + req.StatusCode = uint64(statusCode.(int)) + } + + if timestampAt, ok := d.GetOk("timestamp_at"); ok { + req.TimestampAt = uint64(timestampAt.(int)) + } + if timestampTo, ok := d.GetOk("timestamp_to"); ok { + req.TimestampTo = uint64(timestampTo.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if Page, ok := d.GetOk("page"); ok { + req.Page = uint64(Page.(int)) + } + if Size, ok := d.GetOk("size"); ok { + req.Size = uint64(Size.(int)) + } + + audits, err := c.CloudBroker().User().GetAudit(ctx, req) + if err != nil { + return nil, err + } + + return &audits, nil +} diff --git a/internal/service/cloudbroker/user/utility_user_list.go b/internal/service/cloudbroker/user/utility_user_list.go new file mode 100644 index 00000000..3ddc91a7 --- /dev/null +++ b/internal/service/cloudbroker/user/utility_user_list.go @@ -0,0 +1,81 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package user + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/user" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityUserListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*user.ListUsers, error) { + c := m.(*controller.ControllerCfg) + req := user.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = byId.(string) + } + + if active, ok := d.GetOk("active"); ok { + req.Active = active.(bool) + } + + if email, ok := d.GetOk("email"); ok { + req.Email = email.(string) + } + + if serviceAccount, ok := d.GetOk("service_account"); ok { + req.ServiceAccount = serviceAccount.(bool) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if Page, ok := d.GetOk("page"); ok { + req.Page = uint64(Page.(int)) + } + + if Size, ok := d.GetOk("size"); ok { + req.Size = uint64(Size.(int)) + } + + usersList, err := c.CloudBroker().User().List(ctx, req) + if err != nil { + return nil, err + } + + return usersList, nil +} diff --git a/internal/service/cloudbroker/vfpool/data_source_vfpool.go b/internal/service/cloudbroker/vfpool/data_source_vfpool.go new file mode 100644 index 00000000..27062c92 --- /dev/null +++ b/internal/service/cloudbroker/vfpool/data_source_vfpool.go @@ -0,0 +1,68 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceVFPoolRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vfpool, err := utilityVFpoolCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(d.Get("vfpool_id").(int))) + flattenVFPoolDataSource(d, vfpool) + return nil +} + +func DataSourceVFPool() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVFPoolRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVFPoolSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vfpool/data_source_vfpool_list.go b/internal/service/cloudbroker/vfpool/data_source_vfpool_list.go new file mode 100644 index 00000000..4818f2b2 --- /dev/null +++ b/internal/service/cloudbroker/vfpool/data_source_vfpool_list.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "context" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceVFPoolListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vfpoolList, err := utilityVFpoolListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVFPoolList(vfpoolList)) + d.Set("entry_count", vfpoolList.EntryCount) + return nil +} + +func DataSourceVFPoolList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVFPoolListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVFPoolListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vfpool/flattens.go b/internal/service/cloudbroker/vfpool/flattens.go new file mode 100644 index 00000000..2d2d7a13 --- /dev/null +++ b/internal/service/cloudbroker/vfpool/flattens.go @@ -0,0 +1,142 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vfpool" +) + +func flattenVFPoolList(vfpooll *vfpool.ListVFPool) []map[string]interface{} { + log.Debugf("flattenVFPoolList start") + res := make([]map[string]interface{}, 0, len(vfpooll.Data)) + for _, vfpool := range vfpooll.Data { + temp := map[string]interface{}{ + "account_access": vfpool.AccountAccess, + "created_time": vfpool.CreatedTime, + "description": vfpool.Description, + "gid": vfpool.GID, + "guid": vfpool.GUID, + "vfpool_id": vfpool.ID, + "name": vfpool.Name, + "rg_access": vfpool.RGAccess, + "status": vfpool.Status, + "updated_time": vfpool.UpdatedTime, + "vfs": flattenVFSList(vfpool.VFS), + } + res = append(res, temp) + } + log.Debugf("flattenVFPoolList end") + return res + +} + +func flattenVFPoolDataSource(d *schema.ResourceData, item *vfpool.RecordVFPool) error { + log.Debugf("flattenVFPoolDataSource: start decoded VFPool name %q / ID %d", + item.Name, item.ID) + + d.Set("account_access", item.AccountAccess) + d.Set("created_time", item.CreatedTime) + d.Set("description", item.Description) + d.Set("gid", item.GID) + d.Set("guid", item.GUID) + d.Set("name", item.Name) + d.Set("rg_access", item.RGAccess) + d.Set("status", item.Status) + d.Set("updated_time", item.UpdatedTime) + d.Set("vfs", flattenVFSList(item.VFS)) + + log.Debugf("flattenVFPoolDataSource: decoded VFPool name %q / ID %d, complete", + item.Name, item.ID) + return nil +} + +func flattenVFPoolResource(d *schema.ResourceData, item *vfpool.RecordVFPool) error { + log.Debugf("flattenVFPoolResource: start decoded VFPool name %q / ID %d", + item.Name, item.ID) + + d.Set("account_access", item.AccountAccess) + d.Set("created_time", item.CreatedTime) + d.Set("description", item.Description) + d.Set("gid", item.GID) + d.Set("guid", item.GUID) + d.Set("vfpool_id", item.ID) + d.Set("name", item.Name) + d.Set("rg_access", item.RGAccess) + d.Set("status", item.Status) + d.Set("updated_time", item.UpdatedTime) + d.Set("vfs", flattenVFSList(item.VFS)) + + log.Debugf("flattenVFPoolResource: decoded VFPool name %q / ID %d, complete", + item.Name, item.ID) + return nil +} + + +func flattenVFSList(vfsItem []vfpool.VFS) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vfsItem)) + for _, item := range vfsItem { + temp := map[string]interface{}{ + "node_id": item.NodeID, + "vf_list": flattenVFList(item.VFList), + } + res = append(res, temp) + } + return res +} + +func flattenVFList(vfItem vfpool.VFList) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vfItem)) + for _, item := range vfItem { + temp := map[string]interface{}{ + "nic_name": item.NicName, + "vfs_info": flattenVFInfoList(item.VFSInfo), + } + res = append(res, temp) + } + return res +} + +func flattenVFInfoList(vfInfo vfpool.VFSInfoList) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vfInfo)) + for _, item := range vfInfo { + temp := map[string]interface{}{ + "id": item.ID, + "claimed": item.Claimed, + "vm_id": item.VMID, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudbroker/vfpool/resource_check_input_values.go b/internal/service/cloudbroker/vfpool/resource_check_input_values.go new file mode 100644 index 00000000..3c8ced4d --- /dev/null +++ b/internal/service/cloudbroker/vfpool/resource_check_input_values.go @@ -0,0 +1,24 @@ +package vfpool + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" +) + +func checkParamsExistence(ctx context.Context, c *controller.ControllerCfg, accountIDs, rgIDs []uint64) diag.Diagnostics { + var errs []error + + if err := ic.ExistAccouts(ctx, accountIDs, c); err != nil { + errs = append(errs, err) + } + + if err := ic.ExistRGs(ctx, rgIDs, c); err != nil { + errs = append(errs, err) + } + + return dc.ErrorsToDiagnostics(errs) +} diff --git a/internal/service/cloudbroker/vfpool/resource_vfpool.go b/internal/service/cloudbroker/vfpool/resource_vfpool.go new file mode 100644 index 00000000..1e10ce3b --- /dev/null +++ b/internal/service/cloudbroker/vfpool/resource_vfpool.go @@ -0,0 +1,227 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "context" + "fmt" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vfpool" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func resourceVFPoolCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vfpoolName := d.Get("name").(string) + + log.Debugf("resourceVFPoolCreate: called VFPool with name %s", vfpoolName) + + c := m.(*controller.ControllerCfg) + + req := vfpool.CreateRequest{ + Name: vfpoolName, + } + + if desc, ok := d.GetOk("description"); ok { + req.Description = desc.(string) + } + + if accountAccess, ok := d.GetOk("account_access"); ok { + accountAccessArray := accountAccess.(*schema.Set).List() + + req.AccountAccess = make([]uint64, 0, len(accountAccessArray)) + + for _, access := range accountAccessArray { + req.AccountAccess = append(req.AccountAccess, uint64(access.(int))) + } + } + + if rgAccess, ok := d.GetOk("rg_access"); ok { + rgAccessArray := rgAccess.(*schema.Set).List() + + req.RGAccess = make([]uint64, 0, len(rgAccessArray)) + + for _, access := range rgAccessArray { + req.RGAccess = append(req.RGAccess, uint64(access.(int))) + } + } + + if err := checkParamsExistence(ctx, c, req.AccountAccess, req.RGAccess); err != nil { + return err + } + + config, configOk := d.GetOk("config") + + enableVal := d.Get("enable").(bool) + if enableVal && !configOk { + return diag.FromErr(fmt.Errorf("enable requires config to be set")) + } + + if configOk { + configArray := config.(*schema.Set).List() + req.Config = make([]vfpool.Config, 0, len(configArray)) + + for _, access := range configArray { + temp := access.(map[string]interface{}) + + vfArray := temp["vf_ids"].([]interface{}) + resVfIds := make([]uint64, 0, len(vfArray)) + + for _, vfID := range vfArray { + resVfIds = append(resVfIds, uint64(vfID.(int))) + } + + reqTemp := vfpool.Config{ + NodeID: uint64(temp["node_id"].(int)), + NicName: temp["nic_name"].(string), + VFIDs: resVfIds, + } + req.Config = append(req.Config, reqTemp) + } + } + + vfPoolID, err := c.CloudBroker().VFPool().Create(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(vfPoolID, 10)) + + warnings := dc.Warnings{} + + if err := utilityVFPoolEnabled(ctx, m, enableVal, vfPoolID); err != nil { + warnings.Add(err) + } + + log.Debugf("resourceVFPoolCreate: create VFPool with ID: %d, complete", vfPoolID) + return append(resourceVFPoolRead(ctx, d, m), warnings.Get()...) +} + +func resourceVFPoolRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceVFPoolRead: called VFPool with id %s", d.Id()) + + vfPool, err := utilityVFpoolCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenVFPoolResource(d, vfPool) + + log.Debugf("resourceVFPoolRead: read VFPool with id %s, complete", d.Id()) + return nil +} + +func resourceVFPoolUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vfPoolID, _ := strconv.ParseUint(d.Id(), 10, 64) + + log.Debugf("resourceVFPoolUpdate: called VFPool with id %d", vfPoolID) + + if d.HasChanges("name", "description", "account_access", "rg_access", "config", "enable") { + if err := utilityVFPoolUpdate(ctx, d, m, vfPoolID); err != nil { + return diag.FromErr(err) + } + } + + log.Debugf("resourceVFPoolUpdate: update VFPool with id %d, complete", vfPoolID) + + return resourceVFPoolRead(ctx, d, m) +} + +func resourceVFPoolDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceVFPoolDelete: called VFPool with id %s", d.Id()) + + vfPool, err := utilityVFpoolCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + + req := vfpool.DeleteRequest{ + VFPoolID: vfPool.ID, + } + + if vfPool.Status == "ENABLED" || vfPool.Status == "CREATED" { + reqDisable := vfpool.DisableRequest{ + VFPoolID: vfPool.ID, + } + + log.Debugf("resourceVFPoolDelete: need to disable vfPool with ID: %d, after delete", vfPool.ID) + _, err = c.CloudBroker().VFPool().Disable(ctx, reqDisable) + if err != nil { + return diag.FromErr(err) + } + log.Debugf("resourceVFPoolDelete: disable vfPool with ID: %d, complete", vfPool.ID) + } + + _, err = c.CloudBroker().VFPool().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceVFPool() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceVFPoolCreate, + ReadContext: resourceVFPoolRead, + UpdateContext: resourceVFPoolUpdate, + DeleteContext: resourceVFPoolDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout20m, + Read: &constants.Timeout20m, + Update: &constants.Timeout20m, + Delete: &constants.Timeout20m, + Default: &constants.Timeout20m, + }, + + Schema: resourceVFPoolSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vfpool/schema.go b/internal/service/cloudbroker/vfpool/schema.go new file mode 100644 index 00000000..97e5731f --- /dev/null +++ b/internal/service/cloudbroker/vfpool/schema.go @@ -0,0 +1,394 @@ +package vfpool + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceVFPoolSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "vfpool_id": { + Type: schema.TypeInt, + Required: true, + }, + "account_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vf_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "nic_name": { + Type: schema.TypeString, + Computed: true, + }, + "vfs_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "claimed": { + Type: schema.TypeBool, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + return res +} + +func dataSourceVFPoolListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "gid": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by Grid ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Find by description", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "account_access": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by accountAccess", + }, + "rg_access": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by rgAccess", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "vfpool_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_access": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vf_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "nic_name": { + Type: schema.TypeString, + Computed: true, + }, + "vfs_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "claimed": { + Type: schema.TypeBool, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func resourceVFPoolSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of device", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Description", + }, + "account_access": { + Type: schema.TypeSet, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of account IDs", + }, + "rg_access": { + Type: schema.TypeSet, + Computed: true, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + Description: "List of RG IDs", + }, + "config": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_id": { + Type: schema.TypeInt, + Required: true, + }, + "nic_name": { + Type: schema.TypeString, + Required: true, + }, + "vf_ids": { + Required: true, + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + MinItems: 1, + }, + }, + }, + Description: "List of dict describing configuration data", + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "vfpool_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "vfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vf_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "nic_name": { + Type: schema.TypeString, + Computed: true, + }, + "vfs_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "claimed": { + Type: schema.TypeBool, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + return res +} diff --git a/internal/service/cloudbroker/vfpool/utility_vfpool.go b/internal/service/cloudbroker/vfpool/utility_vfpool.go new file mode 100644 index 00000000..8b3e4d55 --- /dev/null +++ b/internal/service/cloudbroker/vfpool/utility_vfpool.go @@ -0,0 +1,196 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "context" + "fmt" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vfpool" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" +) + +func utilityVFpoolCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vfpool.RecordVFPool, error) { + c := m.(*controller.ControllerCfg) + req := vfpool.GetRequest{} + + if d.Id() != "" { + vfpoolId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VFPoolID = vfpoolId + } else { + req.VFPoolID = uint64(d.Get("vfpool_id").(int)) + } + + vfpoolData, err := c.CloudBroker().VFPool().Get(ctx, req) + if err != nil { + return nil, err + } + + return vfpoolData, nil +} + +func utilityVFPoolEnabled(ctx context.Context, m interface{}, enable bool, vfPoolID uint64) error { + c := m.(*controller.ControllerCfg) + + var err error + + if enable { + _, err = c.CloudBroker().VFPool().Enable(ctx, vfpool.EnableRequest{VFPoolID: vfPoolID}) + } else { + _, err = c.CloudBroker().VFPool().Disable(ctx, vfpool.DisableRequest{VFPoolID: vfPoolID}) + } + + return err +} + +func utilityVFPoolUpdate(ctx context.Context, d *schema.ResourceData, m interface{}, vfPoolID uint64) error { + hasConfig := len(d.Get("config").(*schema.Set).List()) > 0 + if d.Get("enable").(bool) && !hasConfig { + return fmt.Errorf("enable requires config to be set") + } + + c := m.(*controller.ControllerCfg) + + vfPool, err := utilityVFpoolCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return err + } + + req := vfpool.UpdateRequest{ + VFPoolID: vfPoolID, + } + + if d.HasChange("name") { + req.Name = d.Get("name").(string) + } + if d.HasChange("description") { + req.Description = d.Get("description").(string) + } + + if config, ok := d.GetOk("config"); ok { + configArray := config.(*schema.Set).List() + req.Config = make([]vfpool.Config, 0, len(configArray)) + + for _, access := range configArray { + temp := access.(map[string]interface{}) + + vfArray := temp["vf_ids"].([]interface{}) + resVfIds := make([]uint64, 0, len(vfArray)) + + for _, vfID := range vfArray { + resVfIds = append(resVfIds, uint64(vfID.(int))) + } + + reqTemp := vfpool.Config{ + NodeID: uint64(temp["node_id"].(int)), + NicName: temp["nic_name"].(string), + VFIDs: resVfIds, + } + req.Config = append(req.Config, reqTemp) + } + } else { + req.Config = []vfpool.Config{} + } + + if accountAccess, ok := d.GetOk("account_access"); ok { + accountAccessArray := accountAccess.(*schema.Set).List() + + req.AccountAccess = make([]uint64, 0, len(accountAccessArray)) + + for _, access := range accountAccessArray { + req.AccountAccess = append(req.AccountAccess, uint64(access.(int))) + } + + if err := ic.ExistAccouts(ctx, req.AccountAccess, c); err != nil { + return err + } + } else { + req.AccountAccess = []uint64{} + } + + if rgAccess, ok := d.GetOk("rg_access"); ok { + rgAccessArray := rgAccess.(*schema.Set).List() + + req.RGAccess = make([]uint64, 0, len(rgAccessArray)) + + for _, access := range rgAccessArray { + req.RGAccess = append(req.RGAccess, uint64(access.(int))) + } + + if err := ic.ExistRGs(ctx, req.RGAccess, c); err != nil { + return err + } + } else { + req.RGAccess = []uint64{} + } + + if vfPool.Status == "ENABLED" || vfPool.Status == "CREATED" { + reqDisable := vfpool.DisableRequest{ + VFPoolID: vfPoolID, + } + + log.Debugf("utilityVFPoolUpdate: need to disable vfPool with ID: %d, after update", vfPoolID) + _, err = c.CloudBroker().VFPool().Disable(ctx, reqDisable) + if err != nil { + return err + } + log.Debugf("utilityVFPoolUpdate: disable vfPool with ID: %d, complete", vfPoolID) + } + + _, err = c.CloudBroker().VFPool().Update(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityVFPoolUpdate: update vfPool with ID: %d, complete with params=%v", vfPoolID, req) + + if hasConfig && d.Get("enable").(bool) { + reqEnable := vfpool.EnableRequest{ + VFPoolID: vfPoolID, + } + + log.Debugf("utilityVFPoolUpdate: start to enable vfPool with ID: %d, after update", vfPoolID) + _, err = c.CloudBroker().VFPool().Enable(ctx, reqEnable) + if err != nil { + return err + } + log.Debugf("utilityVFPoolUpdate: enable vfPool with ID: %d, complete", vfPoolID) + } + + return nil +} diff --git a/internal/service/cloudbroker/vfpool/utility_vfpool_list.go b/internal/service/cloudbroker/vfpool/utility_vfpool_list.go new file mode 100644 index 00000000..cb23a698 --- /dev/null +++ b/internal/service/cloudbroker/vfpool/utility_vfpool_list.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vfpool + +import ( + "context" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vfpool" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityVFpoolListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vfpool.ListVFPool, error) { + c := m.(*controller.ControllerCfg) + req := vfpool.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if gid, ok := d.GetOk("gid"); ok { + req.GID = uint64(gid.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if accountAccess, ok := d.GetOk("account_access"); ok { + req.AccountAccess = uint64(accountAccess.(int)) + } + if rgAccess, ok := d.GetOk("rg_access"); ok { + req.RGAccess = uint64(rgAccess.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + vfpoolList, err := c.CloudBroker().VFPool().List(ctx, req) + if err != nil { + return nil, err + } + + return vfpoolList, nil +} diff --git a/internal/service/cloudbroker/vins/data_source_vins.go b/internal/service/cloudbroker/vins/data_source_vins.go new file mode 100644 index 00000000..77437abf --- /dev/null +++ b/internal/service/cloudbroker/vins/data_source_vins.go @@ -0,0 +1,68 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vins, err := utilityVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenVinsData(d, vins) + d.SetId(strconv.FormatUint(vins.ID, 10)) + return nil +} + +func DataSourceVins() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: dataSourceVinsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/data_source_vins_audits.go b/internal/service/cloudbroker/vins/data_source_vins_audits.go new file mode 100644 index 00000000..0ac2796c --- /dev/null +++ b/internal/service/cloudbroker/vins/data_source_vins_audits.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + audits, err := utilityVinsAuditsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsAudits(audits)) + + return nil +} + +func DataSourceVinsAudits() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsAuditsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: DataSourceVinsAuditsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/data_source_vins_ext_net_list.go b/internal/service/cloudbroker/vins/data_source_vins_ext_net_list.go new file mode 100644 index 00000000..f21257d8 --- /dev/null +++ b/internal/service/cloudbroker/vins/data_source_vins_ext_net_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsExtNetListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + extNetList, err := utilityVinsExtNetListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsExtNetList(extNetList)) + d.Set("entry_count", extNetList.EntryCount) + + return nil +} + +func DataSourceVinsExtNetList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsExtNetListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: DataSourceVinsExtNetListchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/data_source_vins_ip_list.go b/internal/service/cloudbroker/vins/data_source_vins_ip_list.go new file mode 100644 index 00000000..17641cfd --- /dev/null +++ b/internal/service/cloudbroker/vins/data_source_vins_ip_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsIpListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + ips, err := utilityVinsIpListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsIpList(ips)) + d.Set("entry_count", ips.EntryCount) + + return nil +} + +func DataSourceVinsIpList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsIpListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: DataSourceVinsIpListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/data_source_vins_list.go b/internal/service/cloudbroker/vins/data_source_vins_list.go new file mode 100644 index 00000000..817dca7f --- /dev/null +++ b/internal/service/cloudbroker/vins/data_source_vins_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vinsList, err := utilityVinsListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsList(vinsList)) + d.Set("entry_count", vinsList.EntryCount) + + return nil +} + +func DataSourceVinsList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVinsListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/data_source_vins_list_deleted.go b/internal/service/cloudbroker/vins/data_source_vins_list_deleted.go new file mode 100644 index 00000000..82d6b6c1 --- /dev/null +++ b/internal/service/cloudbroker/vins/data_source_vins_list_deleted.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + vinsList, err := utilityVinsListDeletedCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsListDeleted(vinsList)) + d.Set("entry_count", vinsList.EntryCount) + + return nil +} + +func DataSourceVinsListDeleted() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsListDeletedRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceVinsListDeletedSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/data_source_vins_nat_rule_list.go b/internal/service/cloudbroker/vins/data_source_vins_nat_rule_list.go new file mode 100644 index 00000000..21c903c6 --- /dev/null +++ b/internal/service/cloudbroker/vins/data_source_vins_nat_rule_list.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceVinsNatRuleListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + natRules, err := utilityVinsNatRuleListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenVinsNatRuleList(natRules)) + d.Set("entry_count", natRules.EntryCount) + + return nil +} + +func DataSourceVinsNatRuleList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceVinsNatRuleListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: DataSourceVinsNatRuleListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/data_source_vins_static_route.go b/internal/service/cloudbroker/vins/data_source_vins_static_route.go new file mode 100644 index 00000000..c0f3d7b1 --- /dev/null +++ b/internal/service/cloudbroker/vins/data_source_vins_static_route.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + staticRoute, err := utilityDataStaticRouteCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(staticRoute.ID, 10)) + flattenStaticRouteData(d, staticRoute) + return nil +} + +func DataSourceStaticRoute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceStaticRouteRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceStaticRouteSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/data_source_vins_static_route_list.go b/internal/service/cloudbroker/vins/data_source_vins_static_route_list.go new file mode 100644 index 00000000..f6b5b470 --- /dev/null +++ b/internal/service/cloudbroker/vins/data_source_vins_static_route_list.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceStaticRouteListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + staticRouteList, err := utilityStaticRouteListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenStaticRouteList(staticRouteList)) + d.Set("entry_count", staticRouteList.EntryCount) + + return nil +} + +func DataSourceStaticRouteList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceStaticRouteListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceStaticRouteListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/flattens.go b/internal/service/cloudbroker/vins/flattens.go new file mode 100644 index 00000000..c9f0da4a --- /dev/null +++ b/internal/service/cloudbroker/vins/flattens.go @@ -0,0 +1,672 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenVins(d *schema.ResourceData, vinsRecord *vins.RecordVINS) { + d.Set("vnf_dev", flattenVinsVNFDev(vinsRecord.VNFDev)) + d.Set("account_id", vinsRecord.AccountID) + d.Set("account_name", vinsRecord.AccountName) + d.Set("created_by", vinsRecord.CreatedBy) + d.Set("created_time", vinsRecord.CreatedTime) + d.Set("default_gw", vinsRecord.DefaultGW) + d.Set("default_qos", flattenVinsQOS(vinsRecord.DefaultQOS)) + d.Set("deleted_by", vinsRecord.DeletedBy) + d.Set("deleted_time", vinsRecord.DeletedTime) + d.Set("description", vinsRecord.Description) + d.Set("gid", vinsRecord.GID) + d.Set("guid", vinsRecord.GUID) + d.Set("vins_id", vinsRecord.ID) + d.Set("lock_status", vinsRecord.LockStatus) + d.Set("manager_id", vinsRecord.ManagerID) + d.Set("manager_type", vinsRecord.ManagerType) + d.Set("milestones", vinsRecord.Milestones) + d.Set("name", vinsRecord.Name) + d.Set("netmask", vinsRecord.NetMask) + d.Set("network", vinsRecord.Network) + d.Set("pre_reservations_num", vinsRecord.PreReservationsNum) + d.Set("redundant", vinsRecord.Redundant) + d.Set("rg_id", vinsRecord.RGID) + d.Set("rg_name", vinsRecord.RGName) + d.Set("sec_vnf_dev_id", vinsRecord.SecVNFDevID) + d.Set("status", vinsRecord.Status) + d.Set("updated_by", vinsRecord.UpdatedBy) + d.Set("updated_time", vinsRecord.UpdatedTime) + d.Set("user_managed", vinsRecord.UserManaged) + d.Set("vnfs", flattenVinsRecordVNFs(vinsRecord.VNFs)) + d.Set("vxlan_id", vinsRecord.VXLANID) + d.Set("nat_rule", flattenRuleBlock(vinsRecord.VNFs.NAT.Config.Rules)) + d.Set("computes", flattenComputes(vinsRecord.Computes)) + d.Set("zone_id", vinsRecord.ZoneID) +} + +func flattenVinsData(d *schema.ResourceData, vinsRecord *vins.RecordVINS) { + log.Debugf("flattenVins: decoded ViNS name: %s, ID : %d, account ID %d, RG ID %d", + vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RGID) + + d.Set("vnf_dev", flattenVinsVNFDev(vinsRecord.VNFDev)) + d.Set("account_id", vinsRecord.AccountID) + d.Set("account_name", vinsRecord.AccountName) + d.Set("created_by", vinsRecord.CreatedBy) + d.Set("created_time", vinsRecord.CreatedTime) + d.Set("default_gw", vinsRecord.DefaultGW) + d.Set("default_qos", flattenVinsQOS(vinsRecord.DefaultQOS)) + d.Set("deleted_by", vinsRecord.DeletedBy) + d.Set("deleted_time", vinsRecord.DeletedTime) + d.Set("description", vinsRecord.Description) + d.Set("gid", vinsRecord.GID) + d.Set("guid", vinsRecord.GUID) + d.Set("vins_id", vinsRecord.ID) + d.Set("lock_status", vinsRecord.LockStatus) + d.Set("manager_id", vinsRecord.ManagerID) + d.Set("manager_type", vinsRecord.ManagerType) + d.Set("milestones", vinsRecord.Milestones) + d.Set("name", vinsRecord.Name) + d.Set("netmask", vinsRecord.NetMask) + d.Set("network", vinsRecord.Network) + d.Set("pre_reservations_num", vinsRecord.PreReservationsNum) + d.Set("redundant", vinsRecord.Redundant) + d.Set("rg_id", vinsRecord.RGID) + d.Set("rg_name", vinsRecord.RGName) + d.Set("sec_vnf_dev_id", vinsRecord.SecVNFDevID) + d.Set("status", vinsRecord.Status) + d.Set("updated_by", vinsRecord.UpdatedBy) + d.Set("updated_time", vinsRecord.UpdatedTime) + d.Set("user_managed", vinsRecord.UserManaged) + d.Set("vnfs", flattenVinsRecordVNFs(vinsRecord.VNFs)) + d.Set("vxlan_id", vinsRecord.VXLANID) + d.Set("computes", flattenComputes(vinsRecord.Computes)) + d.Set("zone_id", vinsRecord.ZoneID) + d.Set("enable_secgroups", vinsRecord.EnableSecGroups) + +} + +func flattenLibvirtSettings(libvirtSettings vins.LibvirtSettings) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "guid": libvirtSettings.GUID, + "txmode": libvirtSettings.TXMode, + "ioeventfd": libvirtSettings.IOEventFD, + "event_idx": libvirtSettings.EventIDx, + "queues": libvirtSettings.Queues, + "rx_queue_size": libvirtSettings.RXQueueSize, + "tx_queue_size": libvirtSettings.TXQueueSize, + } + res = append(res, temp) + return res +} + +func flattenVinsVNFDev(vd vins.VNFDev) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "ckey": vd.CKey, + "meta": flattens.FlattenMeta(vd.Meta), + "account_id": vd.AccountID, + "capabilities": vd.Capabilities, + "config": flattenVinsConfig(vd.Config), + "config_saved": vd.ConfigSaved, + "custom_precfg": vd.CustomPreConfig, + "description": vd.Description, + "gid": vd.GID, + "guid": vd.GUID, + "id": vd.ID, + "interfaces": flattenVinsListInterfaces(vd.Interfaces), + "live_migration_job_id": vd.LiveMigrationJobID, + "lock_status": vd.LockStatus, + "milestones": vd.Milestones, + "name": vd.Name, + "status": vd.Status, + "tech_status": vd.TechStatus, + "type": vd.Type, + "vnc_password": vd.VNCPassword, + "vins": vd.VINS, + "zone_id": vd.ZoneID, + } + res = append(res, temp) + return res +} + +func flattenComputes(computes []vins.Computes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(computes)) + for _, compute := range computes { + tmp := map[string]interface{}{ + "id": compute.ID, + "name": compute.Name, + } + res = append(res, tmp) + } + return res +} + +func flattenVinsRecordVNFs(rv vins.RecordVNFs) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "dhcp": flattenVinsRecordDHCP(rv.DHCP), + "gw": flattenVinsRecordGW(rv.GW), + "nat": flattenVinsRecordNAT(rv.NAT), + } + res = append(res, temp) + return res +} + +func flattenVinsRecordDHCP(rv vins.RecordDHCP) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "config": flattenVinsVNFsConfig(rv.Config), + "ckey": rv.CKey, + "meta": flattens.FlattenMeta(rv.Meta), + "account_id": rv.AccountID, + "created_time": rv.CreatedTime, + "devices": flattenVinsPrimaryDevices(rv.Devices), + "gid": rv.GID, + "guid": rv.GUID, + "id": rv.ID, + "lock_status": rv.LockStatus, + "milestones": rv.Milestones, + "owner_id": rv.OwnerID, + "owner_type": rv.OwnerType, + "pure_virtual": rv.PureVirtual, + "routes": flattenVinsRoutes(rv.Routes), + "status": rv.Status, + "tech_status": rv.TechStatus, + "type": rv.Type, + "zone_id": rv.ZoneID, + } + res = append(res, temp) + return res +} + +func flattenVinsRecordGW(rg vins.RecordGW) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "config": flattenVinsGWConfig(rg.Config), + "ckey": rg.CKey, + "meta": flattens.FlattenMeta(rg.Meta), + "account_id": rg.AccountID, + "created_time": rg.CreatedTime, + "devices": flattenVinsPrimaryDevices(rg.Devices), + "gid": rg.GID, + "guid": rg.GUID, + "id": rg.ID, + "lock_status": rg.LockStatus, + "milestones": rg.Milestones, + "owner_id": rg.OwnerID, + "owner_type": rg.OwnerType, + "pure_virtual": rg.PureVirtual, + "routes": flattenVinsRoutes(rg.Routes), + "status": rg.Status, + "tech_status": rg.TechStatus, + "type": rg.Type, + "zone_id": rg.ZoneID, + } + res = append(res, temp) + return res +} + +func flattenVinsRecordNAT(rn vins.RecordNAT) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "config": flattenVinsNATConfig(rn.Config), + "ckey": rn.CKey, + "meta": flattens.FlattenMeta(rn.Meta), + "account_id": rn.AccountID, + "created_time": rn.CreatedTime, + "devices": flattenVinsPrimaryDevices(rn.Devices), + "gid": rn.GID, + "guid": rn.GUID, + "id": rn.ID, + "lock_status": rn.LockStatus, + "milestones": rn.Milestones, + "owner_id": rn.OwnerID, + "owner_type": rn.OwnerType, + "pure_virtual": rn.PureVirtual, + "routes": flattenVinsRoutes(rn.Routes), + "status": rn.Status, + "tech_status": rn.TechStatus, + "type": rn.Type, + "zone_id": rn.ZoneID, + } + res = append(res, temp) + return res +} + +func flattenVinsVNFsConfig(vc vins.VNFsConfig) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "default_gw": vc.DefaultGW, + "dns": vc.DNS, + "ip_end": vc.IPEnd, + "ip_start": vc.IPStart, + "lease": vc.Lease, + "net_mask": vc.NetMask, + "network": vc.Network, + "reservations": flattenVinsListReservations(vc.Reservations), + } + res = append(res, temp) + return res +} + +func flattenVinsGWConfig(gc vins.GWConfig) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "default_gw": gc.DefaultGW, + "ext_net_id": gc.ExtNetID, + "ext_net_ip": gc.ExtNetIP, + "ext_netmask": gc.ExtNetMask, + "qos": flattenVinsQOS(gc.QOS), + } + res = append(res, temp) + return res +} + +func flattenVinsNATConfig(nc vins.NATConfig) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "net_mask": nc.NetMask, + "network": nc.Network, + "rules": flattenRulesItem(nc.Rules), + } + res = append(res, temp) + return res +} + +func flattenRuleBlock(rules []vins.ItemNATRule) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rules)) + for _, rule := range rules { + tmp := map[string]interface{}{ + "int_ip": rule.LocalIP, + "int_port": rule.LocalPort, + "ext_port_start": rule.PublicPortStart, + "ext_port_end": rule.PublicPortEnd, + "proto": rule.Protocol, + "rule_id": rule.ID, + } + res = append(res, tmp) + } + return res +} + +func flattenRulesItem(rules []vins.ItemNATRule) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rules)) + for _, rule := range rules { + tmp := map[string]interface{}{ + "rule_id": rule.ID, + "local_ip": rule.LocalIP, + "local_port": rule.LocalPort, + "protocol": rule.Protocol, + "public_port_end": rule.PublicPortEnd, + "public_port_start": rule.PublicPortStart, + "vm_id": rule.VMID, + "vm_name": rule.VMName, + } + res = append(res, tmp) + } + return res +} + +func flattenVinsPrimaryDevices(d vins.Devices) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "primary": flattenVinsDevices(d.Primary), + } + res = append(res, temp) + return res +} + +func flattenVinsDevices(d vins.Primary) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "dev_id": d.DevID, + "iface01": d.IFace01, + "iface02": d.IFace02, + } + res = append(res, temp) + return res +} + +func flattenVinsRoutes(r vins.ListRoutes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(r)) + for _, v := range r { + temp := map[string]interface{}{ + "destination": v.Destination, + "netmask": v.Netmask, + "gateway": v.Gateway, + "compute_ids": v.ComputeIds, + "guid": v.GUID, + "route_id": v.ID, + } + res = append(res, temp) + } + return res +} + +func flattenVinsListReservations(li vins.ListReservations) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(li)) + for _, v := range li { + temp := map[string]interface{}{ + "account_id": v.AccountID, + "ip": v.IP, + "mac": v.MAC, + "type": v.Type, + "vm_id": v.VMID, + } + res = append(res, temp) + } + return res +} + +func flattenVinsConfig(c vins.Config) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "mgmt": flattenVinsMGMT(c.MGMT), + "resources": flattenVinsResources(c.Resources), + } + res = append(res, temp) + return res +} + +func flattenVinsMGMT(m vins.MGMT) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "ip_addr": m.IPAddress, + "password": m.Password, + "ssh_key": m.SSHKey, + "user": m.User, + } + res = append(res, temp) + return res +} + +func flattenVinsResources(r vins.Resources) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": r.CPU, + "ram": r.RAM, + "node_id": r.NodeID, + "uuid": r.UUID, + } + res = append(res, temp) + return res +} + +func flattenVinsListInterfaces(i vins.ListInterfaces) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(i)) + for _, v := range i { + temp := map[string]interface{}{ + "conn_id": v.ConnID, + "conn_type": v.ConnType, + "def_gw": v.DefGW, + "enabled": v.Enabled, + "enable_secgroups": v.EnableSecGroups, + "flipgroup_id": v.FLIPGroupID, + "guid": v.GUID, + "ip_address": v.IPAddress, + "listen_ssh": v.ListenSSH, + "mac": v.MAC, + "mtu": v.MTU, + "name": v.Name, + "net_id": v.NetID, + "net_mask": v.NetMask, + "net_type": v.NetType, + "node_id": v.NodeID, + "pci_slot": v.PCISlot, + "bus_number": v.BusNumber, + "qos": flattenVinsQOS(v.QOS), + "security_groups": v.SecGroups, + "sdn_interface_id": v.SDNInterfaceID, + "target": v.Target, + "type": v.Type, + "vnfs": v.VNFs, + "libvirt_settings": flattenLibvirtSettings(v.LibvirtSettings), + } + res = append(res, temp) + } + return res +} + +func flattenVinsList(vl *vins.ListVINS) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vl.Data)) + for _, v := range vl.Data { + temp := map[string]interface{}{ + "account_id": v.AccountID, + "account_name": v.AccountName, + "created_by": v.CreatedBy, + "created_time": v.CreatedTime, + "default_gw": v.DefaultGW, + "default_qos": flattenVinsQOS(v.DefaultQOS), + "deleted_by": v.DeletedBy, + "deleted_time": v.DeletedTime, + "description": v.Description, + "enable_secgroups": v.EnableSecGroups, + "external_ip": v.ExternalIP, + "extnet_id": v.ExtnetId, + "free_ips": v.FreeIPs, + "gid": v.GID, + "guid": v.GUID, + "vins_id": v.ID, + "name": v.Name, + "lock_status": v.LockStatus, + "manager_id": v.ManagerID, + "manager_type": v.ManagerType, + "milestones": v.Milestones, + "netmask": v.NetMask, + "network": v.Network, + "pre_reservations_num": v.PreReservationsNum, + "pri_vnf_dev_id": v.PriVNFDevID, + "redundant": v.Redundant, + "rg_id": v.RGID, + "rg_name": v.RGName, + "sec_vnf_dev_id": v.SecVNFDevID, + "status": v.Status, + "updated_by": v.UpdatedBy, + "updated_time": v.UpdatedTime, + "user_managed": v.UserManaged, + "vnfs": flattenVinsVNFs(v.VNFs), + "vxlan_id": v.VXLANID, + "zone_id": v.ZoneID, + } + res = append(res, temp) + } + return res +} + +func flattenVinsListDeleted(vl *vins.ListVINS) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(vl.Data)) + for _, v := range vl.Data { + temp := map[string]interface{}{ + "account_id": v.AccountID, + "account_name": v.AccountName, + "created_by": v.CreatedBy, + "created_time": v.CreatedTime, + "default_gw": v.DefaultGW, + "default_qos": flattenVinsQOS(v.DefaultQOS), + "deleted_by": v.DeletedBy, + "deleted_time": v.DeletedTime, + "description": v.Description, + "external_ip": v.ExternalIP, + "gid": v.GID, + "guid": v.GUID, + "vins_id": v.ID, + "name": v.Name, + "lock_status": v.LockStatus, + "manager_id": v.ManagerID, + "manager_type": v.ManagerType, + "milestones": v.Milestones, + "netmask": v.NetMask, + "network": v.Network, + "pre_reservations_num": v.PreReservationsNum, + "pri_vnf_dev_id": v.PriVNFDevID, + "redundant": v.Redundant, + "rg_id": v.RGID, + "rg_name": v.RGName, + "sec_vnf_dev_id": v.SecVNFDevID, + "status": v.Status, + "updated_by": v.UpdatedBy, + "updated_time": v.UpdatedTime, + "user_managed": v.UserManaged, + "vnfs": flattenVinsVNFs(v.VNFs), + "vxlan_id": v.VXLANID, + "zone_id": v.ZoneID, + } + res = append(res, temp) + } + return res +} + +func flattenVinsVNFs(iv vins.ItemVNFs) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "dhcp": iv.DHCP, + "dns": iv.DNS, + "fw": iv.FW, + "gw": iv.GW, + "nat": iv.NAT, + "vpn": iv.VPN, + } + res = append(res, temp) + return res +} + +func flattenVinsQOS(dq vins.QOS) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "e_rate": dq.ERate, + "guid": dq.GUID, + "in_burst": dq.InBurst, + "in_rate": dq.InRate, + } + res = append(res, temp) + return res +} + +func flattenVinsAudits(auidts vins.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(auidts)) + for _, audit := range auidts { + temp := map[string]interface{}{ + "call": audit.Call, + "response_time": audit.ResponseTime, + "status_code": audit.StatusCode, + "time_stamp": audit.Timestamp, + "user": audit.User, + } + res = append(res, temp) + } + + return res +} + +func flattenVinsExtNetList(extNetList *vins.ListExtNets) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(extNetList.Data)) + for _, extNet := range extNetList.Data { + temp := map[string]interface{}{ + "default_gw": extNet.DefaultGW, + "ext_net_id": extNet.ExtNetID, + "ip": extNet.IP, + "prefix_len": extNet.PrefixLen, + "status": extNet.Status, + "tech_status": extNet.TechStatus, + } + res = append(res, temp) + } + + return res +} + +func flattenVinsNatRuleList(natRules *vins.ListNATRules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(natRules.Data)) + for _, natRule := range natRules.Data { + temp := map[string]interface{}{ + "id": natRule.ID, + "local_ip": natRule.LocalIP, + "local_port": natRule.LocalPort, + "protocol": natRule.Protocol, + "public_port_end": natRule.PublicPortEnd, + "public_port_start": natRule.PublicPortStart, + "vm_id": natRule.VMID, + "vm_name": natRule.VMName, + } + res = append(res, temp) + } + + return res +} + +func flattenVinsIpList(ips *vins.ListIPs) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ips.Data)) + for _, ip := range ips.Data { + temp := map[string]interface{}{ + "client_type": ip.ClientType, + "domain_name": ip.DomainName, + "host_name": ip.Hostname, + "ip": ip.IP, + "mac": ip.MAC, + "type": ip.Type, + "vm_id": ip.VMID, + } + res = append(res, temp) + } + + return res +} + +func flattenStaticRouteList(sr *vins.ListStaticRoutes) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(sr.Data)) + for _, staticRoute := range sr.Data { + temp := map[string]interface{}{ + "route_id": staticRoute.ID, + "destination": staticRoute.Destination, + "gateway": staticRoute.Gateway, + "guid": staticRoute.GUID, + "netmask": staticRoute.Netmask, + "compute_ids": staticRoute.ComputeIds, + } + res = append(res, temp) + } + + return res +} + +func flattenStaticRouteData(d *schema.ResourceData, route *vins.ItemRoutes) { + d.Set("destination", route.Destination) + d.Set("gateway", route.Gateway) + d.Set("guid", route.GUID) + d.Set("netmask", route.Netmask) + d.Set("compute_ids", route.ComputeIds) + d.Set("route_id", route.ID) +} diff --git a/internal/service/cloudbroker/vins/resource_ckeck_input_value.go b/internal/service/cloudbroker/vins/resource_ckeck_input_value.go new file mode 100644 index 00000000..fa3e2862 --- /dev/null +++ b/internal/service/cloudbroker/vins/resource_ckeck_input_value.go @@ -0,0 +1,131 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func checkParamsExistenceCreateInAcc(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + accountId := uint64(d.Get("account_id").(int)) + + if err := ic.ExistAccount(ctx, accountId, c); err != nil { + errs = append(errs, err) + } + + if gid, ok := d.GetOk("gid"); ok { + if err := ic.ExistGID(ctx, uint64(gid.(int)), c); err != nil { + errs = append(errs, err) + } + } + + return dc.ErrorsToDiagnostics(errs) +} + +func checkParamsExistenceCreateInRG(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + rgId := uint64(d.Get("rg_id").(int)) + + if err := ic.ExistGID(ctx, rgId, c); err != nil { + errs = append(errs, err) + } + + extNetID, ok := d.GetOk("ext_net_id") + if ok { + if err := ic.ExistExtNetInVins(ctx, extNetID.(int), c); err != nil { + errs = append(errs, err) + } + } + + if extIP, ok := d.GetOk("ext_ip"); ok { + if extNetID.(int) < 0 { + errs = append(errs, fmt.Errorf("external IP is related only for extNetId >= 0: ext_ip %d, extNetId %d", extIP, extNetID)) + } + } + + return nil +} + +func checkParamsExistenceUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + var errs []error + + if rgId, ok := d.GetOk("rg_id"); ok { + err := ic.ExistRG(ctx, uint64(rgId.(int)), c) + if err != nil { + errs = append(errs, err) + } + } + + if extNetId, ok := d.GetOk("ext_net_id"); ok { + err := ic.ExistExtNetInVins(ctx, extNetId.(int), c) + if err != nil { + errs = append(errs, err) + } + } + + if accountId, ok := d.GetOk("account_id"); ok { + err := ic.ExistAccount(ctx, uint64(accountId.(int)), c) + if err != nil { + errs = append(errs, err) + } + } + + if gid, ok := d.GetOk("gid"); ok { + err := ic.ExistGID(ctx, uint64(gid.(int)), c) + if err != nil { + errs = append(errs, err) + } + } + + return dc.ErrorsToDiagnostics(errs) +} + +func checkParamsExistenceStaticRoute(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics { + vinsId := uint64(d.Get("vins_id").(int)) + + if err := ic.ExistVins(ctx, vinsId, c); err != nil { + return diag.FromErr(err) + } + + return nil +} diff --git a/internal/service/cloudbroker/vins/resource_utility.go b/internal/service/cloudbroker/vins/resource_utility.go new file mode 100644 index 00000000..a1d69e49 --- /dev/null +++ b/internal/service/cloudbroker/vins/resource_utility.go @@ -0,0 +1,178 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func createVinsInAcc(ctx context.Context, d *schema.ResourceData, m interface{}, accID uint64) (vins.CreateInAccountRequest, diag.Diagnostics) { + c := m.(*controller.ControllerCfg) + req := vins.CreateInAccountRequest{} + + if diags := checkParamsExistenceCreateInAcc(ctx, d, c); diags != nil { + return req, diags + } + + req.AccountID = accID + req.Name = d.Get("name").(string) + + if gid, ok := d.GetOk("gid"); ok { + req.GID = uint64(gid.(int)) + } + if IPCIDR, ok := d.GetOk("ipcidr"); ok { + req.IPCIDR = IPCIDR.(string) + } + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + if preReservationsNum, ok := d.GetOk("pre_reservations_num"); ok { + req.PreReservationsNum = uint64(preReservationsNum.(int)) + } + + if routesList, ok := d.GetOk("routes"); ok { + var routes []vins.Route + var route vins.Route + for _, r := range routesList.([]map[string]interface{}) { + route.Netmask = r["netmask"].(string) + route.Destination = r["destination"].(string) + route.Gateway = r["gateway"].(string) + routes = append(routes, route) + } + req.Routes = routes + } + if dns, ok := d.GetOk("dns"); ok { + dnsInterface := dns.(*schema.Set).List() + req.DNSList = make([]string, 0, len(dnsInterface)) + for _, item := range dnsInterface { + req.DNSList = append(req.DNSList, item.(string)) + } + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + req.EnableSecGroups = d.Get("enable_secgroups").(bool) + + return req, nil +} + +func createVinsInRG(ctx context.Context, d *schema.ResourceData, m interface{}, RGID uint64) (vins.CreateInRGRequest, diag.Diagnostics) { + c := m.(*controller.ControllerCfg) + req := vins.CreateInRGRequest{} + + if diags := checkParamsExistenceCreateInRG(ctx, d, c); diags != nil { + return req, diags + } + + req.RGID = RGID + req.Name = d.Get("name").(string) + + if IPCIDR, ok := d.GetOk("ipcidr"); ok { + req.IPCIDR = IPCIDR.(string) + } + + if extNetID, ok := d.GetOk("ext_net_id"); ok { + req.ExtNetID = int64(extNetID.(int)) + } + + if extIP, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = extIP.(string) + } + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + if preReservationsNum, ok := d.GetOk("pre_reservations_num"); ok { + req.PreReservationsNum = uint64(preReservationsNum.(int)) + } + + if routesList, ok := d.GetOk("routes"); ok { + var routes []vins.Route + var route vins.Route + for _, r := range routesList.([]map[string]interface{}) { + route.Netmask = r["netmask"].(string) + route.Destination = r["destination"].(string) + route.Gateway = r["gateway"].(string) + routes = append(routes, route) + } + req.Routes = routes + } + if dns, ok := d.GetOk("dns"); ok { + dnsInterface := dns.(*schema.Set).List() + req.DNSList = make([]string, 0, len(dnsInterface)) + for _, item := range dnsInterface { + req.DNSList = append(req.DNSList, item.(string)) + } + } + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + req.EnableSecGroups = d.Get("enable_secgroups").(bool) + + return req, nil +} + +func isContainsIp(els []interface{}, el interface{}) bool { + elConv := el.(map[string]interface{}) + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + if elOldConv["ip_addr"].(string) == elConv["ip_addr"].(string) && + elOldConv["type"].(string) == elConv["type"].(string) && + elOldConv["mac"].(string) == elConv["mac"].(string) && + elOldConv["compute_id"].(string) == elConv["compute_id"].(string) { + return true + } + } + return false +} + +func isContainsNatRule(els []interface{}, el interface{}) bool { + elConv := el.(map[string]interface{}) + for _, elOld := range els { + elOldConv := elOld.(map[string]interface{}) + if elOldConv["int_ip"].(string) == elConv["int_ip"].(string) && + elOldConv["int_port"].(int) == elConv["int_port"].(int) && + elOldConv["ext_port_start"].(int) == elConv["ext_port_start"].(int) { + return true + } + } + return false +} diff --git a/internal/service/cloudbroker/vins/resource_vins.go b/internal/service/cloudbroker/vins/resource_vins.go new file mode 100644 index 00000000..72df5519 --- /dev/null +++ b/internal/service/cloudbroker/vins/resource_vins.go @@ -0,0 +1,826 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceVinsCreate: called for ViNS name %s, Account ID %d, RG ID %d", + d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + + RGID, rgOk := d.GetOk("rg_id") + AccountID, accountIdOk := d.GetOk("account_id") + + if !rgOk && !accountIdOk { + return diag.Errorf("resourceVinsCreate: no valid accountId or resource group ID specified") + } + + if rgOk && accountIdOk { + return diag.Errorf("resourceVinsCreate: either accountId or resource group ID should be specified") + } + + var vinsID uint64 + if accountIdOk { + req, diags := createVinsInAcc(ctx, d, m, uint64(AccountID.(int))) + if diags != nil { + return diags + } + + apiResp, err := c.CloudBroker().VINS().CreateInAccount(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + vinsID = apiResp + } else if rgOk { + req, diags := createVinsInRG(ctx, d, m, uint64(RGID.(int))) + if diags != nil { + return diags + } + + apiResp, err := c.CloudBroker().VINS().CreateInRG(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + vinsID = apiResp + } + + d.SetId(strconv.FormatUint(vinsID, 10)) + d.Set("vins_id", vinsID) + + log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsID, d.Get("name").(string)) + + warnings := dc.Warnings{} + if _, ok := d.GetOk("ip"); ok { + if errs := resourceVinsIpReserve(ctx, d, m, vinsID); len(errs) != 0 { + for _, err := range errs { + warnings.Add(err) + } + } + } + + if _, ok := d.GetOk("nat_rule"); ok { + if errs := resourceVinsNatRuleAdd(ctx, d, m, vinsID); len(errs) != 0 { + for _, err := range errs { + warnings.Add(err) + } + } + } + + return append(warnings.Get(), resourceVinsRead(ctx, d, m)...) +} + +func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceVinsRead: called for vins id %s, name %s", + d.Id(), d.Get("name").(string)) + + warnings := dc.Warnings{} + + vinsData, err := utilityVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + isEnabled := d.Get("enable").(bool) + + hasChangeState := false + + switch vinsData.Status { + case status.Destroyed: + d.Set("vins_id", 0) + d.SetId("") + return diag.Errorf("The resource cannot be read because it has been destroyed") + // return resourceVinsCreate(ctx, d, m) + case status.Deleted: + // hasChangeState = true + + // req := vins.RestoreRequest{ + // VINSID: vinsData.ID, + // } + // if reason, ok := d.GetOk("reason"); ok { + // req.Reason = reason.(string) + // } + + // _, err := c.CloudBroker().VINS().Restore(ctx, req) + // if err != nil { + // warnings.Add(err) + // } + case status.Modeled: + return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vinsData.Status) + case status.Created: + case status.Enabled: + if !isEnabled { + hasChangeState = true + if err := resourceVinsDisable(ctx, d, m, vinsData.ID); err != nil { + warnings.Add(err) + } + } + case status.Enabling: + case status.Disabled: + if isEnabled { + hasChangeState = true + if err := resourceVinsEnable(ctx, d, m, vinsData.ID); err != nil { + warnings.Add(err) + } + } + case status.Disabling: + case status.Deleting: + return diag.Errorf("ViNS are in progress with status: %s", vinsData.Status) + } + + if hasChangeState { + vinsData, err = utilityVinsCheckPresence(ctx, d, m) + if vinsData == nil { + d.SetId("") + return diag.FromErr(err) + } + } + + flattenVins(d, vinsData) + + log.Debugf("resourceVinsRead: after flattenVins: vins_id %s, name %s", + d.Id(), d.Get("name").(string)) + + return warnings.Get() +} + +func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceVinsUpdate: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d", + d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistenceUpdate(ctx, d, c); diags != nil { + return diags + } + + vinsData, err := utilityVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + isEnabled := d.Get("enable").(bool) + + hasChangeState := false + + warnings := dc.Warnings{} + switch vinsData.Status { + case status.Destroyed: + d.Set("vins_id", 0) + d.SetId("") + return diag.Errorf("The resource cannot be updated because it has been destroyed") + // return resourceVinsCreate(ctx, d, m) + case status.Deleted: + hasChangeState = true + + if err := resourceVinsRestore(ctx, d, m, vinsData.ID); err != nil { + warnings.Add(err) + } + case status.Modeled: + return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vinsData.Status) + case status.Created: + case status.Enabled: + if !isEnabled { + hasChangeState = true + if err := resourceVinsDisable(ctx, d, m, vinsData.ID); err != nil { + warnings.Add(err) + } + } + case status.Enabling: + case status.Disabled: + if isEnabled { + hasChangeState = true + if err := resourceVinsEnable(ctx, d, m, vinsData.ID); err != nil { + warnings.Add(err) + } + } + case status.Disabling: + case status.Deleting: + return diag.Errorf("ViNS are in progress with status: %s", vinsData.Status) + } + + if hasChangeState { + vinsData, err = utilityVinsCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChanges("name", "desc", "enable_secgroups") { + vinsID := uint64(d.Get("vins_id").(int)) + if err := utilityUpdateVINS(ctx, d, m, vinsID); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("enable") { + if err := resourceVinsChangeEnabled(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + if d.HasChange("ext_net_id") { + if err := resourceVinsChangeExtNetId(ctx, d, m); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("ip") { + if errs := resourceVinsChangeIp(ctx, d, m); len(errs) != 0 { + for _, err := range errs { + warnings.Add(err) + } + } + } + if d.HasChange("nat_rule") { + if errs := resourceVinsChangeNatRule(ctx, d, m); len(errs) != 0 { + for _, err := range errs { + warnings.Add(err) + } + } + } + + if d.HasChange("dns") { + if err := resourceVinsChangeDNS(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + if d.HasChange("default_qos") { + if err := resourceVinsChangeDefaultQos(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + if d.HasChange("vnfdev_redeploy") { + if err := resourceVinsChangeVnfRedeploy(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + if d.HasChange("vnfdev_restart") { + if err := resourceVinsChangeVnfRestart(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + if d.HasChange("vnfdev_reset") { + if err := resourceVinsChangeVnfReset(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + if d.HasChange("vnfdev_start") { + if err := resourceVinsChangeVnfStartStop(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + if d.HasChange("zone_id") { + if err := resourceVinsChangeZoneID(ctx, d, m); err != nil { + warnings.Add(err) + } + } + + return append(warnings.Get(), dataSourceVinsRead(ctx, d, m)...) +} + +func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceVinsDelete: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d", + d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) + + c := m.(*controller.ControllerCfg) + + vinsItem, err := utilityVinsCheckPresence(ctx, d, m) + if vinsItem == nil { + d.SetId("") + return diag.FromErr(err) + } + + req := vins.DeleteRequest{VINSID: vinsItem.ID} + + if force, ok := d.GetOk("force"); ok { + req.Force = force.(bool) + } + if permanently, ok := d.GetOk("permanently"); ok { + req.Permanently = permanently.(bool) + } + + if _, err := c.CloudBroker().VINS().Delete(ctx, req); err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func resourceVinsEnable(ctx context.Context, d *schema.ResourceData, m interface{}, vinsId uint64) error { + c := m.(*controller.ControllerCfg) + + req := vins.EnableRequest{ + VINSID: vinsId, + } + + _, err := c.CloudBroker().VINS().Enable(ctx, req) + return err +} + +func resourceVinsDisable(ctx context.Context, d *schema.ResourceData, m interface{}, vinsId uint64) error { + c := m.(*controller.ControllerCfg) + + req := vins.DisableRequest{ + VINSID: vinsId, + } + + _, err := c.CloudBroker().VINS().Disable(ctx, req) + return err +} + +func resourceVinsRestore(ctx context.Context, d *schema.ResourceData, m interface{}, vinsId uint64) error { + c := m.(*controller.ControllerCfg) + + req := vins.RestoreRequest{ + VINSID: vinsId, + } + + _, err := c.CloudBroker().VINS().Restore(ctx, req) + return err +} + +func resourceVinsIpReserve(ctx context.Context, d *schema.ResourceData, m interface{}, vinsId uint64) []error { + var errs []error + c := m.(*controller.ControllerCfg) + + ipRes := d.Get("ip") + + ipsSlice := ipRes.([]interface{}) + for _, ipInterfase := range ipsSlice { + ip := ipInterfase.(map[string]interface{}) + + req := vins.IPReserveRequest{ + VINSID: vinsId, + Type: ip["type"].(string), + } + if ipAddr, ok := ip["ip_addr"]; ok { + req.IPAddr = ipAddr.(string) + } + if macAddr, ok := ip["mac"]; ok { + req.MAC = macAddr.(string) + } + if computeId, ok := ip["compute_id"]; ok { + req.ComputeID = uint64(computeId.(int)) + } + + _, err := c.CloudBroker().VINS().IPReserve(ctx, req) + if err != nil { + errs = append(errs, err) + } + } + return errs +} + +func resourceVinsNatRuleAdd(ctx context.Context, d *schema.ResourceData, m interface{}, vinsId uint64) []error { + var errs []error + c := m.(*controller.ControllerCfg) + + natRule := d.Get("nat_rule") + + addedNatRules := natRule.([]interface{}) + if len(addedNatRules) > 0 { + for _, natRuleInterface := range addedNatRules { + natRule := natRuleInterface.(map[string]interface{}) + + req := vins.NATRuleAddRequest{ + VINSID: vinsId, + IntIP: natRule["int_ip"].(string), + ExtPortStart: uint64(natRule["ext_port_start"].(int)), + } + + if intPort, ok := natRule["int_port"]; ok { + req.IntPort = uint64(intPort.(int)) + } + if extPortEnd, ok := natRule["ext_port_end"]; ok { + req.ExtPortEnd = uint64(extPortEnd.(int)) + } + if proto, ok := natRule["proto"]; ok { + req.Proto = proto.(string) + } + + _, err := c.CloudBroker().VINS().NATRuleAdd(ctx, req) + if err != nil { + errs = append(errs, err) + } + } + } + return errs +} + +func resourceVinsChangeEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + vinsId := uint64(d.Get("vins_id").(int)) + + _, enableNew := d.GetChange("enable") + if enableNew.(bool) { + req := vins.EnableRequest{ + VINSID: vinsId, + } + + _, err := c.CloudBroker().VINS().Enable(ctx, req) + return err + } + + req := vins.DisableRequest{ + VINSID: vinsId, + } + + _, err := c.CloudBroker().VINS().Disable(ctx, req) + return err +} + +func resourceVinsChangeExtNetId(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + vinsId := uint64(d.Get("vins_id").(int)) + oldExtNetId, newExtNedId := d.GetChange("ext_net_id") + log.Debugf("resourceVinsUpdate - resourceVinsChangeExtNetId: changing ViNS ID %s - ext_net_id %d -> %d", d.Id(), oldExtNetId.(int), newExtNedId.(int)) + + if oldExtNetId.(int) > 0 { + // there was preexisting external net connection - disconnect ViNS + req := vins.ExtNetDisconnectRequest{VINSID: vinsId} + + _, err := c.CloudBroker().VINS().ExtNetDisconnect(ctx, req) + return err + } + + if newExtNedId.(int) >= 0 { + req := vins.ExtNetConnectRequest{ + VINSID: vinsId, + NetID: uint64(newExtNedId.(int)), + } + if ip, ok := d.GetOk("ext_ip"); ok && ip != "" { + req.IP = ip.(string) + } + + _, err := c.CloudBroker().VINS().ExtNetConnect(ctx, req) + return err + } + + return nil +} + +func resourceVinsChangeIp(ctx context.Context, d *schema.ResourceData, m interface{}) []error { + c := m.(*controller.ControllerCfg) + + var errs []error + + vinsId := uint64(d.Get("vins_id").(int)) + deletedIps := make([]interface{}, 0) + addedIps := make([]interface{}, 0) + + oldIpInterface, newIpInterface := d.GetChange("ip") + oldIpSlice := oldIpInterface.([]interface{}) + newIpSlice := newIpInterface.([]interface{}) + + for _, el := range oldIpSlice { + if !isContainsIp(newIpSlice, el) { + deletedIps = append(deletedIps, el) + } + } + + for _, el := range newIpSlice { + if !isContainsIp(oldIpSlice, el) { + addedIps = append(addedIps, el) + } + } + + if len(deletedIps) > 0 { + for _, ipInterface := range deletedIps { + ip := ipInterface.(map[string]interface{}) + req := vins.IPReleaseRequest{VINSID: vinsId} + + if ip["ip_addr"].(string) != "" { + req.IPAddr = ip["ip_addr"].(string) + } + if ip["mac"].(string) != "" { + req.MAC = ip["mac"].(string) + } + + _, err := c.CloudBroker().VINS().IPRelease(ctx, req) + if err != nil { + errs = append(errs, err) + } + } + } + + if len(addedIps) > 0 { + for _, ipInterface := range addedIps { + ip := ipInterface.(map[string]interface{}) + req := vins.IPReserveRequest{ + VINSID: vinsId, + Type: ip["type"].(string), + } + + if ip["ip_addr"].(string) != "" { + req.IPAddr = ip["ip_addr"].(string) + } + if ip["mac"].(string) != "" { + req.MAC = ip["mac"].(string) + } + if ip["compute_id"].(int) != 0 { + req.ComputeID = uint64(ip["compute_id"].(int)) + } + + _, err := c.CloudBroker().VINS().IPReserve(ctx, req) + if err != nil { + errs = append(errs, err) + } + } + } + + return errs +} + +func resourceVinsChangeNatRule(ctx context.Context, d *schema.ResourceData, m interface{}) []error { + c := m.(*controller.ControllerCfg) + + var errs []error + + vinsId := uint64(d.Get("vins_id").(int)) + + deletedNatRules := make([]interface{}, 0) + addedNatRules := make([]interface{}, 0) + + oldNatRulesInterface, newNatRulesInterface := d.GetChange("nat_rule") + oldNatRulesSlice := oldNatRulesInterface.([]interface{}) + newNatRulesSlice := newNatRulesInterface.([]interface{}) + + for _, el := range oldNatRulesSlice { + if !isContainsNatRule(newNatRulesSlice, el) { + deletedNatRules = append(deletedNatRules, el) + } + } + + for _, el := range newNatRulesSlice { + if !isContainsNatRule(oldNatRulesSlice, el) { + addedNatRules = append(addedNatRules, el) + } + } + + if len(deletedNatRules) > 0 { + for _, natRuleInterface := range deletedNatRules { + natRule := natRuleInterface.(map[string]interface{}) + req := vins.NATRuleDelRequest{ + VINSID: vinsId, + RuleID: int64(natRule["rule_id"].(int)), + } + + _, err := c.CloudBroker().VINS().NATRuleDel(ctx, req) + errs = append(errs, err) + } + } + + if len(addedNatRules) > 0 { + for _, natRuleInterface := range addedNatRules { + natRule := natRuleInterface.(map[string]interface{}) + req := vins.NATRuleAddRequest{ + VINSID: vinsId, + IntIP: natRule["int_ip"].(string), + ExtPortStart: uint64(natRule["ext_port_start"].(int)), + } + + if natRule["int_port"].(int) != 0 { + req.IntPort = uint64(natRule["int_port"].(int)) + } + if natRule["ext_port_end"].(int) != 0 { + req.ExtPortEnd = uint64(natRule["ext_port_end"].(int)) + } + if natRule["proto"].(string) != "" { + req.Proto = natRule["proto"].(string) + } + + _, err := c.CloudBroker().VINS().NATRuleAdd(ctx, req) + if err != nil { + errs = append(errs, err) + } + } + } + + return errs +} + +func resourceVinsChangeDNS(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + vinsId := uint64(d.Get("vins_id").(int)) + + // empty "dns" is allowed, it will update vnfs.dhcp.config.dns from current values to empty list + dnsInterface := d.Get("dns").(*schema.Set).List() + dnsList := make([]string, 0, len(dnsInterface)) + for _, item := range dnsInterface { + dnsList = append(dnsList, item.(string)) + } + + req := vins.DNSApplyRequest{ + VINSID: vinsId, + DNSList: dnsList, + } + + _, err := c.CloudBroker().VINS().DNSApply(ctx, req) + if err != nil { + return err + } + + return nil +} + +func resourceVinsChangeDefaultQos(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + vinsId := uint64(d.Get("vins_id").(int)) + + defaultQosInterface := d.Get("default_qos").([]interface{}) + + if len(defaultQosInterface) > 0 { + defaultQos := defaultQosInterface[0].(map[string]interface{}) + req := vins.DefaultQOSUpdateRequest{VINSID: vinsId} + if inRate, ok := defaultQos["in_rate"]; ok { + req.IngressRate = uint64(inRate.(int)) + } + if inBurst, ok := defaultQos["in_burst"]; ok { + req.IngressBirst = uint64(inBurst.(int)) + } + if eRate, ok := defaultQos["e_rate"]; ok { + req.EgressRate = uint64(eRate.(int)) + } + + _, err := c.CloudBroker().VINS().DefaultQOSUpdate(ctx, req) + return err + } + + return nil +} + +func resourceVinsChangeVnfRedeploy(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + vinsId := uint64(d.Get("vins_id").(int)) + + _, newRedeploy := d.GetChange("vnfdev_redeploy") + if newRedeploy.(bool) { + req := vins.VNFDevRedeployRequest{VINSID: vinsId} + + _, err := c.CloudBroker().VINS().VNFDevRedeploy(ctx, req) + return err + } + + return nil +} + +func resourceVinsChangeVnfRestart(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + vinsId := uint64(d.Get("vins_id").(int)) + + _, newRestart := d.GetChange("vnfdev_restart") + if newRestart.(bool) { + req := vins.VNFDevRestartRequest{VINSID: vinsId} + + _, err := c.CloudBroker().VINS().VNFDevRestart(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func resourceVinsChangeVnfReset(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + vinsId := uint64(d.Get("vins_id").(int)) + + _, newRestart := d.GetChange("vnfdev_reset") + if newRestart.(bool) { + req := vins.VNFDevResetRequest{VINSID: vinsId} + + _, err := c.CloudBroker().VINS().VNFDevReset(ctx, req) + if err != nil { + return err + } + } + + return nil +} + +func resourceVinsChangeVnfStartStop(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + vinsId := uint64(d.Get("vins_id").(int)) + + _, newStart := d.GetChange("vnfdev_start") + if newStart.(bool) { + req := vins.VNFDevStartRequest{VINSID: vinsId} + + _, err := c.CloudBroker().VINS().VNFDevStart(ctx, req) + if err != nil { + return err + } + } + + req := vins.VNFDevStopRequest{VINSID: vinsId} + + _, err := c.CloudBroker().VINS().VNFDevStop(ctx, req) + return err +} + +func resourceVinsChangeZoneID(ctx context.Context, d *schema.ResourceData, m interface{}) error { + c := m.(*controller.ControllerCfg) + + vinsId := uint64(d.Get("vins_id").(int)) + zoneID := uint64(d.Get("zone_id").(int)) + + req := vins.MigrateToZoneRequest{ + VINSID: vinsId, + ZoneID: zoneID, + } + + _, err := c.CloudBroker().VINS().MigrateToZone(ctx, req) + return err +} + +func ResourceVins() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceVinsCreate, + ReadContext: resourceVinsRead, + UpdateContext: resourceVinsUpdate, + DeleteContext: resourceVinsDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout20m, + Read: &constants.Timeout600s, + Update: &constants.Timeout20m, + Delete: &constants.Timeout30m, + Default: &constants.Timeout600s, + }, + + Schema: resourceVinsSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/resource_vins_static_route.go b/internal/service/cloudbroker/vins/resource_vins_static_route.go new file mode 100644 index 00000000..dfb2ae00 --- /dev/null +++ b/internal/service/cloudbroker/vins/resource_vins_static_route.go @@ -0,0 +1,156 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceStaticRouteCreate: called for vins_id %s", d.Get("vins_id")) + + c := m.(*controller.ControllerCfg) + + if diags := checkParamsExistenceStaticRoute(ctx, d, c); diags != nil { + return diags + } + + req := vins.StaticRouteAddRequest{ + VINSID: uint64(d.Get("vins_id").(int)), + Destination: d.Get("destination").(string), + Netmask: d.Get("netmask").(string), + Gateway: d.Get("gateway").(string), + } + + _, err := c.CloudBroker().VINS().StaticRouteAdd(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + staticRouteData, err := getStaticRouteData(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(fmt.Sprintf("%d#%d", req.VINSID, staticRouteData.ID)) + + return resourceStaticRouteRead(ctx, d, m) +} + +func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceStaticRouteRead: called for route_id %s", d.Id()) + + staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenStaticRouteData(d, staticRouteData) + + return nil +} + +func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + return nil +} + +func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceStaticRouteDelete: called for static route id %s", d.Id()) + + c := m.(*controller.ControllerCfg) + req := vins.StaticRouteDelRequest{} + + arr := strings.Split(d.Id(), "#") + if len(arr) != 2 { + return diag.Errorf("broken state id - %s", d.Id()) + } + + req.VINSID, _ = strconv.ParseUint(arr[0], 10, 64) + req.RouteId, _ = strconv.ParseUint(arr[1], 10, 64) + + _, err := c.CloudBroker().VINS().StaticRouteDel(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func isContainsIds(els []interface{}, el interface{}) bool { + convEl := el.(int) + for _, elOld := range els { + if convEl == elOld.(int) { + return true + } + } + return false +} + +func ResourceStaticRoute() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceStaticRouteCreate, + ReadContext: resourceStaticRouteRead, + UpdateContext: resourceStaticRouteUpdate, + DeleteContext: resourceStaticRouteDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout20m, + Read: &constants.Timeout600s, + Update: &constants.Timeout20m, + Delete: &constants.Timeout600s, + Default: &constants.Timeout600s, + }, + + Schema: resourceStaticRouteSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/vins/schema.go b/internal/service/cloudbroker/vins/schema.go new file mode 100644 index 00000000..b1324032 --- /dev/null +++ b/internal/service/cloudbroker/vins/schema.go @@ -0,0 +1,3482 @@ +package vins + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceVinsSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "vins id", + }, + + "vnf_dev": { + Type: schema.TypeList, + Computed: true, + Description: "vnf dev", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Description: "meta", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account id", + }, + "capabilities": { + Type: schema.TypeList, + Computed: true, + Description: "capabilities", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Description: "config", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "mgmt": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_addr": { + Type: schema.TypeString, + Computed: true, + Description: "ip address", + }, + "password": { + Type: schema.TypeString, + Computed: true, + Description: "password", + }, + "ssh_key": { + Type: schema.TypeString, + Computed: true, + Description: "ssh key", + }, + "user": { + Type: schema.TypeString, + Computed: true, + Description: "user", + }, + }, + }, + }, + "resources": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + Description: "cpu", + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + Description: "ram", + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + Description: "node id", + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + Description: "uuid", + }, + }, + }, + }, + }, + }, + }, + "config_saved": { + Type: schema.TypeBool, + Computed: true, + Description: "is config saved", + }, + "custom_precfg": { + Type: schema.TypeBool, + Computed: true, + Description: "custom pre config", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "id", + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Description: "interfaces", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "conn_id": { + Type: schema.TypeInt, + Computed: true, + Description: "connection id", + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + Description: "connection type", + }, + "def_gw": { + Type: schema.TypeString, + Computed: true, + Description: "default gw", + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "enabled", + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "flipgroup_id": { + Type: schema.TypeInt, + Computed: true, + Description: "flipgroup id", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid", + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + Description: "ip address", + }, + "listen_ssh": { + Type: schema.TypeBool, + Computed: true, + Description: "listen ssh", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "mac", + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + Description: "mtu", + }, + "libvirt_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "txmode": { + Type: schema.TypeString, + Computed: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Computed: true, + }, + "event_idx": { + Type: schema.TypeString, + Computed: true, + }, + "queues": { + Type: schema.TypeInt, + Computed: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "name", + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + Description: "net id", + }, + "net_mask": { + Type: schema.TypeInt, + Computed: true, + Description: "net mask", + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + Description: "net type", + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "pci slot", + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Description: "qos", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "sdn_interface_id": { + Type: schema.TypeString, + Computed: true, + }, + "security_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "target": { + Type: schema.TypeString, + Computed: true, + Description: "target", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Description: "vnfs", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "live_migration_job_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + Description: "lock status", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "name", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "vnc_password": { + Type: schema.TypeString, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Description: "vins", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account id", + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "account name", + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + Description: "created by", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "created time", + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + Description: "default gw", + }, + "default_qos": { + Type: schema.TypeList, + Computed: true, + Description: "default qoa", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + Description: "deleted by", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "deleted time", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + Description: "lock status", + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + Description: "manager id", + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + Description: "manager type", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "name", + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + Description: "net mask", + }, + "network": { + Type: schema.TypeString, + Computed: true, + Description: "network", + }, + "pre_reservations_num": { + Type: schema.TypeInt, + Computed: true, + Description: "pre reservations num", + }, + "redundant": { + Type: schema.TypeBool, + Computed: true, + Description: "redundant", + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + Description: "resource group id", + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + Description: "resource group name", + }, + "sec_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + Description: "updated by", + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + Description: "updated time", + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + Description: "user managed", + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Description: "vnfs", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dhcp": { + Type: schema.TypeList, + Computed: true, + Description: "dhcp", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Description: "meta", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account id", + }, + "config": { + Type: schema.TypeList, + Computed: true, + Description: "config", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "default_gw": { + Type: schema.TypeString, + Computed: true, + Description: "default gw", + }, + "dns": { + Type: schema.TypeList, + Computed: true, + Description: "list of dns", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ip_end": { + Type: schema.TypeString, + Computed: true, + Description: "ip end", + }, + "ip_start": { + Type: schema.TypeString, + Computed: true, + Description: "ip start", + }, + "lease": { + Type: schema.TypeInt, + Computed: true, + Description: "lease", + }, + "net_mask": { + Type: schema.TypeInt, + Computed: true, + Description: "net mask", + }, + "network": { + Type: schema.TypeString, + Computed: true, + Description: "network", + }, + "reservations": { + Type: schema.TypeList, + Computed: true, + Description: "reservations", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "client type", + }, + "ip": { + Type: schema.TypeString, + Computed: true, + Description: "ip", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "mac", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + Description: "vm id", + }, + }, + }, + }, + }, + }, + }, + + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "created time", + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Description: "devices list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "primary": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "iface01": { + Type: schema.TypeString, + Computed: true, + }, + "iface02": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "id", + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + Description: "lock status", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + Description: "owner id", + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + Description: "owner type", + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + Description: "prune virtual", + }, + "routes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Description: "compute ids", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + Description: "route id", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid", + }, + "destination": { + Type: schema.TypeString, + Computed: true, + Description: "destination", + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + Description: "net mask", + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + Description: "gateway", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "gw": { + Type: schema.TypeList, + Computed: true, + Description: "gw", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Description: "meta", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account id", + }, + "config": { + Type: schema.TypeList, + Computed: true, + Description: "config", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "default_gw": { + Type: schema.TypeString, + Computed: true, + Description: "default gw", + }, + "ext_net_id": { + Type: schema.TypeInt, + Computed: true, + Description: "extnet id", + }, + "ext_net_ip": { + Type: schema.TypeString, + Computed: true, + Description: "extnet ip", + }, + "ext_netmask": { + Type: schema.TypeInt, + Computed: true, + Description: "extnet mask", + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Description: "qos", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "created time", + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Description: "devices list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "primary": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "iface01": { + Type: schema.TypeString, + Computed: true, + }, + "iface02": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "id", + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + Description: "losk status", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + Description: "owner id", + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + Description: "owner type", + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + Description: "pure virtual", + }, + "routes": { + Type: schema.TypeList, + Computed: true, + Description: "routes", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "nat": { + Type: schema.TypeList, + Computed: true, + Description: "nat", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Description: "meta", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account id", + }, + "config": { + Type: schema.TypeList, + Computed: true, + Description: "config", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_mask": { + Type: schema.TypeInt, + Computed: true, + Description: "net mask", + }, + "network": { + Type: schema.TypeString, + Computed: true, + Description: "network", + }, + "rules": { + Type: schema.TypeList, + Computed: true, + Description: "nat rules", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "rule_id": { + Type: schema.TypeInt, + Computed: true, + Description: "nat rule id", + }, + "local_ip": { + Type: schema.TypeString, + Computed: true, + Description: "local ip", + }, + "local_port": { + Type: schema.TypeInt, + Computed: true, + Description: "local port", + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + Description: "protocol", + }, + "public_port_end": { + Type: schema.TypeInt, + Computed: true, + Description: "public port end", + }, + "public_port_start": { + Type: schema.TypeInt, + Computed: true, + Description: "public port start", + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + Description: "vm id", + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + Description: "vm name", + }, + }, + }, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "created time", + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Description: "devices list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "primary": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "iface01": { + Type: schema.TypeString, + Computed: true, + }, + "iface02": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "id", + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + Description: "lock status", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + Description: "owner id", + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + Description: "owner type", + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + Description: "pure virtual", + }, + "routes": { + Type: schema.TypeList, + Computed: true, + Description: "routes", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "vxlan_id": { + Type: schema.TypeInt, + Computed: true, + Description: "vxlan id", + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return rets +} + +func dataSourceVinsListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by id", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by account id", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by rg id", + }, + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Find by ext ip", + }, + "vnfdev_id": { + Type: schema.TypeInt, + Optional: true, + Description: "find by VNF Device id", + }, + "include_deleted": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "include deleted computes", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "sort by status", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Zone ID", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "default_qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "extnet_id": { + Type: schema.TypeInt, + Computed: true, + }, + "free_ips": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "pre_reservations_num": { + Type: schema.TypeInt, + Computed: true, + }, + "pri_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "redundant": { + Type: schema.TypeBool, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "sec_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dhcp": { + Type: schema.TypeInt, + Computed: true, + }, + "dns": { + Type: schema.TypeInt, + Computed: true, + }, + "fw": { + Type: schema.TypeInt, + Computed: true, + }, + "gw": { + Type: schema.TypeInt, + Computed: true, + }, + "nat": { + Type: schema.TypeInt, + Computed: true, + }, + "vpn": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "vxlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry count", + }, + } + return res +} + +func dataSourceVinsListDeletedSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by account ID", + }, + "rg_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by resgroup ID", + }, + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Description: "Filter by external IP", + }, + "vnf_dev_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Filter by VNF Device id", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "default_qos": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "external_ip": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "vins_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + }, + "network": { + Type: schema.TypeString, + Computed: true, + }, + "pre_reservations_num": { + Type: schema.TypeInt, + Computed: true, + }, + "pri_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "redundant": { + Type: schema.TypeBool, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + }, + "sec_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dhcp": { + Type: schema.TypeInt, + Computed: true, + }, + "dns": { + Type: schema.TypeInt, + Computed: true, + }, + "fw": { + Type: schema.TypeInt, + Computed: true, + }, + "gw": { + Type: schema.TypeInt, + Computed: true, + }, + "nat": { + Type: schema.TypeInt, + Computed: true, + }, + "vpn": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "vxlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func DataSourceVinsAuditsSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "call": { + Type: schema.TypeString, + Computed: true, + }, + "response_time": { + Type: schema.TypeFloat, + Computed: true, + }, + "status_code": { + Type: schema.TypeInt, + Computed: true, + }, + "time_stamp": { + Type: schema.TypeFloat, + Computed: true, + }, + "user": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } + return rets +} + +func DataSourceVinsExtNetListchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "default_gw": { + Type: schema.TypeString, + Computed: true, + }, + "ext_net_id": { + Type: schema.TypeInt, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "prefix_len": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return rets +} + +func DataSourceVinsIpListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "domain_name": { + Type: schema.TypeString, + Computed: true, + }, + "host_name": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return rets +} + +func DataSourceVinsNatRuleListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + }, + + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "local_ip": { + Type: schema.TypeString, + Computed: true, + }, + "local_port": { + Type: schema.TypeInt, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "public_port_end": { + Type: schema.TypeInt, + Computed: true, + }, + "public_port_start": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return rets +} + +func dataSourceStaticRouteListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "ID of VINS", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} + +func resourceVinsSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + // parameters from CreateInAccount + "name": { + Type: schema.TypeString, + Required: true, + Description: "name", + }, + "account_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "zone id", + }, + "enable_secgroups": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "enable security groups", + }, + "gid": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "ipcidr": { + Type: schema.TypeString, + Optional: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "Optional user-defined text description of this ViNS.", + }, + "pre_reservations_num": { + Type: schema.TypeInt, + Optional: true, + }, + "routes": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + // Additional parameters from CreateInRG + "rg_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + }, + "ext_net_id": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + }, + "ext_ip": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + + // Enable, delete parameters + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "enable for enable/disable requests", + }, + "force": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "force for delete request", + }, + "permanently": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "permanently for delete request", + }, + + // IP release, IP reserve parameters + "ip": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"DHCP", "VIP", "EXCLUDED"}, false), + }, + "ip_addr": { + Type: schema.TypeString, + Optional: true, + }, + "mac": { + Type: schema.TypeString, + Optional: true, + }, + "compute_id": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + }, + + // NAT rule add parameters + "nat_rule": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "int_ip": { + Type: schema.TypeString, + Required: true, + }, + "int_port": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "ext_port_start": { + Type: schema.TypeInt, + Required: true, + }, + "ext_port_end": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "proto": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false), + Computed: true, + }, + "rule_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + + // vnf dev start, stop, restart, reset, redeploy parameters + "vnfdev_start": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "true to start vnfdev, false to stop vnfdev", + }, + "vnfdev_reset": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "vnfdev_restart": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "vnfdev_redeploy": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + // default_qos + "default_qos": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: "default qoa", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + }, + }, + }, + }, + "dns": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + // other resource fields + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "vins id", + }, + "vnf_dev": { + Type: schema.TypeList, + Computed: true, + Description: "vnf dev", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Description: "meta", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account id", + }, + "capabilities": { + Type: schema.TypeList, + Computed: true, + Description: "capabilities", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Description: "config", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "mgmt": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_addr": { + Type: schema.TypeString, + Computed: true, + Description: "ip address", + }, + "password": { + Type: schema.TypeString, + Computed: true, + Description: "password", + }, + "ssh_key": { + Type: schema.TypeString, + Computed: true, + Description: "ssh key", + }, + "user": { + Type: schema.TypeString, + Computed: true, + Description: "user", + }, + }, + }, + }, + "resources": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cpu": { + Type: schema.TypeInt, + Computed: true, + Description: "cpu", + }, + "ram": { + Type: schema.TypeInt, + Computed: true, + Description: "ram", + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + Description: "node id", + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + Description: "uuid", + }, + }, + }, + }, + }, + }, + }, + "config_saved": { + Type: schema.TypeBool, + Computed: true, + Description: "is config saved", + }, + "custom_precfg": { + Type: schema.TypeBool, + Computed: true, + Description: "custom pre config", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "description", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "id", + }, + "interfaces": { + Type: schema.TypeList, + Computed: true, + Description: "interfaces", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "conn_id": { + Type: schema.TypeInt, + Computed: true, + Description: "connection id", + }, + "conn_type": { + Type: schema.TypeString, + Computed: true, + Description: "connection type", + }, + "def_gw": { + Type: schema.TypeString, + Computed: true, + Description: "default gw", + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "enabled", + }, + "enable_secgroups": { + Type: schema.TypeBool, + Computed: true, + }, + "flipgroup_id": { + Type: schema.TypeInt, + Computed: true, + Description: "flipgroup id", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid", + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + Description: "ip address", + }, + "listen_ssh": { + Type: schema.TypeBool, + Computed: true, + Description: "listen ssh", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "mac", + }, + "mtu": { + Type: schema.TypeInt, + Computed: true, + Description: "mtu", + }, + "libvirt_settings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "txmode": { + Type: schema.TypeString, + Computed: true, + }, + "ioeventfd": { + Type: schema.TypeString, + Computed: true, + }, + "event_idx": { + Type: schema.TypeString, + Computed: true, + }, + "queues": { + Type: schema.TypeInt, + Computed: true, + }, + "rx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + "tx_queue_size": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "name", + }, + "net_id": { + Type: schema.TypeInt, + Computed: true, + Description: "net id", + }, + "net_mask": { + Type: schema.TypeInt, + Computed: true, + Description: "net mask", + }, + "net_type": { + Type: schema.TypeString, + Computed: true, + Description: "net type", + }, + "node_id": { + Type: schema.TypeInt, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + Description: "pci slot", + }, + "bus_number": { + Type: schema.TypeInt, + Computed: true, + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Description: "qos", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "sdn_interface_id": { + Type: schema.TypeString, + Computed: true, + }, + "security_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "target": { + Type: schema.TypeString, + Computed: true, + Description: "target", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Description: "vnfs", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "live_migration_job_id": { + Type: schema.TypeInt, + Computed: true, + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + Description: "lock status", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "name", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "vnc_password": { + Type: schema.TypeString, + Computed: true, + }, + "vins": { + Type: schema.TypeList, + Computed: true, + Description: "vins", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + Description: "account name", + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + Description: "created by", + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "created time", + }, + "default_gw": { + Type: schema.TypeString, + Computed: true, + Description: "default gw", + }, + "deleted_by": { + Type: schema.TypeString, + Computed: true, + Description: "deleted by", + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + Description: "deleted time", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + Description: "lock status", + }, + "manager_id": { + Type: schema.TypeInt, + Computed: true, + Description: "manager id", + }, + "manager_type": { + Type: schema.TypeString, + Computed: true, + Description: "manager type", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "netmask": { + Type: schema.TypeInt, + Computed: true, + Description: "net mask", + }, + "network": { + Type: schema.TypeString, + Computed: true, + Description: "network", + }, + "redundant": { + Type: schema.TypeBool, + Computed: true, + Description: "redundant", + }, + "rg_name": { + Type: schema.TypeString, + Computed: true, + Description: "resource group name", + }, + "sec_vnf_dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + Description: "updated by", + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + Description: "updated time", + }, + "user_managed": { + Type: schema.TypeBool, + Computed: true, + Description: "user managed", + }, + "vnfs": { + Type: schema.TypeList, + Computed: true, + Description: "vnfs", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dhcp": { + Type: schema.TypeList, + Computed: true, + Description: "dhcp", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Description: "meta", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account id", + }, + "config": { + Type: schema.TypeList, + Computed: true, + Description: "config", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "default_gw": { + Type: schema.TypeString, + Computed: true, + Description: "default gw", + }, + "dns": { + Type: schema.TypeList, + Computed: true, + Description: "list of dns", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ip_end": { + Type: schema.TypeString, + Computed: true, + Description: "ip end", + }, + "ip_start": { + Type: schema.TypeString, + Computed: true, + Description: "ip start", + }, + "lease": { + Type: schema.TypeInt, + Computed: true, + Description: "lease", + }, + "net_mask": { + Type: schema.TypeInt, + Computed: true, + Description: "net mask", + }, + "network": { + Type: schema.TypeString, + Computed: true, + Description: "network", + }, + "reservations": { + Type: schema.TypeList, + Computed: true, + Description: "reservations", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "client type", + }, + "ip": { + Type: schema.TypeString, + Computed: true, + Description: "ip", + }, + "mac": { + Type: schema.TypeString, + Computed: true, + Description: "mac", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + Description: "vm id", + }, + }, + }, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "created time", + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Description: "devices list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "primary": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "iface01": { + Type: schema.TypeString, + Computed: true, + }, + "iface02": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "id", + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + Description: "lock status", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + Description: "owner id", + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + Description: "owner type", + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + Description: "prune virtual", + }, + "routes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Description: "compute ids", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + Description: "route id", + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid", + }, + "destination": { + Type: schema.TypeString, + Computed: true, + Description: "destination", + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + Description: "net mask", + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + Description: "gateway", + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "gw": { + Type: schema.TypeList, + Computed: true, + Description: "gw", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Description: "meta", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account id", + }, + "config": { + Type: schema.TypeList, + Computed: true, + Description: "config", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "default_gw": { + Type: schema.TypeString, + Computed: true, + Description: "default gw", + }, + "ext_net_id": { + Type: schema.TypeInt, + Computed: true, + Description: "extnet id", + }, + "ext_net_ip": { + Type: schema.TypeString, + Computed: true, + Description: "extnet ip", + }, + "ext_netmask": { + Type: schema.TypeInt, + Computed: true, + Description: "extnet mask", + }, + "qos": { + Type: schema.TypeList, + Computed: true, + Description: "qos", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "e_rate": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "in_burst": { + Type: schema.TypeInt, + Computed: true, + }, + "in_rate": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "created time", + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Description: "devices list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "primary": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "iface01": { + Type: schema.TypeString, + Computed: true, + }, + "iface02": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "id", + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + Description: "losk status", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + Description: "owner id", + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + Description: "owner type", + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + Description: "pure virtual", + }, + "routes": { + Type: schema.TypeList, + Computed: true, + Description: "routes", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "nat": { + Type: schema.TypeList, + Computed: true, + Description: "nat", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + Description: "ckey", + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Description: "meta", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "account id", + }, + "config": { + Type: schema.TypeList, + Computed: true, + Description: "config", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "net_mask": { + Type: schema.TypeInt, + Computed: true, + Description: "net mask", + }, + "network": { + Type: schema.TypeString, + Computed: true, + Description: "network", + }, + "rules": { + Type: schema.TypeList, + Computed: true, + Description: "nat rules", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "rule_id": { + Type: schema.TypeInt, + Computed: true, + Description: "nat rule id", + }, + "local_ip": { + Type: schema.TypeString, + Computed: true, + Description: "local ip", + }, + "local_port": { + Type: schema.TypeInt, + Computed: true, + Description: "local port", + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + Description: "protocol", + }, + "public_port_end": { + Type: schema.TypeInt, + Computed: true, + Description: "public port end", + }, + "public_port_start": { + Type: schema.TypeInt, + Computed: true, + Description: "public port start", + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + Description: "vm id", + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + Description: "vm name", + }, + }, + }, + }, + }, + }, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + Description: "created time", + }, + "devices": { + Type: schema.TypeList, + Computed: true, + Description: "devices list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "primary": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dev_id": { + Type: schema.TypeInt, + Computed: true, + }, + "iface01": { + Type: schema.TypeString, + Computed: true, + }, + "iface02": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "gid", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + Description: "guid", + }, + "id": { + Type: schema.TypeInt, + Computed: true, + Description: "id", + }, + "lock_status": { + Type: schema.TypeString, + Computed: true, + Description: "lock status", + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + Description: "milestones", + }, + "owner_id": { + Type: schema.TypeInt, + Computed: true, + Description: "owner id", + }, + "owner_type": { + Type: schema.TypeString, + Computed: true, + Description: "owner type", + }, + "pure_virtual": { + Type: schema.TypeBool, + Computed: true, + Description: "pure virtual", + }, + "routes": { + Type: schema.TypeList, + Computed: true, + Description: "routes", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "status", + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + Description: "tech status", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "type", + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "vxlan_id": { + Type: schema.TypeInt, + Computed: true, + Description: "vxlan id", + }, + } + + return rets +} + +func dataSourceStaticRouteSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS", + }, + "route_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the static route", + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "destination": { + Type: schema.TypeString, + Computed: true, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "netmask": { + Type: schema.TypeString, + Computed: true, + }, + } + return rets +} + +func resourceStaticRouteSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "destination": { + Type: schema.TypeString, + Required: true, + }, + "gateway": { + Type: schema.TypeString, + Required: true, + }, + "netmask": { + Type: schema.TypeString, + Required: true, + }, + "vins_id": { + Type: schema.TypeInt, + Required: true, + Description: "Unique ID of the ViNS", + }, + + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "route_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Unique ID of the static route", + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + } + + return rets +} diff --git a/internal/service/cloudbroker/vins/utility_vins.go b/internal/service/cloudbroker/vins/utility_vins.go new file mode 100644 index 00000000..63304fee --- /dev/null +++ b/internal/service/cloudbroker/vins/utility_vins.go @@ -0,0 +1,89 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.RecordVINS, error) { + c := m.(*controller.ControllerCfg) + + log.Debug("utilityVinsCheckPresence: locating ViNS by its ID") + req := vins.GetRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VINSID = id + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + } + + vins, err := c.CloudBroker().VINS().Get(ctx, req) + if err != nil { + return nil, err + } + + return vins, nil +} + +func utilityUpdateVINS(ctx context.Context, d *schema.ResourceData, m interface{}, vinsID uint64) error { + c := m.(*controller.ControllerCfg) + + req := vins.UpdateRequest{ + VINSID: vinsID, + } + + if d.HasChange("name") { + req.Name = d.Get("name").(string) + } + if d.HasChange("desc") { + req.Desc = d.Get("desc").(string) + } + if d.HasChange("enable_secgroups") { + req.EnableSecGroups = d.Get("enable_secgroups").(bool) + } + + _, err := c.CloudBroker().VINS().Update(ctx, req) + if err != nil { + return err + } + return nil +} diff --git a/internal/service/cloudbroker/vins/utility_vins_audits.go b/internal/service/cloudbroker/vins/utility_vins_audits.go new file mode 100644 index 00000000..98bfa22a --- /dev/null +++ b/internal/service/cloudbroker/vins/utility_vins_audits.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Sergey Kisil, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityVinsAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (vins.ListAudits, error) { + c := m.(*controller.ControllerCfg) + + req := vins.AuditsRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VINSID = id + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + } + + audits, err := c.CloudBroker().VINS().Audits(ctx, req) + if err != nil { + return nil, err + } + + return audits, nil +} diff --git a/internal/service/cloudbroker/vins/utility_vins_ext_net_list.go b/internal/service/cloudbroker/vins/utility_vins_ext_net_list.go new file mode 100644 index 00000000..53282040 --- /dev/null +++ b/internal/service/cloudbroker/vins/utility_vins_ext_net_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityVinsExtNetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListExtNets, error) { + c := m.(*controller.ControllerCfg) + req := vins.ExtNetListRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VINSID = id + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + } + + extNetList, err := c.CloudBroker().VINS().ExtNetList(ctx, req) + if err != nil { + return nil, err + } + + return extNetList, nil +} diff --git a/internal/service/cloudbroker/vins/utility_vins_ip_list.go b/internal/service/cloudbroker/vins/utility_vins_ip_list.go new file mode 100644 index 00000000..7933a929 --- /dev/null +++ b/internal/service/cloudbroker/vins/utility_vins_ip_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityVinsIpListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListIPs, error) { + c := m.(*controller.ControllerCfg) + req := vins.IPListRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VINSID = id + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + } + + ips, err := c.CloudBroker().VINS().IPList(ctx, req) + if err != nil { + return nil, err + } + + return ips, nil +} diff --git a/internal/service/cloudbroker/vins/utility_vins_list.go b/internal/service/cloudbroker/vins/utility_vins_list.go new file mode 100644 index 00000000..0e4c0a63 --- /dev/null +++ b/internal/service/cloudbroker/vins/utility_vins_list.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListVINS, error) { + c := m.(*controller.ControllerCfg) + req := vins.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) + } + if rgId, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rgId.(int)) + } + if extIp, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = extIp.(string) + } + if VNFDevId, ok := d.GetOk("vnfdev_id"); ok { + req.VNFDevID = uint64(VNFDevId.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if includeDeleted, ok := d.GetOk("include_deleted"); ok { + req.IncludeDeleted = includeDeleted.(bool) + } + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + log.Debugf("utilityVinsListCheckPresence") + vinsList, err := c.CloudBroker().VINS().List(ctx, req) + if err != nil { + return nil, err + } + + return vinsList, nil +} diff --git a/internal/service/cloudbroker/vins/utility_vins_list_deleted.go b/internal/service/cloudbroker/vins/utility_vins_list_deleted.go new file mode 100644 index 00000000..5996a223 --- /dev/null +++ b/internal/service/cloudbroker/vins/utility_vins_list_deleted.go @@ -0,0 +1,83 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityVinsListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListVINS, error) { + c := m.(*controller.ControllerCfg) + req := vins.ListDeletedRequest{} + + if by_id, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(by_id.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if account_id, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(account_id.(int)) + } + if rg_id, ok := d.GetOk("rg_id"); ok { + req.RGID = uint64(rg_id.(int)) + } + if ext_ip, ok := d.GetOk("ext_ip"); ok { + req.ExtIP = ext_ip.(string) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if VNFDevId, ok := d.GetOk("vnfdev_id"); ok { + req.VNFDevId = uint64(VNFDevId.(int)) + } + + log.Debugf("utilityVinsListDeletedCheckPresence") + vinsList, err := c.CloudBroker().VINS().ListDeleted(ctx, req) + if err != nil { + return nil, err + } + + return vinsList, nil +} diff --git a/internal/service/cloudbroker/vins/utility_vins_nat_rule_list.go b/internal/service/cloudbroker/vins/utility_vins_nat_rule_list.go new file mode 100644 index 00000000..dd03370b --- /dev/null +++ b/internal/service/cloudbroker/vins/utility_vins_nat_rule_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityVinsNatRuleListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListNATRules, error) { + c := m.(*controller.ControllerCfg) + req := vins.NATRuleListRequest{} + + if d.Id() != "" { + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.VINSID = id + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + } + + natRuleList, err := c.CloudBroker().VINS().NATRuleList(ctx, req) + if err != nil { + return nil, err + } + + return natRuleList, nil +} diff --git a/internal/service/cloudbroker/vins/utility_vins_static_route.go b/internal/service/cloudbroker/vins/utility_vins_static_route.go new file mode 100644 index 00000000..b487de61 --- /dev/null +++ b/internal/service/cloudbroker/vins/utility_vins_static_route.go @@ -0,0 +1,107 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + "fmt" + "strconv" + "strings" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityDataStaticRouteCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ItemRoutes, error) { + c := m.(*controller.ControllerCfg) + req := vins.StaticRouteListRequest{} + var routeId uint64 + + if d.Id() != "" { + arr := strings.Split(d.Id(), "#") + if len(arr) != 2 { + return nil, fmt.Errorf("broken state id") + } + + req.VINSID, _ = strconv.ParseUint(arr[0], 10, 64) + routeId, _ = strconv.ParseUint(arr[1], 10, 64) + } else { + req.VINSID = uint64(d.Get("vins_id").(int)) + routeId = uint64(d.Get("route_id").(int)) + } + + log.Debugf("utilityStaticRouteCheckPresence, vins_id: %v", req.VINSID) + staticRouteList, err := c.CloudBroker().VINS().StaticRouteList(ctx, req) + if err != nil { + return nil, err + } + + log.Debugf("utilityStaticRouteCheckPresence: ROUTE ID %v", routeId) + + staticRoute := &vins.ItemRoutes{} + for _, route := range staticRouteList.Data { + if routeId == route.ID { + staticRoute = &route + return staticRoute, nil + } + } + + return nil, fmt.Errorf("static route not found") +} + +func getStaticRouteData(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ItemRoutes, error) { + c := m.(*controller.ControllerCfg) + req := vins.StaticRouteListRequest{} + req.VINSID = uint64(d.Get("vins_id").(int)) + + staticRouteList, err := c.CloudBroker().VINS().StaticRouteList(ctx, req) + if err != nil { + return nil, err + } + + destination := d.Get("destination").(string) + gateway := d.Get("gateway").(string) + + staticRoute := &vins.ItemRoutes{} + for _, route := range staticRouteList.Data { + if destination == route.Destination && gateway == route.Gateway { + staticRoute = &route + return staticRoute, nil + } + } + + return nil, fmt.Errorf("static route not found") +} diff --git a/internal/service/cloudbroker/vins/utility_vins_static_route_list.go b/internal/service/cloudbroker/vins/utility_vins_static_route_list.go new file mode 100644 index 00000000..6fe7ce78 --- /dev/null +++ b/internal/service/cloudbroker/vins/utility_vins_static_route_list.go @@ -0,0 +1,58 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package vins + +import ( + "context" + + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityStaticRouteListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListStaticRoutes, error) { + c := m.(*controller.ControllerCfg) + req := vins.StaticRouteListRequest{} + + req.VINSID = uint64(d.Get("vins_id").(int)) + + log.Debugf("utilityStaticRouteListCheckPresence") + staticRouteList, err := c.CloudBroker().VINS().StaticRouteList(ctx, req) + if err != nil { + return nil, err + } + + return staticRouteList, nil +} diff --git a/internal/service/cloudbroker/zone/data_source_zone.go b/internal/service/cloudbroker/zone/data_source_zone.go new file mode 100644 index 00000000..bc6a0c9a --- /dev/null +++ b/internal/service/cloudbroker/zone/data_source_zone.go @@ -0,0 +1,213 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceZoneRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + zone, err := utilityZoneCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(d.Get("zone_id").(int))) + flattenZone(d, zone) + return nil +} + +func dataSourceZoneSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "zone_id": { + Type: schema.TypeInt, + Required: true, + }, + "auto_start": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "deletable": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "node_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "account_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "compute_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "extnet_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "vins_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "lb_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "bservice_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "k8s_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "drs": { + Type: schema.TypeBool, + Computed: true, + }, + "drs_uid": { + Type: schema.TypeString, + Computed: true, + }, + "drs_name": { + Type: schema.TypeString, + Computed: true, + }, + "sso_url": { + Type: schema.TypeString, + Computed: true, + }, + "app_id": { + Type: schema.TypeString, + Computed: true, + }, + "decort_url": { + Type: schema.TypeString, + Computed: true, + }, + "domain": { + Type: schema.TypeString, + Computed: true, + }, + "ping_addr": { + Type: schema.TypeString, + Computed: true, + }, + "broadcast_addr": { + Type: schema.TypeString, + Computed: true, + }, + "ssl_skip_verify": { + Type: schema.TypeBool, + Computed: true, + }, + "sso_type": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func DataSourceZone() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceZoneRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceZoneSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/zone/data_source_zone_cpu_alignment_profile.go b/internal/service/cloudbroker/zone/data_source_zone_cpu_alignment_profile.go new file mode 100644 index 00000000..bb4a3800 --- /dev/null +++ b/internal/service/cloudbroker/zone/data_source_zone_cpu_alignment_profile.go @@ -0,0 +1,97 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceZoneCPUAlignmentProfileRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + profiles, err := utilityZoneCPUAlignmentProfileCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(d.Get("zone_id").(int))) + d.Set("profiles", flattenCPUAlignmentProfiles(profiles)) + return nil +} + +func dataSourceZoneCPUAlignmentProfileSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "zone_id": { + Type: schema.TypeInt, + Required: true, + }, + "profiles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } +} + +func DataSourceZoneCPUAlignmentProfile() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceZoneCPUAlignmentProfileRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceZoneCPUAlignmentProfileSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/zone/data_source_zone_cpu_alignment_profile_list.go b/internal/service/cloudbroker/zone/data_source_zone_cpu_alignment_profile_list.go new file mode 100644 index 00000000..7dd646a5 --- /dev/null +++ b/internal/service/cloudbroker/zone/data_source_zone_cpu_alignment_profile_list.go @@ -0,0 +1,115 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceZoneCPUAlignmentProfileListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + list, err := utilityZoneCPUAlignmentProfileListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenZoneCPUAlignmentProfileList(list)) + d.Set("entry_count", list.EntryCount) + return nil +} + +func dataSourceZoneCPUAlignmentProfileListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "zone_id": { + Type: schema.TypeInt, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "cpu_alignment_profiles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } +} + +func DataSourceZoneCPUAlignmentProfileList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceZoneCPUAlignmentProfileListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceZoneCPUAlignmentProfileListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/zone/data_source_zone_cpu_alignment_profile_test_ds.go b/internal/service/cloudbroker/zone/data_source_zone_cpu_alignment_profile_test_ds.go new file mode 100644 index 00000000..2c7d0ba5 --- /dev/null +++ b/internal/service/cloudbroker/zone/data_source_zone_cpu_alignment_profile_test_ds.go @@ -0,0 +1,159 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceZoneCPUAlignmentProfileTestRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + result, err := utilityZoneCPUAlignmentProfileTestCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + d.SetId(strconv.Itoa(d.Get("zone_id").(int))) + d.Set("profiles", flattenCPUAlignmentProfiles(result.Profiles)) + d.Set("candidates", flattenCPUAlignmentProfileCandidates(result.Candidates)) + d.Set("supported_cpu_models", flattenSupportedCpuModels(result.SupportedCpuModels)) + return nil +} + +func dataSourceZoneCPUAlignmentProfileTestSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "zone_id": { + Type: schema.TypeInt, + Required: true, + }, + "hypervisor_similarity_in_percentage": { + Type: schema.TypeInt, + Optional: true, + }, + "profiles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "candidates": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "count": { + Type: schema.TypeInt, + Computed: true, + }, + "percentage": { + Type: schema.TypeFloat, + Computed: true, + }, + "required_count": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "supported_cpu_models": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "count": { + Type: schema.TypeInt, + Computed: true, + }, + "percentage": { + Type: schema.TypeFloat, + Computed: true, + }, + }, + }, + }, + } +} + +func DataSourceZoneCPUAlignmentProfileTest() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceZoneCPUAlignmentProfileTestRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceZoneCPUAlignmentProfileTestSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/zone/data_source_zone_list.go b/internal/service/cloudbroker/zone/data_source_zone_list.go new file mode 100644 index 00000000..cfc00b54 --- /dev/null +++ b/internal/service/cloudbroker/zone/data_source_zone_list.go @@ -0,0 +1,230 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceZoneListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + zoneList, err := utilityZoneListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") // ensure ID is empty in this case + return diag.FromErr(err) + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenZoneList(zoneList)) + d.Set("entry_count", zoneList.EntryCount) + return nil +} + +func dataSourceZoneListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "by_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by ID", + }, + "gid": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by Grid ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Find by name", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Find by description", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "Find by status", + }, + "deletable": { + Type: schema.TypeBool, + Optional: true, + Description: "Find by deletable", + }, + "node_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Find by nodeId", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + Description: "sort by one of supported fields, format +|-(field)", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "zone_id": { + Type: schema.TypeInt, + Required: true, + }, + "auto_start": { + Type: schema.TypeBool, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "deletable": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "node_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "drs": { + Type: schema.TypeBool, + Computed: true, + }, + "drs_uid": { + Type: schema.TypeString, + Computed: true, + }, + "drs_name": { + Type: schema.TypeString, + Computed: true, + }, + "sso_url": { + Type: schema.TypeString, + Computed: true, + }, + "app_id": { + Type: schema.TypeString, + Computed: true, + }, + "decort_url": { + Type: schema.TypeString, + Computed: true, + }, + "domain": { + Type: schema.TypeString, + Computed: true, + }, + "ping_addr": { + Type: schema.TypeString, + Computed: true, + }, + "broadcast_addr": { + Type: schema.TypeString, + Computed: true, + }, + "ssl_skip_verify": { + Type: schema.TypeBool, + Computed: true, + }, + "sso_type": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + } + + return res +} + +func DataSourceZoneList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceZoneListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceZoneListSchemaMake(), + } +} diff --git a/internal/service/cloudbroker/zone/flattens.go b/internal/service/cloudbroker/zone/flattens.go new file mode 100644 index 00000000..afa5969e --- /dev/null +++ b/internal/service/cloudbroker/zone/flattens.go @@ -0,0 +1,165 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/zone" +) + +func flattenZone(d *schema.ResourceData, item *zone.RecordZone) error { + log.Debugf("flattenZone: start decoding RecordZone name %q / ID %d", + item.Name, item.ID) + + d.Set("zone_id", int(item.ID)) + d.Set("guid", int(item.GUID)) + d.Set("gid", int(item.GID)) + d.Set("name", item.Name) + d.Set("description", item.Description) + d.Set("deletable", item.Deletable) + d.Set("status", item.Status) + d.Set("created_time", item.CreatedTime) + d.Set("updated_time", item.UpdatedTime) + d.Set("node_ids", item.NodeIDs) + d.Set("account_ids", item.AccountIDs) + d.Set("compute_ids", item.ComputeIDs) + d.Set("extnet_ids", item.ExtnetIDs) + d.Set("vins_ids", item.VinsIDs) + d.Set("lb_ids", item.LBIDs) + d.Set("bservice_ids", item.BserviceIDs) + d.Set("k8s_ids", item.K8SIDs) + d.Set("auto_start", item.AutoStart) + d.Set("drs", item.DRS) + d.Set("drs_uid", item.DRSUID) + d.Set("drs_name", item.DRSName) + d.Set("sso_url", item.SSOURL) + d.Set("app_id", item.AppID) + d.Set("decort_url", item.DecortURL) + d.Set("ping_addr", item.PingAddr) + d.Set("broadcast_addr", item.BroadcastAddr) + d.Set("ssl_skip_verify", item.SSLSkipVerify) + d.Set("domain", item.Domain) + d.Set("sso_type", item.SSOType) + d.Set("cpu_alignment_profiles", flattenCPUAlignmentProfiles(item.CpuAlignmentProfiles)) + + log.Debugf("flattenZone: decoded RecordZone name %q / ID %d, complete", + item.Name, item.ID) + return nil +} + +func flattenCPUAlignmentProfiles(profiles []zone.CpuAlignmentProfile) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(profiles)) + for _, p := range profiles { + res = append(res, map[string]interface{}{ + "name": p.Name, + "vendor": p.Vendor, + "model": p.Model, + }) + } + return res +} + +func flattenCPUAlignmentProfileCandidates(candidates []zone.CpuAlignmentProfileCandidate) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(candidates)) + for _, c := range candidates { + res = append(res, map[string]interface{}{ + "name": c.Name, + "vendor": c.Vendor, + "model": c.Model, + "count": int(c.Count), + "percentage": c.Percentage, + "required_count": int(c.RequiredCount), + }) + } + return res +} + +func flattenSupportedCpuModels(models []zone.SupportedCpuModel) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(models)) + for _, m := range models { + res = append(res, map[string]interface{}{ + "vendor": m.Vendor, + "model": m.Model, + "count": int(m.Count), + "percentage": m.Percentage, + }) + } + return res +} + +func flattenZoneCPUAlignmentProfileList(list *zone.ListCPUAlignmentProfiles) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(list.Data)) + for _, item := range list.Data { + res = append(res, map[string]interface{}{ + "zone_id": int(item.ZoneID), + "cpu_alignment_profiles": flattenCPUAlignmentProfiles(item.CpuAlignmentProfiles), + }) + } + return res +} + +func flattenZoneList(zone *zone.ListZones) []map[string]interface{} { + log.Debugf("flattenZoneList start") + res := make([]map[string]interface{}, 0, len(zone.Data)) + for _, zone := range zone.Data { + temp := map[string]interface{}{ + "zone_id": int(zone.ID), + "guid": int(zone.GUID), + "gid": int(zone.GID), + "name": zone.Name, + "description": zone.Description, + "deletable": zone.Deletable, + "status": zone.Status, + "created_time": zone.CreatedTime, + "updated_time": zone.UpdatedTime, + "node_ids": zone.NodeIDs, + "auto_start": zone.AutoStart, + "drs": zone.DRS, + "drs_uid": zone.DRSUID, + "drs_name": zone.DRSName, + "sso_url": zone.SSOURL, + "app_id": zone.AppID, + "decort_url": zone.DecortURL, + "ping_addr": zone.PingAddr, + "broadcast_addr": zone.BroadcastAddr, + "ssl_skip_verify": zone.SSLSkipVerify, + "domain": zone.Domain, + "sso_type": zone.SSOType, + } + res = append(res, temp) + } + log.Debugf("flattenZoneList end") + return res + +} diff --git a/internal/service/cloudbroker/zone/resource_zone.go b/internal/service/cloudbroker/zone/resource_zone.go new file mode 100644 index 00000000..77d8b49e --- /dev/null +++ b/internal/service/cloudbroker/zone/resource_zone.go @@ -0,0 +1,325 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/zone" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" +) + +func resourceZoneCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + zoneName := d.Get("name").(string) + + log.Debugf("resourceZoneCreate: called Zone with name %s", zoneName) + + c := m.(*controller.ControllerCfg) + + req := zone.CreateRequest{ + Name: zoneName, + } + + if aS, ok := d.GetOk("auto_start"); ok { + req.AutoStart = aS.(bool) + } + + if desc, ok := d.GetOk("description"); ok { + req.Description = desc.(string) + } + + if drs, ok := d.GetOkExists("drs"); ok { + req.DRS = drs.(bool) + } + + zoneID, err := c.CloudBroker().Zone().Create(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.FormatUint(zoneID, 10)) + + warnings := dc.Warnings{} + + if nodeIDs, ok := d.GetOk("node_ids"); ok { + nodeIDsArr := nodeIDs.([]interface{}) + if len(nodeIDsArr) > 0 { + + addedUint := make([]uint64, len(nodeIDsArr)) + for i, v := range nodeIDsArr { + addedUint[i] = uint64(v.(int)) + } + + req := zone.AddNodeRequest{ + ID: zoneID, + NodeIDs: addedUint, + } + if _, err := c.CloudBroker().Zone().AddNode(ctx, req); err != nil { + warnings.Add(err) + } + + } + } + + if similarity, ok := d.GetOk("hypervisor_similarity_in_percentage"); ok { + if s := similarity.(int); s > 0 { + if err := utilityZoneCPUAlignmentProfileUpdate(ctx, d, m, zoneID); err != nil { + warnings.Add(err) + } + } + } + + log.Debugf("resourceZoneCreate: create Zone with ID: %d, complete", zoneID) + return append(resourceZoneRead(ctx, d, m), warnings.Get()...) +} + +func resourceZoneRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceZoneRead: called Zone with id %s", d.Id()) + + zone, err := utilityZoneCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenZone(d, zone) + + log.Debugf("resourceZoneRead: read Zone with id %s, complete", d.Id()) + return nil +} + +func resourceZoneUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + zoneID, _ := strconv.ParseUint(d.Id(), 10, 64) + + log.Debugf("resourceZoneUpdate: called Zone with id %d", zoneID) + + if d.HasChanges("name", "description", "node_ids", "auto_start") { + if err := utilityZoneUpdate(ctx, d, m, zoneID); err != nil { + return diag.FromErr(err) + } + } + + if d.HasChange("hypervisor_similarity_in_percentage") { + if err := utilityZoneCPUAlignmentProfileUpdate(ctx, d, m, zoneID); err != nil { + return diag.FromErr(err) + } + } + + log.Debugf("resourceZoneUpdate: update Zone with id %d, complete", zoneID) + + return resourceZoneRead(ctx, d, m) +} + +func resourceZoneDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceZoneDelete: called Zone with id %s", d.Id()) + + zoneItem, err := utilityZoneCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + c := m.(*controller.ControllerCfg) + + req := zone.DeleteRequest{ + ID: zoneItem.ID, + } + + _, err = c.CloudBroker().Zone().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceZone() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceZoneCreate, + ReadContext: resourceZoneRead, + UpdateContext: resourceZoneUpdate, + DeleteContext: resourceZoneDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout20m, + Read: &constants.Timeout20m, + Update: &constants.Timeout20m, + Delete: &constants.Timeout20m, + Default: &constants.Timeout20m, + }, + + Schema: resourceZoneSchemaMake(), + } +} + +func resourceZoneSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "node_ids": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "auto_start": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "drs": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "drs_uid": { + Type: schema.TypeString, + Computed: true, + }, + "drs_name": { + Type: schema.TypeString, + Computed: true, + }, + "sso_url": { + Type: schema.TypeString, + Computed: true, + }, + "app_id": { + Type: schema.TypeString, + Computed: true, + }, + "decort_url": { + Type: schema.TypeString, + Computed: true, + }, + "domain": { + Type: schema.TypeString, + Computed: true, + }, + "ping_addr": { + Type: schema.TypeString, + Computed: true, + }, + "broadcast_addr": { + Type: schema.TypeString, + Computed: true, + }, + "ssl_skip_verify": { + Type: schema.TypeBool, + Computed: true, + }, + "sso_type": { + Type: schema.TypeString, + Computed: true, + }, + "zone_id": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "deletable": { + Type: schema.TypeBool, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "updated_time": { + Type: schema.TypeInt, + Computed: true, + }, + "hypervisor_similarity_in_percentage": { + Type: schema.TypeInt, + Optional: true, + }, + "cpu_alignment_profiles": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + } +} diff --git a/internal/service/cloudbroker/zone/utility_zone.go b/internal/service/cloudbroker/zone/utility_zone.go new file mode 100644 index 00000000..88b7bfab --- /dev/null +++ b/internal/service/cloudbroker/zone/utility_zone.go @@ -0,0 +1,186 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/zone" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" +) + +func utilityZoneCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*zone.RecordZone, error) { + c := m.(*controller.ControllerCfg) + req := zone.GetRequest{} + + if d.Id() != "" { + zoneId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.ID = zoneId + } else { + req.ID = uint64(d.Get("zone_id").(int)) + } + + zoneData, err := c.CloudBroker().Zone().Get(ctx, req) + if err != nil { + return nil, err + } + + return zoneData, nil +} + +func utilityZoneUpdate(ctx context.Context, d *schema.ResourceData, m interface{}, zoneID uint64) error { + c := m.(*controller.ControllerCfg) + + if d.HasChanges("name", "description", "auto_start") { + req := zone.UpdateRequest{ + ID: zoneID, + } + + if d.HasChange("name") { + req.Name = d.Get("name").(string) + } + if d.HasChange("description") { + req.Description = d.Get("description").(string) + } + + if d.HasChange("auto_start") { + req.AutoStart = d.Get("auto_start").(bool) + } + + _, err := c.CloudBroker().Zone().Update(ctx, req) + if err != nil { + return err + } + log.Debugf("utilityZoneUpdate: update zone with ID: %d, complete with params=%v", zoneID, req) + } + + addedNodes := make([]interface{}, 0) + removedNodes := make([]interface{}, 0) + + old_set, new_set := d.GetChange("node_ids") + oldSlice := old_set.([]interface{}) + newSlice := new_set.([]interface{}) + + for _, oldElem := range oldSlice { + if !containsNodes(newSlice, oldElem) { + removedNodes = append(removedNodes, oldElem) + } + } + + for _, newElem := range newSlice { + if !containsNodes(oldSlice, newElem) { + addedNodes = append(addedNodes, newElem) + } + } + + log.Debugf("Found node_ids change with %v deletion(s) and %v addition(s) [zoneID=%v]", len(removedNodes), len(addedNodes), zoneID) + + if len(addedNodes) > 0 { + + addedUint := make([]uint64, len(addedNodes)) + for i, v := range addedNodes { + addedUint[i] = uint64(v.(int)) + } + + req := zone.AddNodeRequest{ + ID: zoneID, + NodeIDs: addedUint, + } + if _, err := c.CloudBroker().Zone().AddNode(ctx, req); err != nil { + return err + } + + } + + if len(removedNodes) > 0 { + removedUint := make([]uint64, len(removedNodes)) + for i, v := range removedNodes { + removedUint[i] = uint64(v.(int)) + } + + req := zone.DelNodeRequest{ + ID: zoneID, + NodeIDs: removedUint, + } + log.Debug("del") + log.Debug(req.NodeIDs) + if _, err := c.CloudBroker().Zone().DelNode(ctx, req); err != nil { + return err + } + } + + return nil +} + +func utilityZoneCPUAlignmentProfileUpdate(ctx context.Context, d *schema.ResourceData, m interface{}, zoneID uint64) error { + c := m.(*controller.ControllerCfg) + + newVal := d.Get("hypervisor_similarity_in_percentage").(int) + + if newVal > 0 { + req := zone.AddCPUAlignmentProfileRequest{ + ZoneID: zoneID, + HypervisorSimilarityInPercentage: uint64(newVal), + } + if _, err := c.CloudBroker().Zone().AddCPUAlignmentProfile(ctx, req); err != nil { + return err + } + log.Debugf("utilityZoneCPUAlignmentProfileUpdate: added CPU alignment profile for zone %d with similarity %d%%", zoneID, newVal) + } else { + req := zone.DeleteCPUAlignmentProfileRequest{ + ZoneID: zoneID, + } + if _, err := c.CloudBroker().Zone().DeleteCPUAlignmentProfile(ctx, req); err != nil { + return err + } + log.Debugf("utilityZoneCPUAlignmentProfileUpdate: deleted CPU alignment profile for zone %d", zoneID) + } + + return nil +} + +func containsNodes(set []interface{}, check interface{}) bool { + for _, elem := range set { + elemConv := elem.(int) + checkConv := check.(int) + if elemConv == checkConv { + return true + } + } + + return false +} diff --git a/internal/service/cloudbroker/zone/utility_zone_cpu_alignment_profile.go b/internal/service/cloudbroker/zone/utility_zone_cpu_alignment_profile.go new file mode 100644 index 00000000..1a48be6b --- /dev/null +++ b/internal/service/cloudbroker/zone/utility_zone_cpu_alignment_profile.go @@ -0,0 +1,77 @@ +/* +Copyright (c) 2019-2024 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/zone" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityZoneCPUAlignmentProfileCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]zone.CpuAlignmentProfile, error) { + c := m.(*controller.ControllerCfg) + + req := zone.GetCPUAlignmentProfileRequest{ + ZoneID: uint64(d.Get("zone_id").(int)), + } + + return c.CloudBroker().Zone().GetCPUAlignmentProfile(ctx, req) +} + +func utilityZoneCPUAlignmentProfileListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*zone.ListCPUAlignmentProfiles, error) { + c := m.(*controller.ControllerCfg) + + req := zone.ListCPUAlignmentProfileRequest{} + + if zoneID, ok := d.GetOk("zone_id"); ok { + req.ZoneID = uint64(zoneID.(int)) + } + + return c.CloudBroker().Zone().ListCPUAlignmentProfile(ctx, req) +} + +func utilityZoneCPUAlignmentProfileTestCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*zone.TestCPUAlignmentProfileResult, error) { + c := m.(*controller.ControllerCfg) + + req := zone.TestCPUAlignmentProfileRequest{ + ZoneID: uint64(d.Get("zone_id").(int)), + } + + if similarity, ok := d.GetOk("hypervisor_similarity_in_percentage"); ok { + req.HypervisorSimilarityInPercentage = uint64(similarity.(int)) + } + + return c.CloudBroker().Zone().TestCPUAlignmentProfile(ctx, req) +} diff --git a/internal/service/cloudbroker/zone/utility_zone_list.go b/internal/service/cloudbroker/zone/utility_zone_list.go new file mode 100644 index 00000000..e17cbf63 --- /dev/null +++ b/internal/service/cloudbroker/zone/utility_zone_list.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package zone + +import ( + "context" + + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/zone" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func utilityZoneListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*zone.ListZones, error) { + c := m.(*controller.ControllerCfg) + req := zone.ListRequest{} + + if byId, ok := d.GetOk("by_id"); ok { + req.ByID = uint64(byId.(int)) + } + if gid, ok := d.GetOk("gid"); ok { + req.GID = uint64(gid.(int)) + } + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if description, ok := d.GetOk("description"); ok { + req.Description = description.(string) + } + if status, ok := d.GetOk("status"); ok { + req.Status = status.(string) + } + if deletable, ok := d.GetOk("deletable"); ok { + req.Deletable = deletable.(bool) + } + if nodeID, ok := d.GetOk("nodeId"); ok { + req.NodeID = uint64(nodeID.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if size, ok := d.GetOk("size"); ok { + req.Size = uint64(size.(int)) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + zoneList, err := c.CloudBroker().Zone().List(ctx, req) + if err != nil { + return nil, err + } + + return zoneList, nil +} diff --git a/internal/service/sdn/access_group/data_decort_sdn_access_group.go b/internal/service/sdn/access_group/data_decort_sdn_access_group.go new file mode 100644 index 00000000..a8353e11 --- /dev/null +++ b/internal/service/sdn/access_group/data_decort_sdn_access_group.go @@ -0,0 +1,87 @@ +package accessgroup + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccessGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accessGroup, err := utilityAccessGroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenAccessGroupDataSource(d, accessGroup) + d.SetId(accessGroup.ID) + return nil +} + +func dataSourceAccessGroupSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Required: true, + Description: "The unique access group ID", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name", + }, + "comment": { + Type: schema.TypeString, + Computed: true, + Description: "Comment description", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation timestamp", + }, + "net_object_access_group": { + Type: schema.TypeList, + Computed: true, + Description: "Net object access group configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Access group ID", + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version identifier", + }, + }, + }, + }, + } + + return res +} + +func DataSourceAccessGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccessGroupRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccessGroupSchemaMake(), + } +} diff --git a/internal/service/sdn/access_group/data_decort_sdn_access_group_list.go b/internal/service/sdn/access_group/data_decort_sdn_access_group_list.go new file mode 100644 index 00000000..c6886256 --- /dev/null +++ b/internal/service/sdn/access_group/data_decort_sdn_access_group_list.go @@ -0,0 +1,40 @@ +package accessgroup + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccessGroupListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + accessGroupList, err := utilityAccessGroupListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccessGroupList(accessGroupList)) + + return nil +} + +func DataSourceAccessGroupList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccessGroupListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccessGroupListSchemaMake(), + } +} + diff --git a/internal/service/sdn/access_group/data_decort_sdn_access_group_user_list.go b/internal/service/sdn/access_group/data_decort_sdn_access_group_user_list.go new file mode 100644 index 00000000..a406d033 --- /dev/null +++ b/internal/service/sdn/access_group/data_decort_sdn_access_group_user_list.go @@ -0,0 +1,39 @@ +package accessgroup + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceAccessGroupUserListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + userList, err := utilityAccessGroupUserListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenAccessGroupUserList(userList)) + + return nil +} + +func DataSourceAccessGroupUserList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceAccessGroupUserListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceAccessGroupUserListSchemaMake(), + } +} diff --git a/internal/service/sdn/access_group/flattens.go b/internal/service/sdn/access_group/flattens.go new file mode 100644 index 00000000..c262456d --- /dev/null +++ b/internal/service/sdn/access_group/flattens.go @@ -0,0 +1,140 @@ +package accessgroup + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/acsgroups" +) + +func flattenAccessGroupDataSource(d *schema.ResourceData, accessGroupRecord *acsgroups.AccessGroup) { + d.Set("display_name", accessGroupRecord.DisplayName) + d.Set("comment", accessGroupRecord.Comment) + d.Set("created_at", accessGroupRecord.CreatedAt) + d.Set("net_object_access_group", flattenNetObjectAccessGroup(accessGroupRecord.NetObjectAccessGroup)) +} + +func flattenAccessGroupResource(d *schema.ResourceData, accessGroupRecord *acsgroups.AccessGroup, userList *acsgroups.UsersList) { + d.Set("display_name", accessGroupRecord.DisplayName) + d.Set("comment", accessGroupRecord.Comment) + d.Set("created_at", accessGroupRecord.CreatedAt) + d.Set("net_object_access_group", flattenNetObjectAccessGroup(accessGroupRecord.NetObjectAccessGroup)) + + defaultSecurityPolicy := accessGroupRecord.DefaultSecurityPolicy + if defaultSecurityPolicy.ID != "" { + flattenedDefaultSecPolicy := map[string]interface{}{ + "display_name": defaultSecurityPolicy.DisplayName, + "id": defaultSecurityPolicy.ID, + "description": defaultSecurityPolicy.Description, + "version_id": int(defaultSecurityPolicy.VersionID), + "access_group_id": defaultSecurityPolicy.AccessGroupID, + "default_open_session_drop": defaultSecurityPolicy.DefaultOpenSessionDrop, + } + + if defaultSecPolicy, ok := d.GetOk("default_security_policy"); ok { + defaultSecPolicyList := defaultSecPolicy.([]interface{}) + if len(defaultSecPolicyList) > 0 { + defaultSecPolicyMap := defaultSecPolicyList[0].(map[string]interface{}) + + if defaultAclDrop, ok := defaultSecPolicyMap["default_acl_drop"].(string); ok && defaultAclDrop != "" { + flattenedDefaultSecPolicy["default_acl_drop"] = defaultAclDrop + } else if defaultSecurityPolicy.DefaultAclDrop != "" { + flattenedDefaultSecPolicy["default_acl_drop"] = defaultSecurityPolicy.DefaultAclDrop + } + + if defaultOpenSessionDrop, ok := defaultSecPolicyMap["default_open_session_drop"].(bool); ok { + flattenedDefaultSecPolicy["default_open_session_drop"] = defaultOpenSessionDrop + } + } else { + if defaultSecurityPolicy.DefaultAclDrop != "" { + flattenedDefaultSecPolicy["default_acl_drop"] = defaultSecurityPolicy.DefaultAclDrop + } + } + } else { + if defaultSecurityPolicy.DefaultAclDrop != "" { + flattenedDefaultSecPolicy["default_acl_drop"] = defaultSecurityPolicy.DefaultAclDrop + } + } + + d.Set("default_security_policy", []map[string]interface{}{flattenedDefaultSecPolicy}) + } + + if userList != nil { + d.Set("users", flattenAccessGroupUsers(userList)) + } +} + +func flattenNetObjectAccessGroup(noag acsgroups.NetObjectAccessGroup) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "access_group_id": noag.AccessGroupID, + "id": noag.ID, + "version_id": noag.VersionID, + } + res = append(res, temp) + return res +} + +func flattenDefaultSecurityPolicy(dsp acsgroups.DefaultSecurityPolicy) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "display_name": dsp.DisplayName, + "id": dsp.ID, + "description": dsp.Description, + "version_id": dsp.VersionID, + "access_group_id": dsp.AccessGroupID, + "default_acl_drop": dsp.DefaultAclDrop, + "default_open_session_drop": dsp.DefaultOpenSessionDrop, + } + res = append(res, temp) + return res +} + +func flattenAccessGroupList(agList *acsgroups.AccessGroupList) []map[string]interface{} { + if agList == nil { + return []map[string]interface{}{} + } + res := make([]map[string]interface{}, 0, len(agList.AccessGroups)) + for _, v := range agList.AccessGroups { + temp := map[string]interface{}{ + "id": v.ID, + "display_name": v.DisplayName, + "comment": v.Comment, + "created_at": v.CreatedAt, + "net_object_access_group": flattenNetObjectAccessGroup(v.NetObjectAccessGroup), + "default_security_policy": flattenDefaultSecurityPolicy(v.DefaultSecurityPolicy), + } + res = append(res, temp) + } + return res +} + +func flattenAccessGroupUserList(userList *acsgroups.UsersList) []map[string]interface{} { + if userList == nil { + return []map[string]interface{}{} + } + res := make([]map[string]interface{}, 0, len(userList.Users)) + for _, v := range userList.Users { + temp := map[string]interface{}{ + "id": v.ID, + "display_name": v.Name, + "role_id": v.RoleID, + "login": v.Login, + } + res = append(res, temp) + } + return res +} + +func flattenAccessGroupUsers(userList *acsgroups.UsersList) []map[string]interface{} { + if userList == nil { + return []map[string]interface{}{} + } + res := make([]map[string]interface{}, 0, len(userList.Users)) + for _, v := range userList.Users { + temp := map[string]interface{}{ + "user_id": v.ID, + "access_group_role_id": v.RoleID, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/sdn/access_group/resource_decort_sdn_access_group.go b/internal/service/sdn/access_group/resource_decort_sdn_access_group.go new file mode 100644 index 00000000..8cce08e7 --- /dev/null +++ b/internal/service/sdn/access_group/resource_decort_sdn_access_group.go @@ -0,0 +1,276 @@ +package accessgroup + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/acsgroups" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/defsecpolicies" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceAccessGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccessGroupCreate: called access group with name %s", + d.Get("display_name").(string)) + c := m.(*controller.ControllerCfg) + + req := acsgroups.CreateRequest{ + DisplayName: d.Get("display_name").(string), + Comment: d.Get("comment").(string), + } + + accessGroup, err := c.SDN().AccessGroups().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(accessGroup.ID) + + if users, ok := d.GetOk("users"); ok { + usersList := users.([]interface{}) + for _, userRaw := range usersList { + userMap := userRaw.(map[string]interface{}) + userReq := acsgroups.UserAddRequest{ + GroupID: accessGroup.ID, + UserID: userMap["user_id"].(string), + AccessGroupRoleID: userMap["access_group_role_id"].(string), + } + _, err := c.SDN().AccessGroups().UserAdd(ctx, userReq) + if err != nil { + log.Warnf("resourceAccessGroupRead: failed to add users for access group %s: %v", d.Id(), err) + + } + } + } + + if defaultSecPolicy, ok := d.GetOk("default_security_policy"); ok { + defaultSecPolicyList := defaultSecPolicy.([]interface{}) + if len(defaultSecPolicyList) > 0 { + defaultSecPolicyMap := defaultSecPolicyList[0].(map[string]interface{}) + + getReq := acsgroups.GetGroupRequest{ + GroupID: accessGroup.ID, + } + fullAccessGroup, err := c.SDN().AccessGroups().Get(ctx, getReq) + if err != nil { + return diag.FromErr(err) + } + + if fullAccessGroup.DefaultSecurityPolicy.ID == "" { + return diag.Errorf("default security policy not found for access group %s", accessGroup.ID) + } + + updateReq := defsecpolicies.UpdateRequest{ + AccessGroupID: accessGroup.ID, + VersionID: uint64(fullAccessGroup.DefaultSecurityPolicy.VersionID), + } + + if defaultAclDrop, ok := defaultSecPolicyMap["default_acl_drop"].(string); ok && defaultAclDrop != "" { + updateReq.DefaultACLDrop = defaultAclDrop + } + + if defaultOpenSessionDrop, ok := defaultSecPolicyMap["default_open_session_drop"].(bool); ok { + updateReq.DefaultOpenSessionDrop = defaultOpenSessionDrop + } + + _, err = c.SDN().DefaultSecurityPolicies().Update(ctx, updateReq) + if err != nil { + return diag.FromErr(err) + } + } + } + + return resourceAccessGroupRead(ctx, d, m) +} + +func resourceAccessGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccessGroupRead: called access group with id %s", d.Id()) + + accessGroup, err := utilityAccessGroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + userList, err := utilityAccessGroupUsersGet(ctx, accessGroup.ID, m) + if err != nil { + log.Warnf("resourceAccessGroupRead: failed to get users for access group %s: %v", d.Id(), err) + userList = nil + } + + flattenAccessGroupResource(d, accessGroup, userList) + d.SetId(accessGroup.ID) + + return nil +} + +func resourceAccessGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccessGroupUpdate: called access group with id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + req := acsgroups.UpdateRequest{ + AccessGroupID: d.Id(), + } + + needUpdate := false + + if d.HasChange("display_name") { + req.DisplayName = d.Get("display_name").(string) + needUpdate = true + } + + if d.HasChange("comment") { + req.Comment = d.Get("comment").(string) + needUpdate = true + } + + var err error + if needUpdate { + _, err = c.SDN().AccessGroups().Update(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + } + + if d.HasChange("users") { + oldUsers, newUsers := d.GetChange("users") + oldUsersList := oldUsers.([]interface{}) + newUsersList := newUsers.([]interface{}) + + oldUsersMap := make(map[string]string) + for _, userRaw := range oldUsersList { + userMap := userRaw.(map[string]interface{}) + userID := userMap["user_id"].(string) + oldUsersMap[userID] = userMap["access_group_role_id"].(string) + } + + newUsersMap := make(map[string]string) + for _, userRaw := range newUsersList { + userMap := userRaw.(map[string]interface{}) + userID := userMap["user_id"].(string) + newUsersMap[userID] = userMap["access_group_role_id"].(string) + } + + for userID := range oldUsersMap { + if _, exists := newUsersMap[userID]; !exists { + userDeleteReq := acsgroups.UserDeleteRequest{ + GroupID: d.Id(), + UserID: userID, + } + _, err := c.SDN().AccessGroups().UserDelete(ctx, userDeleteReq) + if err != nil { + return diag.FromErr(err) + } + } + } + + for userID, roleID := range newUsersMap { + if oldRoleID, exists := oldUsersMap[userID]; !exists || oldRoleID != roleID { + if !exists { + userAddReq := acsgroups.UserAddRequest{ + GroupID: d.Id(), + UserID: userID, + AccessGroupRoleID: roleID, + } + _, err := c.SDN().AccessGroups().UserAdd(ctx, userAddReq) + if err != nil { + return diag.FromErr(err) + } + } else if oldRoleID != roleID { + userUpdateRoleReq := acsgroups.UserUpdateRoleRequest{ + GroupID: d.Id(), + UserID: userID, + AccessGroupRoleID: roleID, + } + _, err := c.SDN().AccessGroups().UserUpdateRole(ctx, userUpdateRoleReq) + if err != nil { + return diag.FromErr(err) + } + } + } + } + } + + if d.HasChange("default_security_policy") { + defaultSecPolicy, ok := d.GetOk("default_security_policy") + if ok { + defaultSecPolicyList := defaultSecPolicy.([]interface{}) + if len(defaultSecPolicyList) > 0 { + defaultSecPolicyMap := defaultSecPolicyList[0].(map[string]interface{}) + + versionID, ok := defaultSecPolicyMap["version_id"].(int) + if !ok || versionID == 0 { + return diag.Errorf("version_id not found in default_security_policy for access group %s", d.Id()) + } + + updateReq := defsecpolicies.UpdateRequest{ + AccessGroupID: d.Id(), + VersionID: uint64(versionID), + } + + if defaultAclDrop, ok := defaultSecPolicyMap["default_acl_drop"].(string); ok && defaultAclDrop != "" { + updateReq.DefaultACLDrop = defaultAclDrop + } + + if defaultOpenSessionDrop, ok := defaultSecPolicyMap["default_open_session_drop"].(bool); ok { + updateReq.DefaultOpenSessionDrop = defaultOpenSessionDrop + } + + _, err = c.SDN().DefaultSecurityPolicies().Update(ctx, updateReq) + if err != nil { + return diag.FromErr(err) + } + } + } + } + + return resourceAccessGroupRead(ctx, d, m) +} + +func resourceAccessGroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccessGroupDelete: called access group with id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + req := acsgroups.DeleteRequest{ + GroupID: d.Id(), + } + + _, err := c.SDN().AccessGroups().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceAccessGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceAccessGroupCreate, + ReadContext: resourceAccessGroupRead, + UpdateContext: resourceAccessGroupUpdate, + DeleteContext: resourceAccessGroupDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceAccessGroupSchemaMake(), + } +} diff --git a/internal/service/sdn/access_group/schema.go b/internal/service/sdn/access_group/schema.go new file mode 100644 index 00000000..4791e679 --- /dev/null +++ b/internal/service/sdn/access_group/schema.go @@ -0,0 +1,393 @@ +package accessgroup + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceAccessGroupListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "per_page": { + Type: schema.TypeInt, + Optional: true, + Description: "Items per page", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"display_name", "created_at", "updated_at", "deleted_at", "owner_login"}, false), + Description: "sort by one of supported fields", + }, + "sort_order": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"asc", "desc"}, false), + Description: "sort order", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: "filter by enabled/disabled group", + }, + "deleted": { + Type: schema.TypeBool, + Optional: true, + Description: "filter by deleted/not deleted group", + }, + "display_name": { + Type: schema.TypeString, + Optional: true, + Description: "filter by display name", + }, + "created_from": { + Type: schema.TypeString, + Optional: true, + Description: "filter by the lower limit of the creation date", + }, + "created_to": { + Type: schema.TypeString, + Optional: true, + Description: "filter by the upper limit of the creation date", + }, + "owner_display_name": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "List of access groups", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name", + }, + "comment": { + Type: schema.TypeString, + Computed: true, + Description: "Comment description", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation timestamp", + }, + "net_object_access_group": { + Type: schema.TypeList, + Computed: true, + Description: "Net object access group configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Access group ID", + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version identifier", + }, + }, + }, + }, + "default_security_policy": { + Type: schema.TypeList, + Computed: true, + Description: "Default security policy configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Policy display name", + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Policy unique identifier", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Policy description", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Policy version identifier", + }, + "access_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Policy access group ID", + }, + "default_acl_drop": { + Type: schema.TypeString, + Computed: true, + Description: "Default ACL drop action", + }, + "default_open_session_drop": { + Type: schema.TypeBool, + Computed: true, + Description: "Default open session drop flag", + }, + }, + }, + }, + }, + }, + }, + } + + return res +} + +func dataSourceAccessGroupUserListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Required: true, + Description: "filter by access group id", + }, + "global_role": { + Type: schema.TypeString, + Optional: true, + Description: "filter by global role", + }, + "access_group_role": { + Type: schema.TypeString, + Optional: true, + Description: "filter by access group role", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: "filter by inclusion", + }, + "deleted": { + Type: schema.TypeBool, + Optional: true, + Description: "delete filter", + }, + "display_name": { + Type: schema.TypeString, + Optional: true, + Description: "filter by display name", + }, + "login": { + Type: schema.TypeString, + Optional: true, + Description: "filter by user login", + }, + "created_by": { + Type: schema.TypeString, + Optional: true, + Description: "who created the user", + }, + "deleted_by": { + Type: schema.TypeString, + Optional: true, + Description: "who deleted the user", + }, + "disabled_by": { + Type: schema.TypeString, + Optional: true, + Description: "who disabled the user", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "result page number", + }, + "per_page": { + Type: schema.TypeInt, + Optional: true, + Description: "number of results per page", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"display_name", "email", "phone", "created_at", "updated_at", "deleted_at"}, false), + Description: "sort by one of supported fields", + }, + "sort_order": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"asc", "desc"}, false), + Description: "sorting order", + }, + "created_from": { + Type: schema.TypeString, + Optional: true, + Description: "filter by the lower limit of the creation date", + }, + "created_to": { + Type: schema.TypeString, + Optional: true, + Description: "filter by the upper limit of the creation date", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "List of users", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name", + }, + "role_id": { + Type: schema.TypeString, + Computed: true, + Description: "Role identifier", + }, + "login": { + Type: schema.TypeString, + Computed: true, + Description: "Login", + }, + }, + }, + }, + } + + return res +} + +func resourceAccessGroupSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Required: true, + Description: "group name", + }, + "comment": { + Type: schema.TypeString, + Required: true, + Description: "description (comment) of the group", + }, + "users": { + Type: schema.TypeList, + Optional: true, + Description: "managing users who are part of a group", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_role_id": { + Type: schema.TypeString, + Required: true, + Description: "id of the assigned role", + }, + "user_id": { + Type: schema.TypeString, + Required: true, + Description: "user ID", + }, + }, + }, + }, + "default_security_policy": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Description: "Default security policy configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "default_acl_drop": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Default ACL drop action", + }, + "default_open_session_drop": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Default open session drop flag", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Policy display name", + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Policy unique identifier", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Policy description", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Policy version identifier", + }, + "access_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Policy access group ID", + }, + }, + }, + }, + // Computed fields + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation timestamp", + }, + "net_object_access_group": { + Type: schema.TypeList, + Computed: true, + Description: "Net object access group configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Access group ID", + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version identifier", + }, + }, + }, + }, + } + + return res +} diff --git a/internal/service/sdn/access_group/utility_access_group.go b/internal/service/sdn/access_group/utility_access_group.go new file mode 100644 index 00000000..d8d97677 --- /dev/null +++ b/internal/service/sdn/access_group/utility_access_group.go @@ -0,0 +1,43 @@ +package accessgroup + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/acsgroups" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityAccessGroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*acsgroups.AccessGroup, error) { + c := m.(*controller.ControllerCfg) + + req := acsgroups.GetGroupRequest{} + + if d.Id() != "" { + req.GroupID = d.Id() + } else { + req.GroupID = d.Get("access_group_id").(string) + } + + accessGroup, err := c.SDN().AccessGroups().Get(ctx, req) + if err != nil { + return nil, err + } + + return accessGroup, nil +} + +func utilityAccessGroupUsersGet(ctx context.Context, groupID string, m interface{}) (*acsgroups.UsersList, error) { + c := m.(*controller.ControllerCfg) + + req := acsgroups.UsersListRequest{ + AccessGroupID: groupID, + } + + userList, err := c.SDN().AccessGroups().UsersList(ctx, req) + if err != nil { + return nil, err + } + + return userList, nil +} diff --git a/internal/service/sdn/access_group/utility_access_group_list.go b/internal/service/sdn/access_group/utility_access_group_list.go new file mode 100644 index 00000000..bfd93f26 --- /dev/null +++ b/internal/service/sdn/access_group/utility_access_group_list.go @@ -0,0 +1,54 @@ +package accessgroup + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/acsgroups" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityAccessGroupListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*acsgroups.AccessGroupList, error) { + c := m.(*controller.ControllerCfg) + req := acsgroups.ListGroupsRequest{} + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if perPage, ok := d.GetOk("per_page"); ok { + req.PerPage = uint64(perPage.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if sortOrder, ok := d.GetOk("sort_order"); ok { + req.SortOrder = sortOrder.(string) + } + if enabled, ok := d.GetOk("enabled"); ok { + req.Enabled = enabled.(bool) + } + if deleted, ok := d.GetOk("deleted"); ok { + req.Deleted = deleted.(bool) + } + if displayName, ok := d.GetOk("display_name"); ok { + req.DisplayName = displayName.(string) + } + if createdFrom, ok := d.GetOk("created_from"); ok { + req.CreatedFrom = createdFrom.(string) + } + if createdTo, ok := d.GetOk("created_to"); ok { + req.CreatedTo = createdTo.(string) + } + if ownerDisplayName, ok := d.GetOk("owner_display_name"); ok { + req.OwnerDisplayName = ownerDisplayName.(string) + } + + log.Debugf("utilityAccessGroupListCheckPresence") + accessGroupList, err := c.SDN().AccessGroups().List(ctx, req) + if err != nil { + return nil, err + } + + return accessGroupList, nil +} diff --git a/internal/service/sdn/access_group/utility_access_group_user_list.go b/internal/service/sdn/access_group/utility_access_group_user_list.go new file mode 100644 index 00000000..83567cf7 --- /dev/null +++ b/internal/service/sdn/access_group/utility_access_group_user_list.go @@ -0,0 +1,74 @@ +package accessgroup + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/acsgroups" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityAccessGroupUserListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*acsgroups.UsersList, error) { + c := m.(*controller.ControllerCfg) + req := acsgroups.UsersListRequest{} + + req.AccessGroupID = d.Get("access_group_id").(string) + + if globalRole, ok := d.GetOk("global_role"); ok { + req.GlobalRole = globalRole.(string) + } + if accessGroupRole, ok := d.GetOk("access_group_role"); ok { + req.AccessGroupRole = accessGroupRole.(string) + } + if enabled, ok := d.GetOk("enabled"); ok { + req.Enabled = enabled.(bool) + } + if deleted, ok := d.GetOk("deleted"); ok { + req.Deleted = deleted.(bool) + } + if displayName, ok := d.GetOk("display_name"); ok { + req.DisplayName = displayName.(string) + } + if login, ok := d.GetOk("login"); ok { + req.Login = login.(string) + } + if createdBy, ok := d.GetOk("created_by"); ok { + req.CreatedBy = createdBy.(string) + } + if updatedBy, ok := d.GetOk("updated_by"); ok { + req.UpdatedBy = updatedBy.(string) + } + if deletedBy, ok := d.GetOk("deleted_by"); ok { + req.DeletedBy = deletedBy.(string) + } + if disabledBy, ok := d.GetOk("disabled_by"); ok { + req.DisabledBy = disabledBy.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if perPage, ok := d.GetOk("per_page"); ok { + req.PerPage = uint64(perPage.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if sortOrder, ok := d.GetOk("sort_order"); ok { + req.SortOrder = sortOrder.(string) + } + if createdFrom, ok := d.GetOk("created_from"); ok { + req.CreatedFrom = createdFrom.(string) + } + if createdTo, ok := d.GetOk("created_to"); ok { + req.CreatedTo = createdTo.(string) + } + + log.Debugf("utilityAccessGroupUserListCheckPresence") + userList, err := c.SDN().AccessGroups().UsersList(ctx, req) + if err != nil { + return nil, err + } + + return userList, nil +} diff --git a/internal/service/sdn/default_security_policy/data_decort_sdn_default_security_policy_list.go b/internal/service/sdn/default_security_policy/data_decort_sdn_default_security_policy_list.go new file mode 100644 index 00000000..44758639 --- /dev/null +++ b/internal/service/sdn/default_security_policy/data_decort_sdn_default_security_policy_list.go @@ -0,0 +1,40 @@ +package defaultsecuritypolicy + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceDefaultSecurityPolicyListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + defaultSecurityPolicyList, err := utilityDefaultSecurityPolicyListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDefaultSecurityPolicyList(defaultSecurityPolicyList)) + + return nil +} + +func DataSourceDefaultSecurityPolicyList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceDefaultSecurityPolicyListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceDefaultSecurityPolicyListSchemaMake(), + } +} + diff --git a/internal/service/sdn/default_security_policy/flattens.go b/internal/service/sdn/default_security_policy/flattens.go new file mode 100644 index 00000000..d13f91da --- /dev/null +++ b/internal/service/sdn/default_security_policy/flattens.go @@ -0,0 +1,130 @@ +package defaultsecuritypolicy + +import ( + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/defsecpolicies" +) + +func flattenDefaultSecurityPolicyList(policyList *defsecpolicies.SecurityPoliciesList) []map[string]interface{} { + if policyList == nil { + return []map[string]interface{}{} + } + res := make([]map[string]interface{}, 0, len(policyList.Policies)) + for _, v := range policyList.Policies { + temp := map[string]interface{}{ + "access_group_id": v.AccessGroupID, + "created_at": v.CreatedAt, + "default_acl_drop": v.DefaultACLDrop, + "default_open_session_drop": v.DefaultOpenSessionDrop, + "description": v.Description, + "display_name": v.DisplayName, + "id": v.ID, + "security_rules": flattenSecurityRules(v.SecurityRules), + "locked_at": v.LockedAt, + "status": flattenStatus(v.Status), + "version_id": int(v.VersionID), + } + res = append(res, temp) + } + return res +} + +func flattenSecurityRules(rules []defsecpolicies.SecurityRule) []map[string]interface{} { + if rules == nil { + return []map[string]interface{}{} + } + res := make([]map[string]interface{}, 0, len(rules)) + for _, v := range rules { + temp := map[string]interface{}{ + "access_group_id": v.AccessGroupID, + "action": v.Action, + "description": v.Description, + "destination_net_object": flattenNetObject(v.DestinationNetObject), + "direction": v.Direction, + "display_name": v.DisplayName, + "enabled": v.Enabled, + "filter": flattenFilter(v.Filter), + "id": v.ID, + "log_enabled": v.LogEnabled, + "log_name": v.LogName, + "log_severity": v.LogSeverity, + "priority": v.Priority, + "security_policy_id": v.SecurityPolicyID, + "source_net_object": flattenNetObject(v.SourceNetObject), + "statistics_enabled": v.StatisticsEnabled, + "version_id": int(v.VersionID), + } + res = append(res, temp) + } + return res +} + +func flattenNetObject(netObj defsecpolicies.NetObject) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "display_name": netObj.DisplayName, + "net_address_pool_id": netObj.NetAddressPoolID, + "net_object_group_id": netObj.NetObjectGroupID, + } + res = append(res, temp) + return res +} + +func flattenFilter(filter defsecpolicies.Filter) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "filters": flattenFilterParams(filter.Filters), + "name": filter.Name, + } + res = append(res, temp) + return res +} + +func flattenFilterParams(params defsecpolicies.FilterParams) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "all": params.All, + "arp": params.ARP, + "dhcp": params.DHCP, + "expression": params.Expression, + "icmp": params.ICMP, + "ip": params.IP, + "ip_v4": params.IPv4, + "ip_v6": params.IPv6, + "keep_opened_sessions": params.KeepOpenedSessions, + "nd": params.ND, + "tcp": params.TCP, + "tcp_dst_ports": params.TCPDstPorts, + "udp": params.UDP, + "udp_dst_ports": params.UDPDstPorts, + } + res = append(res, temp) + return res +} + +func flattenStatus(status defsecpolicies.Status) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "common": status.Common, + "hypervisors": flattenHypervisorStatuses(status.Hypervisors), + } + res = append(res, temp) + return res +} + +func flattenHypervisorStatuses(hypervisors []defsecpolicies.HypervisorStatus) []map[string]interface{} { + if hypervisors == nil { + return []map[string]interface{}{} + } + res := make([]map[string]interface{}, 0, len(hypervisors)) + for _, v := range hypervisors { + temp := map[string]interface{}{ + "status": v.Status, + "name": v.Name, + "display_name": v.DisplayName, + "hypervisor_status": v.HypervisorStatus, + "synced_at": v.SyncedAt, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/sdn/default_security_policy/schema.go b/internal/service/sdn/default_security_policy/schema.go new file mode 100644 index 00000000..daabaf8a --- /dev/null +++ b/internal/service/sdn/default_security_policy/schema.go @@ -0,0 +1,369 @@ +package defaultsecuritypolicy + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceDefaultSecurityPolicyListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Optional: true, + Description: "id of the access group", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "result page number", + }, + "per_page": { + Type: schema.TypeInt, + Optional: true, + Description: "number of results per page", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"created_at", "updated_at"}, false), + Description: "sort by one of the supported fields", + }, + "sort_order": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"asc", "desc"}, false), + Description: "sorting order", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "List of default security policies", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Access group ID", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation timestamp", + }, + "default_acl_drop": { + Type: schema.TypeString, + Computed: true, + Description: "Default ACL drop action", + }, + "default_open_session_drop": { + Type: schema.TypeBool, + Computed: true, + Description: "Default open session drop flag", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name", + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier", + }, + "security_rules": { + Type: schema.TypeList, + Computed: true, + Description: "Security rules", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Access group ID", + }, + "action": { + Type: schema.TypeString, + Computed: true, + Description: "Action", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description", + }, + "destination_net_object": { + Type: schema.TypeList, + Computed: true, + Description: "Destination network object", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name", + }, + "net_address_pool_id": { + Type: schema.TypeString, + Computed: true, + Description: "Network address pool ID", + }, + "net_object_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Network object group ID", + }, + }, + }, + }, + "direction": { + Type: schema.TypeString, + Computed: true, + Description: "Direction", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name", + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Enabled flag", + }, + "filter": { + Type: schema.TypeList, + Computed: true, + Description: "Filter configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "filters": { + Type: schema.TypeList, + Computed: true, + Description: "Filter parameters", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "all": { + Type: schema.TypeBool, + Computed: true, + Description: "All protocols flag", + }, + "arp": { + Type: schema.TypeBool, + Computed: true, + Description: "ARP protocol flag", + }, + "dhcp": { + Type: schema.TypeBool, + Computed: true, + Description: "DHCP protocol flag", + }, + "expression": { + Type: schema.TypeString, + Computed: true, + Description: "Filter expression", + }, + "icmp": { + Type: schema.TypeBool, + Computed: true, + Description: "ICMP protocol flag", + }, + "ip": { + Type: schema.TypeBool, + Computed: true, + Description: "IP protocol flag", + }, + "ip_v4": { + Type: schema.TypeBool, + Computed: true, + Description: "IPv4 protocol flag", + }, + "ip_v6": { + Type: schema.TypeBool, + Computed: true, + Description: "IPv6 protocol flag", + }, + "keep_opened_sessions": { + Type: schema.TypeBool, + Computed: true, + Description: "Keep opened sessions flag", + }, + "nd": { + Type: schema.TypeBool, + Computed: true, + Description: "ND protocol flag", + }, + "tcp": { + Type: schema.TypeBool, + Computed: true, + Description: "TCP protocol flag", + }, + "tcp_dst_ports": { + Type: schema.TypeList, + Computed: true, + Description: "TCP destination ports", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "udp": { + Type: schema.TypeBool, + Computed: true, + Description: "UDP protocol flag", + }, + "udp_dst_ports": { + Type: schema.TypeList, + Computed: true, + Description: "UDP destination ports", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Filter name", + }, + }, + }, + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier", + }, + "log_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Log enabled flag", + }, + "log_name": { + Type: schema.TypeString, + Computed: true, + Description: "Log name", + }, + "log_severity": { + Type: schema.TypeString, + Computed: true, + Description: "Log severity", + }, + "priority": { + Type: schema.TypeInt, + Computed: true, + Description: "Priority", + }, + "security_policy_id": { + Type: schema.TypeString, + Computed: true, + Description: "Security policy ID", + }, + "source_net_object": { + Type: schema.TypeList, + Computed: true, + Description: "Source network object", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name", + }, + "net_address_pool_id": { + Type: schema.TypeString, + Computed: true, + Description: "Network address pool ID", + }, + "net_object_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Network object group ID", + }, + }, + }, + }, + "statistics_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Statistics enabled flag", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version ID", + }, + }, + }, + }, + "locked_at": { + Type: schema.TypeString, + Computed: true, + Description: "Locked timestamp", + }, + "status": { + Type: schema.TypeList, + Computed: true, + Description: "Status information", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "common": { + Type: schema.TypeString, + Computed: true, + Description: "Common status", + }, + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Description: "Hypervisor statuses", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Status", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name", + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + Description: "Hypervisor status", + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + Description: "Last sync timestamp", + }, + }, + }, + }, + }, + }, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version ID", + }, + }, + }, + }, + } + + return res +} + diff --git a/internal/service/sdn/default_security_policy/utility_default_security_policy_list.go b/internal/service/sdn/default_security_policy/utility_default_security_policy_list.go new file mode 100644 index 00000000..5cf41070 --- /dev/null +++ b/internal/service/sdn/default_security_policy/utility_default_security_policy_list.go @@ -0,0 +1,40 @@ +package defaultsecuritypolicy + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/defsecpolicies" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDefaultSecurityPolicyListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*defsecpolicies.SecurityPoliciesList, error) { + c := m.(*controller.ControllerCfg) + req := defsecpolicies.ListRequest{} + + if accessGroupID, ok := d.GetOk("access_group_id"); ok { + req.AccessGroupID = accessGroupID.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if perPage, ok := d.GetOk("per_page"); ok { + req.PerPage = uint64(perPage.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if sortOrder, ok := d.GetOk("sort_order"); ok { + req.SortOrder = sortOrder.(string) + } + + log.Debugf("utilityDefaultSecurityPolicyListCheckPresence") + defaultSecurityPolicyList, err := c.SDN().DefaultSecurityPolicies().List(ctx, req) + if err != nil { + return nil, err + } + + return defaultSecurityPolicyList, nil +} + diff --git a/internal/service/sdn/hypervisors/data_decort_sdn_hypervisor.go b/internal/service/sdn/hypervisors/data_decort_sdn_hypervisor.go new file mode 100644 index 00000000..f48b8f83 --- /dev/null +++ b/internal/service/sdn/hypervisors/data_decort_sdn_hypervisor.go @@ -0,0 +1,36 @@ +package hypervisors + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceHypervisorRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + hypervisor, err := utilityHypervisorCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenHypervisorDataSource(d, hypervisor) + d.SetId(hypervisor.Name) + return nil +} + +func DataSourceHypervisor() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceHypervisorRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceHypervisorSchemaMake(), + } +} diff --git a/internal/service/sdn/hypervisors/data_decort_sdn_hypervisor_list.go b/internal/service/sdn/hypervisors/data_decort_sdn_hypervisor_list.go new file mode 100644 index 00000000..2090fbd0 --- /dev/null +++ b/internal/service/sdn/hypervisors/data_decort_sdn_hypervisor_list.go @@ -0,0 +1,38 @@ +package hypervisors + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceHypervisorListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + hypervisorList, err := utilityHypervisorListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenHypervisorListDataSource(hypervisorList)) + return nil +} + +func DataSourceHypervisorList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceHypervisorListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceHypervisorListSchemaMake(), + } +} diff --git a/internal/service/sdn/hypervisors/flattens.go b/internal/service/sdn/hypervisors/flattens.go new file mode 100644 index 00000000..040189ef --- /dev/null +++ b/internal/service/sdn/hypervisors/flattens.go @@ -0,0 +1,75 @@ +package hypervisors + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/hypervisors" +) + +func flattenHypervisorResource(d *schema.ResourceData, hypervisor *hypervisors.RecordHypervisor) { + d.Set("display_name", hypervisor.DisplayName) + d.Set("hostname", hypervisor.Hostname) + d.Set("ip", hypervisor.IP) + d.Set("name", hypervisor.Name) + d.Set("ports", flattenPorts(hypervisor.Ports)) + d.Set("status", hypervisor.Status) + d.Set("created_at", hypervisor.CreatedAt) + d.Set("synced_at", hypervisor.SyncedAt) +} + +func flattenHypervisorListDataSource(hypervisorList hypervisors.HypervisorsList) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(hypervisorList)) + for _, v := range hypervisorList { + temp := map[string]interface{}{ + "display_name": v.DisplayName, + "hostname": v.Hostname, + "ip": v.IP, + "name": v.Name, + "ports": flattenPorts(v.Ports), + "status": v.Status, + "created_at": v.CreatedAt, + "synced_at": v.SyncedAt, + } + res = append(res, temp) + } + return res +} + +func flattenHypervisorDataSource(d *schema.ResourceData, hypervisor *hypervisors.RecordHypervisor) { + d.Set("display_name", hypervisor.DisplayName) + d.Set("hostname", hypervisor.Hostname) + d.Set("ip", hypervisor.IP) + d.Set("name", hypervisor.Name) + d.Set("ports", flattenPorts(hypervisor.Ports)) + d.Set("status", hypervisor.Status) + d.Set("created_at", hypervisor.CreatedAt) + d.Set("synced_at", hypervisor.SyncedAt) +} + +func flattenPorts(ports hypervisors.Ports) []map[string]interface{} { + final := make([]map[string]interface{}, 0) + + res := map[string]interface{}{} + + data := make([]map[string]interface{}, 0) + info := map[string]interface{}{} + + for _, v := range ports.Data { + temp := map[string]interface{}{ + "id": v.ID, + "unique_identifier": v.UniqueIdentifier, + "display_name": v.DisplayName, + "up": v.UP, + } + data = append(data, temp) + } + + info["active_ports"] = ports.Info.ActivePorts + info["total_ports"] = ports.Info.TotalPorts + + res["data"] = data + res["info"] = []interface{}{info} + + final = append(final, res) + + return final +} diff --git a/internal/service/sdn/hypervisors/resource_hypervisor.go b/internal/service/sdn/hypervisors/resource_hypervisor.go new file mode 100644 index 00000000..7a87a002 --- /dev/null +++ b/internal/service/sdn/hypervisors/resource_hypervisor.go @@ -0,0 +1,87 @@ +package hypervisors + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/hypervisors" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceHypervisorCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + return diag.Errorf( + "It's impossible to create a hypervisor from terraform") +} + +func resourceHypervisorRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + hypervisor, err := utilityHypervisorCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenHypervisorResource(d, hypervisor) + d.SetId(hypervisor.Name) + + return nil +} + +func resourceHypervisorUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + req := hypervisors.UpdateDisplayNameRequest{ + Name: d.Get("name").(string), + DisplayName: d.Get("display_name").(string), + } + + _, err := c.SDN().Hypervisors().UpdateDisplayName(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + return resourceHypervisorRead(ctx, d, m) +} + +func resourceHypervisorDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) + + req := hypervisors.DeleteRequest{ + Name: d.Get("name").(string), + } + + _, err := c.SDN().Hypervisors().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceHypervisor() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceHypervisorCreate, + ReadContext: resourceHypervisorRead, + UpdateContext: resourceHypervisorUpdate, + DeleteContext: resourceHypervisorDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceHypervisorSchemaMake(), + } +} diff --git a/internal/service/sdn/hypervisors/schema.go b/internal/service/sdn/hypervisors/schema.go new file mode 100644 index 00000000..3ded6bda --- /dev/null +++ b/internal/service/sdn/hypervisors/schema.go @@ -0,0 +1,320 @@ +package hypervisors + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceHypervisorSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "display_name": { + Type: schema.TypeString, + Required: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "ports": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "data": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "unique_identifier": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "up": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "active_ports": { + Type: schema.TypeInt, + Computed: true, + }, + "total_ports": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + }, + } + return res +} + +func dataSourceHypervisorListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "per_page": { + Type: schema.TypeInt, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"name", "hostname", "last_sync", + "display_name", "ip", "created_at", "updated_at"}, false), + }, + "sort_order": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"asc", "desc"}, false), + }, + "port_info": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"detailed", "general"}, false), + }, + "hostname": { + Type: schema.TypeString, + Optional: true, + }, + "display_name": { + Type: schema.TypeString, + Optional: true, + }, + "ip": { + Type: schema.TypeString, + Optional: true, + }, + "created_from": { + Type: schema.TypeString, + Optional: true, + }, + "created_to": { + Type: schema.TypeString, + Optional: true, + }, + "updated_from": { + Type: schema.TypeString, + Optional: true, + }, + "updated_to": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "List of hypervisors", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "ports": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "data": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "unique_identifier": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "up": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "active_ports": { + Type: schema.TypeInt, + Computed: true, + }, + "total_ports": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + } + + return res +} + +func dataSourceHypervisorSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "port_info": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"detailed", "general"}, false), + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "ports": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "data": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "unique_identifier": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "up": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "active_ports": { + Type: schema.TypeInt, + Computed: true, + }, + "total_ports": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + }, + } + + return res +} diff --git a/internal/service/sdn/hypervisors/utility_sdn_hypervisor.go b/internal/service/sdn/hypervisors/utility_sdn_hypervisor.go new file mode 100644 index 00000000..7d10d467 --- /dev/null +++ b/internal/service/sdn/hypervisors/utility_sdn_hypervisor.go @@ -0,0 +1,32 @@ +package hypervisors + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/hypervisors" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityHypervisorCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*hypervisors.RecordHypervisor, error) { + c := m.(*controller.ControllerCfg) + + req := hypervisors.GetRequest{} + + if d.Id() != "" { + req.Name = d.Id() + } else { + req.Name = d.Get("name").(string) + } + + if portInfo, ok := d.GetOk("port_info"); ok { + req.PortInfo = portInfo.(string) + } + + hypervisor, err := c.SDN().Hypervisors().Get(ctx, req) + if err != nil { + return nil, err + } + + return hypervisor, nil +} diff --git a/internal/service/sdn/hypervisors/utility_sdn_hypervisor_list.go b/internal/service/sdn/hypervisors/utility_sdn_hypervisor_list.go new file mode 100644 index 00000000..1280a0e2 --- /dev/null +++ b/internal/service/sdn/hypervisors/utility_sdn_hypervisor_list.go @@ -0,0 +1,69 @@ +package hypervisors + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/hypervisors" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityHypervisorListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (hypervisors.HypervisorsList, error) { + c := m.(*controller.ControllerCfg) + req := hypervisors.ListRequest{} + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + + if perPage, ok := d.GetOk("per_page"); ok { + req.PerPage = uint64(perPage.(int)) + } + + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + + if sortOrder, ok := d.GetOk("sort_order"); ok { + req.SortOrder = sortOrder.(string) + } + + if portInfo, ok := d.GetOk("port_info"); ok { + req.PortInfo = portInfo.(string) + } + + if hostname, ok := d.GetOk("hostname"); ok { + req.Hostname = hostname.(string) + } + + if displayName, ok := d.GetOk("display_name"); ok { + req.DisplayName = displayName.(string) + } + + if ip, ok := d.GetOk("ip"); ok { + req.IP = ip.(string) + } + + if createdFrom, ok := d.GetOk("created_from"); ok { + req.CreatedFrom = createdFrom.(string) + } + + if createdTo, ok := d.GetOk("created_to"); ok { + req.CreatedTo = createdTo.(string) + } + + if updatedFrom, ok := d.GetOk("updated_from"); ok { + req.UpdatedFrom = updatedFrom.(string) + } + + if updatedTo, ok := d.GetOk("updated_to"); ok { + req.UpdatedTo = updatedTo.(string) + } + + hypervisorList, err := c.SDN().Hypervisors().List(ctx, req) + if err != nil { + return nil, err + } + + return hypervisorList, nil +} diff --git a/internal/service/sdn/logicalports/data_source_logical_port.go b/internal/service/sdn/logicalports/data_source_logical_port.go new file mode 100644 index 00000000..c22d52ce --- /dev/null +++ b/internal/service/sdn/logicalports/data_source_logical_port.go @@ -0,0 +1,36 @@ +package logicalports + +import ( + "context" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceLogicalPortRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + logicalPort, err := utilityLogicalPortCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenLogicalPort(d, logicalPort) + d.SetId(logicalPort.ID) + return nil +} + +func DataSourceLogicalPort() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLogicalPortRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: dataSourceLogicalPortSchemaMake(), + } +} diff --git a/internal/service/sdn/logicalports/data_source_logical_port_by_unique_id.go b/internal/service/sdn/logicalports/data_source_logical_port_by_unique_id.go new file mode 100644 index 00000000..700fec07 --- /dev/null +++ b/internal/service/sdn/logicalports/data_source_logical_port_by_unique_id.go @@ -0,0 +1,35 @@ +package logicalports + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceLogicalPortByUniqueIDRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + logicalPort, err := utilityLogicalPortByUniqueIDCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenLogicalPort(d, logicalPort) + d.SetId(logicalPort.ID) + return nil +} + +func DataSourceLogicalPortByUniqueID() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLogicalPortByUniqueIDRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: dataSourceLogicalPortByUniqueIDSchemaMake(), + } +} diff --git a/internal/service/sdn/logicalports/data_source_logical_port_list.go b/internal/service/sdn/logicalports/data_source_logical_port_list.go new file mode 100644 index 00000000..4a570699 --- /dev/null +++ b/internal/service/sdn/logicalports/data_source_logical_port_list.go @@ -0,0 +1,39 @@ +package logicalports + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceLogicalPortListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + logicalPortList, err := utilityLogicalPortListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenLogicalPortList(logicalPortList)) + + return nil +} + +func DataSourceLogicalPortList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceLogicalPortListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceLogicalPortListSchemaMake(), + } +} diff --git a/internal/service/sdn/logicalports/flattens.go b/internal/service/sdn/logicalports/flattens.go new file mode 100644 index 00000000..da6f5227 --- /dev/null +++ b/internal/service/sdn/logicalports/flattens.go @@ -0,0 +1,150 @@ +package logicalports + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports" +) + +func flattenLogicalPortResource(d *schema.ResourceData, logicalPort *logicalports.LogicalPort) { + d.Set("id", logicalPort.ID) + d.Set("access_group_id", logicalPort.AccessGroupID) + d.Set("access_group_name", logicalPort.AccessGroupName) + d.Set("adapter_mac", logicalPort.AdapterMAC) + d.Set("address_detection", logicalPort.AddressDetection) + d.Set("description", logicalPort.Description) + d.Set("display_name", logicalPort.DisplayName) + d.Set("enabled", logicalPort.Enabled) + d.Set("external_network_id", logicalPort.ExternalNetworkID) + d.Set("hypervisor", logicalPort.Hypervisor) + d.Set("hypervisor_display_name", logicalPort.HypervisorDisplayName) + d.Set("live_migration_target_hv", logicalPort.LiveMigrationTargetHV) + d.Set("status", flattenStatus(logicalPort.Status)) + d.Set("unique_identifier", logicalPort.UniqueIdentifier) + d.Set("version_id", logicalPort.VersionID) + d.Set("bindings", flattenBindings(logicalPort.Bindings)) + d.Set("labels", flattenLabels(logicalPort.Labels)) + d.Set("created_at", logicalPort.CreatedAt) +} + +func flattenLogicalPortList(lpl *logicalports.LogicalPortsList) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(lpl.Ports)) + for _, v := range lpl.Ports { + temp := map[string]interface{}{ + "id": v.ID, + "access_group_id": v.AccessGroupID, + "access_group_name": v.AccessGroupName, + "adapter_mac": v.AdapterMAC, + "address_detection": v.AddressDetection, + "description": v.Description, + "display_name": v.DisplayName, + "enabled": v.Enabled, + "hypervisor": v.Hypervisor, + "hypervisor_display_name": v.HypervisorDisplayName, + "external_network_id": v.ExternalNetworkID, + "live_migration_target_hv": v.LiveMigrationTargetHV, + "status": flattenStatus(v.Status), + "unique_identifier": v.UniqueIdentifier, + "version_id": v.VersionID, + "bindings": flattenBindings(v.Bindings), + "labels": flattenLabels(v.Labels), + "created_at": v.CreatedAt, + "updated_at": v.UpdatedAt, + } + res = append(res, temp) + } + return res +} + +func flattenLogicalPort(d *schema.ResourceData, logicalPort *logicalports.LogicalPort) { + d.Set("id", logicalPort.ID) + d.Set("access_group_id", logicalPort.AccessGroupID) + d.Set("access_group_name", logicalPort.AccessGroupName) + d.Set("adapter_mac", logicalPort.AdapterMAC) + d.Set("address_detection", logicalPort.AddressDetection) + d.Set("description", logicalPort.Description) + d.Set("display_name", logicalPort.DisplayName) + d.Set("enabled", logicalPort.Enabled) + d.Set("external_network_id", logicalPort.ExternalNetworkID) + d.Set("hypervisor", logicalPort.Hypervisor) + d.Set("hypervisor_display_name", logicalPort.HypervisorDisplayName) + d.Set("live_migration_target_hv", logicalPort.LiveMigrationTargetHV) + d.Set("status", flattenStatus(logicalPort.Status)) + d.Set("unique_identifier", logicalPort.UniqueIdentifier) + d.Set("version_id", logicalPort.VersionID) + d.Set("bindings", flattenBindings(logicalPort.Bindings)) + d.Set("labels", flattenLabels(logicalPort.Labels)) + d.Set("created_at", logicalPort.CreatedAt) + d.Set("updated_at", logicalPort.UpdatedAt) +} + +func flattenLabels(labels logicalports.Labels) []map[string]interface{} { + if labels.VMID == "" && labels.VMName == "" { + return []map[string]interface{}{} + } + return []map[string]interface{}{ + { + "vm_id": labels.VMID, + "vm_name": labels.VMName, + }, + } +} + +func flattenBindings(bindings logicalports.Bindings) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "id": bindings.ID, + "segment_id": bindings.SegmentID, + "segment_display_name": bindings.SegmentDisplayName, + "port_security": bindings.PortSecurity, + "address_detection": bindings.AddressDetection, + "version_id": bindings.VersionID, + "created_at": bindings.CreatedAt, + "updated_at": bindings.UpdatedAt, + "logical_port_addresses": flattenLogicalPortAddresses(bindings.LogicalPortAddresses), + } + res = append(res, temp) + return res +} + +func flattenLogicalPortAddresses(addrs []logicalports.LogicalPortAddress) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(addrs)) + for _, a := range addrs { + res = append(res, map[string]interface{}{ + "ip": a.IP, + "ip_type": a.IPType, + "mac": a.MAC, + "id": a.ID, + "logical_port_id": a.LogicalPortID, + "assigned_at": a.AssignedAt, + "is_discovered": a.IsDiscovered, + "is_primary": a.IsPrimary, + }) + } + return res +} + +func flattenStatus(status logicalports.Status) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "operation_status": status.OperationStatus, + "hypervisor_status": status.HypervisorStatus, + "hypervisors": flattenHypervisors(status.Hypervisors), + } + res = append(res, temp) + return res +} + +func flattenHypervisors(hv []logicalports.HypervisorStatus) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(hv)) + for _, v := range hv { + temp := map[string]interface{}{ + "operation_status": v.OperationStatus, + "name": v.Name, + "display_name": v.DisplayName, + "hypervisor_status": v.HypervisorStatus, + "synced_at": v.SyncedAt, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/sdn/logicalports/resource_logical_port.go b/internal/service/sdn/logicalports/resource_logical_port.go new file mode 100644 index 00000000..2af9f31f --- /dev/null +++ b/internal/service/sdn/logicalports/resource_logical_port.go @@ -0,0 +1,283 @@ +package logicalports + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceLogicalPortCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLogicalPortCreate: called logical port with name %s", + d.Get("display_name").(string)) + c := m.(*controller.ControllerCfg) + + req := logicalports.CreateRequest{ + AccessGroupID: d.Get("access_group_id").(string), + Description: d.Get("description").(string), + DisplayName: d.Get("display_name").(string), + Enabled: d.Get("enabled").(bool), + Hypervisor: d.Get("hypervisor").(string), + PortSecurity: d.Get("port_security").(bool), + SegmentID: d.Get("segment_id").(string), + } + + if adapterMAC, ok := d.GetOk("adapter_mac"); ok { + req.AdapterMAC = adapterMAC.(string) + } + if uniqueID, ok := d.GetOk("unique_identifier"); ok { + req.UniqueIdentifier = uniqueID.(string) + } + if labelsRaw, ok := d.GetOk("labels"); ok { + labelsList := labelsRaw.([]interface{}) + if len(labelsList) > 0 { + labelsMap := labelsList[0].(map[string]interface{}) + req.Labels = logicalports.CreateLabels{ + VMID: labelsMap["vm_id"].(string), + VMName: labelsMap["vm_name"].(string), + } + } + } + if logicalPortAddresses, ok := d.GetOk("logical_port_addresses"); ok { + logicalPortAddressesList := logicalPortAddresses.([]interface{}) + logicalPortsAddressesArr := make([]logicalports.LogicalPortAddress, 0) + for _, logicalPortAddressRaw := range logicalPortAddressesList { + logicalPortAddressMap := logicalPortAddressRaw.(map[string]interface{}) + logicalPortAddress := logicalports.LogicalPortAddress{ + IP: logicalPortAddressMap["ip"].(string), + IPType: logicalPortAddressMap["ip_type"].(string), + IsPrimary: logicalPortAddressMap["is_primary"].(bool), + } + if isDiscovered, ok := logicalPortAddressMap["is_discovered"]; ok { + logicalPortAddress.IsDiscovered = isDiscovered.(bool) + } + if mac, ok := logicalPortAddressMap["mac"]; ok { + logicalPortAddress.MAC = mac.(string) + } + logicalPortsAddressesArr = append(logicalPortsAddressesArr, logicalPortAddress) + } + req.LogicalPortAddresses = logicalPortsAddressesArr + } + + logicalPort, err := c.SDN().LogicalPorts().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(logicalPort.ID) + + return resourceLogicalPortRead(ctx, d, m) +} + +func resourceLogicalPortRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLogicalPortRead: called logical port with id %s", d.Id()) + + logicalPort, err := utilityLogicalPortCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenLogicalPortResource(d, logicalPort) + d.SetId(logicalPort.ID) + + return nil +} + +func resourceLogicalPortUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLogicalPortUpdate: called logical port with id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + migrate := d.Get("migrate").(bool) + + req := logicalports.UpdateRequest{ + LogicalPortID: d.Id(), + VersionID: uint64(d.Get("version_id").(int)), + AdapterMAC: d.Get("adapter_mac").(string), + Description: d.Get("description").(string), + DisplayName: d.Get("display_name").(string), + Enabled: d.Get("enabled").(bool), + PortSecurity: d.Get("port_security").(bool), + SegmentID: d.Get("segment_id").(string), + } + + if !migrate { + req.Hypervisor = d.Get("hypervisor").(string) + } else { + old, _ := d.GetChange("hypervisor") + req.Hypervisor = old.(string) + } + + if d.HasChange("labels") { + if labelsRaw, ok := d.GetOk("labels"); ok { + labelsList := labelsRaw.([]interface{}) + if len(labelsList) > 0 { + labelsMap := labelsList[0].(map[string]interface{}) + req.Labels = logicalports.UpdateLabels{ + VMID: labelsMap["vm_id"].(string), + VMName: labelsMap["vm_name"].(string), + } + } + } + } + + if d.HasChange("logical_port_addresses") { + oldAddresses, newAddresses := d.GetChange("logical_port_addresses") + oldAddressesList := oldAddresses.([]interface{}) + newAddressesList := newAddresses.([]interface{}) + oldAddressesMap := make(map[string]logicalports.LogicalPortAddress) + for _, oldAddressRaw := range oldAddressesList { + logicalPortAddressMap := oldAddressRaw.(map[string]interface{}) + logicalPortAddress := logicalports.LogicalPortAddress{ + IP: logicalPortAddressMap["ip"].(string), + IPType: logicalPortAddressMap["ip_type"].(string), + IsPrimary: logicalPortAddressMap["is_primary"].(bool), + } + if isDiscovered, ok := logicalPortAddressMap["is_discovered"]; ok { + logicalPortAddress.IsDiscovered = isDiscovered.(bool) + } + if mac, ok := logicalPortAddressMap["mac"]; ok { + logicalPortAddress.MAC = mac.(string) + } + oldAddressesMap[logicalPortAddress.IP] = logicalPortAddress + } + newAddressesMap := make(map[string]logicalports.LogicalPortAddress) + for _, newAddressRaw := range newAddressesList { + logicalPortAddressMap := newAddressRaw.(map[string]interface{}) + logicalPortAddress := logicalports.LogicalPortAddress{ + IP: logicalPortAddressMap["ip"].(string), + IPType: logicalPortAddressMap["ip_type"].(string), + IsPrimary: logicalPortAddressMap["is_primary"].(bool), + } + if isDiscovered, ok := logicalPortAddressMap["is_discovered"]; ok { + logicalPortAddress.IsDiscovered = isDiscovered.(bool) + } + if mac, ok := logicalPortAddressMap["mac"]; ok { + logicalPortAddress.MAC = mac.(string) + } + newAddressesMap[logicalPortAddress.IP] = logicalPortAddress + } + + removeAddresses := make([]string, 0) + for addressIP := range oldAddressesMap { + if _, exists := newAddressesMap[addressIP]; !exists { + removeAddresses = append(removeAddresses, addressIP) + } + } + req.RemoveAddresses = removeAddresses + + for addressIP, address := range newAddressesMap { + if oldAddressIP, exists := oldAddressesMap[addressIP]; !exists || address != oldAddressIP { + if !exists { + logicalPortAddress := logicalports.AddAddress{ + IP: address.IP, + IPType: address.IPType, + IsPrimary: address.IsPrimary, + IsDiscovered: address.IsDiscovered, + MAC: address.MAC, + } + req.AddAddresses = append(req.AddAddresses, logicalPortAddress) + } else if address != oldAddressIP { + logicalPortAddress := logicalports.UpdateAddress{ + IP: address.IP, + IPType: address.IPType, + IsPrimary: address.IsPrimary, + IsDiscovered: address.IsDiscovered, + MAC: address.MAC, + } + req.UpdateAddresses = append(req.UpdateAddresses, logicalPortAddress) + } + } + } + + } + + _, err := c.SDN().LogicalPorts().Update(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + if migrate { + if targetHV, ok := d.GetOk("hypervisor"); ok { + // Re-read version_id + lp, err := utilityLogicalPortCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + migrateReq := logicalports.MigrateStartRequest{ + LogicalPortID: d.Id(), + VersionID: lp.VersionID, + TargetHypervisor: targetHV.(string), + } + + _, err = c.SDN().LogicalPorts().StartMigrate(ctx, migrateReq) + if err != nil { + return diag.FromErr(err) + } + // to prevent drift on the next plan + diags := resourceLogicalPortRead(ctx, d, m) + if diags.HasError() { + return diags + } + d.Set("hypervisor", targetHV.(string)) + return diags + } + } + + return resourceLogicalPortRead(ctx, d, m) +} + +func resourceLogicalPortDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceLogicalPortDelete: called logical port with id %s", d.Id()) + c := m.(*controller.ControllerCfg) + + req := logicalports.DeleteRequest{ + ID: d.Id(), + Version: uint64(d.Get("version_id").(int)), + } + + if force, ok := d.GetOk("force"); ok { + req.Force = force.(bool) + } + + _, err := c.SDN().LogicalPorts().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceLogicalPort() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceLogicalPortCreate, + ReadContext: resourceLogicalPortRead, + UpdateContext: resourceLogicalPortUpdate, + DeleteContext: resourceLogicalPortDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceLogicalPortSchemaMake(), + } +} diff --git a/internal/service/sdn/logicalports/schema.go b/internal/service/sdn/logicalports/schema.go new file mode 100644 index 00000000..b2715509 --- /dev/null +++ b/internal/service/sdn/logicalports/schema.go @@ -0,0 +1,1018 @@ +package logicalports + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func logicalPortAddressesSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "ip_type": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + "logical_port_id": { + Type: schema.TypeString, + Computed: true, + }, + "assigned_at": { + Type: schema.TypeString, + Computed: true, + }, + "is_discovered": { + Type: schema.TypeBool, + Computed: true, + }, + "is_primary": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + } +} + +func resourceLogicalPortSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Required: true, + Description: "Access Group ID", + }, + "description": { + Type: schema.TypeString, + Required: true, + Description: "Description", + }, + "display_name": { + Type: schema.TypeString, + Required: true, + Description: "Display Name", + }, + "enabled": { + Type: schema.TypeBool, + Required: true, + Description: "Whether the logical port should be enabled", + }, + "hypervisor": { + Type: schema.TypeString, + Required: true, + Description: "Hypervisor", + }, + "port_security": { + Type: schema.TypeBool, + Required: true, + Description: "Whether the port security is enabled", + }, + "segment_id": { + Type: schema.TypeString, + Required: true, + Description: "Segment ID", + }, + "adapter_mac": { + Type: schema.TypeString, + Optional: true, + Description: "Adapter MAC address", + }, + "unique_identifier": { + Type: schema.TypeString, + Optional: true, + Description: "Unique identifier of the logical port", + }, + "force": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "migrate": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If true, triggers live migration to the hypervisor specified in the 'hypervisor' field. If false, hypervisor changes are applied via the regular update endpoint.", + }, + "logical_port_addresses": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Required: true, + Description: "IP address of the logical port", + }, + "ip_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"IPv4", "IPv6"}, false), + }, + "is_primary": { + Type: schema.TypeBool, + Required: true, + }, + "is_discovered": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "mac": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the logical port", + }, + "access_group_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the access group", + }, + "address_detection": { + Type: schema.TypeBool, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "external_network_id": { + Type: schema.TypeString, + Computed: true, + }, + "hypervisor_display_name": { + Type: schema.TypeString, + Computed: true, + }, + "live_migration_target_hv": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + Description: "Operation status", + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + Description: "Hypervisor status", + }, + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + Description: "Operation status of the hypervisor", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the hypervisor", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the hypervisor", + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + Description: "Status of the hypervisor", + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + Description: "Sync time of the hypervisor", + }, + }, + }, + }, + }, + }, + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier of the binding", + }, + "segment_id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier of the segment", + }, + "segment_display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the segment", + }, + "port_security": { + Type: schema.TypeBool, + Computed: true, + Description: "If the port is secured", + }, + "address_detection": { + Type: schema.TypeBool, + Computed: true, + Description: "If the adapter address detection is enabled", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version ID of the binding", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation time of the binding", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "Update time of the binding", + }, + "logical_port_addresses": logicalPortAddressesSchema(), + }, + }, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version ID of the logical port", + }, + "labels": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vm_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "VM ID label", + }, + "vm_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "VM name label", + }, + }, + }, + Description: "Labels", + }, + } + return res +} + +func dataSourceLogicalPortListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Optional: true, + Description: "Access Group ID", + }, + "segment_id": { + Type: schema.TypeString, + Optional: true, + Description: "Segment ID", + }, + "segment_display_name": { + Type: schema.TypeString, + Optional: true, + Description: "Segment display name", + }, + "external_network_id": { + Type: schema.TypeString, + Optional: true, + Description: "External Network ID", + }, + "unique_identifier": { + Type: schema.TypeString, + Optional: true, + Description: "Unique identifier", + }, + "display_name": { + Type: schema.TypeString, + Optional: true, + Description: "Display name", + }, + "adapter_mac": { + Type: schema.TypeString, + Optional: true, + Description: "Adapter mac", + }, + "hypervisor": { + Type: schema.TypeString, + Optional: true, + Description: "Hypervisor", + }, + "hypervisor_display_name": { + Type: schema.TypeString, + Optional: true, + Description: "Hypervisor display name", + }, + "live_migration_target_hv": { + Type: schema.TypeString, + Optional: true, + Description: "Live migration target HV", + }, + "port_security": { + Type: schema.TypeBool, + Optional: true, + }, + "address_detection": { + Type: schema.TypeBool, + Optional: true, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + }, + "created_from": { + Type: schema.TypeString, + Optional: true, + }, + "created_to": { + Type: schema.TypeString, + Optional: true, + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "per_page": { + Type: schema.TypeInt, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"display_name", "created_at", "updated_at", + "deleted_at", "segment_id", "hypervisor", + "port_security", "segment_display_name", "primary_address", + "hypervisor_display_name"}, false), + }, + "sort_order": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"asc", "dec"}, false), + }, + "operation_status": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "Idle", "SynchronizingAtCore", "SynchronizingAtOVN", + "Synchronized", "NoHypervisorAtOVN", "FailedAtCore", "TemporaryFailedAtCore", + }, false), + Description: "Filter by operation status", + }, + "hypervisor_status": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"Up", "Warning", "Error"}, false), + Description: "Filter by hypervisor status", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the logical port to use", + }, + "access_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the access group", + }, + "access_group_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the access group", + }, + "adapter_mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address of the adapter", + }, + "address_detection": { + Type: schema.TypeBool, + Computed: true, + Description: "If the adapter address detection is enabled", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of the logical port", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the logical port", + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "If the logical port is enabled", + }, + "hypervisor": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the hypervisor", + }, + "hypervisor_display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the hypervisor", + }, + "external_network_id": { + Type: schema.TypeString, + Computed: true, + }, + "live_migration_target_hv": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + Description: "Operation status", + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + Description: "Hypervisor status", + }, + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + Description: "Operation status of the hypervisor", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the hypervisor", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the hypervisor", + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + Description: "Status of the hypervisor", + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + Description: "Sync time of the hypervisor", + }, + }, + }, + }, + }, + }, + }, + "unique_identifier": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier of the logical port", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version ID of the logical port", + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier of the binding", + }, + "segment_id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier of the segment", + }, + "segment_display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the segment", + }, + "port_security": { + Type: schema.TypeBool, + Computed: true, + Description: "If the port is secured", + }, + "address_detection": { + Type: schema.TypeBool, + Computed: true, + Description: "If the adapter address detection is enabled", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version ID of the binding", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation time of the binding", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "Update time of the binding", + }, + "logical_port_addresses": logicalPortAddressesSchema(), + }, + }, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation time of the logical port", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "Update time the logical port", + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vm_id": { + Type: schema.TypeString, + Computed: true, + Description: "VM ID label", + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + Description: "VM name label", + }, + }, + }, + Description: "Labels", + }, + }, + }, + }, + } + return res +} + +func dataSourceLogicalPortByUniqueIDSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "unique_identifier": { + Type: schema.TypeString, + Required: true, + Description: "Unique ID of the logical port to use", + }, + "access_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the access group", + }, + "access_group_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the access group", + }, + "adapter_mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address of the adapter", + }, + "address_detection": { + Type: schema.TypeBool, + Computed: true, + Description: "If the adapter address detection is enabled", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of the logical port", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the logical port", + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "If the logical port is enabled", + }, + "hypervisor": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the hypervisor", + }, + "hypervisor_display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the hypervisor", + }, + "external_network_id": { + Type: schema.TypeString, + Computed: true, + }, + "live_migration_target_hv": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + Description: "Operation status", + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + Description: "Hypervisor status", + }, + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + Description: "Operation status of the hypervisor", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the hypervisor", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the hypervisor", + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + Description: "Status of the hypervisor", + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + Description: "Sync time of the hypervisor", + }, + }, + }, + }, + }, + }, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version ID of the logical port", + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier of the binding", + }, + "segment_id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier of the segment", + }, + "segment_display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the segment", + }, + "port_security": { + Type: schema.TypeBool, + Computed: true, + Description: "If the port is secured", + }, + "address_detection": { + Type: schema.TypeBool, + Computed: true, + Description: "If the adapter address detection is enabled", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version ID of the binding", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation time of the binding", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "Update time of the binding", + }, + "logical_port_addresses": logicalPortAddressesSchema(), + }, + }, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation time of the logical port", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "Update time the logical port", + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vm_id": { + Type: schema.TypeString, + Computed: true, + Description: "VM ID label", + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + Description: "VM name label", + }, + }, + }, + Description: "Labels", + }, + } + return res +} + +func dataSourceLogicalPortSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "logical_port_id": { + Type: schema.TypeString, + Required: true, + Description: "ID of the logical port to use", + }, + "access_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the access group", + }, + "access_group_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the access group", + }, + "adapter_mac": { + Type: schema.TypeString, + Computed: true, + Description: "MAC address of the adapter", + }, + "address_detection": { + Type: schema.TypeBool, + Computed: true, + Description: "If the adapter address detection is enabled", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of the logical port", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the logical port", + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "If the logical port is enabled", + }, + "hypervisor": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the hypervisor", + }, + "hypervisor_display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the hypervisor", + }, + "external_network_id": { + Type: schema.TypeString, + Computed: true, + }, + "live_migration_target_hv": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + Description: "Operation status", + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + Description: "Hypervisor status", + }, + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + Description: "Operation status of the hypervisor", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the hypervisor", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the hypervisor", + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + Description: "Status of the hypervisor", + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + Description: "Sync time of the hypervisor", + }, + }, + }, + }, + }, + }, + }, + "unique_identifier": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier of the logical port", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version ID of the logical port", + }, + "bindings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier of the binding", + }, + "segment_id": { + Type: schema.TypeString, + Computed: true, + Description: "Unique identifier of the segment", + }, + "segment_display_name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name of the segment", + }, + "port_security": { + Type: schema.TypeBool, + Computed: true, + Description: "If the port is secured", + }, + "address_detection": { + Type: schema.TypeBool, + Computed: true, + Description: "If the adapter address detection is enabled", + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + Description: "Version ID of the binding", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation time of the binding", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "Update time of the binding", + }, + "logical_port_addresses": logicalPortAddressesSchema(), + }, + }, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Creation time of the logical port", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "Update time the logical port", + }, + "labels": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vm_id": { + Type: schema.TypeString, + Computed: true, + Description: "VM ID label", + }, + "vm_name": { + Type: schema.TypeString, + Computed: true, + Description: "VM name label", + }, + }, + }, + Description: "Labels", + }, + } + return res +} diff --git a/internal/service/sdn/logicalports/utility_logical_port.go b/internal/service/sdn/logicalports/utility_logical_port.go new file mode 100644 index 00000000..94025a44 --- /dev/null +++ b/internal/service/sdn/logicalports/utility_logical_port.go @@ -0,0 +1,30 @@ +package logicalports + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLogicalPortCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*logicalports.LogicalPort, error) { + c := m.(*controller.ControllerCfg) + + req := logicalports.GetRequest{ + ID: d.Id(), + } + + if d.Id() != "" { + req.ID = d.Id() + } else { + req.ID = d.Get("logical_port_id").(string) + } + + logicalPort, err := c.SDN().LogicalPorts().Get(ctx, req) + if err != nil { + return nil, err + } + + return logicalPort, nil +} diff --git a/internal/service/sdn/logicalports/utility_logical_port_by_unique_id.go b/internal/service/sdn/logicalports/utility_logical_port_by_unique_id.go new file mode 100644 index 00000000..8a76385e --- /dev/null +++ b/internal/service/sdn/logicalports/utility_logical_port_by_unique_id.go @@ -0,0 +1,30 @@ +package logicalports + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLogicalPortByUniqueIDCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*logicalports.LogicalPort, error) { + c := m.(*controller.ControllerCfg) + + req := logicalports.GetByUniqueIdentifierRequest{ + ID: d.Id(), + } + + if d.Id() != "" { + req.ID = d.Id() + } else { + req.ID = d.Get("unique_identifier").(string) + } + + logicalPort, err := c.SDN().LogicalPorts().GetByUniqueIdentifier(ctx, req) + if err != nil { + return nil, err + } + + return logicalPort, nil +} diff --git a/internal/service/sdn/logicalports/utility_logical_port_list.go b/internal/service/sdn/logicalports/utility_logical_port_list.go new file mode 100644 index 00000000..46378cea --- /dev/null +++ b/internal/service/sdn/logicalports/utility_logical_port_list.go @@ -0,0 +1,85 @@ +package logicalports + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityLogicalPortListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*logicalports.LogicalPortsList, error) { + c := m.(*controller.ControllerCfg) + req := logicalports.ListRequest{} + + if accessGroupID, ok := d.GetOk("access_group_id"); ok { + req.AccessGroupID = accessGroupID.(string) + } + if segmentID, ok := d.GetOk("segment_id"); ok { + req.SegmentID = segmentID.(string) + } + if segmentDisplayName, ok := d.GetOk("segment_display_name"); ok { + req.SegmentDisplayName = segmentDisplayName.(string) + } + if externalNetworkID, ok := d.GetOk("external_network_id"); ok { + req.ExternalNetworkID = externalNetworkID.(string) + } + if uniqueID, ok := d.GetOk("unique_identifier"); ok { + req.UniqueIdentifier = uniqueID.(string) + } + if displayName, ok := d.GetOk("display_name"); ok { + req.DisplayName = displayName.(string) + } + if adapterMAC, ok := d.GetOk("adapter_mac"); ok { + req.AdapterMAC = adapterMAC.(string) + } + if hypervisor, ok := d.GetOk("hypervisor"); ok { + req.Hypervisor = hypervisor.(string) + } + if hypervisorDisplayName, ok := d.GetOk("hypervisor_display_name"); ok { + req.HypervisorDisplayName = hypervisorDisplayName.(string) + } + if liveMigrationTargetHV, ok := d.GetOk("live_migration_target_hv"); ok { + req.LiveMigrationTargetHv = liveMigrationTargetHV.(string) + } + if portSecurity, ok := d.GetOk("port_security"); ok { + req.PortSecurity = portSecurity.(bool) + } + if addressDetection, ok := d.GetOk("address_detection"); ok { + req.AddressDetection = addressDetection.(bool) + } + if enabled, ok := d.GetOk("enabled"); ok { + req.Enabled = enabled.(bool) + } + if createdFrom, ok := d.GetOk("created_from"); ok { + req.CreatedFrom = createdFrom.(string) + } + if createdTo, ok := d.GetOk("created_to"); ok { + req.CreatedTo = createdTo.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if perPage, ok := d.GetOk("per_page"); ok { + req.PerPage = uint64(perPage.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if sortOrder, ok := d.GetOk("sort_order"); ok { + req.SortOrder = sortOrder.(string) + } + if operationStatus, ok := d.GetOk("operation_status"); ok { + req.OperationStatus = operationStatus.(string) + } + if hypervisorStatus, ok := d.GetOk("hypervisor_status"); ok { + req.HypervisorStatus = hypervisorStatus.(string) + } + + logicalPortList, err := c.SDN().LogicalPorts().List(ctx, req) + if err != nil { + return nil, err + } + + return logicalPortList, nil +} diff --git a/internal/service/sdn/netobjgroups/computed_schemas.go b/internal/service/sdn/netobjgroups/computed_schemas.go new file mode 100644 index 00000000..e545cd24 --- /dev/null +++ b/internal/service/sdn/netobjgroups/computed_schemas.go @@ -0,0 +1,572 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package netobjgroups + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func hypervisorsInfoComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": {Type: schema.TypeString, Computed: true}, + "name": {Type: schema.TypeString, Computed: true}, + "display_name": {Type: schema.TypeString, Computed: true}, + "hypervisor_status": {Type: schema.TypeString, Computed: true}, + "synced_at": {Type: schema.TypeString, Computed: true}, + }, + }, + } +} + +func statusComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": {Type: schema.TypeString, Computed: true}, + "hypervisor_status": {Type: schema.TypeString, Computed: true}, + "hypervisors": hypervisorsInfoComputedSchema(), + }, + }, + } +} + +func logicalPortAddressesComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": {Type: schema.TypeString, Computed: true}, + "ip_type": {Type: schema.TypeString, Computed: true}, + "is_discovered": {Type: schema.TypeBool, Computed: true}, + "is_primary": {Type: schema.TypeBool, Computed: true}, + "mac": {Type: schema.TypeString, Computed: true}, + "id": {Type: schema.TypeString, Computed: true}, + "logical_port_id": {Type: schema.TypeString, Computed: true}, + "assigned_at": {Type: schema.TypeString, Computed: true}, + }, + }, + } +} + +func bindingsComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": {Type: schema.TypeString, Computed: true}, + "segment_display_name": {Type: schema.TypeString, Computed: true}, + "segment_id": {Type: schema.TypeString, Computed: true}, + "port_security": {Type: schema.TypeBool, Computed: true}, + "address_detection": {Type: schema.TypeBool, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + "created_at": {Type: schema.TypeString, Computed: true}, + "updated_at": {Type: schema.TypeString, Computed: true}, + "logical_port_addresses": logicalPortAddressesComputedSchema(), + }, + }, + } +} + +func excludeFirewallComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "exclusion_reason": {Type: schema.TypeString, Computed: true}, + "logical_port_addresses_excluded": {Type: schema.TypeBool, Computed: true}, + "logical_port_excluded": {Type: schema.TypeBool, Computed: true}, + }, + }, + } +} + +func labelsComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vm_id": {Type: schema.TypeString, Computed: true}, + "vm_name": {Type: schema.TypeString, Computed: true}, + }, + }, + } +} + +func ipv6ConfigComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address_mode": {Type: schema.TypeString, Computed: true}, + "enable_periodic_ra": {Type: schema.TypeBool, Computed: true}, + "interval_ra": {Type: schema.TypeInt, Computed: true}, + "router_preference": {Type: schema.TypeString, Computed: true}, + }, + }, + } +} + +func routerGatewayPortComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "created_at": {Type: schema.TypeString, Computed: true}, + "description": {Type: schema.TypeString, Computed: true}, + "id": {Type: schema.TypeString, Computed: true}, + "router_display_name": {Type: schema.TypeString, Computed: true}, + "router_id": {Type: schema.TypeString, Computed: true}, + "snat_enabled": {Type: schema.TypeBool, Computed: true}, + "updated_at": {Type: schema.TypeString, Computed: true}, + }, + }, + } +} + +func logicalPortSchemaFields() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "id": {Type: schema.TypeString, Computed: true}, + "access_group_id": {Type: schema.TypeString, Computed: true}, + "access_group_name": {Type: schema.TypeString, Computed: true}, + "adapter_mac": {Type: schema.TypeString, Computed: true}, + "address_detection": {Type: schema.TypeBool, Computed: true}, + "description": {Type: schema.TypeString, Computed: true}, + "created_at": {Type: schema.TypeString, Computed: true}, + "display_name": {Type: schema.TypeString, Computed: true}, + "enabled": {Type: schema.TypeBool, Computed: true}, + "exclude_firewall": excludeFirewallComputedSchema(), + "external_network_id": {Type: schema.TypeString, Computed: true}, + "hypervisor": {Type: schema.TypeString, Computed: true}, + "hypervisor_display_name": {Type: schema.TypeString, Computed: true}, + "labels": labelsComputedSchema(), + "live_migration_target_hv": {Type: schema.TypeString, Computed: true}, + "status": statusComputedSchema(), + "bindings": bindingsComputedSchema(), + "unique_identifier": {Type: schema.TypeString, Computed: true}, + "updated_at": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + } +} + +func logicalPortsComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: logicalPortSchemaFields(), + }, + } +} + +func l2ExternalNetworkComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bridge_network_name": {Type: schema.TypeString, Computed: true}, + "created_at": {Type: schema.TypeString, Computed: true}, + "description": {Type: schema.TypeString, Computed: true}, + "display_name": {Type: schema.TypeString, Computed: true}, + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "id": {Type: schema.TypeString, Computed: true}, + "updated_at": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + "vlan_tag": {Type: schema.TypeInt, Computed: true}, + }, + }, + } +} + +func l2ConnectionPortsComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": {Type: schema.TypeString, Computed: true}, + "access_group_id": {Type: schema.TypeString, Computed: true}, + "created_at": {Type: schema.TypeString, Computed: true}, + "updated_at": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + "l2_external_network": l2ExternalNetworkComputedSchema(), + }, + }, + } +} + +func appliedNetObjectGroupsComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": {Type: schema.TypeString, Computed: true}, + "name": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + }, + }, + } +} + +func securityRuleNetObjectComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": {Type: schema.TypeString, Computed: true}, + "net_address_pool_id": {Type: schema.TypeString, Computed: true}, + "net_object_group_id": {Type: schema.TypeString, Computed: true}, + }, + }, + } +} + +func securityRuleFiltersComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "all": {Type: schema.TypeBool, Computed: true}, + "arp": {Type: schema.TypeBool, Computed: true}, + "dhcp": {Type: schema.TypeBool, Computed: true}, + "expression": {Type: schema.TypeString, Computed: true}, + "icmp": {Type: schema.TypeBool, Computed: true}, + "ip": {Type: schema.TypeBool, Computed: true}, + "ip_v4": {Type: schema.TypeBool, Computed: true}, + "ip_v6": {Type: schema.TypeBool, Computed: true}, + "keep_opened_sessions": {Type: schema.TypeBool, Computed: true}, + "nd": {Type: schema.TypeBool, Computed: true}, + "tcp": {Type: schema.TypeBool, Computed: true}, + "tcp_dst_ports": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "udp": {Type: schema.TypeBool, Computed: true}, + "udp_dst_ports": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + } +} + +func securityRuleFilterComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": {Type: schema.TypeString, Computed: true}, + "filters": securityRuleFiltersComputedSchema(), + }, + }, + } +} + +func securityRulesComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": {Type: schema.TypeString, Computed: true}, + "action": {Type: schema.TypeString, Computed: true}, + "description": {Type: schema.TypeString, Computed: true}, + "destination_net_object": securityRuleNetObjectComputedSchema(), + "direction": {Type: schema.TypeString, Computed: true}, + "display_name": {Type: schema.TypeString, Computed: true}, + "enabled": {Type: schema.TypeBool, Computed: true}, + "filter": securityRuleFilterComputedSchema(), + "id": {Type: schema.TypeString, Computed: true}, + "log_enabled": {Type: schema.TypeBool, Computed: true}, + "log_name": {Type: schema.TypeString, Computed: true}, + "log_severity": {Type: schema.TypeString, Computed: true}, + "priority": {Type: schema.TypeInt, Computed: true}, + "security_policy_id": {Type: schema.TypeString, Computed: true}, + "source_net_object": securityRuleNetObjectComputedSchema(), + "statistics_enabled": {Type: schema.TypeBool, Computed: true}, + "type": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + }, + }, + } +} + +func securityPoliciesComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": {Type: schema.TypeString, Computed: true}, + "access_group_name": {Type: schema.TypeString, Computed: true}, + "applied_net_object_groups": appliedNetObjectGroupsComputedSchema(), + "created_at": {Type: schema.TypeString, Computed: true}, + "description": {Type: schema.TypeString, Computed: true}, + "display_name": {Type: schema.TypeString, Computed: true}, + "enabled": {Type: schema.TypeBool, Computed: true}, + "end_priority": {Type: schema.TypeInt, Computed: true}, + "id": {Type: schema.TypeString, Computed: true}, + "security_rules": securityRulesComputedSchema(), + "start_priority": {Type: schema.TypeInt, Computed: true}, + "status": statusComputedSchema(), + "type": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + "updated_at": {Type: schema.TypeString, Computed: true}, + }, + }, + } +} + +func gateawayPortsComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "created_at": {Type: schema.TypeString, Computed: true}, + "description": {Type: schema.TypeString, Computed: true}, + "external_l4_port_max": {Type: schema.TypeInt, Computed: true}, + "external_l4_port_min": {Type: schema.TypeInt, Computed: true}, + "id": {Type: schema.TypeString, Computed: true}, + "snat_enabled": {Type: schema.TypeBool, Computed: true}, + "status": statusComputedSchema(), + "updated_at": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + }, + }, + } +} + +func policiesComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "action": {Type: schema.TypeString, Computed: true}, + "created_at": {Type: schema.TypeString, Computed: true}, + "display_name": {Type: schema.TypeString, Computed: true}, + "enabled": {Type: schema.TypeBool, Computed: true}, + "id": {Type: schema.TypeString, Computed: true}, + "match": {Type: schema.TypeString, Computed: true}, + "next_ipv4_address": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "next_ipv6_address": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "priority": {Type: schema.TypeInt, Computed: true}, + "updated_at": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + }, + }, + } +} + +func segmentComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": {Type: schema.TypeString, Computed: true}, + "access_group_name": {Type: schema.TypeString, Computed: true}, + "created_at": {Type: schema.TypeString, Computed: true}, + "description": {Type: schema.TypeString, Computed: true}, + "display_name": {Type: schema.TypeString, Computed: true}, + "enabled": {Type: schema.TypeBool, Computed: true}, + "id": {Type: schema.TypeString, Computed: true}, + "subnet_v4": {Type: schema.TypeString, Computed: true}, + "subnet_v6": {Type: schema.TypeString, Computed: true}, + "updated_at": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + }, + }, + } +} + +func routerPortsComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "created_at": {Type: schema.TypeString, Computed: true}, + "description": {Type: schema.TypeString, Computed: true}, + "enabled": {Type: schema.TypeBool, Computed: true}, + "id": {Type: schema.TypeString, Computed: true}, + "ipv4_address": {Type: schema.TypeString, Computed: true}, + "ipv6_address": {Type: schema.TypeString, Computed: true}, + "ipv6_config": ipv6ConfigComputedSchema(), + "mac": {Type: schema.TypeString, Computed: true}, + "segment_id": {Type: schema.TypeString, Computed: true}, + "segment": segmentComputedSchema(), + "status": statusComputedSchema(), + "updated_at": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + }, + }, + } +} + +func routerComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": {Type: schema.TypeString, Computed: true}, + "access_group_name": {Type: schema.TypeString, Computed: true}, + "created_at": {Type: schema.TypeString, Computed: true}, + "description": {Type: schema.TypeString, Computed: true}, + "display_name": {Type: schema.TypeString, Computed: true}, + "enabled": {Type: schema.TypeBool, Computed: true}, + "gateaway_ports": gateawayPortsComputedSchema(), + "id": {Type: schema.TypeString, Computed: true}, + "policies": policiesComputedSchema(), + "ports": routerPortsComputedSchema(), + "status": statusComputedSchema(), + "updated_at": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + }, + }, + } +} + +func floatingIPComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": {Type: schema.TypeString, Computed: true}, + "access_group_name": {Type: schema.TypeString, Computed: true}, + "created_at": {Type: schema.TypeString, Computed: true}, + "updated_at": {Type: schema.TypeString, Computed: true}, + "version_id": {Type: schema.TypeInt, Computed: true}, + "logical_port": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: logicalPortSchemaFields(), + }, + }, + "router": routerComputedSchema(), + }, + }, + } +} + +func externalNetworkPortFieldsComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "access_group_id": {Type: schema.TypeString, Computed: true}, + "access_group_name": {Type: schema.TypeString, Computed: true}, + "comment": {Type: schema.TypeString, Computed: true}, + "display_name": {Type: schema.TypeString, Computed: true}, + "enabled": {Type: schema.TypeBool, Computed: true}, + "ipv4": {Type: schema.TypeString, Computed: true}, + "ipv6": {Type: schema.TypeString, Computed: true}, + "ipv6_config": ipv6ConfigComputedSchema(), + "mac": {Type: schema.TypeString, Computed: true}, + "router_gateaway_port": routerGatewayPortComputedSchema(), + "floating_ip": floatingIPComputedSchema(), + }, + }, + } +} + +func externalNetworkPortsComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": {Type: schema.TypeString, Computed: true}, + "access_group_id": {Type: schema.TypeString, Computed: true}, + "access_group_name": {Type: schema.TypeString, Computed: true}, + "bridge_network_name": {Type: schema.TypeString, Computed: true}, + "comment": {Type: schema.TypeString, Computed: true}, + "default_gateway_ipv4": {Type: schema.TypeString, Computed: true}, + "default_gateway_ipv6": {Type: schema.TypeString, Computed: true}, + "description": {Type: schema.TypeString, Computed: true}, + "enabled": {Type: schema.TypeBool, Computed: true}, + "external_network_ports": externalNetworkPortFieldsComputedSchema(), + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "ipv4": {Type: schema.TypeString, Computed: true}, + "status": statusComputedSchema(), + "version_id": {Type: schema.TypeInt, Computed: true}, + "subnet_v4": {Type: schema.TypeString, Computed: true}, + "subnet_v6": {Type: schema.TypeString, Computed: true}, + "created_at": {Type: schema.TypeString, Computed: true}, + "updated_at": {Type: schema.TypeString, Computed: true}, + "vlan_tag": {Type: schema.TypeInt, Computed: true}, + "mac": {Type: schema.TypeString, Computed: true}, + }, + }, + } +} diff --git a/internal/service/sdn/netobjgroups/decort_sdn_network_object_group.go b/internal/service/sdn/netobjgroups/decort_sdn_network_object_group.go new file mode 100644 index 00000000..76c16456 --- /dev/null +++ b/internal/service/sdn/netobjgroups/decort_sdn_network_object_group.go @@ -0,0 +1,178 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package netobjgroups + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceNetworkObjectGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + rec, err := utilityNetworkObjectGroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenNetworkObjectGroupDataSource(d, rec) + d.SetId(rec.ID) + + return nil +} + +func dataSourceNetworkObjectGroupSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "net_object_group_id": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "access_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "access_group_name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "purpose": { + Type: schema.TypeString, + Computed: true, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + "addresses": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "net_address_type": { + Type: schema.TypeString, + Computed: true, + }, + "ip_addr": { + Type: schema.TypeString, + Computed: true, + }, + "ip_addr_range_end": { + Type: schema.TypeString, + Computed: true, + }, + "ip_prefix": { + Type: schema.TypeString, + Computed: true, + }, + "mac_addr": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "counters": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "addresses_count": { + Type: schema.TypeInt, + Computed: true, + }, + "l2_connection_ports_count": { + Type: schema.TypeInt, + Computed: true, + }, + "logical_ports_count": { + Type: schema.TypeInt, + Computed: true, + }, + "security_policies_count": { + Type: schema.TypeInt, + Computed: true, + }, + "security_rules_count": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "l2_connection_ports": l2ConnectionPortsComputedSchema(), + "logical_ports": logicalPortsComputedSchema(), + "external_network_ports": externalNetworkPortsComputedSchema(), + "security_policies": securityPoliciesComputedSchema(), + } +} + +func DataSourceNetworkObjectGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceNetworkObjectGroupRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceNetworkObjectGroupSchemaMake(), + } +} diff --git a/internal/service/sdn/netobjgroups/decort_sdn_network_object_group_list.go b/internal/service/sdn/netobjgroups/decort_sdn_network_object_group_list.go new file mode 100644 index 00000000..b997fdb6 --- /dev/null +++ b/internal/service/sdn/netobjgroups/decort_sdn_network_object_group_list.go @@ -0,0 +1,233 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package netobjgroups + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceNetworkObjectGroupListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + list, err := utilityNetworkObjectGroupListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenNetworkObjectGroupList(list)) + d.Set("entry_count", len(list.Objects)) + + return nil +} + +func dataSourceNetworkObjectGroupListSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + }, + "access_group_id": { + Type: schema.TypeString, + Optional: true, + }, + "page": { + Type: schema.TypeInt, + Optional: true, + }, + "per_page": { + Type: schema.TypeInt, + Optional: true, + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + }, + "sort_order": { + Type: schema.TypeString, + Optional: true, + }, + "created_from": { + Type: schema.TypeString, + Optional: true, + }, + "created_to": { + Type: schema.TypeString, + Optional: true, + }, + "updated_from": { + Type: schema.TypeString, + Optional: true, + }, + "updated_to": { + Type: schema.TypeString, + Optional: true, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "access_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "access_group_name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "purpose": { + Type: schema.TypeString, + Computed: true, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + "addresses": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "net_address_type": { + Type: schema.TypeString, + Computed: true, + }, + "ip_addr": { + Type: schema.TypeString, + Computed: true, + }, + "ip_addr_range_end": { + Type: schema.TypeString, + Computed: true, + }, + "ip_prefix": { + Type: schema.TypeString, + Computed: true, + }, + "mac_addr": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "counters": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "addresses_count": { + Type: schema.TypeInt, + Computed: true, + }, + "l2_connection_ports_count": { + Type: schema.TypeInt, + Computed: true, + }, + "logical_ports_count": { + Type: schema.TypeInt, + Computed: true, + }, + "security_policies_count": { + Type: schema.TypeInt, + Computed: true, + }, + "security_rules_count": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "l2_connection_ports": l2ConnectionPortsComputedSchema(), + "logical_ports": logicalPortsComputedSchema(), + "external_network_ports": externalNetworkPortsComputedSchema(), + "security_policies": securityPoliciesComputedSchema(), + }, + }, + }, + } +} + +func DataSourceNetworkObjectGroupList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceNetworkObjectGroupListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceNetworkObjectGroupListSchemaMake(), + } +} diff --git a/internal/service/sdn/netobjgroups/flattens.go b/internal/service/sdn/netobjgroups/flattens.go new file mode 100644 index 00000000..a578ecb1 --- /dev/null +++ b/internal/service/sdn/netobjgroups/flattens.go @@ -0,0 +1,581 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package netobjgroups + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/netobjgroups" +) + +func flattenNetworkObjectGroupResource(d *schema.ResourceData, rec *netobjgroups.RecordNetObjGroup) { + d.Set("name", rec.Name) + d.Set("access_group_id", rec.AccessGroupID) + d.Set("access_group_name", rec.AccessGroupName) + d.Set("description", rec.Description) + d.Set("type", rec.Type) + d.Set("purpose", rec.Purpose) + d.Set("version_id", int(rec.VersionID)) + d.Set("addresses", flattenAddresses(rec.Addresses)) + d.Set("counters", flattenCounters(rec.Counters)) + d.Set("l2_connection_ports", flattenL2ConnectionPorts(rec.L2ConnectionPorts)) + d.Set("logical_ports", flattenLogicalPorts(rec.LogicalPorts)) + d.Set("external_network_ports", flattenExternalNetworkPorts(rec.ExternalNetworkPorts)) + d.Set("security_policies", flattenSecurityPolicies(rec.SecurityPolicies)) +} + +func flattenNetworkObjectGroupDataSource(d *schema.ResourceData, rec *netobjgroups.RecordNetObjGroup) { + d.Set("name", rec.Name) + d.Set("access_group_id", rec.AccessGroupID) + d.Set("access_group_name", rec.AccessGroupName) + d.Set("description", rec.Description) + d.Set("type", rec.Type) + d.Set("purpose", rec.Purpose) + d.Set("version_id", int(rec.VersionID)) + d.Set("created_at", rec.CreatedAt) + d.Set("updated_at", rec.UpdatedAt) + d.Set("addresses", flattenAddresses(rec.Addresses)) + d.Set("counters", flattenCounters(rec.Counters)) + d.Set("l2_connection_ports", flattenL2ConnectionPorts(rec.L2ConnectionPorts)) + d.Set("logical_ports", flattenLogicalPorts(rec.LogicalPorts)) + d.Set("external_network_ports", flattenExternalNetworkPorts(rec.ExternalNetworkPorts)) + d.Set("security_policies", flattenSecurityPolicies(rec.SecurityPolicies)) +} + +func flattenAddresses(addrs netobjgroups.NetAddresses) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(addrs)) + for _, a := range addrs { + res = append(res, map[string]interface{}{ + "id": a.ID, + "net_address_type": a.NetAddressType, + "ip_addr": a.IPAddr, + "ip_addr_range_end": a.IPAddrRangeEnd, + "ip_prefix": a.IPPrefix, + "mac_addr": a.MACAddr, + }) + } + return res +} + +func flattenCounters(c netobjgroups.Counter) []map[string]interface{} { + return []map[string]interface{}{ + { + "addresses_count": int(c.AddressesCount), + "l2_connection_ports_count": int(c.L2ConnectionPortsCount), + "logical_ports_count": int(c.LogicalPortsCount), + "security_policies_count": int(c.SecurityPoliciesCount), + "security_rules_count": int(c.SecurityRulesCount), + }, + } +} + +func flattenStatus(s netobjgroups.Status) []map[string]interface{} { + return []map[string]interface{}{ + { + "operation_status": s.OperationStatus, + "hypervisor_status": s.HypervisorStatus, + "hypervisors": flattenHypervisorsInfo(s.Hypervisors), + }, + } +} + +func flattenHypervisorsInfo(hvs netobjgroups.HypervisorsInfo) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(hvs)) + for _, hv := range hvs { + res = append(res, map[string]interface{}{ + "operation_status": hv.OperationStatus, + "name": hv.Name, + "display_name": hv.DisplayName, + "hypervisor_status": hv.HypervisorStatus, + "synced_at": hv.SyncedAt, + }) + } + return res +} + +func flattenLogicalPortAddresses(addrs netobjgroups.LogicalPortAddresses) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(addrs)) + for _, a := range addrs { + res = append(res, map[string]interface{}{ + "ip": a.IP, + "ip_type": a.IPType, + "is_discovered": a.IsDiscovered, + "is_primary": a.IsPrimary, + "mac": a.MAC, + "id": a.ID, + "logical_port_id": a.LogicalPortID, + "assigned_at": a.AssignedAt, + }) + } + return res +} + +func flattenBindings(b netobjgroups.Bindings) []map[string]interface{} { + return []map[string]interface{}{ + { + "id": b.ID, + "segment_display_name": b.SegmentDisplayName, + "segment_id": b.SegmentID, + "port_security": b.PortSecurity, + "address_detection": b.AddressDetection, + "version_id": int(b.VersionID), + "created_at": b.CreatedAt, + "updated_at": b.UpdatedAt, + "logical_port_addresses": flattenLogicalPortAddresses(b.LogicalPortAddresses), + }, + } +} + +func flattenExcludeFirewall(e netobjgroups.ExcludeFirewall) []map[string]interface{} { + return []map[string]interface{}{ + { + "exclusion_reason": e.ExclusionReason, + "logical_port_addresses_excluded": e.LogicalPortAddressesExcluded, + "logical_port_excluded": e.LogicalPortExcluded, + }, + } +} + +func flattenLabels(l netobjgroups.Labels) []map[string]interface{} { + return []map[string]interface{}{ + { + "vm_id": l.VMID, + "vm_name": l.VMName, + }, + } +} + +func flattenLogicalPort(lp netobjgroups.LogicalPort) map[string]interface{} { + return map[string]interface{}{ + "id": lp.ID, + "access_group_id": lp.AccessGroupID, + "access_group_name": lp.AccessGroupName, + "adapter_mac": lp.AdapterMAC, + "address_detection": lp.AddressDetection, + "description": lp.Description, + "created_at": lp.CreatedAt, + "display_name": lp.DisplayName, + "enabled": lp.Enabled, + "exclude_firewall": flattenExcludeFirewall(lp.ExcludeFirewall), + "external_network_id": lp.ExternalNetworkID, + "hypervisor": lp.Hypervisor, + "hypervisor_display_name": lp.HypervisorDisplayName, + "labels": flattenLabels(lp.Labels), + "live_migration_target_hv": lp.LiveMigrationTargetHV, + "status": flattenStatus(lp.Status), + "bindings": flattenBindings(lp.Bindings), + "unique_identifier": lp.UniqueIdentifier, + "updated_at": lp.UpdatedAt, + "version_id": int(lp.VersionID), + } +} + +func flattenLogicalPorts(ports netobjgroups.LogicalPorts) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ports)) + for _, lp := range ports { + res = append(res, flattenLogicalPort(lp)) + } + return res +} + +func flattenL2ExternalNetwork(n netobjgroups.L2ExternalNetwork) []map[string]interface{} { + hypervisors := make([]interface{}, 0, len(n.Hypervisors)) + for _, h := range n.Hypervisors { + hypervisors = append(hypervisors, h) + } + vlanTag := 0 + if n.VLANTag != nil { + vlanTag = *n.VLANTag + } + return []map[string]interface{}{ + { + "bridge_network_name": n.BridgeNetworkName, + "created_at": n.CreatedAt, + "description": n.Description, + "display_name": n.DisplayName, + "hypervisors": hypervisors, + "id": n.ID, + "updated_at": n.UpdatedAt, + "version_id": int(n.VersionID), + "vlan_tag": vlanTag, + }, + } +} + +func flattenL2ConnectionPorts(ports netobjgroups.L2ConnectionPorts) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ports)) + for _, p := range ports { + res = append(res, map[string]interface{}{ + "id": p.ID, + "access_group_id": p.AccessGroupID, + "created_at": p.CreatedAt, + "updated_at": p.UpdatedAt, + "version_id": int(p.VersionID), + "l2_external_network": flattenL2ExternalNetwork(p.L2ExternalNetwork), + }) + } + return res +} + +func flattenIPv6Config(c netobjgroups.IPv6Config) []map[string]interface{} { + return []map[string]interface{}{ + { + "address_mode": c.AddressMode, + "enable_periodic_ra": c.EnablePeriodicRA, + "interval_ra": int(c.IntervalRA), + "router_preference": c.RouterPreference, + }, + } +} + +func flattenRouterGatewayPort(r netobjgroups.RouterGateawayPort) []map[string]interface{} { + return []map[string]interface{}{ + { + "created_at": r.CreatedAt, + "description": r.Description, + "id": r.ID, + "router_display_name": r.RouterDisplayName, + "router_id": r.RouterID, + "snat_enabled": r.SNATEnabled, + "updated_at": r.UpdatedAt, + }, + } +} + +func flattenSegment(s netobjgroups.Segment) []map[string]interface{} { + return []map[string]interface{}{ + { + "access_group_id": s.AccessGroupID, + "access_group_name": s.AccessGroupName, + "created_at": s.CreatedAt, + "description": s.Description, + "display_name": s.DisplayName, + "enabled": s.Enabled, + "id": s.ID, + "subnet_v4": s.SubnetV4, + "subnet_v6": s.SubnetV6, + "updated_at": s.UpdatedAt, + "version_id": int(s.VersionID), + }, + } +} + +func flattenRouter(r netobjgroups.Router) []map[string]interface{} { + gateawayPorts := make([]map[string]interface{}, 0, len(r.GateawayPorts)) + for _, gp := range r.GateawayPorts { + gateawayPorts = append(gateawayPorts, map[string]interface{}{ + "created_at": gp.CreatedAt, + "description": gp.Description, + "external_l4_port_max": int(gp.ExternalL4PortMax), + "external_l4_port_min": int(gp.ExternalL4PortMin), + "id": gp.ID, + "snat_enabled": gp.SNATEnabled, + "status": flattenStatus(gp.Status), + "updated_at": gp.UpdatedAt, + "version_id": int(gp.VersionID), + }) + } + + policies := make([]map[string]interface{}, 0, len(r.Policies)) + for _, pol := range r.Policies { + nextIPv4 := make([]interface{}, 0, len(pol.NextIPv4Address)) + for _, ip := range pol.NextIPv4Address { + nextIPv4 = append(nextIPv4, ip) + } + nextIPv6 := make([]interface{}, 0, len(pol.NextIPv6Address)) + for _, ip := range pol.NextIPv6Address { + nextIPv6 = append(nextIPv6, ip) + } + policies = append(policies, map[string]interface{}{ + "action": pol.Action, + "created_at": pol.CreatedAt, + "display_name": pol.DisplayName, + "enabled": pol.Enabled, + "id": pol.ID, + "match": pol.Match, + "next_ipv4_address": nextIPv4, + "next_ipv6_address": nextIPv6, + "priority": pol.Priority, + "updated_at": pol.UpdatedAt, + "version_id": int(pol.VersionID), + }) + } + + ports := make([]map[string]interface{}, 0, len(r.Port)) + for _, port := range r.Port { + ports = append(ports, map[string]interface{}{ + "created_at": port.CreatedAt, + "description": port.Description, + "enabled": port.Enabled, + "id": port.ID, + "ipv4_address": port.IPv4Address, + "ipv6_address": port.IPv6Address, + "ipv6_config": flattenIPv6Config(port.IPv6Config), + "mac": port.MAC, + "segment_id": port.SegmentID, + "segment": flattenSegment(port.Segment), + "status": flattenStatus(port.Status), + "updated_at": port.UpdatedAt, + "version_id": int(port.VersionID), + }) + } + + return []map[string]interface{}{ + { + "access_group_id": r.AccessGroupID, + "access_group_name": r.AccessGroupName, + "created_at": r.CreatedAt, + "description": r.Description, + "display_name": r.DisplayName, + "enabled": r.Enabled, + "gateaway_ports": gateawayPorts, + "id": r.ID, + "policies": policies, + "ports": ports, + "status": flattenStatus(r.Status), + "updated_at": r.UpdatedAt, + "version_id": int(r.VersionID), + }, + } +} + +func flattenFloatingIP(f netobjgroups.FloatingIP) []map[string]interface{} { + return []map[string]interface{}{ + { + "access_group_id": f.AccessGroupID, + "access_group_name": f.AccessGroupName, + "created_at": f.CreatedAt, + "updated_at": f.UpdatedAt, + "version_id": int(f.VersionID), + "logical_port": []map[string]interface{}{flattenLogicalPort(f.LogicalPort)}, + "router": flattenRouter(f.Router), + }, + } +} + +func flattenExternalNetworkPortFields(ports netobjgroups.ExternalNetworkPortsField) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ports)) + for _, p := range ports { + res = append(res, map[string]interface{}{ + "access_group_id": p.AccessGroupID, + "access_group_name": p.AccessGroupName, + "comment": p.Comment, + "display_name": p.DisplayName, + "enabled": p.Enabled, + "ipv4": p.IPv4, + "ipv6": p.IPv6, + "ipv6_config": flattenIPv6Config(p.IPv6Config), + "mac": p.MAC, + "router_gateaway_port": flattenRouterGatewayPort(p.RouterGateawayPort), + "floating_ip": flattenFloatingIP(p.FloatingIP), + }) + } + return res +} + +func flattenExternalNetworkPorts(ports netobjgroups.ExternalNetworkPorts) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ports)) + for _, p := range ports { + hypervisors := make([]interface{}, 0, len(p.Hypervisors)) + for _, h := range p.Hypervisors { + hypervisors = append(hypervisors, h) + } + res = append(res, map[string]interface{}{ + "id": p.ID, + "access_group_id": p.AccessGroupID, + "access_group_name": p.AccessGroupName, + "bridge_network_name": p.BridgeNetworkName, + "comment": p.Comment, + "default_gateway_ipv4": p.DefaultGatewayIPv4, + "default_gateway_ipv6": p.DefaultGatewayIPv6, + "description": p.Description, + "enabled": p.Enabled, + "external_network_ports": flattenExternalNetworkPortFields(p.ExternalNetworkPorts), + "hypervisors": hypervisors, + "ipv4": p.IPv4, + "status": flattenStatus(p.Status), + "version_id": int(p.VersionID), + "subnet_v4": p.SubnetV4, + "subnet_v6": p.SubnetV6, + "created_at": p.CreatedAt, + "updated_at": p.UpdatedAt, + "vlan_tag": p.VLANTag, + "mac": p.MAC, + }) + } + return res +} + +func flattenAppliedNetObjectGroups(groups netobjgroups.AppliedNetObjectGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(groups)) + for _, g := range groups { + res = append(res, map[string]interface{}{ + "id": g.ID, + "name": g.Name, + "version_id": int(g.VersionID), + }) + } + return res +} + +func flattenSecurityRules(rules netobjgroups.SecurityRules) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(rules)) + for _, r := range rules { + srcNetObj := []map[string]interface{}{} + if r.SourceNetObject != nil { + srcNetObj = []map[string]interface{}{ + { + "display_name": r.SourceNetObject.DisplayName, + "net_address_pool_id": r.SourceNetObject.NetAddressPoolID, + "net_object_group_id": r.SourceNetObject.NetObjectGroupID, + }, + } + } + dstNetObj := []map[string]interface{}{} + if r.DestinationNetObject != nil { + dstNetObj = []map[string]interface{}{ + { + "display_name": r.DestinationNetObject.DisplayName, + "net_address_pool_id": r.DestinationNetObject.NetAddressPoolID, + "net_object_group_id": r.DestinationNetObject.NetObjectGroupID, + }, + } + } + filter := []map[string]interface{}{} + if r.Filter != nil { + tcpDstPorts := make([]interface{}, 0, len(r.Filter.Filters.TCPDstPorts)) + for _, p := range r.Filter.Filters.TCPDstPorts { + tcpDstPorts = append(tcpDstPorts, p) + } + udpDstPorts := make([]interface{}, 0, len(r.Filter.Filters.UDPDstPorts)) + for _, p := range r.Filter.Filters.UDPDstPorts { + udpDstPorts = append(udpDstPorts, p) + } + filter = []map[string]interface{}{ + { + "name": r.Filter.Name, + "filters": []map[string]interface{}{ + { + "all": r.Filter.Filters.All, + "arp": r.Filter.Filters.ARP, + "dhcp": r.Filter.Filters.DHCP, + "expression": r.Filter.Filters.Expression, + "icmp": r.Filter.Filters.ICMP, + "ip": r.Filter.Filters.IP, + "ip_v4": r.Filter.Filters.IPv4, + "ip_v6": r.Filter.Filters.IPv6, + "keep_opened_sessions": r.Filter.Filters.KeepOpenedSessions, + "nd": r.Filter.Filters.ND, + "tcp": r.Filter.Filters.TCP, + "tcp_dst_ports": tcpDstPorts, + "udp": r.Filter.Filters.UDP, + "udp_dst_ports": udpDstPorts, + }, + }, + }, + } + } + res = append(res, map[string]interface{}{ + "access_group_id": r.AccessGroupID, + "action": r.Action, + "description": r.Description, + "destination_net_object": dstNetObj, + "direction": r.Direction, + "display_name": r.DisplayName, + "enabled": r.Enabled, + "filter": filter, + "id": r.ID, + "log_enabled": r.LogEnabled, + "log_name": r.LogName, + "log_severity": r.LogSeverity, + "priority": r.Priority, + "security_policy_id": r.SecurityPolicyID, + "source_net_object": srcNetObj, + "statistics_enabled": r.StatisticsEnabled, + "type": r.Type, + "version_id": int(r.VersionID), + }) + } + return res +} + +func flattenSecurityPolicies(policies netobjgroups.SecurityPolicies) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(policies)) + for _, p := range policies { + res = append(res, map[string]interface{}{ + "access_group_id": p.AccessGroupID, + "access_group_name": p.AccessGroupName, + "applied_net_object_groups": flattenAppliedNetObjectGroups(p.AppliedNetObjectGroups), + "created_at": p.CreatedAt, + "description": p.Description, + "display_name": p.DisplayName, + "enabled": p.Enabled, + "end_priority": int(p.EndPriority), + "id": p.ID, + "security_rules": flattenSecurityRules(p.SecurityRules), + "start_priority": int(p.StartPriority), + "status": flattenStatus(p.Status), + "type": p.Type, + "version_id": int(p.VersionID), + "updated_at": p.UpdatedAt, + }) + } + return res +} + +func flattenNetworkObjectGroupList(list *netobjgroups.NetObjGroupList) []map[string]interface{} { + if list == nil { + return []map[string]interface{}{} + } + res := make([]map[string]interface{}, 0, len(list.Objects)) + for _, v := range list.Objects { + res = append(res, map[string]interface{}{ + "id": v.ID, + "name": v.Name, + "access_group_id": v.AccessGroupID, + "access_group_name": v.AccessGroupName, + "description": v.Description, + "type": v.Type, + "purpose": v.Purpose, + "version_id": int(v.VersionID), + "created_at": v.CreatedAt, + "updated_at": v.UpdatedAt, + "addresses": flattenAddresses(v.Addresses), + "counters": flattenCounters(v.Counters), + "l2_connection_ports": flattenL2ConnectionPorts(v.L2ConnectionPorts), + "logical_ports": flattenLogicalPorts(v.LogicalPorts), + "external_network_ports": flattenExternalNetworkPorts(v.ExternalNetworkPorts), + "security_policies": flattenSecurityPolicies(v.SecurityPolicies), + }) + } + return res +} diff --git a/internal/service/sdn/netobjgroups/resource_decort_sdn_network_object_group.go b/internal/service/sdn/netobjgroups/resource_decort_sdn_network_object_group.go new file mode 100644 index 00000000..7ff3a2e8 --- /dev/null +++ b/internal/service/sdn/netobjgroups/resource_decort_sdn_network_object_group.go @@ -0,0 +1,322 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package netobjgroups + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/netobjgroups" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceNetworkObjectGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceNetworkObjectGroupCreate: called with name %s", d.Get("name").(string)) + + c := m.(*controller.ControllerCfg) + + req := netobjgroups.CreateRequest{ + AccessGroupID: d.Get("access_group_id").(string), + Description: d.Get("description").(string), + Name: d.Get("name").(string), + } + + if addrRaw, ok := d.GetOk("addresses"); ok { + req.Addresses = buildAddressesRequest(addrRaw.([]interface{})) + } + + if l2Raw, ok := d.GetOk("l2_connection_ports_bindings"); ok { + req.L2ConnectionPortsBindings = buildL2PortsBindingsRequest(l2Raw.([]interface{})) + } + + rec, err := c.SDN().NetworkObjectGroups().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(rec.ID) + + return resourceNetworkObjectGroupRead(ctx, d, m) +} + +func resourceNetworkObjectGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceNetworkObjectGroupRead: called with id %s", d.Id()) + + rec, err := utilityNetworkObjectGroupCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenNetworkObjectGroupResource(d, rec) + d.SetId(rec.ID) + + return nil +} + +func resourceNetworkObjectGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceNetworkObjectGroupUpdate: called with id %s", d.Id()) + + c := m.(*controller.ControllerCfg) + + req := netobjgroups.UpdateRequest{ + ObjectGroupID: d.Id(), + VersionID: uint64(d.Get("version_id").(int)), + AccessGroupID: d.Get("access_group_id").(string), + Description: d.Get("description").(string), + Name: d.Get("name").(string), + } + + if addrRaw, ok := d.GetOk("addresses"); ok { + req.Addresses = buildAddressesRequest(addrRaw.([]interface{})) + } + + rec, err := c.SDN().NetworkObjectGroups().Update(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(rec.ID) + + return resourceNetworkObjectGroupRead(ctx, d, m) +} + +func resourceNetworkObjectGroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceNetworkObjectGroupDelete: called with id %s", d.Id()) + + c := m.(*controller.ControllerCfg) + + req := netobjgroups.DeleteRequest{ + ObjectGroupID: d.Id(), + VersionID: uint64(d.Get("version_id").(int)), + } + + _, err := c.SDN().NetworkObjectGroups().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + return nil +} + +func buildL2PortsBindingsRequest(raw []interface{}) []netobjgroups.LogicalPortsBindings { + result := make([]netobjgroups.LogicalPortsBindings, 0, len(raw)) + for _, item := range raw { + m := item.(map[string]interface{}) + result = append(result, netobjgroups.LogicalPortsBindings{ + PortID: m["port_id"].(string), + PortVersion: uint64(m["port_version"].(int)), + }) + } + return result +} + +func buildAddressesRequest(raw []interface{}) []netobjgroups.NetAddressRequest { + result := make([]netobjgroups.NetAddressRequest, 0, len(raw)) + for _, item := range raw { + addrMap := item.(map[string]interface{}) + addr := netobjgroups.NetAddressRequest{ + NetAddressType: addrMap["net_address_type"].(string), + } + if v, ok := addrMap["ip_addr"].(string); ok && v != "" { + addr.IPAddr = v + } + if v, ok := addrMap["ip_addr_range_end"].(string); ok && v != "" { + addr.IPAddrRangeEnd = v + } + if v, ok := addrMap["ip_prefix"].(string); ok && v != "" { + addr.IPPrefix = v + } + if v, ok := addrMap["mac_addr"].(string); ok && v != "" { + addr.MACAddr = v + } + result = append(result, addr) + } + return result +} + +func resourceNetworkObjectGroupSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "access_group_id": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Required: true, + }, + "addresses": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "net_address_type": { + Type: schema.TypeString, + Required: true, + }, + "ip_addr": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "ip_addr_range_end": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "ip_prefix": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "mac_addr": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + }, + }, + "l2_connection_ports_bindings": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "port_id": { + Type: schema.TypeString, + Required: true, + }, + "port_version": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + "access_group_name": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "purpose": { + Type: schema.TypeString, + Computed: true, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + }, + "counters": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "addresses_count": { + Type: schema.TypeInt, + Computed: true, + }, + "l2_connection_ports_count": { + Type: schema.TypeInt, + Computed: true, + }, + "logical_ports_count": { + Type: schema.TypeInt, + Computed: true, + }, + "security_policies_count": { + Type: schema.TypeInt, + Computed: true, + }, + "security_rules_count": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "l2_connection_ports": l2ConnectionPortsComputedSchema(), + "logical_ports": logicalPortsComputedSchema(), + "external_network_ports": externalNetworkPortsComputedSchema(), + "security_policies": securityPoliciesComputedSchema(), + } +} + +func ResourceNetworkObjectGroup() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceNetworkObjectGroupCreate, + ReadContext: resourceNetworkObjectGroupRead, + UpdateContext: resourceNetworkObjectGroupUpdate, + DeleteContext: resourceNetworkObjectGroupDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error { + changedKeys := diff.GetChangedKeysPrefix("") + if len(changedKeys) > 0 { + diff.SetNewComputed("version_id") + } + return nil + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout300s, + Default: &constants.Timeout300s, + }, + + Schema: resourceNetworkObjectGroupSchemaMake(), + } +} diff --git a/internal/service/sdn/netobjgroups/utility_network_object_group.go b/internal/service/sdn/netobjgroups/utility_network_object_group.go new file mode 100644 index 00000000..8222d0fe --- /dev/null +++ b/internal/service/sdn/netobjgroups/utility_network_object_group.go @@ -0,0 +1,60 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package netobjgroups + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/netobjgroups" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityNetworkObjectGroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*netobjgroups.RecordNetObjGroup, error) { + c := m.(*controller.ControllerCfg) + + req := netobjgroups.GetRequest{} + + if d.Id() != "" { + req.NetObjGroupID = d.Id() + } else { + req.NetObjGroupID = d.Get("net_object_group_id").(string) + } + + netObjGroup, err := c.SDN().NetworkObjectGroups().Get(ctx, req) + if err != nil { + return nil, err + } + + return netObjGroup, nil +} diff --git a/internal/service/sdn/netobjgroups/utility_network_object_group_list.go b/internal/service/sdn/netobjgroups/utility_network_object_group_list.go new file mode 100644 index 00000000..e9019013 --- /dev/null +++ b/internal/service/sdn/netobjgroups/utility_network_object_group_list.go @@ -0,0 +1,87 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package netobjgroups + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/netobjgroups" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityNetworkObjectGroupListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*netobjgroups.NetObjGroupList, error) { + c := m.(*controller.ControllerCfg) + + req := netobjgroups.ListRequest{} + + if name, ok := d.GetOk("name"); ok { + req.Name = name.(string) + } + if accessGroupID, ok := d.GetOk("access_group_id"); ok { + req.AccessGroupID = accessGroupID.(string) + } + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if perPage, ok := d.GetOk("per_page"); ok { + req.PerPage = uint64(perPage.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if sortOrder, ok := d.GetOk("sort_order"); ok { + req.SortOrder = sortOrder.(string) + } + if createdFrom, ok := d.GetOk("created_from"); ok { + req.CreatedFrom = createdFrom.(string) + } + if createdTo, ok := d.GetOk("created_to"); ok { + req.CreatedTo = createdTo.(string) + } + if updatedFrom, ok := d.GetOk("updated_from"); ok { + req.UpdatedFrom = updatedFrom.(string) + } + if updatedTo, ok := d.GetOk("updated_to"); ok { + req.UpdatedTo = updatedTo.(string) + } + + log.Debugf("utilityNetworkObjectGroupListCheckPresence") + list, err := c.SDN().NetworkObjectGroups().List(ctx, req) + if err != nil { + return nil, err + } + + return list, nil +} diff --git a/internal/service/sdn/segments/decort_sdn_segment.go b/internal/service/sdn/segments/decort_sdn_segment.go new file mode 100644 index 00000000..fedb5ad1 --- /dev/null +++ b/internal/service/sdn/segments/decort_sdn_segment.go @@ -0,0 +1,67 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package segments + +import ( + "context" + + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceSegmentRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + segment, err := utilitySegmentCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenSegment(d, segment) + d.SetId(segment.ID) + return nil +} + +func DataSourceSegment() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSegmentRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + Schema: dataSourceSegmentSchemaMake(), + } +} diff --git a/internal/service/sdn/segments/decort_sdn_segment_list.go b/internal/service/sdn/segments/decort_sdn_segment_list.go new file mode 100644 index 00000000..432e0bea --- /dev/null +++ b/internal/service/sdn/segments/decort_sdn_segment_list.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package segments + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" +) + +func dataSourceSegmentListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + segmentList, err := utilitySegmentListCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenSegmentList(segmentList)) + + return nil +} + +func DataSourceSegmentList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + ReadContext: dataSourceSegmentListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &constants.Timeout30s, + Default: &constants.Timeout60s, + }, + + Schema: dataSourceSegmentListSchemaMake(), + } +} diff --git a/internal/service/sdn/segments/flattens.go b/internal/service/sdn/segments/flattens.go new file mode 100644 index 00000000..13000a3b --- /dev/null +++ b/internal/service/sdn/segments/flattens.go @@ -0,0 +1,157 @@ +package segments + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/segments" +) + +func flattenSegment(d *schema.ResourceData, segmentRecord *segments.SegmentResponse) { + d.Set("access_group_id", segmentRecord.AccessGroupID) + d.Set("access_group_name", segmentRecord.AccessGroupName) + d.Set("created_at", segmentRecord.CreatedAt.String()) + d.Set("description", segmentRecord.Description) + d.Set("dhcp_v4", flattenDHCPv4(segmentRecord.DHCPv4)) + d.Set("dhcp_v6", flattenDHCPv6(segmentRecord.DHCPv6)) + d.Set("display_name", segmentRecord.DisplayName) + d.Set("enabled", segmentRecord.Enabled) + d.Set("l2_connection_port", flattenL2ConnectionPort(segmentRecord.L2ConnectionPort)) + d.Set("logical_ports_info", flattenEntity(segmentRecord.LogicalPortsInfo)) + d.Set("routers_info", flattenEntity(segmentRecord.RoutersInfo)) + d.Set("status", flattenStatus(segmentRecord.Status)) + d.Set("subnet_v4", segmentRecord.SubnetV4) + d.Set("subnet_v6", segmentRecord.SubnetV6) + d.Set("type", segmentRecord.Type) + d.Set("updated_at", segmentRecord.UpdatedAt.String()) + d.Set("version_id", segmentRecord.VersionID) +} + +func flattenStatus(s segments.Status) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "operation_status": s.OperationStatus, + "hypervisors": flattenHypervisors(s.Hypervisors), + } + res = append(res, temp) + return res +} + +func flattenHypervisors(hv []segments.HypervisorStatus) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(hv)) + for _, v := range hv { + temp := map[string]interface{}{ + "operation_status": v.OperationStatus, + "name": v.Name, + "display_name": v.DisplayName, + "hypervisor_status": v.HypervisorStatus, + "synced_at": v.SyncedAt.String(), + } + res = append(res, temp) + } + return res +} + +func flattenEntity(ei []segments.EntityInfo) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(ei)) + for _, v := range ei { + temp := map[string]interface{}{ + "display_name": v.DisplayName, + "id": v.ID, + } + res = append(res, temp) + } + return res +} + +func flattenDHCPv4(dchp segments.DHCPv4Config) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "dns": dchp.DNS, + "excluded_address_ranges": dchp.ExcludedAddressRanges, + "gateway": dchp.Gateway, + "id": dchp.ID, + "lease_time": dchp.LeaseTime, + "server_ip": dchp.ServerIP, + "server_mac": dchp.ServerMAC, + "enabled": dchp.Enabled, + } + res = append(res, temp) + return res +} + +func flattenDHCPv6(dchp segments.DHCPv6Config) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "dns": dchp.DNS, + "address_prefix": dchp.AddressPrefix, + "id": dchp.ID, + "lease_time": dchp.LeaseTime, + "server_mac": dchp.ServerMAC, + "enabled": dchp.Enabled, + } + res = append(res, temp) + return res +} + +func flattenL2ExternalNetwork(net segments.L2ExternalNetwork) []map[string]interface{} { + return []map[string]interface{}{ + { + "id": net.ID, + "display_name": net.DisplayName, + "description": net.Description, + "bridge_network_name": net.BridgeNetworkName, + "hypervisors": net.Hypervisors, + "vlan_tag": net.VLANTag, + "version_id": net.VersionID, + "created_at": net.CreatedAt.String(), + "created_by": net.CreatedBy, + "updated_at": net.UpdatedAt.String(), + "updated_by": net.UpdatedBy, + }, + } +} + +func flattenL2ConnectionPort(port *segments.L2ConnectionPort) []map[string]interface{} { + if port == nil { + return nil + } + return []map[string]interface{}{ + { + "id": port.ID, + "access_group_id": port.AccessGroupID, + "version_id": port.VersionID, + "created_at": port.CreatedAt.String(), + "created_by": port.CreatedBy, + "updated_at": port.UpdatedAt.String(), + "updated_by": port.UpdatedBy, + "l2_external_network": flattenL2ExternalNetwork(port.L2ExternalNetwork), + }, + } +} + +func flattenSegmentList(sl *segments.ListSegment) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(*sl)) + for _, v := range *sl { + temp := map[string]interface{}{ + "access_group_id": v.AccessGroupID, + "access_group_name": v.AccessGroupName, + "created_at": v.CreatedAt.String(), + "description": v.Description, + "dhcp_v4": flattenDHCPv4(v.DHCPv4), + "dhcp_v6": flattenDHCPv6(v.DHCPv6), + "display_name": v.DisplayName, + "enabled": v.Enabled, + "l2_connection_port": flattenL2ConnectionPort(v.L2ConnectionPort), + "logical_ports_info": flattenEntity(v.LogicalPortsInfo), + "routers_info": flattenEntity(v.RoutersInfo), + "status": flattenStatus(v.Status), + "id": v.ID, + "subnet_v4": v.SubnetV4, + "subnet_v6": v.SubnetV6, + "type": v.Type, + "updated_at": v.UpdatedAt.String(), + "version_id": v.VersionID, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/sdn/segments/resource_sdn_segment.go b/internal/service/sdn/segments/resource_sdn_segment.go new file mode 100644 index 00000000..e04b4af5 --- /dev/null +++ b/internal/service/sdn/segments/resource_sdn_segment.go @@ -0,0 +1,365 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package segments + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/segments" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func resourceSegmentCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSegmentCreate: called segment with name %s", + d.Get("display_name").(string)) + c := m.(*controller.ControllerCfg) + + subnetV4, v4ok := d.GetOk("subnet_v4") + subnetV6, v6ok := d.GetOk("subnet_v6") + + if !v4ok && !v6ok { + return diag.Errorf("resourceSegmentCreate: either subnet_v4 or subnet_v6 must be specified") + } + + req := segments.CreateRequest{ + AccessGroupID: d.Get("access_group_id").(string), + Description: d.Get("description").(string), + DisplayName: d.Get("display_name").(string), + Enabled: d.Get("enabled").(bool), + } + + if t, ok := d.GetOk("type"); ok { + req.Type = t.(string) + } + + if v4ok { + req.SubnetV4 = subnetV4.(string) + } + + if v6ok { + req.SubnetV6 = subnetV6.(string) + } + + if dhcpV4, ok := d.GetOk("dhcp_v4"); ok { + dhcpV4 := dhcpV4.([]interface{})[0] + dhcpV4Map := dhcpV4.(map[string]interface{}) + dhcpReq := segments.DHCPv4ConfigRequest{ + Gateway: dhcpV4Map["gateway"].(string), + ServerIP: dhcpV4Map["server_ip"].(string), + Enabled: dhcpV4Map["enabled"].(bool), + } + serverMAC, sMAC := dhcpV4Map["server_mac"] + if sMAC { + dhcpReq.ServerMAC = serverMAC.(string) + } + + leaseTime, lTime := dhcpV4Map["lease_time"] + if lTime { + dhcpReq.LeaseTime = uint64(leaseTime.(int)) + } + + dns, dnsOk := dhcpV4Map["dns"] + if dnsOk { + dnsArr := make([]string, 0) + for _, v := range dns.([]interface{}) { + dnsArr = append(dnsArr, v.(string)) + } + dhcpReq.DNS = dnsArr + } + + adrRanges, earOK := dhcpV4Map["excluded_address_ranges"] + if earOK { + earArr := make([]string, 0) + for _, v := range adrRanges.([]interface{}) { + earArr = append(earArr, v.(string)) + } + dhcpReq.ExcludedAddressRanges = earArr + } + req.DHCPv4 = &dhcpReq + } + + if dhcpV6, ok := d.GetOk("dhcp_v6"); ok { + dhcpV6 := dhcpV6.([]interface{})[0] + dhcpV6Map := dhcpV6.(map[string]interface{}) + dhcpReq := segments.DHCPv6ConfigRequest{ + AddressPrefix: dhcpV6Map["address_prefix"].(string), + Enabled: dhcpV6Map["enabled"].(bool), + } + serverMAC, sMAC := dhcpV6Map["server_mac"] + if sMAC { + dhcpReq.ServerMAC = serverMAC.(string) + } + + leaseTime, lTime := dhcpV6Map["lease_time"] + if lTime { + dhcpReq.LeaseTime = uint64(leaseTime.(int)) + } + + dns, dnsOk := dhcpV6Map["dns"] + if dnsOk { + dnsArr := make([]string, 0) + for _, v := range dns.([]interface{}) { + dnsArr = append(dnsArr, v.(string)) + } + dhcpReq.DNS = dnsArr + } + req.DHCPv6 = &dhcpReq + } + + segmentData, err := c.SDN().Segments().Create(ctx, req) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(segmentData.ID) + d.Set("segment_id", segmentData.ID) + + return append(resourceSegmentRead(ctx, d, m)) +} + +func resourceSegmentRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSegmentRead: called segment with name %s", + d.Get("display_name").(string)) + + segmentData, err := utilitySegmentCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + flattenSegment(d, segmentData) + + return nil +} + +func resourceSegmentUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSegmentUpdate: called segment with name %s", + d.Get("display_name").(string)) + + c := m.(*controller.ControllerCfg) + + segmentData, err := utilitySegmentCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + subnetV4, v4ok := d.GetOk("subnet_v4") + subnetV6, v6ok := d.GetOk("subnet_v6") + + if !v4ok && !v6ok { + return diag.Errorf("resourceSegmentCreate: either subnet_v4 or subnet_v6 must be specified") + } + + needUpdate := false + + req := segments.UpdateRequest{ + SegmentID: segmentData.ID, + VersionID: segmentData.VersionID, + AccessGroupID: d.Get("access_group_id").(string), + Description: d.Get("description").(string), + DisplayName: d.Get("display_name").(string), + Enabled: d.Get("enabled").(bool), + } + + if d.HasChanges("access_group_id", "description", "display_name", "enabled", "type") { + needUpdate = true + } + + if t, ok := d.GetOk("type"); ok { + req.Type = t.(string) + } + + if v4ok { + req.SubnetV4 = subnetV4.(string) + } + + if v6ok { + req.SubnetV6 = subnetV6.(string) + } + + if d.HasChange("dhcp_v4") { + if dhcpV4, ok := d.GetOk("dhcp_v4"); ok { + dhcpV4 := dhcpV4.([]interface{})[0] + dhcpV4Map := dhcpV4.(map[string]interface{}) + dhcpReq := segments.DHCPv4ConfigRequest{ + Gateway: dhcpV4Map["gateway"].(string), + ServerIP: dhcpV4Map["server_ip"].(string), + Enabled: dhcpV4Map["enabled"].(bool), + } + serverMAC, sMAC := dhcpV4Map["server_mac"] + if sMAC { + dhcpReq.ServerMAC = serverMAC.(string) + } + + leaseTime, lTime := dhcpV4Map["lease_time"] + if lTime { + dhcpReq.LeaseTime = uint64(leaseTime.(int)) + } + + dns, dnsOk := dhcpV4Map["dns"] + if dnsOk { + dnsArr := make([]string, 0) + for _, v := range dns.([]interface{}) { + dnsArr = append(dnsArr, v.(string)) + } + dhcpReq.DNS = dnsArr + } + + adrRanges, earOK := dhcpV4Map["excluded_address_ranges"] + if earOK { + earArr := make([]string, 0) + for _, v := range adrRanges.([]interface{}) { + earArr = append(earArr, v.(string)) + } + dhcpReq.ExcludedAddressRanges = earArr + } + req.DHCPv4 = &dhcpReq + } + + needUpdate = true + } + + if d.HasChange("dhcp_v6") { + if dhcpV6, ok := d.GetOk("dhcp_v6"); ok { + dhcpV6 := dhcpV6.([]interface{})[0] + dhcpV6Map := dhcpV6.(map[string]interface{}) + dhcpReq := segments.DHCPv6ConfigRequest{ + AddressPrefix: dhcpV6Map["address_prefix"].(string), + Enabled: dhcpV6Map["enabled"].(bool), + } + serverMAC, sMAC := dhcpV6Map["server_mac"] + if sMAC { + dhcpReq.ServerMAC = serverMAC.(string) + } + + leaseTime, lTime := dhcpV6Map["lease_time"] + if lTime { + dhcpReq.LeaseTime = uint64(leaseTime.(int)) + } + + dns, dnsOk := dhcpV6Map["dns"] + if dnsOk { + dnsArr := make([]string, 0) + for _, v := range dns.([]interface{}) { + dnsArr = append(dnsArr, v.(string)) + } + dhcpReq.DNS = dnsArr + } + req.DHCPv6 = &dhcpReq + } + needUpdate = true + } + + if needUpdate { + segmentData, err = c.SDN().Segments().Update(ctx, req) + } + + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + d.SetId(segmentData.ID) + d.Set("segment_id", segmentData.ID) + + return append(resourceSegmentRead(ctx, d, m)) +} + +func resourceSegmentDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceSegmentUpdate: called segment with name %s", + d.Get("display_name").(string)) + + segmentData, err := utilitySegmentCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + + req := segments.DeleteRequest{ + SegmentID: segmentData.ID, + VersionID: segmentData.VersionID, + } + + if force, ok := d.GetOk("force"); ok { + req.Force = force.(bool) + } + + c := m.(*controller.ControllerCfg) + err = c.SDN().Segments().Delete(ctx, req) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} + +func ResourceSegment() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + CreateContext: resourceSegmentCreate, + ReadContext: resourceSegmentRead, + UpdateContext: resourceSegmentUpdate, + DeleteContext: resourceSegmentDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error { + changedKeys := diff.GetChangedKeysPrefix("") + if len(changedKeys) > 0 { + diff.SetNewComputed("updated_at") + diff.SetNewComputed("version_id") + } + return nil + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &constants.Timeout600s, + Read: &constants.Timeout300s, + Update: &constants.Timeout600s, + Delete: &constants.Timeout900s, + Default: &constants.Timeout300s, + }, + + Schema: resourceSegmentSchemaMake(), + } +} diff --git a/internal/service/sdn/segments/schema.go b/internal/service/sdn/segments/schema.go new file mode 100644 index 00000000..2174c8a1 --- /dev/null +++ b/internal/service/sdn/segments/schema.go @@ -0,0 +1,841 @@ +package segments + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func l2ExternalNetworkSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "bridge_network_name": { + Type: schema.TypeString, + Computed: true, + }, + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "vlan_tag": { + Type: schema.TypeInt, + Computed: true, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func l2ConnectionPortSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "access_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "created_by": { + Type: schema.TypeString, + Computed: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + "updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "l2_external_network": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: l2ExternalNetworkSchema(), + }, + }, + } +} + +func dataSourceSegmentSchemaMake() map[string]*schema.Schema { + sch := map[string]*schema.Schema{ + "segment_id": { + Type: schema.TypeString, + Required: true, + }, + "access_group_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "access_group_name": { + Type: schema.TypeString, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "dhcp_v4": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "excluded_address_ranges": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + "lease_time": { + Type: schema.TypeInt, + Computed: true, + }, + "server_ip": { + Type: schema.TypeString, + Computed: true, + }, + "server_mac": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "dhcp_v6": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address_prefix": { + Type: schema.TypeString, + Computed: true, + }, + "dns": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + "lease_time": { + Type: schema.TypeInt, + Computed: true, + }, + "server_mac": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "l2_connection_port": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: l2ConnectionPortSchema(), + }, + }, + "logical_ports_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "routers_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + }, + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "subnet_v4": { + Type: schema.TypeString, + Computed: true, + }, + "subnet_v6": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + }, + } + return sch +} + +func dataSourceSegmentListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "per_page": { + Type: schema.TypeInt, + Optional: true, + Description: "Items per page", + }, + "sort_by": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"display_name", "subnet", "created_at", "updated_at"}, false), + Description: "sort by one of supported fields", + }, + "sort_order": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"asc", "dec"}, false), + Description: "sort order", + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: "find by enabled status", + }, + "is_synced": { + Type: schema.TypeBool, + Optional: true, + Description: "does core currently believe that its data is synchronized with the data in the OVN?", + }, + "display_name": { + Type: schema.TypeString, + Optional: true, + Description: "find by display name", + }, + "subnet": { + Type: schema.TypeString, + Optional: true, + Description: "IPv4 or IPv6 subnet for the current segment", + }, + "access_group_id": { + Type: schema.TypeString, + Optional: true, + Description: "find by access group id", + }, + "created_from": { + Type: schema.TypeString, + Optional: true, + Description: "find by created date", + }, + "created_to": { + Type: schema.TypeString, + Optional: true, + Description: "find by created date", + }, + "updated_from": { + Type: schema.TypeString, + Optional: true, + Description: "find by updated date", + }, + "updated_to": { + Type: schema.TypeString, + Optional: true, + Description: "find by updated date", + }, + "operation_status": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"Idle", "SynchronizingAtCore", "SynchronizingAtOVN", "Synchronized", "NoHypervisorAtOVN", "FailedAtCore", "TemporaryFailedAtCore"}, false), + Description: "filter by operation status", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "access_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "access_group_name": { + Type: schema.TypeString, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "dhcp_v4": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "excluded_address_ranges": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gateway": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + "lease_time": { + Type: schema.TypeInt, + Computed: true, + }, + "server_ip": { + Type: schema.TypeString, + Computed: true, + }, + "server_mac": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "dhcp_v6": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address_prefix": { + Type: schema.TypeString, + Computed: true, + }, + "dns": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + "lease_time": { + Type: schema.TypeInt, + Computed: true, + }, + "server_mac": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "l2_connection_port": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: l2ConnectionPortSchema(), + }, + }, + "logical_ports_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "routers_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + }, + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "subnet_v4": { + Type: schema.TypeString, + Computed: true, + }, + "subnet_v6": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "entry_count": { + Type: schema.TypeInt, + Computed: true, + Description: "entry count", + }, + } + return res +} + +func resourceSegmentSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "access_group_id": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Required: true, + }, + "display_name": { + Type: schema.TypeString, + Required: true, + }, + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + "force": { + Type: schema.TypeBool, + Optional: true, + }, + "subnet_v4": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "subnet_v6": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "dhcp_v4": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "excluded_address_ranges": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gateway": { + Type: schema.TypeString, + Required: true, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + "lease_time": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "server_ip": { + Type: schema.TypeString, + Required: true, + }, + "server_mac": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + }, + }, + }, + "dhcp_v6": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address_prefix": { + Type: schema.TypeString, + Required: true, + }, + "dns": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + "lease_time": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "server_mac": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + }, + }, + }, + "access_group_name": { + Type: schema.TypeString, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "l2_connection_port": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: l2ConnectionPortSchema(), + }, + }, + "logical_ports_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "routers_info": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + }, + "hypervisors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "operation_status": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "hypervisor_status": { + Type: schema.TypeString, + Computed: true, + }, + "synced_at": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + "version_id": { + Type: schema.TypeInt, + Computed: true, + }, + } + return res +} diff --git a/internal/service/sdn/segments/utility_segment.go b/internal/service/sdn/segments/utility_segment.go new file mode 100644 index 00000000..8d5d526a --- /dev/null +++ b/internal/service/sdn/segments/utility_segment.go @@ -0,0 +1,28 @@ +package segments + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/segments" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilitySegmentCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*segments.SegmentResponse, error) { + c := m.(*controller.ControllerCfg) + + req := segments.GetRequest{} + + if d.Id() != "" { + req.SegmentID = d.Id() + } else { + req.SegmentID = d.Get("segment_id").(string) + } + + segment, err := c.SDN().Segments().Get(ctx, req) + if err != nil { + return nil, err + } + + return segment, nil +} diff --git a/internal/service/sdn/segments/utility_segment_list.go b/internal/service/sdn/segments/utility_segment_list.go new file mode 100644 index 00000000..9265afdc --- /dev/null +++ b/internal/service/sdn/segments/utility_segment_list.go @@ -0,0 +1,66 @@ +package segments + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/segments" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilitySegmentListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*segments.ListSegment, error) { + c := m.(*controller.ControllerCfg) + req := segments.ListRequest{} + + if page, ok := d.GetOk("page"); ok { + req.Page = uint64(page.(int)) + } + if perPage, ok := d.GetOk("per_page"); ok { + req.PerPage = uint64(perPage.(int)) + } + if sortBy, ok := d.GetOk("sort_by"); ok { + req.SortBy = sortBy.(string) + } + if sortOrder, ok := d.GetOk("sort_order"); ok { + req.SortOrder = sortOrder.(string) + } + if enabled, ok := d.GetOk("enabled"); ok { + req.Enabled = enabled.(bool) + } + if isSynced, ok := d.GetOk("is_synced"); ok { + req.IsSynced = isSynced.(bool) + } + if displayName, ok := d.GetOk("display_name"); ok { + req.DisplayName = displayName.(string) + } + if subnet, ok := d.GetOk("subnet"); ok { + req.Subnet = subnet.(string) + } + if accessGroupID, ok := d.GetOk("access_group_id"); ok { + req.AccessGroupID = accessGroupID.(string) + } + if createdFrom, ok := d.GetOk("created_from"); ok { + req.CreatedFrom = createdFrom.(string) + } + if createdTo, ok := d.GetOk("created_to"); ok { + req.CreatedTo = createdTo.(string) + } + if updatedFrom, ok := d.GetOk("updated_from"); ok { + req.UpdatedFrom = updatedFrom.(string) + } + if updatedTo, ok := d.GetOk("updated_to"); ok { + req.UpdatedTo = updatedTo.(string) + } + if operationStatus, ok := d.GetOk("operation_status"); ok { + req.OperationStatus = operationStatus.(string) + } + + log.Debugf("utilitySegmentListCheckPresence") + segmentList, err := c.SDN().Segments().List(ctx, req) + if err != nil { + return nil, err + } + + return &segmentList, nil +} diff --git a/internal/statefuncs/statefuncs.go b/internal/statefuncs/statefuncs.go new file mode 100644 index 00000000..44c17aff --- /dev/null +++ b/internal/statefuncs/statefuncs.go @@ -0,0 +1,30 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package statefuncs + +import "strings" + +func StateFuncToLower(argval interface{}) string { + return strings.ToLower(argval.(string)) +} + +func StateFuncToUpper(argval interface{}) string { + return strings.ToUpper(argval.(string)) +} diff --git a/internal/status/status.go b/internal/status/status.go new file mode 100644 index 00000000..223d0da9 --- /dev/null +++ b/internal/status/status.go @@ -0,0 +1,201 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package status + +type Status = string + +var ( + // An object is Confirmed + // Status available for: + // - Account + Confirmed Status = "CONFIRMED" + + // The disk is linked to any Compute + // Status available for: + // - Disk + Assigned Status = "ASSIGNED" + + // An object enabled for operations + // Status available for: + // - Compute + // - Disk + // - Vins + // - BasicService + // - K8s Cluster + // - Load Balancer + // - cloudbroker/extnet + Enabled Status = "ENABLED" + + // Enabling in process + // Status available for: + // - Disk + // - Vins + // - BasicService + // - K8s Cluster + // - Load Balancer + Enabling Status = "ENABLING" + + // An object disabled for operations + // Status available for: + // - Compute + // - Disk + // - Vins + // - Account + // - BasicService + // - K8s Cluster + // - Load Balancer + // - cloudbroker/extnet + Disabled Status = "DISABLED" + + // Disabling in process + // Status available for: + // - Disk + // - Vins + // - BasicService + // - K8s Cluster + // - Load Balancer + Disabling Status = "DISABLING" + + // An object model has been created in the database + // Status available for: + // - Image + // - Disk + // - Compute + // - Vins + // - BasicService + // - K8s Cluster + // - Load Balancer + Modeled Status = "MODELED" + + // In the process of creation + // Status available for: + // - Image + // - Disk + // - K8s Cluster + // - Load Balancer + Creating Status = "CREATING" + + // An object was created successfully + // Status available for: + // - Image + // - Disk + // - Compute + // - Vins + // - K8s Cluster + // - BasicService + // - Load Balancer + Created Status = "CREATED" + + // Physical resources are allocated for the object + // Status available for: + // - Compute + // - Disk + Allocated Status = "ALLOCATED" + + // The object has released (returned to the platform) the physical resources that it occupied + // Status available for: + // - Compute + // - Disk + Unallocated Status = "UNALLOCATED" + + // Destroying in progress + // Status available for: + // - Disk + // - Compute + // - Vins + // - Account + // - BasicService + // - K8s Cluster + // - Load Balancer + Destroying Status = "DESTROYING" + + // Permanently deleted + // Status available for: + // - Image + // - Disk + // - Compute + // - Vins + // - Account + // - BasicService + // - K8s Cluster + // - Load Balancer + Destroyed Status = "DESTROYED" + + // Deleting in progress to Trash + // Status available for: + // - Compute + // - Vins + // - BasicService + // - K8s Cluster + // - Load Balancer + Deleting Status = "DELETING" + + // Deleted to Trash + // Status available for: + // - Compute + // - Vins + // - Account + // - BasicService + // - Disk + // - K8s Cluster + // - Load Balancer + Deleted Status = "DELETED" + + // Deleted from storage + // Status available for: + // - Image + // - Disk + Purged Status = "PURGED" + + // Repeating deploy of the object in progress + // Status available for: + // - Compute + Redeploying Status = "REDEPLOYING" + + // The resource is not bound to vnf device + // Status available for: + // - vins vnf + Stashed Status = "STASHED" + + // Object is in restoration process + // Status available for: + // - BasicService + // - K8s Cluster + // - Load Balancer + Restoring Status = "RESTORING" + + // Object is in reconfiguration process + // Status available for: + // - BasicService + Reconfiguring Status = "RECONFIGURING" +) diff --git a/internal/techstatus/techstatus.go b/internal/techstatus/techstatus.go new file mode 100644 index 00000000..c241231d --- /dev/null +++ b/internal/techstatus/techstatus.go @@ -0,0 +1,100 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud +Orchestration Technology) with Terraform by Hashicorp. + +Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort + +Please see README.md to learn where to place source code so that it +builds seamlessly. + +Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki +*/ + +package techstatus + +type TechStatus = string + +var ( + // Start in progress - send an execution command + // Status available for: + // - Compute + Starting TechStatus = "STARTING" + + // An object started + // Can be stopped + // Correctly running + // Status available for: + // - Compute + Started TechStatus = "STARTED" + + // Stop in progress - send an execution command + // Status available for: + // - Compute + Stopping TechStatus = "STOPPING" + + // An object stopped + // Can be started + // Limited functionality + // Status available for: + // - Compute + Stopped TechStatus = "STOPPED" + + // Pause in progress - send an execution command + // Status available for: + // - Compute + Pausing TechStatus = "PAUSING" + + // An object paused + // Can be restarted + // Currently running + // Status available for: + // - Compute + Paused TechStatus = "PAUSED" + + // Migrate in progress + // Status available for: + // - Compute + Migrating TechStatus = "MIGRATING" + + // An object failure status + // Can be reastarted + // Limited functionality + // Status available for: + // - Compute + Down TechStatus = "DOWN" + + // An object configuration process + // Status available for: + // - Compute + Scheduled TechStatus = "SCHEDULED" + + // Physical resources are allocated for the object + // Status available for: + // - Image + Allocated TechStatus = "ALLOCATED" + + // The object has released (returned to the platform) the physical resources that it occupied + // Status available for: + // - Image + Unallocated TechStatus = "UNALLOCATED" +) diff --git a/internal/validators/validator.go b/internal/validators/validator.go new file mode 100644 index 00000000..6cca2159 --- /dev/null +++ b/internal/validators/validator.go @@ -0,0 +1,22 @@ +package validators + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func DivisibleBy(divisibility int) schema.SchemaValidateFunc { + return func(i interface{}, k string) (warnings []string, errors []error) { + total, ok := i.(int) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %s to be integer", k)) + return warnings, errors + } + if total%divisibility != 0 { + errors = append(errors, fmt.Errorf("expected value of %s to be divisible by %d", k, divisibility)) + } + + return warnings, errors + } +} diff --git a/samples/README.md b/samples/README.md new file mode 100644 index 00000000..cdfa4142 --- /dev/null +++ b/samples/README.md @@ -0,0 +1,338 @@ +# Примеры применения ресурсов terraform-provider-decort + +Каждый файл снабжен комментариями, которые кратко описывают возможности и параметры ресурса. +Для успешной работы необходим установленный terraform. + +## Ресурсы в примерах + +- cloudapi: + - data: + - account + - account_audits_list + - account_computes_list + - account_consumed_units + - account_consumed_units_by_type + - account_deleted_list + - account_disks_list + - account_flipgroups_list + - account_list + - account_reserved_units + - account_resource_consumption_get + - account_resource_consumption_list + - account_rg_list + - account_templates_list + - account_vins_list + - audit + - bservice + - bservice_deleted_list + - bservice_group + - bservice_list + - bservice_snapshot_list + - disk + - disk_list + - disk_list_deleted + - disk_list_types + - disk_list_types_detailed + - disk_list_unattached + - disk_replication + - disk_snapshot + - disk_snapshot_list + - dpdknet + - dpdknet_list + - extnet + - extnet_computes_list + - extnet_default + - extnet_list + - extnet_reserved_ip_list + - flipgroup + - flipgroup_list + - image + - image_list + - k8ci_list + - k8s + - k8s_computes + - k8s_list + - k8s_list_deleted + - k8s_wg + - k8s_wg_cloud_init + - k8s_wg_list + - kvmvm + - kvmvm_audits + - kvmvm_get_audits + - kvmvm_get_console_url + - kvmvm_get_log + - kvmvm_list + - vkvmvm_list_deleted + - kvmvm_pci_device_list + - kvmvm_pfw_list + - kvmvm_snapshot_usage + - kvmvm_user_list + - kvmvm_vgpu_list + - kvmvm_cpu_alignment_profile + - lb + - lb_list + - lb_list_deleted + - location_url + - locations_list + - resgroup + - rg_affinity_group_computes + - rg_affinity_groups_get + - rg_affinity_groups_list + - rg_audits + - rg_list + - rg_list_computes + - rg_list_deleted + - rg_list_lb + - rg_list_pfw + - rg_list_vins + - rg_resource_consumption_get + - rg_resource_consumption_list + - rg_usage + - security_group + - security_group_list + - sep_and_pools_available_list + - snapshot_list + + - storage_policy + - storage_policy_list + - trunk + - trunk_list + - vfpool + - vfpool_list + - vins + - vins_audits + - vins_ext_net_list + - vins_ip_list + - vins_list + - vins_list_deleted + - vins_nat_rule_list + - vins_static_route + - vins_static_route_list + - zone + - zone_list + - resources: + - account + - bservice + - bservice_group + - disk + - disk_snapshot + - flipgroup + - image + - image_from_blank_compute + - image_from_platform_disk + - image_virtual + - k8s + - k8s_cp + - k8s_wg + - kvmvm + - lb + - lb_backend + - lb_backend_server + - lb_frontend + - lb_frontend_bind + - pfw + - resgroup + - security_group + - snapshot + - vins + - vins_static_route +- cloudbroker: + - data: + - cb_account + - cb_account_audits_list + - cb_account_available_templates_list + - cb_account_computes_list + - cb_account_disks_list + - cb_account_flipgroups_list + - cb_account_list + - cb_account_list_deleted + - cb_account_resource_consumption_get + - cb_account_resource_consumption_list + - cb_account_rg_list + - cb_account_vins_list + - cb_audit + - cb_audit_linked_jobs + - cb_audit_list + - cb_audits_export_to_file + - cb_disk + - cb_disk_list + - cb_disk_list_deleted + - cb_disk_list_types + - cb_disk_list_types_detailed + - cb_disk_list_unattached + - cb_disk_replication + - cb_disk_snapshot + - cb_disk_snapshot_list + - cb_dpdknet + - cb_dpdknet_list + - cb_extnet + - cb_extnet_default + - cb_extnet_list + - cb_extnet_reserved_ip_list + - cb_extnet_static_route + - cb_extnet_static_route_list + - cb_flipgroup + - cb_flipgroup_list + - cb_grid + - cb_grid_get_consumption + - cb_grid_get_diagnosis + - cb_grid_get_settings + - cb_grid_get_status + - cb_grid_list + - cb_grid_list_consumption + - cb_grid_list_emails + - cb_grid_post_status + - cb_image + - cb_image_list + - cb_k8ci + - cb_k8ci_list + - cb_k8ci_list_deleted + - cb_k8s + - cb_k8s_computes + - cb_k8s_list + - cb_k8s_list_deleted + - cb_k8s_wg + - cb_k8s_wg_cloud_init + - cb_k8s_wg_list + - cb_kvmvm + - cb_kvmvm_affinity_relations + - cb_kvmvm_audits + - cb_kvmvm_boot_order_get + - cb_kvmvm_get_audits + - cb_kvmvm_get_console_url + - cb_kvmvm_get_log + - cb_kvmvm_list + - cb_kvmvm_list_deleted + - cb_kvmvm_migrate_storage_info + - cb_kvmvm_pci_device_list + - cb_kvmvm_pfw_list + - cb_kvmvm_snapshot_list + - cb_kvmvm_snapshot_usage + - cb_kvmvm_user_list + - cb_kvmvm_vgpu_list + - cb_kvmvm_cpu_alignment_profile + - cb_lb + - cb_lb_list + - cb_lb_list_deleted + - cb_node + - cb_node_list + - cb_node_network_info + - cb_node_pci_devices + - cb_pcidevice + - cb_pcidevice_list + - cb_rg + - cb_rg_affinity_group_computes + - cb_rg_affinity_groups_get + - cb_rg_affinity_groups_list + - cb_rg_audits + - cb_rg_list + - cb_rg_list_computes + - cb_rg_list_deleted + - cb_rg_list_lb + - cb_rg_list_pfw + - cb_rg_list_vins + - cb_rg_resource_consumption_get + - cb_rg_resource_consumption_list + - cb_rg_usage + - cb_security_group + - cb_security_group_list + - cb_sep + - cb_sep_and_pools_available_list + - cb_sep_config + - cb_sep_consumption + - cb_sep_disk_list + - cb_sep_list + - cb_sep_pool + - cb_storage_policy + - cb_storage_policy_list + - cb_trunk + - cb_trunk_list + - cb_user + - cb_user_get_audit + - cb_user_list + - cb_vfpool + - cb_vfpool_list + - cb_vins + - cb_vins_audits + - cb_vins_ext_net_list + - cb_vins_ip_list + - cb_vins_list + - cb_vins_list_deleted + - cb_vins_nat_rule_list + - cb_vins_static_route + - cb_vins_static_route_list + - cb_zone + - cb_zone_list + - cb_zone_cpu_alignment_profile + - cb_zone_cpu_alignment_profile_list + - cb_zone_cpu_alignment_profile_test + - resources: + - cb_account + - cb_cdrom_image + - cb_disk + - cb_disk_snapshot + - cb_dpdknet + - cb_extnet + - cb_extnet_static_route + - cb_flipgroup + - cb_image + - cb_image_from_blank_compute + - cb_image_from_platform_disk + - cb_k8ci + - cb_k8s_cp + - cb_k8s_wg + - cb_kvmvm + - cb_lb + - cb_lb_backend + - cb_lb_backend_server + - cb_lb_frontend + - cb_lb_frontend_bind + - cb_pcidevice + - cb_rg + - cb_security_group + - cb_sep + - cb_sep_config + - cb_sep_template + - cb_storage_policy + - cb_trunk + - cb_user + - cb_vfpool + - cb_vins + - cb_vins_static_route + - cb_virtual_image + - decort_cb_multi_image + - cb_zone +- sdn + - data: + - sdn_access_group + - sdn_access_group_list + - sdn_access_group_user_list + - sdn_default_security_policy_list + - sdn_segment + - sdn_segment_list + - sdn_logical_port + - sdn_logical_port_get_by_unique_identifier + - sdn_logical_port_list + - sdn_hypervisor + - sdn_hypervisor_list + - sdn_network_object_group + - sdn_network_object_group_list + - resources: + - sdn_access_group + - sdn_segment + - sdn_logical_port + - sdn_hypervisor + - sdn_network_object_group + +## Как пользоваться примерами + +1. Установить terraform +2. Установить terraform-provider-decort с помощью команды `terraform init` (выполняется автоматически), либо вручную. +3. Заменить параметр _controller_url_ на ваш. +4. Заменить параметр _oauth2_url_ на ваш. +5. Добавить ключи + _DECORT_APP_SECRET_ и _DECORT_APP_ID_ + в качестве переменных окружения, либо + можно добавить `app_id` и `app_secret` + в блок `provider`,что небезопасно, т.к. данные + могут быть похищены при передачи файла. diff --git a/samples/cloudapi/account/data_account/main.tf b/samples/cloudapi/account/data_account/main.tf new file mode 100644 index 00000000..675c8301 --- /dev/null +++ b/samples/cloudapi/account/data_account/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации об аккаунте +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account" "a" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 11111 +} + +output "test" { + value = data.decort_account.a +} diff --git a/samples/cloudapi/account/data_account_audits_list/main.tf b/samples/cloudapi/account/data_account_audits_list/main.tf new file mode 100644 index 00000000..1ea2d735 --- /dev/null +++ b/samples/cloudapi/account/data_account_audits_list/main.tf @@ -0,0 +1,44 @@ +/*Deprecated + +Данный datasource является **deprecated** и будет удалён в следующих версиях. Вместо него неоходимо использовать datasource **decort_audit_list**. +*/ + +/* +Пример использования +Получение информации об использовании аккаунта +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_audits_list" "aal" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 11111 +} + +output "test" { + value = data.decort_account_audits_list.aal +} diff --git a/samples/cloudapi/account/data_account_computes_list/main.tf b/samples/cloudapi/account/data_account_computes_list/main.tf new file mode 100644 index 00000000..12f4e3bc --- /dev/null +++ b/samples/cloudapi/account/data_account_computes_list/main.tf @@ -0,0 +1,96 @@ +/* +Пример использования +Получение списка computes, используемых аккаунтом +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_computes_list" "acl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 1111 + + #фильтр по id compute + #опциональный параметр + #тип - целое число + #compute_id = 100 + + #фильтр по имени compute + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #rg_name = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STARTED" + + #фильтр по ip address + #опциональный параметр + #тип - строка + #ip_address = "1.1.1.1.1" + + #фильтр по имени внешней сети + #опциональный параметр + #тип - строка + #extnet_name = "test" + + #фильтр по id внешней сети + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "test" { + value = data.decort_account_computes_list.acl +} diff --git a/samples/cloudapi/account/data_account_consumed_units/main.tf b/samples/cloudapi/account/data_account_consumed_units/main.tf new file mode 100644 index 00000000..a0a93cf7 --- /dev/null +++ b/samples/cloudapi/account/data_account_consumed_units/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о расходуемых ресурсах аккаута +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_consumed_units" "acu" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 22222 +} + +output "test" { + value = data.decort_account_consumed_units.acu +} diff --git a/samples/cloudapi/account/data_account_consumed_units_by_type/main.tf b/samples/cloudapi/account/data_account_consumed_units_by_type/main.tf new file mode 100644 index 00000000..d74264f0 --- /dev/null +++ b/samples/cloudapi/account/data_account_consumed_units_by_type/main.tf @@ -0,0 +1,54 @@ +/* +Пример использования +Ресурса cdrom image +Ресурс позволяет: +1. Создавать образ +2. Редактировать образ +3. Удалять образ +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_consumed_units_by_type" "acubt" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 33333 + + #тип вычислительной единицы + #обязательный параметр + #тип - строка + #значения: + #CU_C - кол-во виртуальных cpu ядер + #CU_M - кол-во RAM, в МБ + #CU_D - кол-во используемой дисковой памяти, в ГБ + #CU_I - кол-во публичных ip адресов + #CU_DM - кол-во доступной дисковой памяти, в ГБ + #gpu_units - кол-во GPU + cu_type = "CU_C" +} + +output "test" { + value = data.decort_account_consumed_units_by_type.acubt +} diff --git a/samples/cloudapi/account/data_account_deleted_list/main.tf b/samples/cloudapi/account/data_account_deleted_list/main.tf new file mode 100644 index 00000000..e5b24fc0 --- /dev/null +++ b/samples/cloudapi/account/data_account_deleted_list/main.tf @@ -0,0 +1,67 @@ +/* +Пример использования +Получение информации об удаленных аккаунтах +Информация предоставляется только по аккаунтам, удаленным без флага permanently +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_deleted_list" "adl" { + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по ACL + #опциональный параметр + #тип - строка + #acl = "test" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" +} + +output "test" { + value = data.decort_account_deleted_list.adl +} diff --git a/samples/cloudapi/account/data_account_disks_list/main.tf b/samples/cloudapi/account/data_account_disks_list/main.tf new file mode 100644 index 00000000..fa01087a --- /dev/null +++ b/samples/cloudapi/account/data_account_disks_list/main.tf @@ -0,0 +1,75 @@ +/* +Пример использования +Получение информации о дисках, которые использует аккаунт +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_disks_list" "adl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 11111 + + #фильтр по id диска + #опциональный параметр + #тип - целое число + #disk_id = 100 + + #фильтр по имени диска + #опциональный параметр + #тип - строка + #name = "data_disk" + + #фильтр по максимальному размеру диска + #опциональный параметр + #тип - целое число + #disk_max_size = 100 + + #тип диска + #опциональный параметр + #тип - строка + #возможные типы: "b" - boot_disk, "d" - data_disk + #type = "d" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_account_disks_list.adl +} diff --git a/samples/cloudapi/account/data_account_flipgroups_list/main.tf b/samples/cloudapi/account/data_account_flipgroups_list/main.tf new file mode 100644 index 00000000..16334d35 --- /dev/null +++ b/samples/cloudapi/account/data_account_flipgroups_list/main.tf @@ -0,0 +1,84 @@ +/* +Пример использования +Получение информации о flipgroups, используемых аккаунтом +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_flipgroups_list" "afgl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 1111 + + #фильтр по имени flipgroup + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id vins + #опциональный параметр + #тип - целое число + #vins_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #vins_name = "test" + + #фильтр по id extnet + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #фильтр по IP + #опциональный параметр + #тип - строка + #by_ip = "1.1.1.1.1" + + #фильтр по id flipgroup + #опциональный параметр + #тип - целое число + #flipgroup_id = 100 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_account_flipgroups_list.afgl +} diff --git a/samples/cloudapi/account/data_account_get_resource_consumption/main.tf b/samples/cloudapi/account/data_account_get_resource_consumption/main.tf new file mode 100644 index 00000000..7d28dc74 --- /dev/null +++ b/samples/cloudapi/account/data_account_get_resource_consumption/main.tf @@ -0,0 +1,38 @@ +/* +Получение списка текущего потребления ресурсов аккаунта +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_resource_consumption_get" "rc_get" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 111 +} + +output "test" { + value = data.decort_account_resource_consumption_get.rc_get +} + diff --git a/samples/cloudapi/account/data_account_list/main.tf b/samples/cloudapi/account/data_account_list/main.tf new file mode 100644 index 00000000..f349f2ab --- /dev/null +++ b/samples/cloudapi/account/data_account_list/main.tf @@ -0,0 +1,77 @@ +/* +Пример использования +Получение списка доступных аккаунтов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_list" "al" { + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по ACL + #опциональный параметр + #тип - строка + #acl = "test" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 +} + +output "test" { + value = data.decort_account_list.al +} diff --git a/samples/cloudapi/account/data_account_reserved_units/main.tf b/samples/cloudapi/account/data_account_reserved_units/main.tf new file mode 100644 index 00000000..3966bef1 --- /dev/null +++ b/samples/cloudapi/account/data_account_reserved_units/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о зарезервированных вычислительных мощностях +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_reserved_units" "aru" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 11111 +} + +output "test" { + value = data.decort_account_reserved_units.aru +} diff --git a/samples/cloudapi/account/data_account_resource_consumption_list/main.tf b/samples/cloudapi/account/data_account_resource_consumption_list/main.tf new file mode 100644 index 00000000..9f0e666e --- /dev/null +++ b/samples/cloudapi/account/data_account_resource_consumption_list/main.tf @@ -0,0 +1,35 @@ +/* +Получение списка текущего потребления ресурсов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_resource_consumption_list" "rc_list" { + #нет входных параметров +} + +output "test" { + value = data.decort_account_resource_consumption_list.rc_list +} + diff --git a/samples/cloudapi/account/data_account_rg_list/main.tf b/samples/cloudapi/account/data_account_rg_list/main.tf new file mode 100644 index 00000000..231fed4a --- /dev/null +++ b/samples/cloudapi/account/data_account_rg_list/main.tf @@ -0,0 +1,81 @@ +/* +Пример использования +Получение информации о ресурных группах, используемых аккаунтом +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_rg_list" "argl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 66666 + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 11111 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id vins + #опциональный параметр + #тип - целое число + #vins_id = 100 + + #фильтр по id compute + #опциональный параметр + #тип - целое число + #vm_id = 100 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "CREATED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" +} + +output "test" { + value = data.decort_account_rg_list.argl +} diff --git a/samples/cloudapi/account/data_account_templates_list/main.tf b/samples/cloudapi/account/data_account_templates_list/main.tf new file mode 100644 index 00000000..286b2216 --- /dev/null +++ b/samples/cloudapi/account/data_account_templates_list/main.tf @@ -0,0 +1,76 @@ +/* +Пример использования +Получение информации о шаблонах, используемых аккаунтом +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_templates_list" "atl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 11111 + + #фильтр "включая удаленные шаблоны" + #опциональный параметр + #тип - булев + #include_deleted = true + + #фильтр по id образа + #опциональный параметр + #тип - целое число + #image_id = 1111 + + #фильтр по имени + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по типу + #опциональный параметр + #тип - строка + #type = "linux" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 +} + +output "test" { + value = data.decort_account_templates_list.atl +} diff --git a/samples/cloudapi/account/data_account_vins_list/main.tf b/samples/cloudapi/account/data_account_vins_list/main.tf new file mode 100644 index 00000000..2c0a6cc7 --- /dev/null +++ b/samples/cloudapi/account/data_account_vins_list/main.tf @@ -0,0 +1,76 @@ +/* +Пример использования +Получение списка vins, используемых аккаунтом +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_account_vins_list" "avl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 22222 + + #фильтр по id vins + #опциональный параметр + #тип - целое число + #vins_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 11111 + + #фильтр по IP внешней сети + #опциональный параметр + #тип - строка + #ext_ip = "test" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 +} + +output "test" { + value = data.decort_account_vins_list.avl +} diff --git a/samples/cloudapi/account/resource_account/main.tf b/samples/cloudapi/account/resource_account/main.tf new file mode 100644 index 00000000..a82fdead --- /dev/null +++ b/samples/cloudapi/account/resource_account/main.tf @@ -0,0 +1,146 @@ +/* +Пример использования +Ресурса account +Ресурс позволяет: +1. Редактировать аккаунт +2. Удалять аккаунт +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_account" "a" { + #имя аккаунта + #обязательный параметр + #тип - строка + #используется при обновлении + account_name = "new_my_account" + + #описание + #опциональный параметр + #тип - строка + #используется при обновлении + #desc = "description" + + #доступность аккаунта + #опциональный параметр + #тип - булев + #используется при обновлении + #enable = true + + #id аккаунта, позволяет сформировать .tfstate, если аккаунт имеется на платформе + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #отправлять ли на электронную почту письмо о доступе + #опциональный параметр + #тип - булев + #используется при обновлении + #send_access_emails = true + + #добавление/редактирование/удаление пользователей, к которым привязан аккаунт + #опциональный параметр + #используется при обновлении + #тип - объект, кол-во таких объектов не ограничено + #users { + #id пользователя + #обязательный параметр + #тип - строка + #user_id = "username_2@decs3o" + + #тип доступа пользователя + #обязательный параметр + #тип - строка + #возможные параметры: + #R - чтение + #RCX - запись + #ARCXDU - админ + #access_type = "R" + #} + + #users { + #user_id = "username_1@decs3o" + #access_type = "R" + #} + + #ограничение используемых ресурсов + #опциональный параметр + #тип - объект + #используется при обновлении + #resource_limits { + #кол-во используемых ядер cpu + #опциональный параметр + #тип - целое число + #если установлена -1 - кол-во неограничено + #cu_c = 2 + + #кол-во используемой RAM, в МБ + #опциональный параметр + #тип - целое число + #если установлена -1 - кол-во неограничено + #cu_m = 1024 + + #размер дисков, в ГБ + #опциональный параметр + #тип - целое число + #если установлена -1 - размер неограничено + #cu_d = 23 + + #кол-во используемых публичных IP + #опциональный параметр + #тип - целое число + #если установлена -1 - кол-во неограничено + #cu_i = 2 + + #кол-во графических процессоров + #опциональный параметр + #тип - целое число + #если установлена -1 - кол-во неограничено + #gpu_units = 2 + #} + + #восстановление аккаунта + #опциональный параметр + #тип - булев + #применяется к удаленным аккаунтам + #по умолчанию - false + #restore = false + + #флаг для удаления аккаунта, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #по умолчанию - false + #permanently = true + + #зона по умолчанию для аккаунта + #опциональный параметр + #тип - целое число + #используется при обновлении + #default_zone_id = 1111 +} + +output "test" { + value = decort_account.a +} diff --git a/samples/cloudapi/audit/data_audit/main.tf b/samples/cloudapi/audit/data_audit/main.tf new file mode 100644 index 00000000..2885e67c --- /dev/null +++ b/samples/cloudapi/audit/data_audit/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение аудита по guid +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_audit" "audit" { + #guid аудита + #обязательный параметр + #тип - строка + audit_guid = "abcdefg" + +} + +output "test" { + value = data.decort_audit.audit +} diff --git a/samples/cloudapi/audit/data_audit_list/main.tf b/samples/cloudapi/audit/data_audit_list/main.tf new file mode 100644 index 00000000..eee0ec6d --- /dev/null +++ b/samples/cloudapi/audit/data_audit_list/main.tf @@ -0,0 +1,136 @@ +/* +Пример использования +Получение списка аудитов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_audit_list" "al" { + #фильтр по аудитам с временной меткой после указанного значения + #опциональный параметр + #тип - целое число + #timestamp_at = 123456 + + #фильтр по аудитам с временной меткой до указанного значения + #опциональный параметр + #тип - целое число + #timestamp_to = 123456 + + #фильтр по пользователю (Mongo RegExp поддерживаются) + #опциональный параметр + #тип - строка + #user = "username" + + #фильтр по api endpoint (Mongo RegExp поддерживаются) + #опциональный параметр + #тип - строка + #call = "/restmachine/cloudbroker/audit/list" + + #фильтр по минимальному HTTP статус-коду + #опциональный параметр + #тип - целое число + #min_status_code = 200 + + #фильтр по максимальному HTTP статус-коду + #опциональный параметр + #тип - целое число + #max_status_code = 500 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 2 + + #идентификатор запроса + #опциональный параметр + #тип - строка + #request_id = "35" + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 3 + + #id ресурсной группы + #опциональный параметр + #тип - целое число + #resgroup_id = 3 + + #id компьюта + #опциональный параметр + #тип - целое число + #compute_id = 3 + + #id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 3 + + #id vins + #опциональный параметр + #тип - целое число + #vins_id = 3 + + #id базовой службы + #опциональный параметр + #тип - целое число + #service_id = 3 + + #id k8s-кластера + #опциональный параметр + #тип - целое число + #k8s_id = 3 + + #id flipgroup + #опциональный параметр + #тип - целое число + #flipgroup_id = 3 + + #id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #lb_id = 3 + + #id sep + #опциональный параметр + #тип - целое число + #sep_id = 3 + + #исключить ли строки + #опциональный параметр + #тип - булев + #default – false + #exclude_audit_lines = false + +} + +output "test" { + value = data.decort_audit_list.al +} diff --git a/samples/cloudapi/bservice/data_bservice/main.tf b/samples/cloudapi/bservice/data_bservice/main.tf new file mode 100644 index 00000000..ffce4997 --- /dev/null +++ b/samples/cloudapi/bservice/data_bservice/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о basic service +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_bservice" "b" { + #id сервиса + #обязательный параметр + #тип - целое число + service_id = 11111 +} + +output "test" { + value = data.decort_bservice.b +} diff --git a/samples/cloudapi/bservice/data_bservice_deleted_list/main.tf b/samples/cloudapi/bservice/data_bservice_deleted_list/main.tf new file mode 100644 index 00000000..5f195d27 --- /dev/null +++ b/samples/cloudapi/bservice/data_bservice_deleted_list/main.tf @@ -0,0 +1,64 @@ +/* +Пример использования +Получение списка удаленных basic service +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_bservice_deleted_list" "bsdl" { + #id аккаунта для фильтрации данных + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #account_id = 11111 + + #id ресурсной группы, используется для фильтрации + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #rg_id = 11111 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 + +} + +output "test" { + value = data.decort_bservice_deleted_list.bsdl +} diff --git a/samples/cloudapi/bservice/data_bservice_group/main.tf b/samples/cloudapi/bservice/data_bservice_group/main.tf new file mode 100644 index 00000000..eda6c89e --- /dev/null +++ b/samples/cloudapi/bservice/data_bservice_group/main.tf @@ -0,0 +1,44 @@ +/* +Пример использования +Получение информации о вычислительной группе, принадлежащей basic service +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_bservice_group" "bsg" { + #id сервиса + #обязательный параметр + #тип - целое число + service_id = 11111 + + #id вычислительной группы + #обязательный параметр + #тип - целое число + compgroup_id = 12121 + +} + +output "test" { + value = data.decort_bservice_group.bsg +} diff --git a/samples/cloudapi/bservice/data_bservice_list/main.tf b/samples/cloudapi/bservice/data_bservice_list/main.tf new file mode 100644 index 00000000..f1c6f5dc --- /dev/null +++ b/samples/cloudapi/bservice/data_bservice_list/main.tf @@ -0,0 +1,99 @@ +/* +Пример использования +Получение списка доступных базовых сервисов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_bservice_list" "bsl" { + #фильтр по id базового сервиса + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени базового сервиса + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для фильтрации данных + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #account_id = 11111 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #rg_name = "test" + + #id ресурсной группы, используется для фильтрации + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #rg_id = 11111 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STARTED" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "test" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 +} + +output "test" { + value = data.decort_bservice_list.bsl +} diff --git a/samples/cloudapi/bservice/data_bservice_snapshot_list/main.tf b/samples/cloudapi/bservice/data_bservice_snapshot_list/main.tf new file mode 100644 index 00000000..33b4ec63 --- /dev/null +++ b/samples/cloudapi/bservice/data_bservice_snapshot_list/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение списка снимков состояний basic service +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_bservice_snapshot_list" "bsl" { + #id basic service + #обязательный параметр + #тип - целое число + service_id = 11111 +} + +output "test" { + value = data.decort_bservice_snapshot_list.bsl +} diff --git a/samples/cloudapi/bservice/resource_bservice/main.tf b/samples/cloudapi/bservice/resource_bservice/main.tf new file mode 100644 index 00000000..21355149 --- /dev/null +++ b/samples/cloudapi/bservice/resource_bservice/main.tf @@ -0,0 +1,112 @@ +/* +Пример использования +Ресурса bservice +Ресурс позволяет: +1. Создавать basic service +2. Редактировать basic service +3. Удалять basic service +4. Создавать снимки состояний basic service +5. Совершать восстановление по снимкам состояний +6. Удалять снимки состояний +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_bservice" "b" { + #имя basic service + #обязательный параметр + #тип - строка + #используется при создании + service_name = "my_test_bservice_sn" + + #id ресурсной группы + #обязательный параметр + #тип - целое число + #используется при создании + rg_id = 11111 + + #доступность сервиса + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #по умолчанию - false + #enable = true + + #снимок состояния + #опциональный параметр + #тип - объект + #используется при обновлении + #может быть несколько в ресурсе + #snapshots { + #имя снимка состояния + #обязательный параметр + #тип - строка + #label = "test_snapshot" + + #восстановление сервиса из снимка состояния + #опциональный параметр + #тип - булев + #по умолчанию - false + #восстановление происходит только при переключении с false на true + #rollback = false + #} + + #старт сервиса + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #по умолчанию - false + #start = false + + #восстановление сервиса после удаления + #опциональный параметр + #тип - булев + #используется при обновлении + #по умолчанию - false + #restore = true + + #мгновенное удаление сервиса без права восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #по умолчанию - false + #permanently = true + + #id сервиса, позволяет сформировать .tfstate, если сервис есть в платформе + #опциональный параметр + #тип - булев + #используется при создании + #service_id = 11111 + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 + +} + +output "test" { + value = decort_bservice.b +} diff --git a/samples/cloudapi/bservice/resource_bservice_group/main.tf b/samples/cloudapi/bservice/resource_bservice_group/main.tf new file mode 100644 index 00000000..e232d242 --- /dev/null +++ b/samples/cloudapi/bservice/resource_bservice_group/main.tf @@ -0,0 +1,184 @@ +/* +Пример использования +Работы с ресурсом basic service group +Ресурс позволяет: +1. Создавать группы +2. Редактировать группы +3. Удалять группы +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_bservice_group" "bsg" { + #id basic service + #обязательный параметр + #тип - целое число + #используется при создании + service_id = 444444 + + #название группы + #обязательный параметр + #тип - строка + #используется при создании и обновлении + compgroup_name = "tf_group_rename" + + #id группы + #опциональный параметр + #тип - целое число + #применяется при создании .tfstate - файла, если группа имеется в плафторме + #compgroup_id = 33333 + + #кол-во вычислительных ресурсов + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + comp_count = 1 + + #кол-во ядер на выч. ресурс + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + cpu = 2 + + #кол-во оперативной памяти на выч. ресурс, в МБ + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + ram = 512 + + #размер диска для выч. ресурса, в ГБ + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + disk = 11 + + #id образа диска + #обязательный параметр + #используется при создании + image_id = 2222 + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #id Storage endpoint provider + #опциональный параметр + #тип - целое число + #используется при создании + #sep_id = 3 + + #наименование SEPPool, используется если установлен sepId, также может быть пустым + #опциональный параметр + #тип - строка + #используется при создании + #sep_pool = "name" + + #тег группы + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #role = "tf_test_changed" + + #id сетей extnet + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #должен быть использован vins или extnets + #extnets = [1111, 2222] + + #id сетей vinses + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #должен быть использован vins или extnets + #vinses = [1111, 2222] + + #время таймуата перед стартом + #опциональный параметр + #тип - целое число + #используется при создании + #timeout_start = 0 + + #перечень аргументов для cloud-init создаваемым группам узлов Worker + #опциональный параметр + #тип - файл в формате YAML + #используется при создании + #cloud_init = file("initconfig.tftpl") + + #чипсет для добавляемых виртуальных машин + #возможные значения - i440fx, Q35 + #по умолчанию - Q35 + #опциональный параметр + #тип - строка + #используется при создании + #chipset = "Q35" + + #id групп родителей + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #parents = [2222] + + #принудительное обновление параметров выч. мощностей (ram,disk,cpu) и имени группы + #опциональный параметр + #тип - булев + #используется при обновлении + #по умолчанию - false + #force_update = true + + #старт/стоп вычислительных мощностей + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #по умолчанию - false + #start = false + + #принудительная остановка вычислительных мощностей + #опциональный параметр + #тип - булев + #используется при обновлении + #по умолчанию - false + #force_stop = false + + #удаление вычислительных мощностей + #опциональный параметр + #тип - массив целых чисел + #используется при обновлении + #remove_computes = [32287] + + #режим увеличения числа выч. мощностей + #опциональный параметр + #возможные значения - "RELATIVE" и "ABSOLUTE" + #тип - строка + #используется в связке с comp_count при редактировании группы + #используется при обновлении + #по умолчанию - "RELATIVE" + #mode = "RELATIVE" +} + +output "test" { + value = decort_bservice_group.bsg +} diff --git a/samples/cloudapi/disk/data_disk/main.tf b/samples/cloudapi/disk/data_disk/main.tf new file mode 100644 index 00000000..f314c16c --- /dev/null +++ b/samples/cloudapi/disk/data_disk/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных диска +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_disk" "acl" { + #фильтр по id диска + #обязательный параметр + #тип - целое число + disk_id = 49304 +} + +output "test" { + value = data.decort_disk.acl +} diff --git a/samples/cloudapi/disk/data_disk_list/main.tf b/samples/cloudapi/disk/data_disk_list/main.tf new file mode 100644 index 00000000..13254d0e --- /dev/null +++ b/samples/cloudapi/disk/data_disk_list/main.tf @@ -0,0 +1,109 @@ +/* +Пример использования +Получение списка доступных дисков +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_disk_list" "dl" { + #фильтр по id диска + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени диска + #опциональный параметр + #тип - строка + #name = "data_disk" + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "user" + + #фильтр по максимальному размеру диска + #опциональный параметр + #тип - целое число + #disk_max_size = 100 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по доступности иным пользователям + #опциональный параметр + #тип - булев + #shared = "false" + + #id аккаунта для получения списка дисков + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #id SEP для получения списка дисков + #опциональный параметр + #тип - целое число + #sep_id = 11111 + + #фильтр по имени pool + #опциональный параметр + #тип - строка + #pool_name = "test" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 + + #id политики хранения + #опциональный параметр + #тип - целое число + #storage_policy_id = 1 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 1281 + + #фильтр по id ВМ + #опциональный параметр + #тип - целое число + #compute_id = 123 +} + +output "test" { + value = data.decort_disk_list.dl +} diff --git a/samples/cloudapi/disk/data_disk_list_deleted/main.tf b/samples/cloudapi/disk/data_disk_list_deleted/main.tf new file mode 100644 index 00000000..40132734 --- /dev/null +++ b/samples/cloudapi/disk/data_disk_list_deleted/main.tf @@ -0,0 +1,80 @@ +/* +Пример использования +Получение списка дисков со статусом DELETED +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_disk_list_deleted" "dld" { + #фильтр по id диска + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени диска + #опциональный параметр + #тип - строка + #name = "data_disk" + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "user" + + #фильтр по максимальному размеру диска + #опциональный параметр + #тип - целое число + #disk_max_size = 100 + + #фильтр по доступности иным пользователям + #опциональный параметр + #тип - булев + #shared = "false" + + #id аккаунта для получения списка дисков + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_disk_list_deleted.dld +} diff --git a/samples/cloudapi/disk/data_disk_list_unattached/main.tf b/samples/cloudapi/disk/data_disk_list_unattached/main.tf new file mode 100644 index 00000000..5c454066 --- /dev/null +++ b/samples/cloudapi/disk/data_disk_list_unattached/main.tf @@ -0,0 +1,93 @@ +/* +Пример использования +Получение списка доступных неприсоединенных дисков +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +data "decort_disk_list_unattached" "dlu" { + #фильтр по id диска + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "user" + + #фильтр по максимальному размеру диска + #опциональный параметр + #тип - целое число + #disk_max_size = 100 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 100 + + #фильтр по id sep + #опциональный параметр + #тип - целое число + #sep_id = 1 + + #фильтр по имени pool + #опциональный параметр + #тип - строка + #pool_name = "test" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 + + #id политики хранения + #опциональный параметр + #тип - целое число + #storage_policy_id = 1 +} + +output "test" { + value = data.decort_disk_list_unattached.dlu +} diff --git a/samples/cloudapi/disk/data_disk_replication/main.tf b/samples/cloudapi/disk/data_disk_replication/main.tf new file mode 100644 index 00000000..7093d383 --- /dev/null +++ b/samples/cloudapi/disk/data_disk_replication/main.tf @@ -0,0 +1,45 @@ +/* +Пример использования +Получение статуса репликации диска +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +data "decort_disk_replication" "dr" { + #id диска для которого подключена репликация + #обязательный параметр + #тип - целое число + disk_id = 49304 + + #id реплики диска + #обязательный параметр + #тип - целое число + replica_disk_id = 1213 +} + +output "test" { + value = data.decort_disk_replication.dr +} diff --git a/samples/cloudapi/disk/data_disk_snapshot/main.tf b/samples/cloudapi/disk/data_disk_snapshot/main.tf new file mode 100644 index 00000000..d0177641 --- /dev/null +++ b/samples/cloudapi/disk/data_disk_snapshot/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение конкретного снапшота +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "" + source = "basis/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_disk_snapshot" "ds" { + #номер диска + #обязательный параметр + #тип - целое число + disk_id = 20100 + + #ярлык диска + #обязательный параметр + #тип - строка + label = "label" +} + +output "test" { + value = data.decort_disk_snapshot.ds +} diff --git a/samples/cloudapi/disk/data_disk_snapshot_list/main.tf b/samples/cloudapi/disk/data_disk_snapshot_list/main.tf new file mode 100644 index 00000000..7f47e437 --- /dev/null +++ b/samples/cloudapi/disk/data_disk_snapshot_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение списка снапшотов диска +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_disk_snapshot_list" "ds" { + #номер диска + #обязательный параметр + #тип - целое число + disk_id = 20100 +} + +output "test" { + value = data.decort_disk_snapshot_list.ds +} diff --git a/samples/cloudapi/disk/resource_disk/main.tf b/samples/cloudapi/disk/resource_disk/main.tf new file mode 100644 index 00000000..207a8e56 --- /dev/null +++ b/samples/cloudapi/disk/resource_disk/main.tf @@ -0,0 +1,76 @@ +/* +Пример использования +Получение информации об уже существующем диске. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_disk" "acl" { + #id владельца диска + #обязательный параметр + #тип - целое число + #используется при создании + account_id = 88366 + + #имя диска + #обязательный параметр + #тип - строка + #используется при создании и обновлении + disk_name = "super-disk-re" + + #размер диска, в ГБ + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + size_max = 20 + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + storage_policy_id = 1 + + #флаг для отключения диска от ВМ при удалении + #опциональный параметр + #тип - булев + #используется при удалении + #detach = false + + #флаг для удаления диска, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = false + + #флаг, отвечающий за доступность диска другим ресурсам + #опциональный параметр + #тип - строка + #возможные значенния - "none", "writethrough" + #используется при создании и обновлении + #shareable = false +} + +output "test" { + value = decort_disk.acl +} diff --git a/samples/cloudapi/disk/resource_disk_snapshot/main.tf b/samples/cloudapi/disk/resource_disk_snapshot/main.tf new file mode 100644 index 00000000..890466f7 --- /dev/null +++ b/samples/cloudapi/disk/resource_disk_snapshot/main.tf @@ -0,0 +1,51 @@ +/* +Пример использования +Ресурс снапшота диска +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_disk_snapshot" "ds" { + #номер диска + #обязательный параметр + #тип - целое число + #используется при создании + disk_id = 20100 + + #ярлык диска + #обязательный параметр + #тип - строка + #используется при создании + label = "label" + + #флаг rollback + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #rollback = false +} + +output "test" { + value = decort_disk_snapshot.ds +} diff --git a/samples/cloudapi/dpdknet/data_dpdknet/main.tf b/samples/cloudapi/dpdknet/data_dpdknet/main.tf new file mode 100644 index 00000000..095d9643 --- /dev/null +++ b/samples/cloudapi/dpdknet/data_dpdknet/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных диска +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_dpdknet" "dpdk" { + #фильтр по id DPDK сети + #обязательный параметр + #тип - целое число + dpdk_id = 49304 +} + +output "test" { + value = data.decort_dpdknet.dpdk +} diff --git a/samples/cloudapi/dpdknet/data_dpdknet_list/main.tf b/samples/cloudapi/dpdknet/data_dpdknet_list/main.tf new file mode 100644 index 00000000..bff81ae2 --- /dev/null +++ b/samples/cloudapi/dpdknet/data_dpdknet_list/main.tf @@ -0,0 +1,79 @@ +/* +Пример использования +Получение списка доступных дисков +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_dpdknet_list" "dl" { + #фильтр по id DPDK сети + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по grid ID + #опциональный параметр + #тип - целое число + #gid = 100 + + #фильтр по имени сети + #опциональный параметр + #тип - строка + #name = "test_dpdk" + + #фильтр по описания + #опциональный параметр + #тип - строка + #desc = "user" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по compute IDs + #опциональный параметр + #тип - массив чисел + #compute_ids = [11111,22222] + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_dpdknet_list.dl +} diff --git a/samples/cloudapi/extnet/data_extnet/main.tf b/samples/cloudapi/extnet/data_extnet/main.tf new file mode 100644 index 00000000..d981de85 --- /dev/null +++ b/samples/cloudapi/extnet/data_extnet/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о сети +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_extnet" "e" { + #идентификатор сети + #обязательный параметр + #тип - целое число + net_id = 1111 +} + +output "test" { + value = data.decort_extnet.e +} diff --git a/samples/cloudapi/extnet/data_extnet_computes_list/main.tf b/samples/cloudapi/extnet/data_extnet_computes_list/main.tf new file mode 100644 index 00000000..871bccb6 --- /dev/null +++ b/samples/cloudapi/extnet/data_extnet_computes_list/main.tf @@ -0,0 +1,64 @@ +/* +Пример использования +Получение информации о вычислительных ресурсах, использующих сеть аккаунта +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_extnet_computes_list" "ecl" { + #идентификатор аккаунта + #обязательный параметр + #тип - целое число + account_id = 1111 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 11111 + + #фильтр по id виртуальной машины + #опциональный параметр + #тип - целое число + #compute_id = 11111 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_extnet_computes_list.ecl +} diff --git a/samples/cloudapi/extnet/data_extnet_default/main.tf b/samples/cloudapi/extnet/data_extnet_default/main.tf new file mode 100644 index 00000000..c983e3f6 --- /dev/null +++ b/samples/cloudapi/extnet/data_extnet_default/main.tf @@ -0,0 +1,35 @@ +/* +Пример использования +Получение информации о сети по умолчанию +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_extnet_default" "ed" { + #нет входных параметров +} + +output "test" { + value = data.decort_extnet_default.ed +} diff --git a/samples/cloudapi/extnet/data_extnet_list/main.tf b/samples/cloudapi/extnet/data_extnet_list/main.tf new file mode 100644 index 00000000..06747e00 --- /dev/null +++ b/samples/cloudapi/extnet/data_extnet_list/main.tf @@ -0,0 +1,95 @@ +/* +Пример использования +Получение списка сетей +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_extnet_list" "el" { + #id аккаунта для фильтрации результата + #опциональный параметр + #тип - целое число + #account_id = 1111111 + + #фильтр по id внешней сети + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени внешней сети + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по IP внешней сети + #опциональный параметр + #тип - строка + #network = "test" + + #фильтр по id vlan + #опциональный параметр + #тип - целое число + #vlan_id = 100 + + #фильтр по id vnfDevices + #опциональный параметр + #тип - целое число + #vnfdev_id = 100 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 + + #имя моста openVswitch + #опциональный параметр + #тип - строка + #ovs_bridge = "key" + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 +} + +output "test" { + value = data.decort_extnet_list.el +} diff --git a/samples/cloudapi/extnet/data_extnet_reserved_ip_list/main.tf b/samples/cloudapi/extnet/data_extnet_reserved_ip_list/main.tf new file mode 100644 index 00000000..f0e13659 --- /dev/null +++ b/samples/cloudapi/extnet/data_extnet_reserved_ip_list/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о зарезервированных IP адресах или пуле адресов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_extnet_reserved_ip_list" "ex_reserved_ip" { + #идентификатор аккаунта, для которого зарезервированны ресурсы + #обязательный параметр + #тип - целое число + account_id = 1111 + + #идентификатор сети + #опциональный параметр + #тип - целое число + #extnet_id = 1111 +} + +output "test" { + value = data.decort_extnet_reserved_ip_list.ex_reserved_ip +} diff --git a/samples/cloudapi/flipgroup/data_flipgroup/main.tf b/samples/cloudapi/flipgroup/data_flipgroup/main.tf new file mode 100644 index 00000000..89dbf9fa --- /dev/null +++ b/samples/cloudapi/flipgroup/data_flipgroup/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение группы виртуальных машин по id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_flipgroup" "fg" { + #id флипгруппы + #обязательный параметр + #тип - целое число + flipgroup_id = 999 +} + +output "fg_out" { + value = data.decort_flipgroup.fg +} diff --git a/samples/cloudapi/flipgroup/data_flipgroup_list/main.tf b/samples/cloudapi/flipgroup/data_flipgroup_list/main.tf new file mode 100644 index 00000000..3be25dac --- /dev/null +++ b/samples/cloudapi/flipgroup/data_flipgroup_list/main.tf @@ -0,0 +1,101 @@ +/* +Пример использования +Получение группы виртуальных машин, доступных текущему пользователю +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_flipgroup_list" "fg" { + #фильтр по id flipgroup + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени flipgroup + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id vins + #опциональный параметр + #тип - целое число + #vins_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #vins_name = "test" + + #фильтр по id extnet + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #фильтр по IP + #опциональный параметр + #тип - строка + #by_ip = "1.1.1.1.1" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 100 + + #фильтр по id conn + #опциональный параметр + #тип - целое число + #conn_id = 100 + + #фильтр по id клиентов + #опциональный параметр + #тип - массив целых чисел + #client_ids = [10,11] + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "CREATED" +} + +output "fg_out" { + value = data.decort_flipgroup_list.fg +} diff --git a/samples/cloudapi/flipgroup/resource_flipgroup/main.tf b/samples/cloudapi/flipgroup/resource_flipgroup/main.tf new file mode 100644 index 00000000..b3490dc2 --- /dev/null +++ b/samples/cloudapi/flipgroup/resource_flipgroup/main.tf @@ -0,0 +1,85 @@ +/* +Управления плавающими группами (флипгруппами). +Ресурс позволяет: +1. Создать флипгруппу +2. Удалить флипгруппу +3. Добавить/удалить клиентов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_flipgroup" "fg" { + #id аккаунта + #обязательный параметр + #тип - целое число + #используется при создании + account_id = 999 + + #наименование Flipgroup + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "flipgroup_name" + + #тип сети (EXTNET, ViNS) + #обязательный параметр + #тип - строка + #используется при создании + net_type = "EXTNET" + + #id сети + #обязательный параметр + #тип - целое число + #используется при создании + net_id = 13 + + #тип клиентов (в данный момент поддерживается только тип 'compute') + #опциональный параметр + #тип - строка + #используется при создании + #по умолчанию - "compute" + #client_type = "compute" + + #ip-адрес + #опциональный параметр + #тип - строка + #используется при создании + #ip = "127.0.0.1" + + #список клиентов, прикрепленных к флипгруппе + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #client_ids = [11269] + + #описание флипгруппы + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "CHANGED" +} + +output "fg_out" { + value = decort_flipgroup.fg +} diff --git a/samples/cloudapi/image/data_image/main.tf b/samples/cloudapi/image/data_image/main.tf new file mode 100644 index 00000000..f70f345e --- /dev/null +++ b/samples/cloudapi/image/data_image/main.tf @@ -0,0 +1,44 @@ +/* +Пример использования +Получение информации об образе +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_image" "image" { + #id образа + #обязательный параметр + #тип - целое число + image_id = 111 + + #показывать ли информацию об удаленном образе + #опциональный параметр + #тип - булев + #по умолчанию - false + #show_all = false +} + +output "test" { + value = data.decort_image.image +} diff --git a/samples/cloudapi/image/data_image_list/main.tf b/samples/cloudapi/image/data_image_list/main.tf new file mode 100644 index 00000000..4fef3b05 --- /dev/null +++ b/samples/cloudapi/image/data_image_list/main.tf @@ -0,0 +1,122 @@ +/* +Пример использования +Получение списка доступных образов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_image_list" "il" { + #фильтр по id sep + #опциональный параметр + #тип - целое число + #sep_id = 1 + + #фильтр по id образа + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени образа + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по архитектуре + #опциональный параметр + #тип - строка + #architecture = "x86_64" + + #фильтр по типу образа + #опциональный параметр + #тип - массив строк + #type_image = ["linux", "windows"] + + #фильтр по размеру образа + #опциональный параметр + #тип - целое число + #image_size = 100 + + #фильтр по имени SEP + #опциональный параметр + #тип - строка + #sep_name = "test" + + #фильтр по имени Pool + #опциональный параметр + #тип - строка + #pool = "test" + + #фильтр по доступу + #опциональный параметр + #тип - булев + #public = true + + #фильтр по hot_resize + #опциональный параметр + #тип - булев + #hot_resize = true + + #фильтр по bootable + #опциональный параметр + #тип - булев + #bootable = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 + + #фильтр по enabled + #опциональный параметр + #тип - булев + #enabled = true + + #фильтр по id политики хранения + #опциональный параметр + #тип - целое число + #storage_policy_id = 6 +} + +output "test" { + value = data.decort_image_list.il +} diff --git a/samples/cloudapi/image/resource_image/main.tf b/samples/cloudapi/image/resource_image/main.tf new file mode 100644 index 00000000..e8c04ff7 --- /dev/null +++ b/samples/cloudapi/image/resource_image/main.tf @@ -0,0 +1,127 @@ +/* +Пример использования +Работа с образом +Ресурс позволяет: +1. Управлять образом +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_image" "img" { + #наименование образа + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "image_name" + + #тип образа (linux, windows и др.) + #обязательный параметр + #тип - строка + #используется при создании + type = "linux" + + #прямая ссылка на образ + #обязательный параметр + #тип - строка + #используется при создании + url = "https://dl-cdn.alpinelinux.org/alpine/v3.17/releases/x86_64/alpine-virt-3.17.3-x86_64.iso" + + #тип загрузчика (bios/uefi) + #обязательный параметр + #тип - строка + #используется при создании + boot_type = "bios" + + #id аккаунта + #обязательный параметр + #тип - целое число + #используется при создании + account_id = 138 + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #поддержка hot resize + #опциональный параметр + #тип - булев + #используется при создании + #hot_resize = true + + #юзернейм для образа + #опциональный параметр + #тип - целое число + #используется при создании + #username = "userx" + + #пароль для образа + #опциональный параметр + #тип - строка + #используется при создании + #password = "passx" + + #юзернейм для загрузки binary media + #опциональный параметр + #тип - строка + #используется при создании + #username_dl = "userxdl" + + #пароль для загрузки binary media + #опциональный параметр + #тип - строка + #используется при создании + #password_dl = "passxdl" + + #storage endpoint provider ID + #опциональный параметр + #тип - целое число + #используется при создании + #sep_id = 1 + + #pool для образа + #опциональный параметр + #тип - строка + #используется при создании + #pool_name = "pool" + + #наименование сетевого интерфейса для вашего компьютера с Linux + #eth - встроенный, ens - pci слот + #опциональный параметр + #тип - строка + #используется при создании + #network_interface_naming = "ens" + + #позволяет создавать образ в синхронном режиме + #опциональный параметр + #тип - булев + #используется при создании + #по умолчанию - false + #sync_mode = true +} + +output "img_out" { + value = decort_image.img +} diff --git a/samples/cloudapi/image/resource_image_from_blank_compute/main.tf b/samples/cloudapi/image/resource_image_from_blank_compute/main.tf new file mode 100644 index 00000000..82319c44 --- /dev/null +++ b/samples/cloudapi/image/resource_image_from_blank_compute/main.tf @@ -0,0 +1,103 @@ +/* +Ресурс образа из компьюта, созданного как blank позволяет: +1. Создавать +2. Редактировать +3. Удалять ресурс +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_image_from_blank_compute" "img" { + #id виртуальной машины, созданной как blank + #обязательный параметр + #тип - целое число + #используется при создании + compute_id = 1234 + + #наименование образа + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "image_name" + + #тип загрузчика (bios/uefi) + #обязательный параметр + #тип - строка + #используется при создании + boot_type = "bios" + + #тип образа (linux, windows и др.) + #обязательный параметр + #тип - строка + #используется при создании + type = "linux" + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #юзернейм для образа + #опциональный параметр + #тип - строка + #используется при создании + #username = "userx" + + #пароль для образа + #опциональный параметр + #тип - строка + #используется при создании + #password = "passx" + + #id аккаунта + #опциональный параметр + #тип - целое число + #используется при создании + #account_id = 138 + + #pool для образа + #опциональный параметр + #тип - строка + #используется при создании + #pool_name = "pool" + + #поддержка hot resize + #опциональный параметр + #тип - булев + #используется при создании + #hot_resize = true + + #флаг для создания образа в асинхронном режиме + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при создании + #async_mode = true + +} + +output "img_out" { + value = decort_image_from_blank_compute.img +} diff --git a/samples/cloudapi/image/resource_image_from_platform_disk/main.tf b/samples/cloudapi/image/resource_image_from_platform_disk/main.tf new file mode 100644 index 00000000..a6422b73 --- /dev/null +++ b/samples/cloudapi/image/resource_image_from_platform_disk/main.tf @@ -0,0 +1,111 @@ +/* +Ресурс образа из платформенного диска позволяет: +1. Создавать +2. Редактировать +3. Удалять ресурс +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_image_from_platform_disk" "img" { + #id диска + #обязательный параметр + #тип - целое число + #используется при создании + disk_id = 1234 + + #наименование образа + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "image_name" + + #тип загрузчика + #обязательный параметр + #возможные значения - bios, uefi + #тип - строка + #используется при создании + boot_type = "bios" + + #тип образа (linux, windows и др.) + #обязательный параметр + #тип - строка + #используется при создании + type = "linux" + + #драйверы компьютов, подходящие для данного образа + #опциональный параметр + #тип - массив строк + #используется при создании + #drivers = ["KVM_X86"] + + #имя пользователя для образа + #опциональный параметр + #тип - строка + #используется при создании + #username = "userx" + + #пароль для образа + #опциональный параметр + #тип - строка + #используется при создании + #password = "passx" + + #id аккаунта + #опциональный параметр + #тип - целое число + #используется при создании + #account_id = 138 + + #pool для образа + #опциональный параметр + #тип - строка + #используется при создании + #pool_name = "pool" + + #поддержка hot resize + #опциональный параметр + #тип - булев + #используется при создании + #hot_resize = true + + #флаг загрузочного образа + #опциональный параметр + #по умолчанию - true + #тип - булев + #используется при создании + #bootable = true + + #флаг для создания образа в асинхронном режиме + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при создании + #async_mode = true + +} + +output "img_out" { + value = decort_image_from_platform_disk.img +} \ No newline at end of file diff --git a/samples/cloudapi/image/resource_image_virtual/main.tf b/samples/cloudapi/image/resource_image_virtual/main.tf new file mode 100644 index 00000000..d8a6ef06 --- /dev/null +++ b/samples/cloudapi/image/resource_image_virtual/main.tf @@ -0,0 +1,56 @@ +/* +Пример использования +Управления виртуальным образом +Ресурс позволяет: +1. Создавать image virtual +2. Изменять image virtual +2. Удалять image virtual +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_image_virtual" "iv" { + #имя виртуального образа + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "iv-name" + + #id реального образа, на который будет ссылаться виртуальный + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + link_to = 123 + + #id аккаунта + #обязательный параметр + #тип - целое число + #используется при создании + account_id = 123 + +} + +output "sr" { + value = decort_image_virtual.iv +} diff --git a/samples/cloudapi/k8s/data_k8ci_list/main.tf b/samples/cloudapi/k8s/data_k8ci_list/main.tf new file mode 100644 index 00000000..509d8428 --- /dev/null +++ b/samples/cloudapi/k8s/data_k8ci_list/main.tf @@ -0,0 +1,97 @@ +/* +Пример использования +Получение информации о k8ci +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_k8ci_list" "k8ci_list" { + #фильтр по id кластера + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени кластера + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по ip + #опциональный параметр + #тип - строка + #ip_address = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #lb_id = 100 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #bservice_id = 100 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #включение удаленных k8s в результат + #опциональный параметр + #тип - булев + #если не задан - выводятся все неудаленные данные + #includedeleted = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output_k8ci" { + value = data.decort_k8ci_list.k8ci_list +} diff --git a/samples/cloudapi/k8s/data_k8s/main.tf b/samples/cloudapi/k8s/data_k8s/main.tf new file mode 100644 index 00000000..8ea2b032 --- /dev/null +++ b/samples/cloudapi/k8s/data_k8s/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о k8s кластере +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "" + source = "basis/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_k8s" "k8s" { + #id кластера + #обязательный параметр + #тип - целое число + k8s_id = 49304 +} + +output "output_k8s" { + value = data.decort_k8s.k8s +} diff --git a/samples/cloudapi/k8s/data_k8s_computes/main.tf b/samples/cloudapi/k8s/data_k8s_computes/main.tf new file mode 100644 index 00000000..9daa4a5b --- /dev/null +++ b/samples/cloudapi/k8s/data_k8s_computes/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получения информации о виртуальных машинах кластера +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_k8s_computes" "computes" { + #id кластера + #обязательный параметр + #тип - целое число + k8s_id = 999 +} + +output "computes_out" { + value = data.decort_k8s_computes.computes +} diff --git a/samples/cloudapi/k8s/data_k8s_list/main.tf b/samples/cloudapi/k8s/data_k8s_list/main.tf new file mode 100644 index 00000000..18ecd344 --- /dev/null +++ b/samples/cloudapi/k8s/data_k8s_list/main.tf @@ -0,0 +1,103 @@ +/* +Пример использования +Получение списка доступных кластеров +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_k8s_list" "k8s_list" { + #фильтр по id кластера + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени кластера + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по ip + #опциональный параметр + #тип - строка + #ip_address = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #lb_id = 100 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #bservice_id = 100 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #включение удаленных k8s в результат + #опциональный параметр + #тип - булев + #если не задан - выводятся все неудаленные данные + #includedeleted = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 +} + +output "output_k8s_list" { + value = data.decort_k8s_list.k8s_list +} diff --git a/samples/cloudapi/k8s/data_k8s_list_deleted/main.tf b/samples/cloudapi/k8s/data_k8s_list_deleted/main.tf new file mode 100644 index 00000000..b455c425 --- /dev/null +++ b/samples/cloudapi/k8s/data_k8s_list_deleted/main.tf @@ -0,0 +1,86 @@ +/* +Пример использования +Получение списка удаленных кластеров +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_k8s_list_deleted" "k8s_list_deleted" { + #фильтр по id кластера + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени кластера + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по ip + #опциональный параметр + #тип - строка + #ip_address = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #lb_id = 100 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #bservice_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output_k8s_list_deleted" { + value = data.decort_k8s_list_deleted.k8s_list_deleted +} diff --git a/samples/cloudapi/k8s/data_k8s_wg/main.tf b/samples/cloudapi/k8s/data_k8s_wg/main.tf new file mode 100644 index 00000000..e666e48a --- /dev/null +++ b/samples/cloudapi/k8s/data_k8s_wg/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о k8s кластере +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_k8s_wg" "k8s_wg" { + #id кластера + #обязательный параметр + #тип - целое число + k8s_id = 49304 + + #id группы воркеров + #обязательный параметр + #тип - целое число + wg_id = 43329 +} + +output "output_k8s_wg" { + value = data.decort_k8s_wg.k8s_wg +} diff --git a/samples/cloudapi/k8s/data_k8s_wg_cloud_init/main.tf b/samples/cloudapi/k8s/data_k8s_wg_cloud_init/main.tf new file mode 100644 index 00000000..da8b924f --- /dev/null +++ b/samples/cloudapi/k8s/data_k8s_wg_cloud_init/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о мета данных рабочей группы k8s кластера +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_k8s_wg_cloud_init" "wg_cloud_init" { + #id кластера + #обязательный параметр + #тип - целое число + k8s_id = 977 + + #id группы воркеров + #обязательный параметр + #тип - целое число + wg_id = 2110 +} + +output "wg_cloud_init" { + value = data.decort_k8s_wg_cloud_init.wg_cloud_init +} diff --git a/samples/cloudapi/k8s/data_k8s_wg_list/main.tf b/samples/cloudapi/k8s/data_k8s_wg_list/main.tf new file mode 100644 index 00000000..bfb5985b --- /dev/null +++ b/samples/cloudapi/k8s/data_k8s_wg_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение списка доступных групп воркеров в кластере +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_k8s_wg_list" "k8s_wg_list" { + #id кластера + #обязательный параметр + #тип - целое число + k8s_id = 49304 +} + +output "output_k8s_wg_list" { + value = data.decort_k8s_wg_list.k8s_wg_list +} diff --git a/samples/cloudapi/k8s/resource_k8s/main.tf b/samples/cloudapi/k8s/resource_k8s/main.tf new file mode 100644 index 00000000..302abb99 --- /dev/null +++ b/samples/cloudapi/k8s/resource_k8s/main.tf @@ -0,0 +1,363 @@ +/* +Пример использования +Управление кластером +Ресурс позволяет: +1. Создавать кластер +2. Управлять кластером +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_k8s" "cluster" { + #имя кластера + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "tftest" + + #id resource group + #обязательный параметр + #тип - целое число + #используется при создании + rg_id = 776 + + #id catalogue item + #обязательный параметр + #тип - целое число + #используется при создании + k8sci_id = 9 + + #сетевой плагин + #обязательный параметр + #тип - строка + #используется при создании + network_plugin = "flannel" + + #имя для первой worker group, созданной в кластере + #обязательный параметр + #тип - строка + #используется при создании + wg_name = "workers" + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #список labels для дефолтной worker группы + #опциональный параметр + #тип - массив строк + #используется при создании + #labels = ["key1=val1", "key2=val2"] + + #список annotations для дефолтной worker группы + #опциональный параметр + #в скором времени параметры labels, annotations, taints будут полностью перенесены в блок workers + #тип - массив строк + #используется при создании + #annotations = ["key1=val1", "key2=val2"] + + #список taints для дефолтной worker группы + #опциональный параметр + #в скором времени параметры labels, annotations, taints будут полностью перенесены в блок workers + #тип - массив строк + #используется при создании + #taints = ["key1=value1:NoSchedule", "key2=value2:NoExecute"] + + #настройка мастер node или nodes + #опциональный параметр + #максимальное кол-во элементов - 1 + #тип - список нод + #используется при создании + #masters { + #кол-во node (1, 3 или 5) + #обязательный параметр + #тип - целое число + #num = 1 + + #кол-во cpu + #обязательный параметр + #тип - целое число + #cpu = 2 + + #кол-во RAM, в МБ + #обязательный параметр + #тип - целое число + #ram = 2048 + + #размер диска, в ГБ + #обязательный параметр + #тип - целое число + #disk = 10 + + #идентификатор SEP для создания загрузочных дисков для master узлов + #опциональный параметр + #тип - целое число + #sep_id = 3 + + #наименование MasterSEPPool, используется если установлен master sepId, также может быть пустым + #опциональный параметр + #тип - строка + #sep_pool = "data_01" + #} + + #настройка worker группы + #опциональный параметр + #первая указанная воркер-группа должна соответствовать изначально созданной вместе с кластером. + #используется при создании и обновлении + #labels, annotations, taints для дефолтной worker группы указываются в корне ресурса при создании кластера. + #workers { + #имя группы + #обязательный параметр + #тип - строка + #name = "test" + + #кол-во node + #обязательный параметр + #тип - целое число + #num = 1 + + #кол-во cpu + #обязательный параметр + #тип - целое число + #cpu = 2 + + #кол-во RAM, в МБ + #обязательный параметр + #тип - целое число + #ram = 2048 + + #размер диска, в ГБ + #обязательный параметр + #тип - целое число + #disk = 10 + + #идентификатор SEP + #опциональный параметр + #тип - целое число + #sep_id = 1010 + + #имя SEP pool'a + #опциональный параметр + #тип - строка + #sep_pool = "data01" + + #тип эмулируемой системы + #опциональный параметр + #тип - строка + #возможные значения: "i440fx", "Q35" + #по умолчанию - Q35 + #chipset = "Q35" + #} + + #далее можно создавать произвольное кол-во дополнительных worker групп + #labels, annotations и taints для последующих групп указываются непосредственно в блоке workers + #workers { + #наименование worker группы + #обязательный параметр + #тип - строка + #name = "additional_wg" + + #кол-во node + #обязательный параметр + #тип - целое число + #num = 2 + + #кол-во cpu + #обязательный параметр + #тип - целое число + #cpu = 2 + + #кол-во RAM, в МБ + #обязательный параметр + #тип - целое число + #ram = 4096 + + #размер диска, в ГБ + #обязательный параметр + #тип - целое число + #disk = 10 + + #идентификатор SEP + #опциональный параметр + #тип - целое число + #sep_id = 1010 + + #имя SEP pool'a + #опциональный параметр + #тип - строка + #sep_pool = "data01" + + #тип эмулируемой системы + #опциональный параметр + #тип - строка + #возможные значения: "i440fx", "Q35" + #по умолчанию - Q35 + #chipset = "Q35" + + #список лейблов + #опциональный параметр + #тип - массив строк + #labels = ["label1=value1", "label2=value2"] + + #список аннотаций + #опциональный параметр + #тип - массив строк + #annotations = ["key1=value1", "key2=value2"] + + #список taints + #опциональный параметр + #тип - массив строк + #taints = ["key1=value1:NoSchedule", "key2=value2:NoExecute"] + #} + + #id extnet + #опциональный параметр + #тип - целое число + #используется при создании + #extnet_id = 0 + + #id vins + #опциональный параметр + #тип - целое число + #используется при создании + #vins_id = 1234 + + #создать Kubernetes cluster с masters nodes с подключенным LB + #опциональный параметр + #тип - булев + #используется при создании + #with_lb = true + + #пользовательские значения sysctl для LB + #опциональный параметр + #тип - список мап + #используется при создании и обновлении + #lb_sysctl_params = [{ key1 = "value1", key2 = "value2" }] + + #создать схему отказоустойчивой LB + #опциональный параметр + #тип - булев + #используется при создании + #ha_mode = true + + #дополнительные SAN (Subject Alternative Names) для использования в процессе автоматического выписывания сертификата Кластера Kubernetes; + #возможность взаимодействовать с кластером по FQDN + #параметр получает список строк – IP-адреса и/или DNS (по формату RFC 1123 c поддержкой wildcard) + #опциональный параметр + #тип - массив строк + #используется при создании + #additional_sans = ["192.168.201.0", "192.168.201.1"] + + #используется для определения настроек и действий, которые должны быть выполнены перед запуском любого другого компонента в кластере + #это позволяет вам настраивать такие вещи, как регистрация node, настройка network и другие задачи инициализации + #опциональный параметр + #тип - строка + #используется при создании + #init_config = "{JSON string}" + + #используется для определения глобальных настроек и конфигураций для всего кластера + #он включает в себя такие параметры, как имя кластера, настройки DNS, методы аутентификации и другие конфигурации в масштабах кластера + #опциональный параметр + #тип - строка + #используется при создании + #cluster_config = "{JSON string}" + + #используется для настройки поведения и параметров Kubelet, который является агентом primary node, запускаемым на каждом node кластера + #он включает в себя такие параметры, как IP-адрес node, распределение ресурсов, политики удаления модулей и другие конфигурации, специфичные для Kubelet + #опциональный параметр + #тип - строка + #используется при создании + #kubelet_config = "{JSON string}" + + #используется для настройки поведения и параметров присоединения node к кластеру + #он включает в себя такие параметры, как режим прокси-сервера, диапазоны IP-адресов кластера и другие конфигурации, специфичные для Kube-proxy + #опциональный параметр + #тип - строка + #используется при создании + #kube_proxy_config = "{JSON string}" + + #используется для настройки поведения и параметров присоединения node к кластеру + #он включает в себя такие параметры, как cluster's control plane endpoint, токен и ключ сертификата + #опциональный параметр + #тип - строка + #используется при создании + #join_config = "{JSON string}" + + #описание кластера + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "description" + + #перечень аргументов для cloud-init создаваемым группам узлов Worker + #опциональный параметр + #тип - файл с форматом в виде yaml + #используется при создании + #cloud_init = file("initconfig.tftpl") + + #при создании кластера использовать подключение только к сети ExtNet + #опциональный параметр + #тип - булев + #используется при создании + #extnet_only = true + + #добавить ssl-сертификат в формате x509 pem + #опциональный параметр + #тип - файл с форматом в виде x509 pem + #используется при создании + #oidc_cert = file("ca.crt") + + #тип эмулируемой системы + #опциональный параметр + #тип - строка + #возможные значения: "i440fx", "Q35" + #по умолчанию - Q35 + #используется при создании + #chipset = "Q35" + + #запуск,остановка кластера + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #start = true + + #флаг для удаления кластера, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = true + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 + +} + +output "test_cluster" { + value = decort_k8s.cluster +} diff --git a/samples/cloudapi/k8s/resource_k8s_cp/initconfig.tftpl b/samples/cloudapi/k8s/resource_k8s_cp/initconfig.tftpl new file mode 100644 index 00000000..06df7c0d --- /dev/null +++ b/samples/cloudapi/k8s/resource_k8s_cp/initconfig.tftpl @@ -0,0 +1,9 @@ +--- +users: +- groups: users, wheel + name: user + plain_text_passwd: examplePassword + primary_group: user + ssh_authorized_keys: + - ssh-rsa EXAMPLE%id_rsa.pub + sudo: ALL=(ALL) NOPASSWD:ALL diff --git a/samples/cloudapi/k8s/resource_k8s_cp/main.tf b/samples/cloudapi/k8s/resource_k8s_cp/main.tf new file mode 100644 index 00000000..1e7af125 --- /dev/null +++ b/samples/cloudapi/k8s/resource_k8s_cp/main.tf @@ -0,0 +1,213 @@ +/* +Пример использования +Управление control plane кластера k8s +Ресурс позволяет: +1. Создать кластер +2. Удалить кластер +3. Настроить мастер-узел +4. Изменить кол-во ВМ в мастер-узле +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_k8s_cp" "cp" { + #название кластера + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "k8s-cp" + + #k8sCI ID + #обязательный параметр + #тип - целое число + #используется при создании + k8sci_id = 55 + + #плагин сети (flannel, weavenet или calico) + #обязательный параметр + #тип - строка + #используется при создании + network_plugin = "flannel" + + #id ресурсной группы + #обязательный параметр + #тип - целое число + #используется при создании + rg_id = 1387 + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #кол-во ядер мастер-узла + #опциональный параметр + #тип - целое число + #используется при создании + #cpu = 2 + + #объем RAM мастер-узла, в МБ + #опциональный параметр + #тип - целое число + #используется при создании + #ram = 2048 + + #кол-во ВМ мастер-узла (1, 3 или 5) + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #num = 1 + + #размер диска мастер-узла, в ГБ + #опциональный параметр + #тип - целое число + #используется при создании + #disk = 10 + + #описание кластера + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "" + + #id extnet + #опциональный параметр + #тип - целое число + #используется при создании + #extnet_id = 0 + + #id vins + #опциональный параметр + #тип - целое число + #используется при создании + #vins_id = 1234 + + #storage Endpoint ID + #опциональный параметр + #тип - целое число + #используется при создании + #sep_id = 0 + + #sep pool + #опциональный параметр + #тип - строка + #используется при создании + #sep_pool = "pool" + + #старт/стоп кластера + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #start = true + + #создать кластер с/без балансировщика нагрузки + #опциональный параметр + #тип - булев + #используется при создании + #with_lb = true + + #создать схему отказоустойчивой LB + #опциональный параметр + #тип - булев + #используется при создании + #ha_mode = true + + #дополнительные SAN (Subject Alternative Names) для использования в процессе автоматического выписывания сертификата Кластера Kubernetes; + #возможность взаимодействовать с кластером по FQDN + #параметр получает список строк – IP-адреса и/или DNS (по формату RFC 1123 c поддержкой wildcard) + #опциональный параметр + #тип - массив строк + #используется при создании + #additional_sans = ["192.168.201.0","192.168.201.1"] + + #используется для определения настроек и действий, которые должны быть выполнены перед запуском любого другого компонента в кластере + #это позволяет вам настраивать такие вещи, как регистрация node, настройка network и другие задачи инициализации + #опциональный параметр + #тип - строка + #используется при создании + #init_config = "{JSON string}" + + #используется для определения глобальных настроек и конфигураций для всего кластера + #он включает в себя такие параметры, как имя кластера, настройки DNS, методы аутентификации и другие конфигурации в масштабах кластера + #опциональный параметр + #тип - строка + #используется при создании + #cluster_config = "{JSON string}" + + #используется для настройки поведения и параметров Kubelet, который является агентом primary node, запускаемым на каждом node кластера + #он включает в себя такие параметры, как IP-адрес node, распределение ресурсов, политики удаления модулей и другие конфигурации, специфичные для Kubelet + #опциональный параметр + #тип - строка + #используется при создании + #kubelet_config = "{JSON string}" + + #используется для настройки поведения и параметров присоединения node к кластеру + #он включает в себя такие параметры, как режим прокси-сервера, диапазоны IP-адресов кластера и другие конфигурации, специфичные для Kube-proxy + #опциональный параметр + #тип - строка + #используется при создании + #kube_proxy_config = "{JSON string}" + + #используется для настройки поведения и параметров присоединения node к кластеру + #он включает в себя такие параметры, как cluster's control plane endpoint, токен и ключ сертификата + #опциональный параметр + #тип - строка + #используется при создании + #join_config = "{JSON string}" + + #при создании кластре использовать подключение только к сети ExtNet + #опциональный параметр + #тип - булев + #используется при создании + #extnet_only = true + + #добавить ssl-сертификат в формате x509 pem + #опциональный параметр + #тип - файл с форматом в виде x509 pem + #используется при создании + #oidc_cert = file("ca.crt") + + #пользовательские значения sysctl для LB + #опциональный параметр + #тип - список мап + #используется при создании и обновлении + #lb_sysctl_params = [{ key1 = "value1", key2 = "value2" }] + + #флаг для удаления кластера, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = true + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 +} + +output "cp_out" { + value = decort_k8s_cp.cp +} diff --git a/samples/cloudapi/k8s/resource_k8s_wg/initconfig.tftpl b/samples/cloudapi/k8s/resource_k8s_wg/initconfig.tftpl new file mode 100644 index 00000000..06df7c0d --- /dev/null +++ b/samples/cloudapi/k8s/resource_k8s_wg/initconfig.tftpl @@ -0,0 +1,9 @@ +--- +users: +- groups: users, wheel + name: user + plain_text_passwd: examplePassword + primary_group: user + ssh_authorized_keys: + - ssh-rsa EXAMPLE%id_rsa.pub + sudo: ALL=(ALL) NOPASSWD:ALL diff --git a/samples/cloudapi/k8s/resource_k8s_wg/main.tf b/samples/cloudapi/k8s/resource_k8s_wg/main.tf new file mode 100644 index 00000000..e337d0a1 --- /dev/null +++ b/samples/cloudapi/k8s/resource_k8s_wg/main.tf @@ -0,0 +1,99 @@ +/* +Пример использования +Управления worker groups (рабочики группами, wg) кластера +Ресурс позволяет: +1. Создавать wg +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +resource "decort_k8s_wg" "wg" { + #id экземпляра k8s + #обязательный параметр + #тип - целое число + #используется при создании + k8s_id = 1234 + + #имя worker group + #обязательный параметр + #тип - строка + #используется при создании + name = "workers-2" + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #количество worker node + #опциональный параметр + #тип - целое число + #по умолчанию - 1 + #используется при создании и обновлении + #num = 2 + + #количество cpu для 1 worker node + #опциональный параметр + #тип - целое число + #по умолчанию - 1 + #используется при создании + #cpu = 1 + + #количество RAM для одной worker node, в МБ + #опциональный параметр + #тип - целое число + #по умолчанию - 1024 + #используется при создании + #ram = 1024 + + #тип эмулируемой системы + #опциональный параметр + #тип - строка + #возможные значения: "i440fx", "Q35" + #по умолчанию - Q35 + #используется при создании + #chipset = "Q35" + + #размер загрузочного диска для worker node, в ГБ + #опциональный параметр + #тип - целое число + #по умолчанию - 0 + #если установлен параметр 0, то размер диска будет равен размеру образа + #используется при создании + #disk = 10 + + #перечень аргументов для cloud-init для виртуальных машин worker групп + #опциональный параметр + #тип - файл с форматом в виде yaml + #используется при создании и обновлении + #cloud_init = file("initconfig.tftpl") + +} + + +output "test_wg" { + value = decort_k8s_wg.wg +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm/main.tf b/samples/cloudapi/kvmvm/data_kvmvm/main.tf new file mode 100644 index 00000000..41307ee5 --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение данных о compute (виртуальной машине) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm" "comp" { + #получение информации по идентификатору машины - compute_id + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 11346 +} + +output "test" { + value = data.decort_kvmvm.comp +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_audits/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_audits/main.tf new file mode 100644 index 00000000..1256a26b --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_audits/main.tf @@ -0,0 +1,92 @@ +/*Deprecated + +Данный datasource является **deprecated** и будет удалён в следующих версиях. Вместо него неоходимо использовать datasource **decort_audit_list**. +*/ + +/* +Пример использования +Получение данных об аудитах compute (виртуальной машине) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_audits" "kvmvm_audits" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 + + #найти все аудиты после определенного момента времени + #опциональный параметр + #тип - целое число + #timestamp_to = 11 + + #найти все аудиты до определенного момента времени + #опциональный параметр + #тип - целое число + #timestamp_at = 11 + + #фильтр по юзеру + #опциональный параметр + #тип - строка + #user = "user" + + #фильтр по эндпоинту апи + #опциональный параметр + #тип - строка + #call = "call" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #значение по умолчанию - 1 + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #значение по умолчанию - 100 + #size = 100 + + #найти по минимальному коду статуса HTTP + #опциональный параметр + #тип - целое число + #min_status_code = 1 + + #найти по максимальному коду статуса HTTP + #опциональный параметр + #тип - целое число + #max_status_code = 140 + +} + +output "output" { + value = data.decort_kvmvm_audits.kvmvm_audits + } diff --git a/samples/cloudapi/kvmvm/data_kvmvm_cpu_alignment_profile/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_cpu_alignment_profile/main.tf new file mode 100644 index 00000000..7d8d176c --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_cpu_alignment_profile/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных о профиле CPU alignment виртуальной машины +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_cpu_alignment_profile" "cpu_alignment_profile" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 100 +} + +output "output" { + value = data.decort_kvmvm_cpu_alignment_profile.cpu_alignment_profile +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_get_audits/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_get_audits/main.tf new file mode 100644 index 00000000..0a194885 --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_get_audits/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных об аудитах compute (виртуальной машине) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_get_audits" "kvmvm_get_audits" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 +} + +output "output" { + value = data.decort_kvmvm_get_audits.kvmvm_get_audits +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_get_console_url/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_get_console_url/main.tf new file mode 100644 index 00000000..e6e00ad6 --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_get_console_url/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение url compute (виртуальной машины) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_get_console_url" "kvmvm_get_console_url" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 +} + +output "output" { + value = data.decort_kvmvm_get_console_url.kvmvm_get_console_url +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_get_log/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_get_log/main.tf new file mode 100644 index 00000000..14ea3c45 --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_get_log/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение логов compute (виртуальной машины) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_get_log" "kvmvm_get_log" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 + + #путь до log файла + #обязательный параметр + #тип - строка + path = "/var/log/file.log" +} + +output "output" { + value = data.decort_kvmvm_get_log.kvmvm_get_log +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_list/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_list/main.tf new file mode 100644 index 00000000..585f2030 --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_list/main.tf @@ -0,0 +1,115 @@ +/* +Пример использования +Получение данных об списке compute (виртуальных машин) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_list" "compute_list" { + #фильтр по id ВМ + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени ВМ + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка ВМ + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #rg_name = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по ip + #опциональный параметр + #тип - строка + #ip_address = "test" + + #фильтр по имени extnet + #опциональный параметр + #тип - строка + #extnet_name = "test" + + #фильтр по id extnet + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #флаг влючения в результат удаленных балансироващиков нагрузки + #опциональный параметр + #тип - булев + #по умолчанию - false + #если не задан - выводятся все доступные неудаленные балансировщики + #includedeleted = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 + +} + +output "output" { + value = data.decort_kvmvm_list.compute_list +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_list_deleted/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_list_deleted/main.tf new file mode 100644 index 00000000..853f999f --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_list_deleted/main.tf @@ -0,0 +1,96 @@ +/* +Пример использования +Получение данных о списке удаленных compute (виртуальных машин) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_list_deleted" "compute_list" { + #фильтр по id виртуальной машины + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени виртуальной машины + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 100 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #rg_name = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "some" + + #фильтр по ip + #опциональный параметр + #тип - строка + #ip_address = "test" + + #фильтр по имени extNet + #опциональный параметр + #тип - строка + #extnet_name = "test" + + #фильтр по id extNet + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output" { + value = data.decort_kvmvm_list_deleted.compute_list +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_pci_device_list/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_pci_device_list/main.tf new file mode 100644 index 00000000..f7c25e05 --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_pci_device_list/main.tf @@ -0,0 +1,76 @@ +/* +Пример использования +Получение данных о списке подключенных устройств (PCI) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_pci_device_list" "pci_device_list" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 100 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по id устройства + #опциональный параметр + #тип - целое число + #device_id = 100 + + #фильтр по имени устройства + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output" { + value = data.decort_kvmvm_pci_device_list.pci_device_list +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_pfw_list/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_pfw_list/main.tf new file mode 100644 index 00000000..c1cf5cde --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_pfw_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных об списке port forwarding compute (виртуальных машин) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "" + source = "basis/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_pfw_list" "kvmvm_pfw_list" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10524 +} + +output "output" { + value = data.decort_kvmvm_pfw_list.kvmvm_pfw_list +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_snapshot_usage/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_snapshot_usage/main.tf new file mode 100644 index 00000000..2755d6fe --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_snapshot_usage/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации об использовании снапшотов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_snapshot_usage" "snapshot_usage" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 + + #название снапшота + #опциональный параметр + #тип - строка + label = "label 1" +} + +output "output" { + value = data.decort_kvmvm_snapshot_usage.snapshot_usage +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_user_list/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_user_list/main.tf new file mode 100644 index 00000000..f5a0a808 --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_user_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных об юзерах compute (виртуальной машины) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_user_list" "kvmvm_user_list" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 +} + +output "output" { + value = data.decort_kvmvm_user_list.kvmvm_user_list +} diff --git a/samples/cloudapi/kvmvm/data_kvmvm_vgpu_list/main.tf b/samples/cloudapi/kvmvm/data_kvmvm_vgpu_list/main.tf new file mode 100644 index 00000000..4f6a6771 --- /dev/null +++ b/samples/cloudapi/kvmvm/data_kvmvm_vgpu_list/main.tf @@ -0,0 +1,75 @@ +/* +Пример использования +Получение данных о списке подключенных графических процессоров +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_kvmvm_vgpu_list" "vgpu_list" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 100 + + #фильтр по id графического процессора + #опциональный параметр + #тип - целое число + #gpu_id = 100 + + #фильтр по типу графического процессора + #опциональный параметр + #тип - строка + #type = "NVIDIA" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр "включая удаленные графические процессоры" + #опциональный параметр + #тип - булев + #includedeleted = "false" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output" { + value = data.decort_kvmvm_vgpu_list.vgpu_list +} diff --git a/samples/cloudapi/kvmvm/resource_kvmvm/initconfig.tftpl b/samples/cloudapi/kvmvm/resource_kvmvm/initconfig.tftpl new file mode 100644 index 00000000..587b59ce --- /dev/null +++ b/samples/cloudapi/kvmvm/resource_kvmvm/initconfig.tftpl @@ -0,0 +1,14 @@ +{ +"users": [ + { + "groups": "users, wheel", + "name": "user", + "plain_text_passwd": "examplePassword", + "primary_group": "user", + "ssh_authorized_keys": [ + "ssh-rsa EXAMPLE%id_rsa.pub" + ], + "sudo": "ALL=(ALL) NOPASSWD:ALL" + } +] +} diff --git a/samples/cloudapi/kvmvm/resource_kvmvm/main.tf b/samples/cloudapi/kvmvm/resource_kvmvm/main.tf new file mode 100644 index 00000000..611d4221 --- /dev/null +++ b/samples/cloudapi/kvmvm/resource_kvmvm/main.tf @@ -0,0 +1,622 @@ +/* +Пример использования +Работа с ресурсом kvmvm (compute) +Ресурс позволяет: +1. Создавать compute +2. Редактировать compute +3. Удалять compute +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_kvmvm" "comp" { + #имя compute + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "test-tf-compute-update-new" + + #id resource group + #обязательный параметр + #тип - целое число + #используется при создании + rg_id = 1111 + + #число cpu + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + cpu = 1 + + #кол-во оперативной памяти, МБ + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + ram = 2048 + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 1 + + #тип эмулируемой системы + #опциональный параметр + #тип - строка + #возможные значения: "i440fx", "Q35" + #по умолчанию - "Q35" + #используется при создании и обновлении + #chipset = "i440fx" + + #тип часов для ВМ + #опциональный параметр + #возможные значения: "default", "linux", "windows", "none" + #по умолчанию - "default" + #используется при создании и обновлении + #clock = "linux" + + #размер загрузочного диска + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #boot_disk_size = 20 + + #id сепа для boot диска + #опциональный параметр + #тип - целое число + #используется при создании + #sep_id = 1 + + #название пула + #опциональный параметр + #тип - строка + #используется при создании + #pool = "data02" + + #конфигурация cloud init + #опциональный параметр + #тип - файл в формате JSON + #используется при создании + #cloud_init = file("initconfig.tftpl") + + #описание compute + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #description = "test update description in tf words update" + + #id образа диска для создания compute + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #image_id = 111 + + #создание без загрузочного диска в остановленном состоянии + #опциональный параметр + #если значение равно True, параметры image_id, boot_disk_size, sep_id, pool игнорируются + #тип - булев + #используется при создании + #without_boot_disk = true + + #создание без образа ОС + #опциональный параметр + #тип - булев + #используется при создании + #create_blank = false + + #необходимость выравнивать ВМ по NUMA + #опциональный параметр + #возможные значения - "none, "strict", "loose" + #по умолчанию - "none" + #тип - строка + #используется при создании и обновлении + #numa_affinity = "loose" + + #id образа CD-ROM для загрузки + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #alt_boot_id = 1 + + #необходимость запускать ВМ на выделенных CPU ядрах + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при создании и обновлении + #cpu_pin = true + + #необходимость использовать для выделения RAM виртуальной машины Huge Pages + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при создании и обновлении + #hp_backed = true + + #список PCI девайсов + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #pci_devices = [1, 2] + + #создание и добавление диска для compute + #опциональный параметр + #тип - список дисков + #используется при создании и обновлении + #disks { + #имя диска + #обязательный для диска параметр + #тип - строка + #disk_name = "disk_name" + + #id политики хранения + #обязательный для диска параметр + #тип - целое число + #storage_policy_id = 1 + + #размер диска + #обязательный для диска параметр + #тип - целое число + #size = 5 + + #id сепа + #опциональный параметр + #тип - целое число + #sep_id = 1 + + #название пула + #опциональный параметр + #тип - строка + #pool = "data01" + + #описание диска + #опциональный параметр + #тип - строка + #desc = "" + + #id образа + #опциональный параметр + #тип - целое число + #image_id = 378 + + #флаг для удаления диска + #опциональный параметр + #тип - булев + #permanently = false + + #блок для управления IO-лимитами диска + #опциональный параметр + #тип - блок + #iotune { + #read_bytes_sec = 0 + #read_bytes_sec_max = 0 + #read_iops_sec = 0 + #read_iops_sec_max = 0 + #size_iops_sec = 0 + #total_bytes_sec = 0 + #total_bytes_sec_max = 0 + #total_iops_sec = 3000 + #total_iops_sec_max = 0 + #write_bytes_sec = 0 + #write_bytes_sec_max = 0 + #write_iops_sec = 0 + #write_iops_sec_max = 0 + #} + #} + + #правила affinity + #опциональный параметр + #может быть один, несколько или ни одного блока + #тип - блок правил + #используется при создании и обновлении + #affinity_rules { + #тип правила + #обязательный параметр + #возможные значения - compute или node + #тип - строка + #topology = "compute" + + #строгость правила + #обязательный параметр + #возможные значения - RECOMMENDED и REQUIRED + #тип - строка + #policy = "RECOMMENDED" + + #режим проверки + #обязательный параметр + #возможные значения - ANY, EQ, NE + #тип - строка + #mode = "ANY" + + #ключ правила + #обязательный параметр + #тип - строка + #key = "testkey" + + #ключ правила + #обязательный параметр + #тип - строка + #value = "testvalue" + #} + + #правила anti-affinity + #опциональный параметр + #может быть один, несколько или ни одного блока + #тип - список правил + #используется при создании и обновлении + #anti_affinity_rules { + #тип правила + #обязательный параметр + #возможные значения - compute или node + #тип - строка + #topology = "compute" + + #строгость правила + #обязательный параметр + #возможные значения - RECOMMENDED и REQUIRED + #тип - строка + #policy = "RECOMMENDED" + + #режим проверки + #обязательный параметр + #возможные значения - ANY, EQ, NE + #тип - строка + #mode = "ANY" + + #ключ правила + #обязательный параметр + #тип - строка + #key = "testkey" + + #ключ правила + #обязательный параметр + #тип -строка + #value = "testvalue" + #} + + #установка метки для вм + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #affinity_label = "test4" + + #имя профиля CPU alignment + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #cpu_alignment_profile = "balanced" + + #id экстра дисков + #опциональный параметр + #тип - список целых чисел + #используется при создании и обновлении + #extra_disks = [1234, 4322, 1344] + + #присоединение сетей и удаление сетей в компьюте + #опциональный параметр + #тип - блок сетей + #используется при создании и обновлении + #network { + #тип сети + #обязательный параметр + #тип - строка + #возможные значения - "VINS", "EXTNET", "VFNIC", "DPDK", "SDN", "TRUNK" (при выборе типа DPDK, необходимо указать hp_backed = true) + #net_type = "VINS" + + #id сети + #обязательный параметр + #при использовании SDN необходимо указать любое значение отличное от 0 + #тип - целое число + #net_id = 1234 + + #ip адрес входящий в сеть + #опциональный параметр + #тип - строка + #ip_address = "127.0.0.1" + + #mac-адрес интерфейса компьюта + #опциональный параметр + #тип - строка + #mac = "52:54:01:12:34:60" + + #вес сети, указывается при необходимости указания порядка подключения сетей + #первой подключается сеть с наименьшим весом + #сеть с нулевым или неуказанным весом имеет наименьший приоритет + #опциональный параметр + #тип - целое число + #weight = 15 + + #максимальный объём данных, который может быть передан за одну итерацию + #используется с сетями типа "DPDK", "TRUNK", "EXTNET" + #возможные значения - 1500-9216 + #опциональный параметр + #тип - целое число + #mtu = 1500 + + #id sdn сети + #используется только с сетями типа "SDN" + #опциональный параметр + #тип - строка + #sdn_interface_id = "f2d87a70-ea35-468d-8aef-bb1ecbe2e476" + + #включение сетевого интерфейса + #используется с сетями типа "VINS", "EXTNET", "DPDK", "SDN", "TRUNK" + #по умолчанию - true + #опциональный параметр + #тип - булев + #enabled = true + + #маска подсети + #используется только с сетями типа "DPDK" и "VFNIC" + #опциональный параметр + #тип - целое число + #net_mask = 32 + #} + + #группы безопасности + #опциональный параметр + #тип - блок + #не применяется к сетям типа "VFNIC", "TRUNK", "SDN" + #используется при создании и обновлении + #security_groups { + #тип сети + #обязательный параметр + #тип - строка + #возможные значения - "VINS", "EXTNET", "DPDK" (при выборе типа DPDK, необходимо указать hp_backed = true) + #net_type = "VINS" + + #id сети + #обязательный параметр + #при использовании SDN необходимо указать любое значение отличное от 0 + #тип - целое число + #net_id = 1234 + + #список id групп безопасности + #обязательный параметр + #тип - массив целых чисел + #security_groups = [12, 34] + + #флаг, указывающий, включены ли группы безопасности + #опциональный параметр + #тип - булев + #по умолчанию: false + #enable_secgroups = false + #} + + #добавление и удаление тэгов + #опциональный параметр + #тип - блок тэгов + #используется при создании и обновлении + #tags { + #ключ для тэга + #обязательный параметр + #тип - строка + #key = "key" + + #значения тэга + #обязательный параметр + #тип - строка + #value = "value" + #} + + #добавление и удаление port forwarding + #опциональный параметр + #тип - блок переадресации портов + #используется при создании и обновлении + #port_forwarding { + #номер внешнего начального порта для правила + #обязательный параметр + #тип - целое число + #public_port_start = 2023 + + #номер внешнего последнего порта для правила + #опциональный параметр + #тип - целое число + #по умолчанию - -1 + #public_port_end = 2023 + + #номер внутреннего базового порта + #обязательный параметр + #тип - целое число + #local_port = 80 + + #сетевой протокол + #обязательный параметр + #тип - строка + #proto = "tcp" + #} + + #предоставить/забрать пользователю доступ к компьюту + #опциональный параметр + #тип - блок прав пользователя + #используется при создании и обновлении + #user_access { + #имя юзера, которому предоставляем доступ + #обязательный параметр + #тип - строка + #username = "kasim_baybikov_1@decs3o" + + #права: 'R' - только на чтение, 'RCX' - чтение/запись, 'ARCXDU' - админ + #обязательный параметр + #тип - строка + #access_type = "ARCXDU" + #} + + #создать/удалить снапшот компьюта + #опциональный параметр + #тип - блок снапшотов + #используется при создании и обновлении + #snapshot { + #лейбл снапшота + #обязательный параметр + #тип - строка + #label = "label1" + #} + + #флаг для удаления снапшотов в асинхронном режиме + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при удалении + #snapshot_delete_async = true + + #rollback на нужный снапшот + #опциональный параметр + #не имеет смысла при отсутсвии снапшотов + #тип - блок rollback + #используется при обновлении + #rollback { + #лейбл снапшота + #обязательный параметр + #тип - строка + #label = "label1" + #} + + #вставить/удалить СD rom + #опциональный параметр + #максимальное кол-во - 1 + #тип - блок cd + #используется при создании и обновлении + #cd { + #id образа диска CD rom + #обязательный параметр + #тип - целое число + #cdrom_id = 344 + #} + + #добавить компьют на ноду + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #pin_to_node = true + + #список ядер для использования в механизме vcpupinning. Количество указанных ядер должно быть равно количеству виртуальных процессоров ВМ + #игнорируется если cpu_pin=false или pin_to_node=false + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #preferred_cpu = [1234, 456] + + #флаг для старта компьюта при рестарте ноды + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #auto_start_w_node = true + + #флаг доступности компьюта для проведения с ним операций + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enabled = true + + #pause/resume компьюта + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #pause = true + + #сделать компьют заново + #опциональный параметр + #тип - булев + #используется при обновлении + #reset = true + + #восстановить компьют из корзины + #опциональный параметр + #тип - булев + #используется при обновлении + #restore = true + + #флаг для редеплоя компьюта + #опциональный параметр + #тип - булев + #используется при обновлении + #force_stop = true + + #флаг для ресайза компьюта + #опциональный параметр + #тип - булев + #используется при обновлении + #force_resize = true + + #запуск/стоп компьюта + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #started = true + + #detach диска при удалении компьюта + #опциональный параметр + #тип - булев + #используется при удалении + #detach_disks = true + + #флаг для удаления компьюта, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = false + + #тип вм + #возможные значения - linux, windows, unknown + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #loader_type = "unknown" + + #тип загрузки образа + #возможные значения - bios, uefi + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #boot_type = "bios" + + #изменение размера ВМ + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #hot_resize = false + + #наименование сетевого интерфейса + #возможные значения - eth, ens + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #network_interface_naming = "ens" + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 + + #версия ОС, установленная на ВМ + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #os_version = "name" +} + +output "test" { + value = decort_kvmvm.comp +} diff --git a/samples/cloudapi/lb/data_lb/main.tf b/samples/cloudapi/lb/data_lb/main.tf new file mode 100644 index 00000000..c3293b7a --- /dev/null +++ b/samples/cloudapi/lb/data_lb/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о load balancer (балансировщик нагрузки) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_lb" "lb" { + #id балансировщика нагрузки + #обязательный параметр + #тип - целое число + lb_id = 238 +} + +output "test" { + value = data.decort_lb.lb +} diff --git a/samples/cloudapi/lb/data_lb_list/main.tf b/samples/cloudapi/lb/data_lb_list/main.tf new file mode 100644 index 00000000..1e31b320 --- /dev/null +++ b/samples/cloudapi/lb/data_lb_list/main.tf @@ -0,0 +1,105 @@ +/* +Пример использования +Получение списка load balancer (балансировщиков нагрузки) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_lb_list" "lbl" { + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени балансировщика нагрузки + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка балансировщиков нагрузки + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по IP front + #опциональный параметр + #тип - строка + #front_ip = "ENABLED" + + #фильтр по IP back + #опциональный параметр + #тип - строка + #back_ip = "ENABLED" + + #флаг включения в результат удаленных балансировщиков нагрузки + #опциональный параметр + #тип - булев + #по умолчанию - false + #если не задан - выводятся все доступные неудаленные балансировщики + #includedeleted = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 +} + +output "test" { + value = data.decort_lb_list.lbl +} diff --git a/samples/cloudapi/lb/data_lb_list_deleted/main.tf b/samples/cloudapi/lb/data_lb_list_deleted/main.tf new file mode 100644 index 00000000..a3252a5e --- /dev/null +++ b/samples/cloudapi/lb/data_lb_list_deleted/main.tf @@ -0,0 +1,86 @@ +/* +Пример использования +Получение списка удаленных load balancer (балансировщиков нагрузок) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_lb_list_deleted" "lbld" { + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени балансировщика нагрузки + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка балансировщиков нагрузки + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #фильтр по IP front + #опциональный параметр + #тип - строка + #front_ip = "ENABLED" + + #фильтр по IP back + #опциональный параметр + #тип - строка + #back_ip = "ENABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "test" { + value = data.decort_lb_list_deleted.lbld +} diff --git a/samples/cloudapi/lb/resource_lb/main.tf b/samples/cloudapi/lb/resource_lb/main.tf new file mode 100644 index 00000000..1cf821d1 --- /dev/null +++ b/samples/cloudapi/lb/resource_lb/main.tf @@ -0,0 +1,138 @@ +/* +Пример использования +Управление балансировщиком нагрузки (load balancer) +Ресурс позволяет: +1. Создавать load balancer +2. Редактировать load balancer +3. Удалять load balancer +/* + +#Раскомментируйте этот код +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_lb" "lb" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + #используется при создании + rg_id = 1111 + + #наименование load balancer + #обязательный параметр + #тип - строка + #используется при создании + name = "tf-test-lb" + + #id внешней сети + #опциональный параметр + #id внешней сети и id виртуальной сети не могут быть одновременно = 0 + #тип - целое число + #используется при создании + #extnet_id = 6 + + #id виртуальной сети + #опциональный параметр + #id внешней сети и id виртуальной сети не могут быть одновременно = 0 + #тип - целое число + #используется при создании + #vins_id = 758 + + #флаг запуска load balancer + #опциональный параметр + #если load balancer был в статусе "stopped" (start = false), + #то для успешного старта, он должен быть доступен (enable = true) + #по умолчанию - true + #тип - булев + #используется при создании и обновлении + #start = true + + #создать схему отказоустойчивой LB + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #ha_mode = true + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "temp super lb for testing tf provider" + + #флаг доступности load balancer + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enable = true + + #флаг перезапуска load balancer + #перезагрузка срабатывает только при изменении флага с false на true + #опциональный параметр + #тип - булев + #используется при обновлении + #restart = false + + #флаг сброса конфигурации load balancer + #сброс срабатывает только при изменении флага с false на true + #опциональный параметр + #тип - булев + #используется при обновлении + #config_reset = false + + #флаг для удаления load balancer, без возможности восстановления + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при удалении + #permanently = false + + #флаг восстановления load balancer + #опциональный параметр + #восстановить можно load balancer, удаленным с флагом permanently = false + #тип - булев + #используется при обновлении + #restore = true + + #флаг используемый при рестарте load balancer + #опциональный параметр + #при значении "true" рестарт производится на обоих нодах в HA mode + #по умолчанию - true + #тип - булев + #используется при обновлении + #safe = true + + #пользовательские значения sysctl для LB + #опциональный параметр + #тип - список мап + #используется при создании и обновлении + #sysctl_params = [{ key1 = "value1", key2 = "value2" }] + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 +} + +output "test" { + value = decort_lb.lb +} diff --git a/samples/cloudapi/lb/resource_lb_backend/main.tf b/samples/cloudapi/lb/resource_lb_backend/main.tf new file mode 100644 index 00000000..1b15280c --- /dev/null +++ b/samples/cloudapi/lb/resource_lb_backend/main.tf @@ -0,0 +1,127 @@ +/* +Пример использования +Ресурса load balancer backend +Ресурс позволяет: +1. Создавать backend +2. Редактировать backend +3. Удалять backend +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_lb_backend" "lb" { + #id балансировщика нагрузки + #обязательный параметр + #тип - целое число + #используется при создании + lb_id = 668 + + #имя бекенда для создания сервера + #обязательный параметр + #тип - строка + #используется при создании + name = "testBackend" + + #алгоритм балансировки + #опциональный параметр + #по умолчанию - "roundrobin" + #доступные значения - "roundrobin", "static-rr", "leastconn" + #тип - строка + #используется при создании и обновлении + #algorithm = "roundrobin" + + #------------------- + #настройки для серверов по умолчанию + #------------------- + + #интервал между проверками, в миллисекундах + #опциональный параметр + #по умолчанию - 5000 + #тип - целое число + #используется при создании и обновлении + #inter = 5000 + + #интервал между проверками доступности сервера после восстановления, в миллисекундах + #опциональный параметр + #по умолчанию - 1000 + #тип - целое число + #используется при создании и обновлении + #downinter = 1000 + + #кол-во проверок, которые сервер должен успешно пройти + #опциональный параметр + #по умолчанию - 2 + #тип - целое число + #используется при создании и обновлении + #rise = 2 + + #кол-во проверок, которые сервер может не пройти и после этого получить статус "unavailable" + #опциональный параметр + #по умолчанию - 2 + #тип - целое число + #используется при создании и обновлении + #fall = 2 + + #кол-во миллисекунд - время между получением сервера статуса "available" и открытием соединений + #опциональный параметр + #по умолчанию - 60000 + #тип - целое число + #используется при создании и обновлении + #slowstart = 60000 + + #максимальное кол-во соединений сервера, при достижении этого кол-ва, сервер выходит из схемы балансирования + #опциональный параметр + #по умолчанию - 250 + #тип - целое число + #используется при создании и обновлении + #maxconn = 250 + + #максимальное кол-во соединений в очереди серевера, при достижении этого кол-ва, соединения будут перенаправлены на другой сервер + #опциональный параметр + #по умолчанию - 256 + #тип - целое число + #используется при создании и обновлении + #maxqueue = 256 + + #вес сервера для балансировки + #опциональный параметр + #мин - 0 + #макс - 255 + #по умолчанию - 100 + #тип - целое число + #используется при создании и обновлении + #weight = 100 + + timeouts { + create = "5m" + read = "5m" + update = "5m" + delete = "5m" + } + +} + +output "test" { + value = decort_lb_backend.lb +} diff --git a/samples/cloudapi/lb/resource_lb_backend_server/main.tf b/samples/cloudapi/lb/resource_lb_backend_server/main.tf new file mode 100644 index 00000000..dd63ff89 --- /dev/null +++ b/samples/cloudapi/lb/resource_lb_backend_server/main.tf @@ -0,0 +1,141 @@ +/* +Пример использования +Ресурса load balancer backend server +Ресурс позволяет: +1. Создавать server +2. Редактировать server +3. Удалять server +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_lb_backend_server" "lb" { + #id балансировщика нагрузки + #обязательный параметр + #тип - целое число + #используется при создании + lb_id = 668 + + #имя бекенда для создания сервера + #обязательный параметр + #тип - строка + #используется при создании + backend_name = "testBackend" + + #имя сервера + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "testServer" + + #ip адрес сервера + #обязательный параметр + #тип - строка + #используется при создании и обновлении + address = "192.168.5.33" + + #порт сервера + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + port = 6553 + + #проверка доступности сервера + #опциональный параметр + #по умолчанию - "enabled" + #доступные значения - "disabled", "enabled" + #тип - строка + #используется при создании и обновлении + #check = "enabled" + + #интервал между проверками, в миллисекундах + #опциональный параметр + #по умолчанию - 5000 + #тип - целое число + #используется при создании и обновлении + #inter = 5000 + + #интервал между проверками доступности сервера после восстановления, в миллисекундах + #опциональный параметр + #по умолчанию - 1000 + #тип - целое число + #используется при создании и обновлении + #downinter = 1000 + + #кол-во проверок, которые сервер должен успешно пройти + #опциональный параметр + #тип - целое число + #по умолчанию - 2 + #используется при создании и обновлении + #rise = 2 + + #кол-во проверок, которые сервер может не пройти и после этого получить статус "unavailable" + #опциональный параметр + #по умолчанию - 2 + #тип - целое число + #используется при создании и обновлении + #fall = 2 + + #кол-во миллисекунд - время между получением сервера статуса "available" и открытием соединений + #опциональный параметр + #по умолчанию - 60000 + #тип - целое число + #используется при создании и обновлении + #slowstart = 60000 + + #максимальное кол-во соединений сервера, при достижении этого кол-ва, сервер выходит из схемы балансирования + #опциональный параметр + #по умолчанию - 250 + #тип - целое число + #используется при создании и обновлении + #maxconn = 250 + + #максимальное кол-во соединений в очереди серевера, при достижении этого кол-ва, соединения будут перенаправлены на другой сервер + #опциональный параметр + #по умолчанию - 256 + #тип - целое число + #используется при создании и обновлении + #maxqueue = 256 + + #вес сервера для балансировки + #опциональный параметр + #мин - 0 + #макс - 255 + #по умолчанию - 100 + #тип - целое число + #используется при создании и обновлении + #weight = 100 + + timeouts { + create = "5m" + read = "5m" + update = "5m" + delete = "5m" + } + +} + +output "test" { + value = decort_lb_backend_server.lb +} diff --git a/samples/cloudapi/lb/resource_lb_frontend/main.tf b/samples/cloudapi/lb/resource_lb_frontend/main.tf new file mode 100644 index 00000000..5a874cbf --- /dev/null +++ b/samples/cloudapi/lb/resource_lb_frontend/main.tf @@ -0,0 +1,62 @@ +/* +Пример использования +Ресурса load balancer frontend +Ресурс позволяет: +1. Создавать frontend +2. Удалять frontend +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_lb_frontend" "lb" { + #id балансировщика нагрузки + #обязательный параметр + #тип - целое число + #используется при создании + lb_id = 668 + + #имя бекенда для создания фронтенда + #обязательный параметр + #тип - строка + #используется при создании + backend_name = "testBackend" + + #имя фронтенда + #обязательный параметр + #тип - строка + #используется при создании + name = "testFrontend" + + timeouts { + create = "5m" + read = "5m" + update = "5m" + delete = "5m" + } + +} + +output "test" { + value = decort_lb_frontend.lb +} diff --git a/samples/cloudapi/lb/resource_lb_frontend_bind/main.tf b/samples/cloudapi/lb/resource_lb_frontend_bind/main.tf new file mode 100644 index 00000000..253bcd34 --- /dev/null +++ b/samples/cloudapi/lb/resource_lb_frontend_bind/main.tf @@ -0,0 +1,75 @@ +/* +Пример использования +Ресурса load balancer frontend bind (привязка фронтенда балансировщика нагрузок) +Ресурс позволяет: +1. Создавать привязку +2. Редактировать привязку +3. Удалять привязку +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_lb_frontend_bind" "lb" { + #id балансировщика нагрузки + #обязательный параметр + #тип - целое число + #используется при создании + lb_id = 668 + + #имя фронтенда для создания привязки + #обязательный параметр + #тип - строка + #используется при создании + frontend_name = "testFrontend" + + #наименование привязки + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "testBinding" + + #адрес привязки фронтенда + #обязательный параметр + #тип - строка + #используется при создании и обновлении + address = "111.111.111.111" + + #порт для привязки фронтенда + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + port = 1111 + + timeouts { + create = "5m" + read = "5m" + update = "5m" + delete = "5m" + } + +} + +output "test" { + value = decort_lb_frontend_bind.lb +} diff --git a/samples/cloudapi/location/data_location_url/main.tf b/samples/cloudapi/location/data_location_url/main.tf new file mode 100644 index 00000000..7c16a008 --- /dev/null +++ b/samples/cloudapi/location/data_location_url/main.tf @@ -0,0 +1,37 @@ +/* +Пример использования +Получение информации о площадках +Ресурс позволяет: +1. получать информацию об url площадки (grid/location). +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_location_url" "lu" { + #нет входных параметров +} + +output "test" { + value = data.decort_location_url.lu +} diff --git a/samples/cloudapi/location/data_locations_list/main.tf b/samples/cloudapi/location/data_locations_list/main.tf new file mode 100644 index 00000000..cdef3c25 --- /dev/null +++ b/samples/cloudapi/location/data_locations_list/main.tf @@ -0,0 +1,71 @@ +/* +Пример использования +Получение информации о доступных локациях. +Ресурс позволяет: +1) получать информацию о grid_id для создания ресурсов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_locations_list" "ll" { + #фильтр по флагу + #опциональный параметр + #тип - строка + #flag = "some" + + #фильтр по id локации + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени локации + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по коду локации + #опциональный параметр + #тип - строка + #location_code = "europe" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_locations_list.ll +} diff --git a/samples/cloudapi/pfw/resource_pfw/main.tf b/samples/cloudapi/pfw/resource_pfw/main.tf new file mode 100644 index 00000000..b94e189b --- /dev/null +++ b/samples/cloudapi/pfw/resource_pfw/main.tf @@ -0,0 +1,66 @@ +/* +Пример использования +Управление правилами трансляции сетевых портов для виртуальных серверов +Ресурс позволяет: +1. Создавать правила для трансляции сетевых портов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_pfw" "pfw" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + #используется при создании + compute_id = 11269 + + #начальный порт правила + #обязательный параметр + #тип - целое число + #используется при создании + public_port_start = 200 + + #внутренний порт + #обязательный параметр + #тип - целое число + #используется при создании + local_base_port = 22 + + #протокол соединения (tcp / udp) + #обязательный параметр + ##тип - строка + #используется при создании + proto = "tcp" + + #конечный порт (включительно) + #опциональный параметр + #тип - целое число + #используется при создании + #public_port_end = 21321 + +} + +output "pfw_out" { + value = decort_pfw.pfw +} diff --git a/samples/cloudapi/rg/data_rg/main.tf b/samples/cloudapi/rg/data_rg/main.tf new file mode 100644 index 00000000..8f74a0f3 --- /dev/null +++ b/samples/cloudapi/rg/data_rg/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации о ресурсной группе (RG) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_resgroup" "rg" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 1535 + +} + +output "output" { + value = data.decort_resgroup.rg +} diff --git a/samples/cloudapi/rg/data_rg_affinity_group_computes/main.tf b/samples/cloudapi/rg/data_rg_affinity_group_computes/main.tf new file mode 100644 index 00000000..76c4c26b --- /dev/null +++ b/samples/cloudapi/rg/data_rg_affinity_group_computes/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о специальной группе компьютов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_affinity_group_computes" "lc" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #название специальной группы компьютов + #обязательный параметр + #тип - строка + affinity_group = "TEST" +} + +output "output" { + value = data.decort_rg_affinity_group_computes.lc +} diff --git a/samples/cloudapi/rg/data_rg_affinity_groups_get/main.tf b/samples/cloudapi/rg/data_rg_affinity_groups_get/main.tf new file mode 100644 index 00000000..235d2263 --- /dev/null +++ b/samples/cloudapi/rg/data_rg_affinity_groups_get/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о списке компьютов из определенной группы +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_affinity_groups_get" "get_groups" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #название специальной группы компьютов + #обязательный параметр + #тип - строка + affinity_group = "TEST" +} + +output "output" { + value = data.decort_rg_affinity_groups_get.get_groups +} diff --git a/samples/cloudapi/rg/data_rg_affinity_groups_list/main.tf b/samples/cloudapi/rg/data_rg_affinity_groups_list/main.tf new file mode 100644 index 00000000..fc633fbf --- /dev/null +++ b/samples/cloudapi/rg/data_rg_affinity_groups_list/main.tf @@ -0,0 +1,50 @@ +/* +Пример использования +Получение информации о списке специальных групп компьютов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_affinity_groups_list" "list_groups" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output" { + value = data.decort_rg_affinity_groups_list.list_groups +} diff --git a/samples/cloudapi/rg/data_rg_audits/main.tf b/samples/cloudapi/rg/data_rg_audits/main.tf new file mode 100644 index 00000000..ed9916b6 --- /dev/null +++ b/samples/cloudapi/rg/data_rg_audits/main.tf @@ -0,0 +1,43 @@ +/*Deprecated + +Данный datasource является **deprecated** и будет удалён в следующих версиях. Вместо него неоходимо использовать datasource **decort_audit_list**. +*/ + +/* +Пример использования +Получение информации о списке аудитов ресурсной группы +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_audits" "rg_audits" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 +} + +output "output" { + value = data.decort_rg_audits.rg_audits +} diff --git a/samples/cloudapi/rg/data_rg_get_resource_consumption/main.tf b/samples/cloudapi/rg/data_rg_get_resource_consumption/main.tf new file mode 100644 index 00000000..9213eb06 --- /dev/null +++ b/samples/cloudapi/rg/data_rg_get_resource_consumption/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение списка текущего потребления ресурсов ресурсной группы +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_resource_consumption_get" "rc_get" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 111 +} + +output "test" { + value = data.decort_rg_resource_consumption_get.rc_get +} + diff --git a/samples/cloudapi/rg/data_rg_list/main.tf b/samples/cloudapi/rg/data_rg_list/main.tf new file mode 100644 index 00000000..d311fc50 --- /dev/null +++ b/samples/cloudapi/rg/data_rg_list/main.tf @@ -0,0 +1,93 @@ +/* +Пример использования +Получение информации о списке всех ресурсных групп к которым есть доступ +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} */ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_list" "rg_list" { + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка ресурсных групп + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "test" + + #фильтр по времени создания (после указанного времени) + #опциональный параметр + #тип - целое число + #created_after = "123" + + #фильтр по времени создания (перед указанным временем) + #опциональный параметр + #тип - целое число + #created_before = "123" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по lock status + #опциональный параметр + #тип - строка + #lock_status = "UNLOCKED" + + #отображать удаленные ресурсные группы или нет + #опциональный параметр + #тип - булев + #includedeleted = false + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 2 +} + +output "output" { + value = data.decort_rg_list.rg_list +} diff --git a/samples/cloudapi/rg/data_rg_list_computes/main.tf b/samples/cloudapi/rg/data_rg_list_computes/main.tf new file mode 100644 index 00000000..8d9f0e97 --- /dev/null +++ b/samples/cloudapi/rg/data_rg_list_computes/main.tf @@ -0,0 +1,96 @@ +/* +Пример использования +Получение информации о списке компьютов в ресурсной группе +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_list_computes" "list_computes" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #фильтр по id compute + #опциональный параметр + #тип - целое число + #compute_id = 100 + + #фильтр по имени compute + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STARTED" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по ip address + #опциональный параметр + #тип - строка + #ip_address = "1.1.1.1.1" + + #фильтр по имени внешней сети + #опциональный параметр + #тип - строка + #extnet_name = "test" + + #фильтр по id внешней сети + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output" { + value = data.decort_rg_list_computes.list_computes +} diff --git a/samples/cloudapi/rg/data_rg_list_deleted/main.tf b/samples/cloudapi/rg/data_rg_list_deleted/main.tf new file mode 100644 index 00000000..cc3bac86 --- /dev/null +++ b/samples/cloudapi/rg/data_rg_list_deleted/main.tf @@ -0,0 +1,84 @@ +/* +Пример использования +Получение информации о списке удаленных ресурсных групп +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_list_deleted" "list_deleted" { + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка ресурсных групп + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "test" + + #фильтр по времени создания (после указанного времени) + #опциональный параметр + #тип - целое число + #created_after = "123" + + #фильтр по времени создания (перед указанным временем) + #опциональный параметр + #тип - целое число + #created_before = "123" + + #фильтр по lock status + #опциональный параметр + #тип - строка + #lock_status = "UNLOCKED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 2 +} + +output "output" { + value = data.decort_rg_list_deleted.list_deleted +} diff --git a/samples/cloudapi/rg/data_rg_list_lb/main.tf b/samples/cloudapi/rg/data_rg_list_lb/main.tf new file mode 100644 index 00000000..1233775c --- /dev/null +++ b/samples/cloudapi/rg/data_rg_list_lb/main.tf @@ -0,0 +1,85 @@ +/* +Пример использования +Получение информации о списке балансировщиков в ресурсной группе +*/ +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_list_lb" "list_lb" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени балансировщика нагрузки + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по IP front + #опциональный параметр + #тип - строка + #front_ip = "ENABLED" + + #фильтр по IP back + #опциональный параметр + #тип - строка + #back_ip = "ENABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output" { + value = data.decort_rg_list_lb.list_lb +} diff --git a/samples/cloudapi/rg/data_rg_list_pfw/main.tf b/samples/cloudapi/rg/data_rg_list_pfw/main.tf new file mode 100644 index 00000000..4747fd8d --- /dev/null +++ b/samples/cloudapi/rg/data_rg_list_pfw/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о списке правил переадресации портов для ресурсной группы. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_list_pfw" "list_pfw" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 +} + +output "output" { + value = data.decort_rg_list_pfw.list_pfw +} diff --git a/samples/cloudapi/rg/data_rg_list_vins/main.tf b/samples/cloudapi/rg/data_rg_list_vins/main.tf new file mode 100644 index 00000000..0fe57772 --- /dev/null +++ b/samples/cloudapi/rg/data_rg_list_vins/main.tf @@ -0,0 +1,76 @@ +/* +Пример использования +Получение информации о списке винсов в ресурсной группе +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_list_vins" "list_vins" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #фильтр по id vins + #опциональный параметр + #тип - целое число + #vins_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка балансировщиков нагрузки + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по IP внешней сети + #опциональный параметр + #тип - строка + #ext_ip = "test" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 +} + +output "output" { + value = data.decort_rg_list_vins.list_vins +} diff --git a/samples/cloudapi/rg/data_rg_resource_consumption_list/main.tf b/samples/cloudapi/rg/data_rg_resource_consumption_list/main.tf new file mode 100644 index 00000000..be6a1f10 --- /dev/null +++ b/samples/cloudapi/rg/data_rg_resource_consumption_list/main.tf @@ -0,0 +1,36 @@ +/* +Пример использования +Получение списка текущего потребления ресурсов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_resource_consumption_list" "rc_list" { + #нет входных параметров +} + +output "test" { + value = data.decort_rg_resource_consumption_list.rc_list +} + diff --git a/samples/cloudapi/rg/data_rg_usage/main.tf b/samples/cloudapi/rg/data_rg_usage/main.tf new file mode 100644 index 00000000..74638ef1 --- /dev/null +++ b/samples/cloudapi/rg/data_rg_usage/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации об использовании ресурсов в ресурсной группе +*/ +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_rg_usage" "rg_usage" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 +} + +output "output" { + value = data.decort_rg_usage.rg_usage +} diff --git a/samples/cloudapi/rg/resource_rg/main.tf b/samples/cloudapi/rg/resource_rg/main.tf new file mode 100644 index 00000000..994d1853 --- /dev/null +++ b/samples/cloudapi/rg/resource_rg/main.tf @@ -0,0 +1,218 @@ +/* +Пример использования +Ресурсов RG +Ресурс позволяет: +1. Создавать RG +2. Редактировать RG +3. Удалять RG +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_resgroup" "rg" { + #имя ресурсной группы + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "testing_rg_1" + + #id аккаунта которому будет принадлежать ресурсная группа + #обязательный параметр + #тип - целое число + #используется при создании + account_id = 123 + + #id платформы + #обязательный параметр + #тип - целое число + #используется при создании + gid = 1234 + + #тип сети по умолчанию для этой ресурсной группы + #опциональный параметр + #виртуальные машины, созданные в этой RG, по умолчанию будут подключены к этой сети + #допустимые значения: PRIVATE, PUBLIC, NONE + #по умолчанию - PRIVATE + #тип - строка + #используется при создании + #def_net_type = "NONE" + + #ip cidr частной сети, если сеть по умолчанию PRIVATE + #опциональный параметр + #тип - строка + #используется при создании + #ipcidr = "1.1.1.1" + + #id внешней сети + #опциональный параметр + #тип - целое число + #используется при создании + #ext_net_id = 123 + + #ip внешней сети + #опциональный параметр + #тип - строка + #используется при создании + #ext_ip = "1.1.1.1" + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #description = "qwerty" + + #флаг доступности ресурсной группы + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enable = true + + #имя пользователя + #опциональный параметр + #тип - строка + #используется при создании + #owner = "name_user" + + #блок для предоставления прав на ресурсную группу + #опциональный параметр + #тип - блок прав доступа + #используется при создании и обновлении + #access { + #имя юзера предоставляемому права + #обязательный параметр при использовании блока + #тип - строка + #user = "kasim_baybikov_1@decs3o" + + #тип прав + #опциональный параметр + #тип - строка + #right = "RCX" + #} + + #установить сеть по умолчанию + #опциональный параметр + #тип - блок сетей + #используется при создании и обновлении + #def_net { + #тип сети + #обязательный параметр при использовании блока + #тип - строка + #net_type = "PUBLIC" + + #id сети + #опциональный параметр + #идентификатор сегмента сети. Если net_type — PUBLIC, а net_id — 0, + #то будет выбран сегмент внешней сети по умолчанию. Если net_type + #имеет значение PRIVATE и net_id=0, будет выбран первый vins, определенный для этой ресурсной группы + #в противном случае net_id идентифицирует либо существующий сегмент внешней сети, либо vins + #тип - целое число + #net_id = 1234 + + #} + + #лимиты ресурсов для ресурсной группы + #опциональный параметр + #тип - блок конфигураций + #используется при создании и обновлении + #quota { + #максимальное количество ядер процессора + #опциональный параметр + #по умолчанию: -1 + #тип - целое число + #cpu = 5 + + #максимальный размер памяти, в МБ + #опциональный параметр + #по умолчанию: -1 + #тип - целое число + #ram = 1024 + + #максимальный размер объединенных виртуальных дисков в ГБ + #опциональный параметр + #по умолчанию: -1 + #тип - целое число + #disk = 180 + + #максимальное количество назначенных общедоступных IP-адресов + #опциональный параметр + #по умолчанию: -1 + #тип - целое число + #ext_ips = 29 + #} + + #список названий pools + #опциональный параметр + #игнорируется при создании ресурса, применяется только при обновлении + #тип - массив строк + #используется при обновлении + #uniq_pools = ["sep1_poolName1", "sep2_poolName2"] + + #флаг для принудительного удаления ресурсной группы + #опциональный параметр + #тип - булев + #используется при удалении + #force = true + + #флаг для удаления ресурсной группы, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = true + + #восстановление группы после удаления + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при обновлении + #restore = true + + #идентификатор группы доступа SDN + #опциональный параметр + #тип - строка + #используется при создании + #sdn_access_group_id = "64e039f4-3705-4feb-84ff-a59fbdb1ebfe" + + #добавление/удаление политик хранения + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #storage_policy { + #id политики хранения + #обязательный параметр + #тип - целое число + #id = 8 + #лимит ресурсов хранения в ГБ + #опциональный параметр + #тип - целое число + #значение по умолчанию - -1 + #limit = 111 + #} +} + + +output "output" { + value = decort_resgroup.rg +} + + diff --git a/samples/cloudapi/secgroup/data_security_group/main.tf b/samples/cloudapi/secgroup/data_security_group/main.tf new file mode 100644 index 00000000..b9ceb039 --- /dev/null +++ b/samples/cloudapi/secgroup/data_security_group/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о security group по её id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_security_group" "sc" { + #идентификатор группы безопасности + #обязательный параметр + #тип - целое число + security_group_id = 1111 +} + +output "test" { + value = data.decort_security_group.sc +} \ No newline at end of file diff --git a/samples/cloudapi/secgroup/data_security_group_list/main.tf b/samples/cloudapi/secgroup/data_security_group_list/main.tf new file mode 100644 index 00000000..ba8e4963 --- /dev/null +++ b/samples/cloudapi/secgroup/data_security_group_list/main.tf @@ -0,0 +1,89 @@ +/* +Пример использования +Получение списка security group +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_security_group_list" "lsc" { + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы результата + #опциональный параметр + #тип - целое число + #size = 1 + + #фильтр по id + #опциональный параметр + #тип - целое число + #by_id = 1111 + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 1111 + + #фильтр по имени + #опциональный параметр + #тип - строка + #name = "security_group_name" + + #фильтр по описанию + #опциональный параметр + #тип - строка + #desc = "desc" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #фильтр по созданию до временной метки + #опциональный параметр + #тип - целое число + #created_min = 1111 + + #фильтр по созданию после временной метки + #опциональный параметр + #тип - целое число + #created_max = 1111 + + #фильтр по обновлению после временной метки + #опциональный параметр + #тип - целое число + #updated_min = 1111 + + #фильтр по обновлению до временной метки + #опциональный параметр + #тип - целое число + #updated_max = 1111 +} + +output "test" { + value = data.decort_security_group_list.lsc +} diff --git a/samples/cloudapi/secgroup/resource_security_group/main.tf b/samples/cloudapi/secgroup/resource_security_group/main.tf new file mode 100644 index 00000000..43e94ee5 --- /dev/null +++ b/samples/cloudapi/secgroup/resource_security_group/main.tf @@ -0,0 +1,96 @@ +/* +Пример использования +Ресурса группы безопасности: +1. Создание ресурса +2. Изменение ресурса +3. Удаление ресурса +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_security_group" "name" { + #id аккаунта, которому принадлежит группа безопасности + #обязательный параметр + #тип - целое число + #используется при создании + account_id = 111 + + #название группы безопасности + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "NAME" + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #description = "desc" + + #правила + #опциональный параметр + #тип - блок + #используется при обновлении + #rules { + #направление движения + #обязательный параметр + #тип - строка + #возможные значения - inbound, outbound + #direction = "inbound" + + #версия протокола IP + #опциональный параметр + #тип - строка + #возможные значения - IPv4, IPv6 + #значение по умолчанию - IPv4 + #ethertype = "IPv4" + + #сетевой протокол + #опциональный параметр + #тип - строка + #возможные значения - icmp, tcp, udp + #protocol = "icmp" + + #номер начального порта (для TCP/UDP) + #опциональный параметр + #тип - целое число + #port_range_min = 11 + + #номер конечного порта (для TCP/UDP) + #опциональный параметр + #тип - целое число + #port_range_max = 15 + + #удаленный IP префикс в нотации CIDR + #опциональный параметр + #тип - строка + #remote_ip_prefix = "192.168.1.0/24" + + #} +} + +output "test" { + value = decort_security_group.name +} \ No newline at end of file diff --git a/samples/cloudapi/sep/data_available_sep_and_pools_list/main.tf b/samples/cloudapi/sep/data_available_sep_and_pools_list/main.tf new file mode 100644 index 00000000..91feae0e --- /dev/null +++ b/samples/cloudapi/sep/data_available_sep_and_pools_list/main.tf @@ -0,0 +1,44 @@ +/* +Пример использования +Получение данных доступных sep и pools +*/ + +#Раскомментируйте код ниже, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sep_and_pools_available_list" "ap" { + #идентификатор аккаунта + #обязательный параметр + #тип - целое число + account_id = 1111 + + #идентификатор ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 1111 +} + +output "test" { + value = data.decort_sep_and_pools_available_list.ap +} + diff --git a/samples/cloudapi/snapshot/data_snapshot_list/main.tf b/samples/cloudapi/snapshot/data_snapshot_list/main.tf new file mode 100644 index 00000000..6ccc3e65 --- /dev/null +++ b/samples/cloudapi/snapshot/data_snapshot_list/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение списка snapshot +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +data "decort_snapshot_list" "sl" { + #обязательный параметр + #id вычислительной мощности + #тип - целое число + compute_id = 24074 +} + +output "test" { + value = data.decort_snapshot_list.sl +} diff --git a/samples/cloudapi/snapshot/resource_snapshot/main.tf b/samples/cloudapi/snapshot/resource_snapshot/main.tf new file mode 100644 index 00000000..1c5f2b5c --- /dev/null +++ b/samples/cloudapi/snapshot/resource_snapshot/main.tf @@ -0,0 +1,65 @@ +/* +Пример использования +Управление snapshot +Ресурс позволяет: +1. Создавать snapshot +2. Удалять snapshot +3. Откатывать snapshot +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_snapshot" "s" { + #id вычислительной мощности + #обязательный параметр + #тип - целое число + #используется при создании + compute_id = 24074 + + #наименование snapshot + #обязательный параметр + #тип - строка + #используется при создании + label = "test_ssht_3" + + #флаг отката + #опциональный параметр + #если флаг был изменен с false на true, то произойдет откат + #по умолчанию - false + #тип - булев + #используется при обновлении + #rollback = false + + #флаг для удаления снапшота в асинхронном режиме + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при удалении + #delete_async_mode = true + +} + +output "test" { + value = decort_snapshot.s +} diff --git a/samples/cloudapi/stpolicy/data_storage_policy/main.tf b/samples/cloudapi/stpolicy/data_storage_policy/main.tf new file mode 100644 index 00000000..2fe60b01 --- /dev/null +++ b/samples/cloudapi/stpolicy/data_storage_policy/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о storage policy по её id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_storage_policy" "sp" { + #идентификатор политики хранения + #обязательный параметр + #тип - целое число + storage_policy_id = 11111 +} + +output "test" { + value = data.decort_storage_policy.sp +} \ No newline at end of file diff --git a/samples/cloudapi/stpolicy/data_storage_policy_list/main.tf b/samples/cloudapi/stpolicy/data_storage_policy_list/main.tf new file mode 100644 index 00000000..5fed6ea3 --- /dev/null +++ b/samples/cloudapi/stpolicy/data_storage_policy_list/main.tf @@ -0,0 +1,100 @@ +/* +Пример использования +Получение списка storage policy +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_storage_policy_list" "lsp" { + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 1111 + + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы результата + #опциональный параметр + #тип - целое число + #size = 1 + + #фильтр по id + #опциональный параметр + #тип - целое число + #by_id = 1111 + + #фильтр по имени + #опциональный параметр + #тип - строка + #name = "storage_policy_name" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "status" + + #фильтр по описанию + #опциональный параметр + #тип - строка + #desc = "desc" + + #фильтр по лимиту iops + #опциональный параметр + #тип - целое число + #limit_iops = 1111 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #resgroup_id = 1111 + + #фильтр по id сеп + #опциональный параметр + #тип - целое число + #sep_id = 1111 + + #фильтр по имени пула + #опциональный параметр + #тип - строка + #pool_name = "name" + + #сортировка по статусу SEP + #опциональный параметр + #тип - строка + #возможные значения - ENABLED, DISABLED + #sep_tech_status = "ENABLED" +} + +output "test" { + value = data.decort_storage_policy_list.lsp +} \ No newline at end of file diff --git a/samples/cloudapi/trunk/data_trunk/main.tf b/samples/cloudapi/trunk/data_trunk/main.tf new file mode 100644 index 00000000..74d4fea2 --- /dev/null +++ b/samples/cloudapi/trunk/data_trunk/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных транка +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_trunk" "name" { + #идентификатор транка + #обязательный параметр + #тип - целое число + trunk_id = 1111 +} + +output "test" { + value = data.decort_trunk.name +} \ No newline at end of file diff --git a/samples/cloudapi/trunk/data_trunk_list/main.tf b/samples/cloudapi/trunk/data_trunk_list/main.tf new file mode 100644 index 00000000..f2ab32fd --- /dev/null +++ b/samples/cloudapi/trunk/data_trunk_list/main.tf @@ -0,0 +1,72 @@ +/* +Пример использования +Получение списка транковых портов. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* + +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_trunk_list" "name" { + #фильтр по id транка + #опциональный параметр + #тип - массив целых чисел + #trunk_ids = [10,11] + + #фильтр по id учетных записей с доступом к транку + #опциональный параметр + #тип - массив целых чисел + #account_ids = [10,11] + + #фильтр по тегам транка (значение от 1 до 4095) + #опциональный параметр + #тип - строка + #trunk_tags = "4095" + + #сортировка по статусу + #опциональный параметр + #тип - строка + #status = "DISABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_trunk_list.name +} \ No newline at end of file diff --git a/samples/cloudapi/vfpool/data_vfpool/main.tf b/samples/cloudapi/vfpool/data_vfpool/main.tf new file mode 100644 index 00000000..b3da2325 --- /dev/null +++ b/samples/cloudapi/vfpool/data_vfpool/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о vfpool по его id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vfpool" "vfpool" { + #идентификатор vfpool + #обязательный параметр + #тип - целое число + vfpool_id = 2 +} + +output "test" { + value = data.decort_vfpool.vfpool +} + diff --git a/samples/cloudapi/vfpool/data_vfpool_list/main.tf b/samples/cloudapi/vfpool/data_vfpool_list/main.tf new file mode 100644 index 00000000..df516c3f --- /dev/null +++ b/samples/cloudapi/vfpool/data_vfpool_list/main.tf @@ -0,0 +1,87 @@ +/* +Пример использования +Получение списка vfpool +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vfpool_list" "vfpool_list" { + #фильтрация списка для получения информации о конкретном vfpool по его id + #опциональный параметр + #тип - целое число + #by_id = 1 + + #фильтрация списка для получения информации о vfpool, которые принадлежат к определенному GRID + #опциональный параметр + #тип - целое число + #gid = 1 + + #фильтрация списка для получения информации о конкретном vfpool по его имени + #опциональный параметр + #тип - строка + #name = "alpha-cpu-04" + + #фильтрация списка для получения информации о конкретном vfpool по его описанию + #опциональный параметр + #тип - строка + #description = "some" + + #фильтрация списка для получения информации о vfpool, которые имеют соответствующий статус + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтрация списка для получения информации о vfpool, которые доступны конкретному аккаунту + #опциональный параметр + #тип - целое число + #account_access = 1 + + #фильтрация списка для получения информации о vfpool, которые доступны конкретной ресурсной группе + #опциональный параметр + #тип - целое число + #rg_access = 1 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 +} + +output "test" { + value = data.decort_vfpool_list.vfpool_list +} + diff --git a/samples/cloudapi/vins/data_vins/main.tf b/samples/cloudapi/vins/data_vins/main.tf new file mode 100644 index 00000000..89bf771a --- /dev/null +++ b/samples/cloudapi/vins/data_vins/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации об уже существующем виртуальном сетевом сегменте (Virtual Network Segment, ViNS). +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vins" "vins" { + #обязательный параметр + #id желаемого vins + #тип - целое число + vins_id = 10101 + +} + +output "test" { + value = data.decort_vins.vins +} diff --git a/samples/cloudapi/vins/data_vins_audits/main.tf b/samples/cloudapi/vins/data_vins_audits/main.tf new file mode 100644 index 00000000..e459c5c7 --- /dev/null +++ b/samples/cloudapi/vins/data_vins_audits/main.tf @@ -0,0 +1,44 @@ +/*Deprecated + +Данный datasource является **deprecated** и будет удалён в следующих версиях. Вместо него неоходимо использовать datasource **decort_audit_list**. +*/ + +/* +Пример использования +Получение списка записей аудита для внутренней сети vins. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vins_audits" "vins_audits" { + #обязательный параметр + #id желаемого vins + #тип - целое число + vins_id = 10101 + +} + +output "test" { + value = data.decort_vins_audits.vins_audits +} diff --git a/samples/cloudapi/vins/data_vins_ext_net_list/main.tf b/samples/cloudapi/vins/data_vins_ext_net_list/main.tf new file mode 100644 index 00000000..dba2b7bc --- /dev/null +++ b/samples/cloudapi/vins/data_vins_ext_net_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о внешних сетях виртуальной сети (Vins). +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vins_ext_net_list" "vins_ext_net_list" { + #обязательный параметр + #id желаемого vins + #тип - целое число + vins_id = 10101 +} + +output "test" { + value = data.decort_vins_ext_net_list.vins_ext_net_list +} diff --git a/samples/cloudapi/vins/data_vins_ip_list/main.tf b/samples/cloudapi/vins/data_vins_ip_list/main.tf new file mode 100644 index 00000000..2d377c70 --- /dev/null +++ b/samples/cloudapi/vins/data_vins_ip_list/main.tf @@ -0,0 +1,40 @@ +/* +Пример использования +Получение информации о списке зарезервированных IP адресов виртуальной сети (Vins) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vins_ip_list" "vins_ip_list" { + #обязательный параметр + #id желаемого vins + #тип - целое число + vins_id = 10101 + +} + +output "test" { + value = data.decort_vins_ip_list.vins_ip_list +} + diff --git a/samples/cloudapi/vins/data_vins_list/main.tf b/samples/cloudapi/vins/data_vins_list/main.tf new file mode 100644 index 00000000..712b809a --- /dev/null +++ b/samples/cloudapi/vins/data_vins_list/main.tf @@ -0,0 +1,99 @@ +/* +Пример использования +Получение списка удаленных виртуальных сетей (Vins). +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vins_list" "vl" { + #фильтр по id vins + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка балансировщиков нагрузки + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по IP внешней сети + #опциональный параметр + #тип - строка + #ext_ip = "test" + + #фильтр по VNF Device id + #опциональный параметр + #тип - целое число + #vnf_dev_id = 14 + + #включение удаленных vins в результат + #опциональный параметр + #тип - булев + #если не задан - выводятся все неудаленные данные + #include_deleted = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #поиск по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 + +} + +output "test" { + value = data.decort_vins_list.vl +} diff --git a/samples/cloudapi/vins/data_vins_list_deleted/main.tf b/samples/cloudapi/vins/data_vins_list_deleted/main.tf new file mode 100644 index 00000000..37980827 --- /dev/null +++ b/samples/cloudapi/vins/data_vins_list_deleted/main.tf @@ -0,0 +1,79 @@ +/* +Пример использования +Получение списка удаленных vins +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vins_list_deleted" "vins_list_deleted" { + #фильтр по id vins + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка балансировщиков нагрузки + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по IP внешней сети + #опциональный параметр + #тип - строка + #ext_ip = "test" + + #фильтр по id vnfDevices + #опциональный параметр + #тип - целое число + #vnfdev_id = 11111 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_vins_list_deleted.vins_list_deleted +} diff --git a/samples/cloudapi/vins/data_vins_nat_rule_list/main.tf b/samples/cloudapi/vins/data_vins_nat_rule_list/main.tf new file mode 100644 index 00000000..0e406006 --- /dev/null +++ b/samples/cloudapi/vins/data_vins_nat_rule_list/main.tf @@ -0,0 +1,40 @@ +/* +Пример использования +Получение списка natRule vins +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vins_nat_rule_list" "vins_nat_rule_list" { + #id желаемого vins + #обязательный параметр + #тип - целое число + vins_id = 10101 + +} + +output "test" { + value = data.decort_vins_nat_rule_list.vins_nat_rule_list +} + diff --git a/samples/cloudapi/vins/data_vins_static_route/main.tf b/samples/cloudapi/vins/data_vins_static_route/main.tf new file mode 100644 index 00000000..545c66e6 --- /dev/null +++ b/samples/cloudapi/vins/data_vins_static_route/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о статическом пути +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vins_static_route" "route" { + #id vins в котором добавлены routes + #обязательный параметр + #тип - целое число + vins_id = 1111 + + #id route + #обязательный параметр + #тип - целое число + route_id = 1 +} + +output "route" { + value = data.decort_vins_static_route.route +} diff --git a/samples/cloudapi/vins/data_vins_static_route_list/main.tf b/samples/cloudapi/vins/data_vins_static_route_list/main.tf new file mode 100644 index 00000000..7143cf10 --- /dev/null +++ b/samples/cloudapi/vins/data_vins_static_route_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о списке статических путей +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_vins_static_route_list" "list" { + #id vins в котором добавлены routes + #обязательный параметр + #тип - целое число + vins_id = 1111 +} + +output "list" { + value = data.decort_vins_static_route_list.list +} diff --git a/samples/cloudapi/vins/resource_vins/main.tf b/samples/cloudapi/vins/resource_vins/main.tf new file mode 100644 index 00000000..a0c375b9 --- /dev/null +++ b/samples/cloudapi/vins/resource_vins/main.tf @@ -0,0 +1,208 @@ +/* +Пример использования +Управление vins +Ресурс позволяет: +1. Создавать vins +2. Удалять vins +3. Восстанвливать vins +4. Добавлять и убирать подключение к внешней сети +5. Резервировать и освобождать ip для vins +6. Добавлять и удалять natrule +7. Перезапускать и редеплоить vnfdev +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +resource "decort_vins" "vins" { + #имя создаваемого ресурса + #обязательный параметр + #тип - строка + #используется при создании + name = "Test_name" + + #id ресурсной группы для создания ресурса + #должен быть указан или rg_id или account_id + #опциональный параметр + #тип - целое число + #используется при создании + rg_id = 10101 + + #id аккаунта для создания ресурса + #должен быть указан или rg_id или account_id + #опциональный параметр + #тип - целое число + #используется при создании + account_id = 2023 + + #id внешней сети для подключения к ней ресурса + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #ext_net_id = 2222 + + #ip внешней сети для подключения к нему ресурса + #опциональный параметр + #тип - строка + #используется при создании + #ext_ip_addr = "1.1.1.1" + + #private network IP CIDR + #опциональный параметр + #тип - строка + #используется при создании + #ipcidr = "192.168.0.1" + + #количество зарезервированных адресов на момент создания + #опциональный параметр + #тип - целое число + #используется при создании + #pre_reservations_num = 2 + + #grid (platform) ID + #опциональный параметр + #тип - целое число + #используется при создании + #gid = 2002 + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "Description" + + #ручное подключение и отключение ресурса + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enable = true + + #флаг для удаления VINS, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = true + + #удаляет за собой все зависимые ресурсы + #опциональный параметр + #тип - булев + #используется при удалении + #force = true + + #блок для резервирования ip + #опциональный параметр + #тип - блок ip + #используется при создании и обновлении + #ip { + #тип подключения + #обязательный параметр + #тип - строка + #type = "DHCP" + + #ip который необходимо зарезервировать + #опциональный параметр + #тип - строка + #ip_addr = "192.168.5.5" + + #mac который необходимо зарезервировать + #опциональный параметр + #тип - строка + #mac_addr = "ff:ff:ff:ff:ff:ff" + #} + + #блок для добавления natRule + #опциональный параметр + #тип - блок правил nat + #используется при создании и обновлении + #nat_rule { + #ip внутренний + #опциональный параметр + #тип - строка + #int_ip = "192.168.0.28" + + #внутренний порт + #опциональный параметр + #тип - целое число + #int_port = 80 + + #начало диапазона внешних портов + #опциональный параметр + #тип - целое число + #ext_port_start = 8001 + + #конец диапазона внешних портов + #опциональный параметр + #тип - целое число + #ext_port_end = 8001 + + #протокол natRule + #опциональный параметр + #тип - строка + #proto = "tcp" + #} + + #восстановление ресурса + #опциональный параметр + #тип - булев + #используется при обновлении + #restore = true + + #перезапуск vnfDev + #опциональный параметр + #тип - булев + #используется при обновлении + #vnfdev_restart = true + + #редеплой vnfDev + #опциональный параметр + #тип - булев + #используется при обновлении + #vnfdev_redeploy = true + + #список dns + #опциональный параметр + #если при создании указать пустой список, то ресурс создается с полем vnfs.dhcp.config.dns, имеющим значение по умолчанию + #если при обновлении указать пустой список, то ресурс обновит в модели поле vnfs.dhcp.config.dns с текущего значения на пустой список + #тип - список строк + #используется при создании и обновлении + #dns = ["1.1.1.1", "2.2.2.2"] + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 + + #флаг, указывающий, включены ли группы безопасности для этой сети + #опциональный параметр + #тип - булев + #используется при создании + #значение по умолчанию - false + #enable_secgroups = false + +} + +output "test" { + value = decort_vins.vins +} diff --git a/samples/cloudapi/vins/resource_vins_static_route/main.tf b/samples/cloudapi/vins/resource_vins_static_route/main.tf new file mode 100644 index 00000000..5171ce3d --- /dev/null +++ b/samples/cloudapi/vins/resource_vins_static_route/main.tf @@ -0,0 +1,64 @@ +/* +Пример использования +Работа с vins static routes +Ресурс позволяет: +1. Создавать static routes +2. Удалять static routes +3. Получать информацию о всех static routes в данном Vins +4. Предоставлять доступ виртуальным машинам к static routes +5. Удалять доступ виртуальным машинам к static routes +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_vins_static_route" "sr" { + #id VINS + #обязательный параметр + #тип - целое число + #используется при создании + vins_id = 1111 + + #destination network + #обязательный параметр + #тип - строка + #используется при создании + destination = "192.168.201.0" + + #destination network mask + #обязательный параметр + #тип - строка + #используется при создании + netmask = "255.255.255.255" + + #ip-адрес из пула свободных IP-адресов ViNS ID + #обязательный параметр + #тип - строка + #используется при создании + gateway = "192.168.201.40" +} + +output "sr" { + value = decort_vins_static_route.sr +} + diff --git a/samples/cloudapi/zone/data_zone/main.tf b/samples/cloudapi/zone/data_zone/main.tf new file mode 100644 index 00000000..4b556a01 --- /dev/null +++ b/samples/cloudapi/zone/data_zone/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о zone по ее id +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_zone" "zone" { + #идентификатор zone + #обязательный параметр + #тип - целое число + zone_id = 2 +} + +output "test" { + value = data.decort_zone.zone +} + diff --git a/samples/cloudapi/zone/data_zone_list/main.tf b/samples/cloudapi/zone/data_zone_list/main.tf new file mode 100644 index 00000000..de468740 --- /dev/null +++ b/samples/cloudapi/zone/data_zone_list/main.tf @@ -0,0 +1,87 @@ +/* +Пример использования +Получение списка zone +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_zone_list" "zone_list" { + #фильтрация списка для получения информации о конкретном zone по его id + #опциональный параметр + #тип - целое число + #by_id = 1 + + #фильтрация списка для получения информации о zone, которые принадлежат к определенному GRID + #опциональный параметр + #тип - целое число + #gid = 1 + + #фильтрация списка для получения информации о конкретном zone по его имени + #опциональный параметр + #тип - строка + #name = "alpha-cpu-04" + + #фильтрация списка для получения информации о конкретном zone по его описанию + #опциональный параметр + #тип - строка + #description = "some" + + #фильтрация списка для получения информации о zone, которые имеют соответствующий статус + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтрация списка для получения информации о zone, которые удалены + #опциональный параметр + #тип - булев + #deletable = false + + #фильтрация списка для получения информации о zone с конкретными nodeId + #опциональный параметр + #тип - целое число + #node_id = 1 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 +} + +output "test" { + value = data.decort_zone_list.zone_list +} + diff --git a/samples/cloudbroker/account/data_account/main.tf b/samples/cloudbroker/account/data_account/main.tf new file mode 100644 index 00000000..8ef19c1b --- /dev/null +++ b/samples/cloudbroker/account/data_account/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации об аккаунте +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account" "acc" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 11111 + +} + +output "test" { + value = data.decort_cb_account.acc +} diff --git a/samples/cloudbroker/account/data_account_audits_list/main.tf b/samples/cloudbroker/account/data_account_audits_list/main.tf new file mode 100644 index 00000000..88c7ba83 --- /dev/null +++ b/samples/cloudbroker/account/data_account_audits_list/main.tf @@ -0,0 +1,44 @@ +/*Deprecated + +Данный datasource является **deprecated** и будет удалён в следующих версиях. Вместо него неоходимо использовать datasource **decort_cb_audit_list**. +*/ + +/* +Пример использования +Получение информации об использовании аккаунта +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_audits_list" "aal" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 11111 + +} + +output "test" { + value = data.decort_cb_account_audits_list.aal +} diff --git a/samples/cloudbroker/account/data_account_available_templates/main.tf b/samples/cloudbroker/account/data_account_available_templates/main.tf new file mode 100644 index 00000000..3281ca67 --- /dev/null +++ b/samples/cloudbroker/account/data_account_available_templates/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации о доступных образах, которые использует аккаунт +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_available_templates_list" "atl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 11111 + +} + +output "test" { + value = data.decort_cb_account_available_templates_list.atl +} diff --git a/samples/cloudbroker/account/data_account_computes_list/main.tf b/samples/cloudbroker/account/data_account_computes_list/main.tf new file mode 100644 index 00000000..3faa4007 --- /dev/null +++ b/samples/cloudbroker/account/data_account_computes_list/main.tf @@ -0,0 +1,97 @@ +/* +Пример использования +Получение списка computes, используемых аккаунтом +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_computes_list" "acl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 1111 + + #фильтр по id compute + #опциональный параметр + #тип - целое число + #compute_id = 100 + + #фильтр по имени compute + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #rg_name = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STARTED" + + #фильтр по ip address + #опциональный параметр + #тип - строка + #ip_address = "1.1.1.1.1" + + #фильтр по имени внешней сети + #опциональный параметр + #тип - строка + #extnet_name = "test" + + #фильтр по id внешней сети + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 1 + +} + +output "test" { + value = data.decort_cb_account_computes_list.acl +} diff --git a/samples/cloudbroker/account/data_account_disks_list/main.tf b/samples/cloudbroker/account/data_account_disks_list/main.tf new file mode 100644 index 00000000..0e393cf8 --- /dev/null +++ b/samples/cloudbroker/account/data_account_disks_list/main.tf @@ -0,0 +1,76 @@ +/* +Пример использования +Получение информации о дисках, которые использует аккаунт +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_disks_list" "adl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 11111 + + #фильтр по id диска + #опциональный параметр + #тип - целое число + #disk_id = 100 + + #фильтр по имени диска + #опциональный параметр + #тип - строка + #name = "data_disk" + + #фильтр по максимальному размеру диска + #опциональный параметр + #тип - целое число + #disk_max_size = 100 + + #тип диска + #опциональный параметр + #тип - строка + #возможные типы: "b" - boot_disk, "d" - data_disk + #type = "d" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 + +} + +output "test" { + value = data.decort_cb_account_disks_list.adl +} diff --git a/samples/cloudbroker/account/data_account_flipgroups_list/main.tf b/samples/cloudbroker/account/data_account_flipgroups_list/main.tf new file mode 100644 index 00000000..f953c5e0 --- /dev/null +++ b/samples/cloudbroker/account/data_account_flipgroups_list/main.tf @@ -0,0 +1,85 @@ +/* +Пример использования +Получение информации о flipgroups, используемых аккаунтом +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_flipgroups_list" "afgl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 1111 + + #фильтр по имени flipgroup + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id vins + #опциональный параметр + #тип - целое число + #vins_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #vins_name = "test" + + #фильтр по id extnet + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #фильтр по IP + #опциональный параметр + #тип - строка + #by_ip = "1.1.1.1.1" + + #фильтр по id flipgroup + #опциональный параметр + #тип - целое число + #flipgroup_id = 100 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 + +} + +output "test" { + value = data.decort_cb_account_flipgroups_list.afgl +} diff --git a/samples/cloudbroker/account/data_account_get_resource_consumption/main.tf b/samples/cloudbroker/account/data_account_get_resource_consumption/main.tf new file mode 100644 index 00000000..1e03723b --- /dev/null +++ b/samples/cloudbroker/account/data_account_get_resource_consumption/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение списка текущего потребления ресурсов аккаунта +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_resource_consumption_get" "rc_get" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 111 + +} + +output "test" { + value = data.decort_cb_account_resource_consumption_get.rc_get +} diff --git a/samples/cloudbroker/account/data_account_list/main.tf b/samples/cloudbroker/account/data_account_list/main.tf new file mode 100644 index 00000000..9f3532ac --- /dev/null +++ b/samples/cloudbroker/account/data_account_list/main.tf @@ -0,0 +1,78 @@ +/* +Пример использования +Получение всех аккаунтов,имеющихся в системе +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_list" "al" { + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по ACL + #опциональный параметр + #тип - строка + #acl = "test" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 3 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 + +} + +output "test" { + value = data.decort_cb_account_list.al +} diff --git a/samples/cloudbroker/account/data_account_list_deleted/main.tf b/samples/cloudbroker/account/data_account_list_deleted/main.tf new file mode 100644 index 00000000..5f190283 --- /dev/null +++ b/samples/cloudbroker/account/data_account_list_deleted/main.tf @@ -0,0 +1,68 @@ +/* +Пример использования +Получение информации об удаленных аккаунтах +Информация предоставляется только по аккаунтам, удаленным без флага permanently +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_list_deleted" "adl" { + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 3 + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по ACL + #опциональный параметр + #тип - строка + #acl = "test" + +} + +output "test" { + value = data.decort_cb_account_list_deleted.adl +} diff --git a/samples/cloudbroker/account/data_account_resource_consumption_list/main.tf b/samples/cloudbroker/account/data_account_resource_consumption_list/main.tf new file mode 100644 index 00000000..fbec27af --- /dev/null +++ b/samples/cloudbroker/account/data_account_resource_consumption_list/main.tf @@ -0,0 +1,35 @@ +/* +Пример использования +Получение списка текущего потребления ресурсов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_resource_consumption_list" "rc_list" { + #нет входных параметров +} + +output "test" { + value = data.decort_cb_account_resource_consumption_list.rc_list +} diff --git a/samples/cloudbroker/account/data_account_rg_list/main.tf b/samples/cloudbroker/account/data_account_rg_list/main.tf new file mode 100644 index 00000000..357203b1 --- /dev/null +++ b/samples/cloudbroker/account/data_account_rg_list/main.tf @@ -0,0 +1,82 @@ +/* +Пример использования +Получение информации о ресурных группах, используемых аккаунтом +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_rg_list" "argl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 66666 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 3 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 11111 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id vins + #опциональный параметр + #тип - целое число + #vins_id = 100 + + #фильтр по id compute + #опциональный параметр + #тип - целое число + #vm_id = 100 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "CREATED" + +} + +output "test" { + value = data.decort_cb_account_rg_list.argl +} diff --git a/samples/cloudbroker/account/data_account_vins_list/main.tf b/samples/cloudbroker/account/data_account_vins_list/main.tf new file mode 100644 index 00000000..18c42e05 --- /dev/null +++ b/samples/cloudbroker/account/data_account_vins_list/main.tf @@ -0,0 +1,77 @@ +/* +Пример использования +Получение списка vins, используемых аккаунтом +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_account_vins_list" "avl" { + #id аккаунта + #обязательный параметр + #тип - целое число + account_id = 22222 + + #фильтр по id vins + #опциональный параметр + #тип - целое число + #vins_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 11111 + + #фильтр по IP внешней сети + #опциональный параметр + #тип - строка + #ext_ip = "test" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 3 + +} + +output "test" { + value = data.decort_cb_account_vins_list.avl +} diff --git a/samples/cloudbroker/account/resource_account/main.tf b/samples/cloudbroker/account/resource_account/main.tf new file mode 100644 index 00000000..c17c8ed9 --- /dev/null +++ b/samples/cloudbroker/account/resource_account/main.tf @@ -0,0 +1,208 @@ +/* +Пример использования +Ресурса account +Ресурс позволяет: +1. Создавать аккаунт +2. Редактировать аккаунт +3. Удалять аккаунт +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_account" "acc" { + #отображаемое имя аккаунта + #обязательный параметр + #тип - строка + #используется при создании и обновлении + account_name = "new_my_account" + + #имя пользователя, для которого создается аккаунт + #обязательный параметр + #тип - строка + #используется при создании + username = "username@decs3o" + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "description" + + #доступность аккаунта + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enable = true + + #электронная почта, на которую будет отправлена информация о доступе + #опциональный параметр + #тип - строка + #применяется при создании аккаунта + #используется при создании + #emailaddress = "example@basis.ru" + + #отправлять ли на электронную почту письмо о доступе + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #send_access_emails = true + + #пары sep_id и sep_pool_name + #опциональный параметр + #тип - массив строк + #используется при создании и обновлении + #каждая строка представляет собой пару, sepID_sepPoolName + #uniq_pools = ["sep1_poolName1", "sep2_poolName2"] + + #ограничение используемых ресурсов + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #resource_limits { + #кол-во используемых ядер cpu + #опциональный параметр + #тип - целое число + #если установлена -1 - кол-во неограниченно + #cu_c = 2 + + #кол-во используемой RAM в МБ + #опциональный параметр + #тип - целое число + #если установлена -1 - кол-во неограниченно + #cu_m = 1024 + + #размер дисков, в ГБ + #опциональный параметр + #тип - целое число + #если установлена -1 - размер неограничен + #cu_dm = 23 + + #кол-во используемых публичных IP + #опциональный параметр + #тип - целое число + #если установлена -1 - кол-во неограничено + #cu_i = 2 + + #кол-во графических процессоров + #опциональный параметр + #тип - целое число + #если установлена -1 - кол-во неограничено + #gpu_units = 2 + #} + + #добавление/удаление политик хранения + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #storage_policy { + #id политики хранения + #обязательный параметр + #тип - целое число + #id = 111 + + #лимит ресурсов хранения в ГБ + #опциональный параметр + #тип - целое число + #значение "-1", если не ограничено + #limit = 111 + #} + + #добавление/редактирование/удаление пользователей, к которым привязан аккаунт + #опциональный параметр + #тип - блок, кол-во таких блоков не ограничено + #используется при создании и обновлении + #users { + #id пользователя + #обязательный параметр + #тип - строка + #user_id = "username_2@decs3o" + + #тип доступа пользователя + #обязательный параметр + #тип - строка + #возможные параметры: + #R - чтение + #RCX - запись + #ARCXDU - админ + #access_type = "R" + #} + + + #параметр распределения CPU + #опциональный параметр + #тип - строка + #если "strict" виртуальная машина не может быть запущена из-за нехватки ресурсов. + #"loose" позволяет запускать виртуальную машину, если недостаточно ресурсов. + #используется при создании и обновлении + #cpu_allocation_parameter = "strict" + + #параметр коэффициента распределения CPU + #опциональный параметр + #тип - целое число + #один pCPU = коэффициент*vCPU (принимает нулевое или положительное значение) + #используется при создании и обновлении + #cpu_allocation_ratio = 1 + + #флаг для удаления аккаунта, без возможности восстановления + #опциональный параметр + #тип - булев + #по умолчанию - false + #используется при удалении + #permanently = true + + #флаг для восстановление аккаунта из корзины + #опциональный параметр + #тип - булев + #используется при обновлении + #restore = true + + #предоставление аккаунту доступа к конкретным образам + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #available_templates = [1,2] + + #доступ к дополнительным функциям управления ВМ + #опциональный параметр + #возможные значенния - "hugepages", "numa", "cpupin", "vfnic", "dpdk, "changemac", "trunk" + #тип - массив строк + #используется при создании и обновлении + #compute_features = ["hugepages", "numa", "cpupin", "vfnic"] + + #зона по умолчанию для аккаунта + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #default_zone_id = 1111 + + #управление зонами аккаунта + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #zone_ids = [1,2,3] +} + +output "test" { + value = decort_cb_account.acc +} diff --git a/samples/cloudbroker/audit/data_audit/main.tf b/samples/cloudbroker/audit/data_audit/main.tf new file mode 100644 index 00000000..f0d715e6 --- /dev/null +++ b/samples/cloudbroker/audit/data_audit/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение аудита по guid +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_audit" "audit" { + #guid аудита + #обязательный параметр + #тип - строка + audit_guid = "abcdefg" + +} + +output "test" { + value = data.decort_cb_audit.audit +} diff --git a/samples/cloudbroker/audit/data_audit_linked_jobs/main.tf b/samples/cloudbroker/audit/data_audit_linked_jobs/main.tf new file mode 100644 index 00000000..65326d21 --- /dev/null +++ b/samples/cloudbroker/audit/data_audit_linked_jobs/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение списка заданий, связанных с указанный событием. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_audit_linked_jobs" "jobs" { + #guid аудита + #обязательный параметр + #тип - строка + audit_guid = "abcdefg" + +} + +output "test" { + value = data.decort_cb_audit_linked_jobs.jobs +} diff --git a/samples/cloudbroker/audit/data_audit_list/main.tf b/samples/cloudbroker/audit/data_audit_list/main.tf new file mode 100644 index 00000000..2cddd1d4 --- /dev/null +++ b/samples/cloudbroker/audit/data_audit_list/main.tf @@ -0,0 +1,141 @@ +/* +Пример использования +Получение списка аудитов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_audit_list" "al" { + #фильтр по аудитам с временной меткой после указанного значения + #опциональный параметр + #тип - целое число + #timestamp_at = 123456 + + #фильтр по аудитам с временной меткой до указанного значения + #опциональный параметр + #тип - целое число + #timestamp_to = 123456 + + #фильтр по пользователю (Mongo RegExp поддерживаются) + #опциональный параметр + #тип - строка + #user = "username" + + #фильтр по api endpoint (Mongo RegExp поддерживаются) + #опциональный параметр + #тип - строка + #call = "/restmachine/cloudbroker/audit/list" + + #фильтр по минимальному HTTP статус-коду + #опциональный параметр + #тип - целое число + #min_status_code = 200 + + #фильтр по максимальному HTTP статус-коду + #опциональный параметр + #тип - целое число + #max_status_code = 500 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 2 + + #идентификатор запроса + #опциональный параметр + #тип - строка + #request_id = "35" + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 3 + + #id ресурсной группы + #опциональный параметр + #тип - целое число + #resgroup_id = 3 + + #id компьюта + #опциональный параметр + #тип - целое число + #compute_id = 3 + + #id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 3 + + #id vins + #опциональный параметр + #тип - целое число + #vins_id = 3 + + #id базовой службы + #опциональный параметр + #тип - целое число + #service_id = 3 + + #id k8s-кластера + #опциональный параметр + #тип - целое число + #k8s_id = 3 + + #id flipgroup + #опциональный параметр + #тип - целое число + #flipgroup_id = 3 + + #id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #lb_id = 3 + + #id sep + #опциональный параметр + #тип - целое число + #sep_id = 3 + + #id узла + #опциональный параметр + #тип - целое число + #node_id = 3 + + #исключить ли строки + #опциональный параметр + #тип - булев + #default – false + #exclude_audit_lines = false + +} + +output "test" { + value = data.decort_cb_audit_list.al +} diff --git a/samples/cloudbroker/audit/data_audits_export_to_file/main.tf b/samples/cloudbroker/audit/data_audits_export_to_file/main.tf new file mode 100644 index 00000000..95372dbf --- /dev/null +++ b/samples/cloudbroker/audit/data_audits_export_to_file/main.tf @@ -0,0 +1,40 @@ +/* +Пример использования +Получения списка аудитов в виде архива csv файлов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_audits_export_to_file" "audit" { + #путь, где будет создан архив + #если не указан, создается в директории с main.tf с именем "audits.tar.gz" + #обязательный параметр + #тип - строка + file_path = "abcdefg.tar.gz" + +} + +output "test" { + value = data.decort_cb_audits_export_to_file.audit +} diff --git a/samples/cloudbroker/disk/data_disk/main.tf b/samples/cloudbroker/disk/data_disk/main.tf new file mode 100644 index 00000000..94116d02 --- /dev/null +++ b/samples/cloudbroker/disk/data_disk/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации об уже существующем диске. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_disk" "acl" { + #id диска + #обязательный параметр + #тип - целое число + disk_id = 49304 + +} + +output "test" { + value = data.decort_cb_disk.acl +} diff --git a/samples/cloudbroker/disk/data_disk_list/main.tf b/samples/cloudbroker/disk/data_disk_list/main.tf new file mode 100644 index 00000000..c0817e50 --- /dev/null +++ b/samples/cloudbroker/disk/data_disk_list/main.tf @@ -0,0 +1,109 @@ +/* +Пример использования +Получение списка доступных дисков +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_disk_list" "dl" { + #фильтр по id диска + #опциональный параметр + #тип - целое число + #by_id = 11111 + + #фильтр по имени диска + #опциональный параметр + #тип - строка + #name = "disk name" + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "account name" + + #фильтр по максимальному размеру диска + #опциональный параметр + #тип - целое число + #disk_max_size = 3 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "started" + + #фильтр по полю shared + #опциональный параметр + #тип - булев + #shared = true + + #id аккаунта для получения списка дисков + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по sep id + #опциональный параметр + #тип - целое число + #sep_id = 1 + + #фильтр по названию pool + #опциональный параметр + #тип - строка + #pool = "pool name" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 + + #id политики хранения + #опциональный параметр + #тип - целое число + #storage_policy_id = 1 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 1281 + + #фильтр по id ВМ + #опциональный параметр + #тип - целое число + #compute_id = 123 +} + +output "test" { + value = data.decort_cb_disk_list.dl +} diff --git a/samples/cloudbroker/disk/data_disk_list_deleted/main.tf b/samples/cloudbroker/disk/data_disk_list_deleted/main.tf new file mode 100644 index 00000000..da447141 --- /dev/null +++ b/samples/cloudbroker/disk/data_disk_list_deleted/main.tf @@ -0,0 +1,80 @@ +/* +Пример использования +Получение списка удаленных дисков +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_disk_list_deleted" "dld" { + #фильтр по id диска + #опциональный параметр + #тип - целое число + #by_id = 11111 + + #фильтр по имени диска + #опциональный параметр + #тип - строка + #name = "disk name" + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "account name" + + #фильтр по максимальному размеру диска + #опциональный параметр + #тип - целое число + #disk_max_size = 3 + + #фильтр по полю shared + #опциональный параметр + #тип - булев + #shared = true + + #id аккаунта для получения списка дисков + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 + +} + +output "test" { + value = data.decort_cb_disk_list_deleted.dld +} diff --git a/samples/cloudbroker/disk/data_disk_list_unattached/main.tf b/samples/cloudbroker/disk/data_disk_list_unattached/main.tf new file mode 100644 index 00000000..7b55b218 --- /dev/null +++ b/samples/cloudbroker/disk/data_disk_list_unattached/main.tf @@ -0,0 +1,91 @@ +/* +Пример использования +Получение списка доступных неприсоединенных дисков +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_disk_list_unattached" "dlu" { + #фильтр по id диска + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "user" + + #фильтр по максимальному размеру диска + #опциональный параметр + #тип - целое число + #disk_max_size = 100 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 100 + + #фильтр по id sep + #опциональный параметр + #тип - целое число + #sep_id = 1 + + #фильтр по имени pool + #опциональный параметр + #тип - строка + #pool = "test" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 3 + + #id политики хранения + #опциональный параметр + #тип - целое число + #storage_policy_id = 1 +} + +output "test" { + value = data.decort_cb_disk_list_unattached.dlu +} diff --git a/samples/cloudbroker/disk/data_disk_replication/main.tf b/samples/cloudbroker/disk/data_disk_replication/main.tf new file mode 100644 index 00000000..5a0b2e8e --- /dev/null +++ b/samples/cloudbroker/disk/data_disk_replication/main.tf @@ -0,0 +1,44 @@ +/* +Пример использования +Получение статуса репликации диска +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_disk_replication" "dr" { + #id диска для которого подключена репликация + #обязательный параметр + #тип - целое число + disk_id = 49304 + + #id реплики диска + #обязательный параметр + #тип - целое число + replica_disk_id = 1213 + +} + +output "test" { + value = data.decort_cb_disk_replication.dr +} diff --git a/samples/cloudbroker/disk/data_disk_snapshot/main.tf b/samples/cloudbroker/disk/data_disk_snapshot/main.tf new file mode 100644 index 00000000..23727587 --- /dev/null +++ b/samples/cloudbroker/disk/data_disk_snapshot/main.tf @@ -0,0 +1,44 @@ +/* +Пример использования +Получение конкретного снапшота +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_disk_snapshot" "ds" { + #номер диска + #обязательный параметр + #тип - целое число + disk_id = 20100 + + #ярлык диска + #обязательный параметр + #тип - строка + label = "label" + +} + +output "test" { + value = data.decort_cb_disk_snapshot.ds +} diff --git a/samples/cloudbroker/disk/data_disk_snapshot_list/main.tf b/samples/cloudbroker/disk/data_disk_snapshot_list/main.tf new file mode 100644 index 00000000..87a7cd76 --- /dev/null +++ b/samples/cloudbroker/disk/data_disk_snapshot_list/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение списка снапшотов диска +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_disk_snapshot_list" "ds" { + #номер диска + #обязательный параметр + #тип - целое число + disk_id = 20100 + +} + +output "test" { + value = data.decort_cb_disk_snapshot_list.ds +} diff --git a/samples/cloudbroker/disk/resource_disk/main.tf b/samples/cloudbroker/disk/resource_disk/main.tf new file mode 100644 index 00000000..b7f36e2b --- /dev/null +++ b/samples/cloudbroker/disk/resource_disk/main.tf @@ -0,0 +1,153 @@ +/* +Пример использования +Ресурса диска: +1. Создание ресурса +2. Изменение ресурса +3. Удаление ресурса +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_disk" "my_disk01" { + #id аккаунта + #обязательный параметр + #тип - целое число + #используется при создании + account_id = 88366 + + #название диска + #обязательный параметр + #тип - строка + #используется при создании и обновлении + disk_name = "super-disk-re" + + #максимальный размер диска, в ГБ + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + size_max = 20 + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + storage_policy_id = 1 + + #описание диска + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "description" + + #sep id + #опциональный параметр + #тип - целое число + #по умолчанию - 0 + #используется при создании + #sep_id = 1 + + #название pool + #опциональный параметр + #тип - строка + #используется при создании + #pool = "pool_name" + + #список node + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #node_ids = [10,11] + + #флаг для восстановления диска + #опциональный параметр + #тип - булев + #используется при обновлении + #restore = true + + #флаг для удаления диска, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = true + + #флаг поделиться диском + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #shareable = true + + #установка режима кэширования + #опциональный параметр + #тип - строка + #значение по умолчанию - none + #используется при создании и обновлении + #cache = "none" + + #флаг отсоединения диска от машины перед удалением + #опциональный параметр + #тип - булев + #используется при удалении + #detach = true + + #настройки лимитов операций записи/чтения с диска + #опциональный параметр + #тип - блок + #тип вложенных полей - целое число + #используется при создании и обновлении + #iotune { + #read_bytes_sec = 0 + #read_bytes_sec_max = 0 + #read_iops_sec = 0 + #read_iops_sec_max = 0 + #size_iops_sec = 0 + #total_bytes_sec = 0 + #total_bytes_sec_max = 0 + #total_iops_sec = 3000 + #total_iops_sec_max = 0 + #write_bytes_sec = 0 + #write_bytes_sec_max = 0 + #write_iops_sec = 0 + #write_iops_sec_max = 0 + #} + + #включение режима unmap для диска + #опциональный параметр + #тип - строка + #по умолчанию - "ignore" + #возможные варианты: "ignore" или "unmap" + #используется при создании и обновлении + #discard = "unmap" + + #размер блока диска + #опциональный параметр + #доступные значения - "4k", "512", "512e" + #тип - строка + #используется при создании и обновлении + #block_size = "4k" +} + +output "test" { + value = decort_cb_disk.my_disk01 +} diff --git a/samples/cloudbroker/disk/resource_disk_snapshot/main.tf b/samples/cloudbroker/disk/resource_disk_snapshot/main.tf new file mode 100644 index 00000000..8060c01f --- /dev/null +++ b/samples/cloudbroker/disk/resource_disk_snapshot/main.tf @@ -0,0 +1,60 @@ +/* +Пример использования +Ресурс снапшота диска +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_disk_snapshot" "ds" { + #номер диска + #обязательный параметр + #тип - целое число + #используется при создании + disk_id = 20100 + + #ярлык диска + #обязательный параметр + #тип - строка + #используется при создании + label = "label" + + #флаг rollback + #опциональный параметр + #тип - булев + #по умолчанию - false + #используется при создании и обновлении + #rollback = true + + #timestamp + #опциональный параметр + #тип - целое число + #применимо совместно с rollback = true + #используется при создании и обновлении + #timestamp = 15 +} + +output "test" { + value = decort_cb_disk_snapshot.ds +} diff --git a/samples/cloudbroker/dpdknet/data_dpdknet/main.tf b/samples/cloudbroker/dpdknet/data_dpdknet/main.tf new file mode 100644 index 00000000..d2550ee1 --- /dev/null +++ b/samples/cloudbroker/dpdknet/data_dpdknet/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных диска +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_dpdknet" "dpdk" { + #фильтр по id DPDK сети + #обязательный параметр + #тип - целое число + dpdk_id = 49304 +} + +output "test" { + value = data.decort_cb_dpdknet.dpdk +} diff --git a/samples/cloudbroker/dpdknet/data_dpdknet_list/main.tf b/samples/cloudbroker/dpdknet/data_dpdknet_list/main.tf new file mode 100644 index 00000000..da385d14 --- /dev/null +++ b/samples/cloudbroker/dpdknet/data_dpdknet_list/main.tf @@ -0,0 +1,89 @@ +/* +Пример использования +Получение списка доступных дисков +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_dpdknet_list" "dl" { + #фильтр по id DPDK сети + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по grid ID + #опциональный параметр + #тип - целое число + #gid = 100 + + #фильтр по имени сети + #опциональный параметр + #тип - строка + #name = "test_dpdk" + + #фильтр по описания + #опциональный параметр + #тип - строка + #desc = "user" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по доступным аккаунтам + #опциональный параметр + #тип - массив чисел + #account_access = [11111,22222] + + #фильтр по доступным ресурсным группам + #опциональный параметр + #тип - массив чисел + #rg_access = [11111,22222] + + #фильтр по compute IDs + #опциональный параметр + #тип - массив чисел + #compute_ids = [11111,22222] + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_cb_dpdknet_list.dl +} diff --git a/samples/cloudbroker/dpdknet/resource_dpdknet/main.tf b/samples/cloudbroker/dpdknet/resource_dpdknet/main.tf new file mode 100644 index 00000000..1440cd39 --- /dev/null +++ b/samples/cloudbroker/dpdknet/resource_dpdknet/main.tf @@ -0,0 +1,93 @@ +/* +Пример использования +Ресурса диска: +1. Создание ресурса +2. Изменение ресурса +3. Удаление ресурса +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_dpdknet" "dpdk" { + #название + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "dpdk-name" + + #gid + #обязательный параметр + #тип - целое число + #используется при создании + gid = 212 + + #vlanid для тегирования трафика на интерфейсе для компьюта + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + vlan_id = 123 + + #ovs bridge в котором будут создаваться интерфейсы для компьютов, созданные из этой сети + #обязательный параметр + #тип - строка + #используется при создании и обновлении + ovs_bridge = "OVSBridge" + + #описание сети + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "description" + + #список id аккаунтов, которым может быть выделена сеть в эксклюзивное пользование + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #account_access = [10,11] + + #список id ресурсных групп, которым может быть выделена сеть в эксклюзивное пользование + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #rg_access = [10,11] + + #флаг доступности сети для проведения с ней операций + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при создании и обновлении + #enabled = true + + #флаг, указывающий, включены ли группы безопасности для этой сети + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #значение по умолчанию - false + #enable_secgroups = false +} + +output "test" { + value = decort_cb_dpdknet.dpdk +} diff --git a/samples/cloudbroker/extnet/data_extnet/main.tf b/samples/cloudbroker/extnet/data_extnet/main.tf new file mode 100644 index 00000000..9e34247d --- /dev/null +++ b/samples/cloudbroker/extnet/data_extnet/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации о внешней сети +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_extnet" "ex" { + #id сети + #обязательный параметр + #тип - целое число + extnet_id = 13 + +} + +output "ex_out" { + value = data.decort_cb_extnet.ex +} diff --git a/samples/cloudbroker/extnet/data_extnet_default/main.tf b/samples/cloudbroker/extnet/data_extnet_default/main.tf new file mode 100644 index 00000000..08641518 --- /dev/null +++ b/samples/cloudbroker/extnet/data_extnet_default/main.tf @@ -0,0 +1,35 @@ +/* +Пример использования +Получение информации о доступной внешней сети по умолчанию +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_extnet_default" "ed" { + #нет входных параметров +} + +output "default_net_id_out" { + value = data.decort_cb_extnet_default.ed +} diff --git a/samples/cloudbroker/extnet/data_extnet_list/main.tf b/samples/cloudbroker/extnet/data_extnet_list/main.tf new file mode 100644 index 00000000..fe28532a --- /dev/null +++ b/samples/cloudbroker/extnet/data_extnet_list/main.tf @@ -0,0 +1,91 @@ +/* +Пример использования +Получение списка внешних сетей +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_extnet_list" "ex_list" { + #id аккаунта для фильтрации результата + #опциональный параметр + #тип - целое число + #account_id = 1111111 + + #фильтр по id внешней сети + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени внешней сети + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по IP внешней сети + #опциональный параметр + #тип - строка + #network = "test" + + #фильтр по id vlan + #опциональный параметр + #тип - целое число + #vlan_id = 100 + + #фильтр по id vnfDevices + #опциональный параметр + #тип - целое число + #vnfdev_id = 100 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 + +} + +output "ex_out" { + value = data.decort_cb_extnet_list.ex_list +} diff --git a/samples/cloudbroker/extnet/data_extnet_reserved_ip_list/main.tf b/samples/cloudbroker/extnet/data_extnet_reserved_ip_list/main.tf new file mode 100644 index 00000000..62dab23e --- /dev/null +++ b/samples/cloudbroker/extnet/data_extnet_reserved_ip_list/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о зарезервированных IP адресах или пуле адресов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_extnet_reserved_ip_list" "ex_reserved_ip" { + #идентификатор аккаунта, для которого зарезервированны ресурсы + #обязательный параметр + #тип - целое число + account_id = 1111 + + #идентификатор сети + #опциональный параметр + #тип - целое число + #extnet_id = 1111 +} + +output "test" { + value = data.decort_cb_extnet_reserved_ip_list.ex_reserved_ip +} diff --git a/samples/cloudbroker/extnet/data_extnet_static_route/main.tf b/samples/cloudbroker/extnet/data_extnet_static_route/main.tf new file mode 100644 index 00000000..0e2c7f24 --- /dev/null +++ b/samples/cloudbroker/extnet/data_extnet_static_route/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о static routes по id в данном extnet +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_extnet_static_route" "route" { + #id extnet в котором добавлены routes + #обязательный параметр + #тип - целое число + extnet_id = 1111 + + #id route + #обязательный параметр + #тип - целое число + route_id = 1 +} + +output "route" { + value = data.decort_cb_extnet_static_route.route +} diff --git a/samples/cloudbroker/extnet/data_extnet_static_route_list/main.tf b/samples/cloudbroker/extnet/data_extnet_static_route_list/main.tf new file mode 100644 index 00000000..3ec48b12 --- /dev/null +++ b/samples/cloudbroker/extnet/data_extnet_static_route_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение списка static routes в данном extnet +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "" + source = "basis/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_extnet_static_route_list" "list" { + #id extnet в котором добавлены routes + #обязательный параметр + #тип - целое число + extnet_id = 1111 +} + +output "list" { + value = data.decort_cb_extnet_static_route_list.list +} diff --git a/samples/cloudbroker/extnet/resource_extnet/main.tf b/samples/cloudbroker/extnet/resource_extnet/main.tf new file mode 100644 index 00000000..15504c78 --- /dev/null +++ b/samples/cloudbroker/extnet/resource_extnet/main.tf @@ -0,0 +1,259 @@ +/* +Пример использования +Ресурса extnet +Ресурс позволяет: +1. Создавать extnet +2. Удалять extnet +3. Получать информацию о extnet +4. Предоставлять доступ аккаунтов к extnet +5. Удалять доступ аккаунтов к extnet +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* + terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } + } +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_extnet" "new_extnet" { + #наименование внешней сети + #обязательный параметр + #тип - строка + #используется при создании + name = "test_extnet" + + #id платформы + #обязательный параметр + #тип - целое число + #используется при создании + gid = 500 + + #cidr + #обязательный параметр + #тип - строка + #используется при создании + ipcidr = "192.168.0.0/24" + + #id виртуальной локальной сети + #обязательный параметр + #тип - целое число + #используется при создании + vlan_id = 111 + + #ip-адрес шлюза внешней сети + #опциональный параметр + #тип - строка + #используется при создании + #gateway = "1.1.1.1" + + #cписок DNS адресов + #опциональный параметр + #тип - массив строк + #используется при создании и обновлении + #dns = ["8.8.8.8", "9.9.9.9"] + + #список NTP адресов + #опциональный параметр + #тип - массив строк + #используется при создании и обновлении + #ntp = ["ntp0.ntp-servers.net", "ntp1.ntp-servers.net"] + + #ip-адреса для проверки доступности сети + #опциональный параметр + #тип - массив строк + #используется при создании + #check_ips = ["191.255.0.0,", "191.255.0.0,"] + + #если true - DHCP-сервер создан не будет + #опциональный параметр + #тип - булев + #используется при создании + #virtual = true + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "test desc" + + #начало диапазона IP-адресов + #опциональный параметр + #тип - строка + #используется при создании + #start_ip = "191.255.0.0" + + #окончание диапазона IP-адресов + #опциональный параметр + #тип - строка + #используется при создании + #end_ip = "191.255.0.40" + + #IP для создания первичного vnfdev + #опциональный параметр + #тип - строка + #используется при создании + #vnfdev_ip = "191.255.0.20" + + #количество предварительно созданных бронирований + #опциональный параметр + #тип - целое число + #по умолчанию - 128 + #используется при создании + #pre_reservations_num = 128 + + #имя bridge Openvswitch для подключения к внешней сети + #опциональный параметр + #тип - строка + #используется при создании + #ovs_bridge = "some" + + #включение/выключение внешней сети + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enable = true + + #сделать сеть сетью по умолчанию + #опциональный параметр + #тип - булев + #используется при обновлении + #set_default = true + + #список исключенных IP адресов + #опциональный параметр + #тип - массив строк + #используется при создании и обновлении + #excluded_ips = ["192.168.0.4", "192.168.0.5"] + + #диапазон исключенных IP адресов + #опциональный параметр + #тип - блок + #тип вложенных полей - строка + #используется при создании и обновлении + #excluded_ips_range { + #начало диапазона + #обязательный параметр + #тип - строка + #ip_start = "192.168.0.4" + + #окончание диапазона + #обязательный параметр + #тип - строка + #ip_end = "192.168.0.50" + #} + + #список id аккаунтов, которым предоставлен доступ к extnet + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #shared_with = [112, 123] + + #изменение настроек ограничения трафика сети + #по умолчанию - 0, т.е. без ограничений + #опциональный параметр + #тип - блок, + #тип вложенных полей - целое число + #используется при обновлении + #default_qos { + #ограничение внутреннего трафика в кбит + #опциональный параметр + #тип - целое число + #in_rate = 0 + + #ограничение внутреннего burst трафика в кбит + #опциональный параметр + #тип - целое число + #in_burst = 0 + + #ограничение внешнего трафика в кбит + #опциональный параметр + #тип - целое число + #e_rate = 0 + #} + + #список зарезервированных IP или пула адресов + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #reserved_ip { + #идентификатор аккаунта, для которого резервируются ресурсы + #обязательный параметр + #тип - целое число + #account_id = 11111 + + #количество резервируемых IP + #опциональный параметр + #тип - целое число + #ip_count = 15 + + #список резервируемых IP + #опциональный параметр + #тип - массив строк + #ips = ["192.168.10.10", "192.168.10.20"] + #} + + #id node на который происходит миграция + #опциональный параметр + #тип - целое число + #используется при обновлении + #migrate = 1 + + #перезапустить сеть + #опциональный параметр + #тип - булев + #используется при обновлении + #restart = true + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 + + #режим высокой доступности + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #highly_available = true + + #IP для создания вторичного vnfdev + #опциональный параметр + #тип - строка + #используется при создании + #sec_vnfdev_ip = "191.255.0.20" + + #mtu + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #mtu = 1500 + + #флаг, указывающий, включены ли группы безопасности для этой сети + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #значение по умолчанию - false + #enable_secgroups = false +} + +output "extnet" { + value = decort_cb_extnet.new_extnet +} \ No newline at end of file diff --git a/samples/cloudbroker/extnet/resource_extnet_static_route/main.tf b/samples/cloudbroker/extnet/resource_extnet_static_route/main.tf new file mode 100644 index 00000000..7baca1cd --- /dev/null +++ b/samples/cloudbroker/extnet/resource_extnet_static_route/main.tf @@ -0,0 +1,69 @@ +/* +Пример использования +Ресурса extnet static routes +Ресурс позволяет: +1. Создавать static routes +2. Удалять static routes +3. Получать информацию о всех static routes в данном extnet +4. Предоставлять доступ виртуальным машинам к static routes +5. Удалять доступ виртуальным машинам к static routes +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_extnet_static_route" "sr" { + #id extnet + #обязательный параметр + #тип - целое число + #используется при создании + extnet_id = 1111 + + #destination network + #обязательный параметр + #тип - строка + #используется при создании + destination = "192.168.201.0" + + #destination network mask + #обязательный параметр + #тип - строка + #используется при создании + netmask = "255.255.255.255" + + #ip-адрес из пула свободных IP-адресов extnet ID + #обязательный параметр + #тип - строка + #используется при создании + gateway = "192.168.201.40" + + #список виртуальных машин, которым будет предоставлен доступ к роуту + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #compute_ids = [111,222] +} + +output "sr" { + value = decort_cb_extnet_static_route.sr +} diff --git a/samples/cloudbroker/flipgroup/data_flipgroup/main.tf b/samples/cloudbroker/flipgroup/data_flipgroup/main.tf new file mode 100644 index 00000000..f7dde1fa --- /dev/null +++ b/samples/cloudbroker/flipgroup/data_flipgroup/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение flipgroup по id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_flipgroup" "fg" { + #id флипгруппы + #обязательный параметр + #тип - целое число + flipgroup_id = 999 + +} + +output "fg_out" { + value = data.decort_cb_flipgroup.fg +} diff --git a/samples/cloudbroker/flipgroup/data_flipgroup_list/main.tf b/samples/cloudbroker/flipgroup/data_flipgroup_list/main.tf new file mode 100644 index 00000000..5664dbf4 --- /dev/null +++ b/samples/cloudbroker/flipgroup/data_flipgroup_list/main.tf @@ -0,0 +1,102 @@ +/* +Пример использования +Получение списка flipgroup +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_flipgroup_list" "fg" { + #фильтр по id flipgroup + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени flipgroup + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id vins + #опциональный параметр + #тип - целое число + #vins_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #vins_name = "test" + + #фильтр по id extnet + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #фильтр по IP + #опциональный параметр + #тип - строка + #by_ip = "1.1.1.1.1" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 3 + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 100 + + #фильтр по id conn + #опциональный параметр + #тип - целое число + #conn_id = 100 + + #фильтр по id клиентов + #опциональный параметр + #тип - массив целых чисел + #client_ids = [10,11] + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "CREATED" + +} + +output "fg_out" { + value = data.decort_cb_flipgroup_list.fg +} diff --git a/samples/cloudbroker/flipgroup/resource_flipgroup/main.tf b/samples/cloudbroker/flipgroup/resource_flipgroup/main.tf new file mode 100644 index 00000000..63456dbf --- /dev/null +++ b/samples/cloudbroker/flipgroup/resource_flipgroup/main.tf @@ -0,0 +1,86 @@ +/* +Пример использования +Работа с ресурсом flipgroup (группа с плавающим ip-адресом) +Ресурс позволяет: +1. Создавать flipgroup +2. Редактировать flipgroup +3. Удалять flipgroup +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + oauth2_url = "https://sso-alpha.dev.decs.online" + controller_url = "https://alpha.dev.decs.online" + app_id = "" + app_secret = "" +} + +resource "decort_cb_flipgroup" "fg" { + #id аккаунта + #обязательный параметр + #тип - целое число + #используется при создании + account_id = 999 + + #наименование Flipgroup + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "flipgroup_name" + + #тип сети + #обязательный параметр + #возможные значенния - "EXTNET", "VINS" + #тип - строка + #используется при создании + net_type = "EXTNET" + + #id сети + #обязательный параметр + #тип - целое число + #используется при создании + net_id = 13 + + #тип клиентов (в данный момент поддерживается только тип 'compute') + #опциональный параметр + #тип - строка + #используется при создании + #по умолчанию - "compute" + #client_type = "compute" + + #ip-адрес + #опциональный параметр + #тип - строка + #используется при создании + #ip = "127.0.0.1" + + #cписок клиентов, прикрепленных к флипгруппе + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #client_ids = [11269] + + #описание флипгруппы + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "CHANGED" +} + +output "fg_out" { + value = decort_cb_flipgroup.fg +} diff --git a/samples/cloudbroker/grid/data_grid/main.tf b/samples/cloudbroker/grid/data_grid/main.tf new file mode 100644 index 00000000..8e5adb01 --- /dev/null +++ b/samples/cloudbroker/grid/data_grid/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение data source grid по id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_grid" "grid" { + #id grid для получения информации + #обязательный параметр + #тип - целое число + grid_id = 215 + +} + +output "test" { + value = data.decort_cb_grid.grid +} diff --git a/samples/cloudbroker/grid/data_grid_get_consumption/main.tf b/samples/cloudbroker/grid/data_grid_get_consumption/main.tf new file mode 100644 index 00000000..15683458 --- /dev/null +++ b/samples/cloudbroker/grid/data_grid_get_consumption/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации и потребленных и зарезервированных ресурсах grid по id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_grid_get_consumption" "cons" { + #id grid для получения информации + #обязательный параметр + #тип - целое число + grid_id = 215 + +} + +output "test" { + value = data.decort_cb_grid_get_consumption.cons +} diff --git a/samples/cloudbroker/grid/data_grid_get_post_status/main.tf b/samples/cloudbroker/grid/data_grid_get_post_status/main.tf new file mode 100644 index 00000000..0326d768 --- /dev/null +++ b/samples/cloudbroker/grid/data_grid_get_post_status/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Проверка статуса активности текущей среды. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_grid_get_status" "gs" { + #нет входных параметров +} + +data "decort_cb_grid_post_status" "ps" { + #нет входных параметров +} + +output "test-gs" { + value = data.decort_cb_grid_get_status.gs +} + +output "test-ps" { + value = data.decort_cb_grid_post_status.ps +} diff --git a/samples/cloudbroker/grid/data_grid_get_settings/main.tf b/samples/cloudbroker/grid/data_grid_get_settings/main.tf new file mode 100644 index 00000000..c4c74e7d --- /dev/null +++ b/samples/cloudbroker/grid/data_grid_get_settings/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение настроек grid (платформы) по id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_grid_get_settings" "gs" { + #id grid для получения информации + #обязательный параметр + #тип - целое число + grid_id = 215 + +} + +output "test" { + value = data.decort_cb_grid_get_settings.gs +} diff --git a/samples/cloudbroker/grid/data_grid_list/main.tf b/samples/cloudbroker/grid/data_grid_list/main.tf new file mode 100644 index 00000000..a443fd6b --- /dev/null +++ b/samples/cloudbroker/grid/data_grid_list/main.tf @@ -0,0 +1,62 @@ +/* +Пример использования +Получение списка grid +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_grid_list" "gl" { + #фильтр по id grid + #опциональный параметр + #тип - целое число + #by_id = 1 + + #название grid + #опциональный параметр + #тип - строка + #name = "grid name" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 3 + +} + +output "test" { + value = data.decort_cb_grid_list.gl +} diff --git a/samples/cloudbroker/grid/data_grid_list_consumption/main.tf b/samples/cloudbroker/grid/data_grid_list_consumption/main.tf new file mode 100644 index 00000000..201e34b1 --- /dev/null +++ b/samples/cloudbroker/grid/data_grid_list_consumption/main.tf @@ -0,0 +1,35 @@ +/* +Пример использования +Получение информации и потребленных и зарезервированных ресурсах во всех grid +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_grid_list_consumption" "lc" { + #нет входных параметров +} + +output "test" { + value = data.decort_cb_grid_list_consumption.lc +} diff --git a/samples/cloudbroker/grid/data_grid_list_emails/main.tf b/samples/cloudbroker/grid/data_grid_list_emails/main.tf new file mode 100644 index 00000000..137d40b4 --- /dev/null +++ b/samples/cloudbroker/grid/data_grid_list_emails/main.tf @@ -0,0 +1,46 @@ +/* +Пример использования +Получение списка email-адресов пользователей. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_grid_list_emails" "gle" { + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 3 + +} + +output "test" { + value = data.decort_cb_grid_list_emails.gle +} diff --git a/samples/cloudbroker/grid/decort_cb_grid_get_diagnosis/main.tf b/samples/cloudbroker/grid/decort_cb_grid_get_diagnosis/main.tf new file mode 100644 index 00000000..4f0e1357 --- /dev/null +++ b/samples/cloudbroker/grid/decort_cb_grid_get_diagnosis/main.tf @@ -0,0 +1,44 @@ +/* +Пример использования +Получение снимка платформы с дополнительной диагностической информацией, такой как журналы и т.д. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_grid_get_diagnosis" "grid" { + #id grid для получения информации + #обязательный параметр + #тип - целое число + gid = 215 + + #путь, где будет создан архив + #если не указан, создается в директории с main.tf с именем "diagnosis.tar.gz" + #обязательный параметр + #тип - строка + file_path = "abcdefg.tar.gz" +} + +output "test" { + value = data.decort_cb_grid_get_diagnosis.grid +} diff --git a/samples/cloudbroker/image/data_image/main.tf b/samples/cloudbroker/image/data_image/main.tf new file mode 100644 index 00000000..d2fdcc78 --- /dev/null +++ b/samples/cloudbroker/image/data_image/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение образа по id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_image" "image" { + #id образа + #обязательный параметр + #тип - целое число + image_id = 5912 + +} + +output "test" { + value = data.decort_cb_image.image +} diff --git a/samples/cloudbroker/image/data_image_list/main.tf b/samples/cloudbroker/image/data_image_list/main.tf new file mode 100644 index 00000000..f6f345cf --- /dev/null +++ b/samples/cloudbroker/image/data_image_list/main.tf @@ -0,0 +1,122 @@ +/* +Пример использования +Получение списка образов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_image_list" "il" { + #фильтр по id sep + #опциональный параметр + #тип - целое число + #sep_id = 1 + + #фильтр по id образа + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени образа + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по архитектуре + #опциональный параметр + #тип - строка + #architecture = "x86_64" + + #фильтр по типу образа + #опциональный параметр + #тип - массив строк + #type_image = ["linux", "windows"] + + #фильтр по размеру образа + #опциональный параметр + #тип - целое число + #image_size = 100 + + #фильтр по имени SEP + #опциональный параметр + #тип - строка + #sep_name = "test" + + #фильтр по имени Pool + #опциональный параметр + #тип - строка + #pool = "test" + + #фильтр по доступу + #опциональный параметр + #тип - булев + #public = true + + #фильтр по hot_resize + #опциональный параметр + #тип - булев + #hot_resize = true + + #фильтр по bootable + #опциональный параметр + #тип - булев + #bootable = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 3 + + #фильтр по enabled + #опциональный параметр + #тип - булев + #enabled = true + + #фильтр по id политики хранения + #опциональный параметр + #тип - целое число + #storage_policy_id = 6 + +} + +output "test" { + value = data.decort_cb_image_list.il +} diff --git a/samples/cloudbroker/image/resource_image/main.tf b/samples/cloudbroker/image/resource_image/main.tf new file mode 100644 index 00000000..331d9cd7 --- /dev/null +++ b/samples/cloudbroker/image/resource_image/main.tf @@ -0,0 +1,147 @@ +/* +Пример использования +Ресурса image +Ресурс позволяет: +1. Создавать образ +2. Редактировать образ +3. Удалять образ +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_image" "my_image" { + #имя образа + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "test_image_rename" + + #адрес образа + #обязательный параметр + #тип - строка + #используется при создании + url = "https://colba.decs.online/index.php/s/G3H7AREngzeKGw2/download" + + #тип загрузки образа + #обязательный параметр + #тип - строка + #возможные варианты: "bios" или "uefi" + #используется при создании + boot_type = "bios" + + #тип образа + #обязательный параметр + #тип - строка + #возможные варианты - "linux", "windows", "unknown" + #используется при создании + image_type = "linux" + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #поддержка hot resize + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #hot_resize = true + + #id аккаунта владельца образа + #опциональный параметр + #тип данных - целое число + #используется при создании и обновлении + #account_id = 57252 + + #имя пользователя и пароль + #опциональные параметры + #тип - строка + #используется при создании и обновлении + #username = "Valera" + #password = "123" + + #имя пользователя и пароль для загрузки бинарных данных + #опциональные параметры + #тип - строка + #используется при создании + #username_dl = "Valera1" + #password_dl = "1231" + + #sep id + #опциональный параметр + #тип - целое число + #используется при создании + #sep_id = 1206 + + #пул для создания образа + #опциональный параметр + #тип - строка + #используется при создании + #pool_name = "vmstor" + + #доступность образа + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enabled = true + + #является ли образ загрузочным + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #bootable = true + + #позволяет создавать образ в синхронном режиме + #опциональный параметр + #тип - булев + #используется при создании + #по умолчанию - false + #sync_mode = true + + #настройка доступа образа аккаунтам + #опциональный параметр + #тип - массив целых чисел + #пустой массив - удаление всех доступов, если они были + #используется при создании и обновлении + #shared_with = [28096, 57121] + + #установка computeci + #опциональный параметр + #тип - целое число + #чтобы сбросить, необходимо передать 0 + #используется при обновлении + #computeci_id = 1 + + #наименование сетевого интерфейса для вашего компьютера с Linux + #eth - встроенный, ens - pci слот + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #network_interface_naming = "ens" +} + +output "test" { + value = decort_cb_image.my_image +} diff --git a/samples/cloudbroker/image/resource_image_cdrom/main.tf b/samples/cloudbroker/image/resource_image_cdrom/main.tf new file mode 100644 index 00000000..06ca1f32 --- /dev/null +++ b/samples/cloudbroker/image/resource_image_cdrom/main.tf @@ -0,0 +1,112 @@ +/* +Пример использования +Ресурса cdrom image +Ресурс позволяет: +1. Создавать образ +2. Редактировать образ +3. Удалять образ +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_cdrom_image" "my_image" { + #имя образа + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "test_image_rename" + + #адрес образа + #обязательный параметр + #тип - строка + #используется при создании + url = "https://colba.decs.online/index.php/s/G3H7AREngzeKGw2/download" + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #поддержка hot resize + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #hot_resize = true + + #id аккаунта владельца образа + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #account_id = 57252 + + #имя пользователя и пароль для загрузки бинарных данных + #опциональные параметры + #тип - строка + #используется при создании и обновлении + #username_dl = "Valera1" + #password_dl = "1231" + + #sep id + #опциональный параметр + #тип - целое число + #используется при создании + #sep_id = 1206 + + #пул для создания образа + #опциональный тип + #тип - строка + #используется при создании + #pool_name = "vmstor" + + #доступность образа + #опциональный параметр + #тип - булев + #используется при обновлении + #enabled = true + + #настройка доступа образа аккаунтам + #опциональный параметр + #тип - массив целых чисел + #пустой массив - удаление всех доступов, если они были + #используется при обновлении + #shared_with = [28096, 57121] + + #установка computeci + #опциональный параметр + #тип - целое число + #чтобы сбросить, необходимо передать 0 + #используется при обновлении + #computeci_id = 1 + + #является ли образ загрузочным + #опциональный параметр + #тип - булев + #используется при обновлении + #bootable = true +} + +output "test" { + value = decort_cb_cdrom_image.my_image +} diff --git a/samples/cloudbroker/image/resource_image_from_blank_compute/main.tf b/samples/cloudbroker/image/resource_image_from_blank_compute/main.tf new file mode 100644 index 00000000..5da83a28 --- /dev/null +++ b/samples/cloudbroker/image/resource_image_from_blank_compute/main.tf @@ -0,0 +1,138 @@ +/* +Ресурс образа из компьюта, созданного как blank позволяет: +1. Создавать +2. Редактировать +3. Удалять ресурс +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_image_from_blank_compute" "my_image" { + #id виртуальной машины, созданной как blank + #обязательный параметр + #тип - целое число + #используется при создании + compute_id = 1234 + + #имя образа + #обязательный параметр + #тип - строка + #при изменении - изменяет название созданного образа + #используется при создании и обновлении + name = "test_image_rename" + + #тип загрузки образа + #обязательный параметр + #тип - строка + #возможные варианты: "bios" или "uefi" + #используется при создании + boot_type = "bios" + + #тип образа + #обязательный параметр + #тип - строка + #возможные варианты - "linux", "windows", "unknown" + #используется при создании + image_type = "linux" + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #имя пользователя для образа + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #username = "userx" + + #пароль для образа + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #password = "passx" + + #id аккаунта + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #account_id = 138 + + #название pool + #опциональный параметр + #тип - строка + #используется при создании + #pool_name = "pool" + + #поддержка hot resize + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #hot_resize = true + + #флаг для создания образа в асинхронном режиме + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при создании + #async_mode = true + + #доступность образа + #опциональный параметр + #тип - булев + #используется при обновлении + #enabled = true + + #является ли образ загрузочным + #опциональный параметр + #тип - булев + #используется при обновлении + #bootable = true + + #настройка доступа образа аккаунтам + #опциональный параметр + #тип - массив целых чисел + #пустой массив - удаление всех доступов, если они были + #используется при создании и обновлении + #shared_with = [28096, 57121] + + #установка computeci + #опциональный параметр + #тип - целое число + #чтобы сбросить, необходимо передать 0 + #используется при обновлении + #computeci_id = 1 + + #наименование сетевого интерфейса для вашего компьютера с Linux + #eth - встроенный, ens - pci слот + #опциональный параметр + #тип - строка + #используется при обновлении + #network_interface_naming = "ens" +} + +output "test" { + value = decort_cb_image_from_blank_compute.my_image +} diff --git a/samples/cloudbroker/image/resource_image_from_platform_disk/main.tf b/samples/cloudbroker/image/resource_image_from_platform_disk/main.tf new file mode 100644 index 00000000..d882cd2d --- /dev/null +++ b/samples/cloudbroker/image/resource_image_from_platform_disk/main.tf @@ -0,0 +1,131 @@ +/* +Ресурс образа из платформенного диска: +1. Создавать +2. Редактировать +3. Удалять ресурс +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_image_from_platform_disk" "my_image" { + #id платформенного диска + #обязательный параметр + #тип - целое число + #используется при создании + disk_id = 1234 + + #имя образа + #обязательный параметр + #тип - строка + #при изменении - изменяет название созданного образа + #используется при создании и обновлении + name = "test_image_rename" + + #тип загрузки образа + #обязательный параметр + #тип - строка + #возможные варианты: "bios" или "uefi" + #используется при создании + boot_type = "bios" + + #тип образа + #обязательный параметр + #тип - строка + #возможные варианты - "linux", "windows", "unknown" + #используется при создании + image_type = "linux" + + #имя пользователя для образа + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #username = "userx" + + #пароль для образа + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #password = "passx" + + #id аккаунта + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #account_id = 138 + + #название pool + #опциональный параметр + #тип - строка + #используется при создании + #pool_name = "pool" + + #поддержка hot resize + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #hot_resize = true + + #является ли образ загрузочным + #тип - булев + #используется при создании и обновлении + #bootable = true + + #флаг для создания образа в асинхронном режиме + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при создании + #async_mode = true + + #доступность образа + #опциональный параметр + #тип - булев + #используется при обновлении + #enabled = true + + #настройка доступа образа аккаунтам + #опциональный параметр + #тип - массив целых чисел + #пустой массив - удаление всех доступов, если они были + #используется при создании и обновлении + #shared_with = [28096, 57121] + + #установка computeci + #опциональный параметр + #тип - целое число + #чтобы сбросить, необходимо передать 0 + #используется при обновлении + #computeci_id = 1 + + #наименование сетевого интерфейса для вашего компьютера с Linux + #eth - встроенный, ens - pci слот + #опциональный параметр + #тип - строка + #используется при обновлении + #network_interface_naming = "ens" +} + +output "test" { + value = decort_cb_image_from_platform_disk.my_image +} diff --git a/samples/cloudbroker/image/resource_multi_image/main.tf b/samples/cloudbroker/image/resource_multi_image/main.tf new file mode 100644 index 00000000..53c858d6 --- /dev/null +++ b/samples/cloudbroker/image/resource_multi_image/main.tf @@ -0,0 +1,100 @@ +/* +Пример использования +Ресурса multi image +Ресурс позволяет: +1. Создавать образ +2. Редактировать образ +3. Удалять образ +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_multi_image" "my_multi_image" { + #имя мульти-образа + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "test_multi_image" + + #список id реальных образов, на основе которых создаётся мульти-образ + #обязательный параметр + #тип - массив целых чисел + #используется при создании и обновлении (добавляет/удаляет привязки) + target_ids = [6125, 6126] + + #id аккаунта владельца образа + #опциональный параметр + #тип данных - целое число + #используется при создании и обновлении + #account_id = 57252 + + #является ли образ загрузочным + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #bootable = true + + #поддержка hot resize + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #hot_resize = true + + #имя пользователя + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #username = "Valera" + + #пароль пользователя + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #password = "123" + + #доступность образа + #опциональный параметр + #тип - булев, по умолчанию true + #используется при создании и обновлении + #enabled = false + + #настройка доступа образа аккаунтам + #опциональный параметр + #пустой массив - удаление всех доступов, если они были + #тип - массив целых чисел + #используется при создании и обновлении + #shared_with = [28096, 57121] + + #установка computeci + #опциональный параметр + #чтобы сбросить, необходимо передать 0 + #тип - целое число + #используется при создании и обновлении + #computeci_id = 1 + +} + +output "test" { + value = decort_cb_multi_image.my_multi_image +} diff --git a/samples/cloudbroker/image/resource_virtual_image/main.tf b/samples/cloudbroker/image/resource_virtual_image/main.tf new file mode 100644 index 00000000..f4aefa26 --- /dev/null +++ b/samples/cloudbroker/image/resource_virtual_image/main.tf @@ -0,0 +1,100 @@ +/* +Пример использования +Ресурса virtual image +Ресурс позволяет: +1. Создавать образ +2. Редактировать образ +3. Удалять образ +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_virtual_image" "my_image" { + #имя виртуального образа + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "test_vi_im_new_rename" + + #id образа, на основе которого будет создан виртуальный + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + link_to = 6125 + + #id аккаунта владельца образа + #опциональный параметр + #тип данных - целое число + #используется при создании и обновлении + #account_id = 57252 + + #является ли образ загрузочным + #опциональный параметр + #тип - булев + #используется при обновлении + #bootable = true + + #поддержка hot resize + #опциональный параметр + #тип - булев + #используется при обновлении + #hot_resize = true + + #имя пользователя + #опциональный параметр + #тип - строка + #используется при обновлении + #username = "Valera" + + #пароль пользователя + #опциональный параметр + #тип - строка + #используется при обновлении + #password = "123" + + #доступность образа + #опциональный параметр + #тип - булев + #используется при обновлении + #enabled = false + + #настройка доступа образа аккаунтам + #опциональный параметр + #пустой массив - удаление всех доступов, если они были + #тип - массив целых чисел + #используется при обновлении + #shared_with = [28096, 57121] + + #установка computeci + #опциональный параметр + #чтобы сбросить, необходимо передать 0 + #тип - целое число + #используется при обновлении + #computeci_id = 1 + +} + +output "test" { + value = decort_cb_virtual_image.my_image +} diff --git a/samples/cloudbroker/k8s/data_k8ci/main.tf b/samples/cloudbroker/k8s/data_k8ci/main.tf new file mode 100644 index 00000000..44ac28b5 --- /dev/null +++ b/samples/cloudbroker/k8s/data_k8ci/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о k8ci +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true + } + +data "decort_cb_k8ci" "k8ci" { + #id k8ci + #обязательный параметр + #тип - целое число + k8ci_id = 111 +} + +output "test" { + value = data.decort_cb_k8ci.k8ci +} diff --git a/samples/cloudbroker/k8s/data_k8ci_list/main.tf b/samples/cloudbroker/k8s/data_k8ci_list/main.tf new file mode 100644 index 00000000..353345f7 --- /dev/null +++ b/samples/cloudbroker/k8s/data_k8ci_list/main.tf @@ -0,0 +1,74 @@ +/* +Пример использования +Получение списка k8ci +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true + } + +data "decort_cb_k8ci_list" "k8cil" { + #фильтр по id k8ci + #опциональный параметр + #тип - целое число + #by_id = 111 + + #фильтр по имени k8ci + #опциональный параметр + #тип - строка + #name = "name" + + #фильтр по статусу k8ci + #опциональный параметр + #тип - строка + #status = "status" + + #фильтр по network plugin + #опциональный параметр + #тип - строка + #network_plugin = "flannel" + + #исключить из результата недоступные k8ci + #опциональный параметр + #тип - булев + #include_disabled = "true" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 3 +} + +output "test" { + value = data.decort_cb_k8ci_list.k8cil +} diff --git a/samples/cloudbroker/k8s/data_k8ci_list_deleted/main.tf b/samples/cloudbroker/k8s/data_k8ci_list_deleted/main.tf new file mode 100644 index 00000000..ab58eb29 --- /dev/null +++ b/samples/cloudbroker/k8s/data_k8ci_list_deleted/main.tf @@ -0,0 +1,64 @@ +/* +Пример использования +Получение списка удаленных k8ci +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true + } + +data "decort_cb_k8ci_list_deleted" "k8cild" { + #фильтр по id k8ci + #опциональный параметр + #тип - целое число + #by_id = 111 + + #фильтр по имени k8ci + #опциональный параметр + #тип - строка + #name = "name" + + #фильтр по network plugin + #опциональный параметр + #тип - строка + #network_plugin = "flannel" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 3 +} + +output "test" { + value = data.decort_cb_k8ci_list_deleted.k8cild +} diff --git a/samples/cloudbroker/k8s/data_k8s/main.tf b/samples/cloudbroker/k8s/data_k8s/main.tf new file mode 100644 index 00000000..2b5ca80a --- /dev/null +++ b/samples/cloudbroker/k8s/data_k8s/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о k8s кластере +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_k8s" "k8s" { + #id кластера + #обязательный параметр + #тип - целое число + k8s_id = 49304 +} + +output "output_k8s" { + value = data.decort_cb_k8s.k8s +} diff --git a/samples/cloudbroker/k8s/data_k8s_computes/main.tf b/samples/cloudbroker/k8s/data_k8s_computes/main.tf new file mode 100644 index 00000000..761ef6ad --- /dev/null +++ b/samples/cloudbroker/k8s/data_k8s_computes/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о компьютах k8s кластера +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + oauth2_url = "https://sso.digitalenergy.online" + controller_url = "https://mr4.digitalenergy.online" + app_id = "" + app_secret = "" +} + +data "decort_cb_k8s_computes" "computes" { + #id кластера + #обязательный параметр + #тип - целое число + k8s_id = 999 +} + +output "computes_out" { + value = data.decort_cb_k8s_computes.computes +} diff --git a/samples/cloudbroker/k8s/data_k8s_list/main.tf b/samples/cloudbroker/k8s/data_k8s_list/main.tf new file mode 100644 index 00000000..94721670 --- /dev/null +++ b/samples/cloudbroker/k8s/data_k8s_list/main.tf @@ -0,0 +1,103 @@ +/* +Пример использования +Получение списка доступных кластеров +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_k8s_list" "k8s_list" { + #фильтр по id кластера + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени кластера + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по ip + #опциональный параметр + #тип - строка + #ip_address = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #lb_id = 100 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #bservice_id = 100 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #включение удаленных k8s в результат + #опциональный параметр + #тип - булев + #если не задан - выводятся все неудаленные данные + #include_deleted = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 +} + +output "output_k8s_list" { + value = data.decort_cb_k8s_list.k8s_list +} diff --git a/samples/cloudbroker/k8s/data_k8s_list_deleted/main.tf b/samples/cloudbroker/k8s/data_k8s_list_deleted/main.tf new file mode 100644 index 00000000..7543c6b4 --- /dev/null +++ b/samples/cloudbroker/k8s/data_k8s_list_deleted/main.tf @@ -0,0 +1,87 @@ +/* +Пример использования +Получение списка удаленных кластеров +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_k8s_list_deleted" "k8s_list_deleted" { + #фильтр по id кластера + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени кластера + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по ip + #опциональный параметр + #тип - строка + #ip_address = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #lb_id = 100 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #bservice_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output_k8s_list_deleted" { + value = data.decort_cb_k8s_list_deleted.k8s_list_deleted +} + diff --git a/samples/cloudbroker/k8s/data_k8s_wg/main.tf b/samples/cloudbroker/k8s/data_k8s_wg/main.tf new file mode 100644 index 00000000..4ae7da75 --- /dev/null +++ b/samples/cloudbroker/k8s/data_k8s_wg/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о k8s кластере +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_k8s_wg" "k8s_wg" { + #id кластера + #обязательный параметр + #тип - целое число + k8s_id = 49304 + + #id группы воркеров + #обязательный параметр + #тип - целое число + wg_id = 43329 +} + +output "output_k8s_wg" { + value = data.decort_cb_k8s_wg.k8s_wg +} diff --git a/samples/cloudbroker/k8s/data_k8s_wg_cloud_init/main.tf b/samples/cloudbroker/k8s/data_k8s_wg_cloud_init/main.tf new file mode 100644 index 00000000..9f3ea0d3 --- /dev/null +++ b/samples/cloudbroker/k8s/data_k8s_wg_cloud_init/main.tf @@ -0,0 +1,46 @@ +/* +Пример использования +Получение информации о мета данных рабочей группы k8s кластера +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_k8s_wg_cloud_init" "wg_cloud_init" { + #id кластера + #обязательный параметр + #тип - целое число + k8s_id = 977 + + #id группы воркеров + #обязательный параметр + #тип - целое число + wg_id = 2110 +} + +output "wg_cloud_init" { + value = data.decort_cb_k8s_wg_cloud_init.wg_cloud_init +} + + + diff --git a/samples/cloudbroker/k8s/data_k8s_wg_list/main.tf b/samples/cloudbroker/k8s/data_k8s_wg_list/main.tf new file mode 100644 index 00000000..bae2513c --- /dev/null +++ b/samples/cloudbroker/k8s/data_k8s_wg_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение списка доступных рабочих групп в кластере +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_k8s_wg_list" "k8s_wg_list" { + #id кластера + #обязательный параметр + #тип - целое число + k8s_id = 49304 +} + +output "output_k8s_wg_list" { + value = data.decort_cb_k8s_wg_list.k8s_wg_list +} diff --git a/samples/cloudbroker/k8s/resource_k8ci/main.tf b/samples/cloudbroker/k8s/resource_k8ci/main.tf new file mode 100644 index 00000000..ed3f2c3c --- /dev/null +++ b/samples/cloudbroker/k8s/resource_k8ci/main.tf @@ -0,0 +1,104 @@ +/* +Пример использования +Ресурса k8ci +Ресурс позволяет: +1. Создавать k8ci +2. Редактировать k8ci +3. Удалять k8ci +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_k8ci" "k8ci" { + #имя k8ci + #обязательный параметр + #тип - строка + #используется при создании + name = "test" + + #тег версии + #обязательный параметр + #тип - строка + #используется при создании + version = "1.1.1" + + #максимальное число master компьютов + #обязательный параметр + #тип - целое число + #используется при создании + max_master_count = 1 + + #максимальное число worker компьютов + #обязательный параметр + #тип - целое число + #используется при создании + max_worker_count = 1 + + #id образа для master + #обязательный параметр + #тип - целое число + #используется при создании + master_image_id = 4 + + #id образа для worker + #обязательный параметр + #тип - целое число + #используется при создании + worker_image_id = 4 + + #network plugins + #обязательный параметр + #тип - массив строк + #используется при создании + network_plugins = ["flannel"] + + #доступность k8ci + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enabled = false + + #флаг для удаления k8ci, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = true + + #описание + #опциональный параметр + #тип - строка + #используется при создании + #desc = "some" + + #доступность k8ci другим аккаунтам + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #shared_with = [1111] + +} + +output "test" { + value = decort_cb_k8ci.k8ci +} diff --git a/samples/cloudbroker/k8s/resource_k8s_cp/main.tf b/samples/cloudbroker/k8s/resource_k8s_cp/main.tf new file mode 100644 index 00000000..4249f4b6 --- /dev/null +++ b/samples/cloudbroker/k8s/resource_k8s_cp/main.tf @@ -0,0 +1,234 @@ +/* +Пример использования +Ресурса k8s +Ресурс позволяет: +1. Создавать кластер +2. Редактировать кластер +3. Удалять кластер +4. Настроить мастер-узел +5. Изменить кол-во ВМ в мастер-узле +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + oauth2_url = "https://sso.digitalenergy.online" + controller_url = "https://mr4.digitalenergy.online" + app_id = "" + app_secret = "" +} + +resource "decort_cb_k8s_cp" "cp" { + #название кластера + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "k8s-cp" + + #k8sCI ID + #обязательный параметр + #тип - целое число + #используется при создании + k8sci_id = 55 + + #плагин сети + #обязательный параметр + #возможные значения - "flannel", "weavenet", "calico" + #тип - строка + #используется при создании + network_plugin = "flannel" + + #id ресурсной группы + #обязательный параметр + #тип - целое число + #используется при создании + rg_id = 1387 + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #кол-во ядер мастер-узла + #опциональный параметр + #тип - целое число + #используется при создании + #cpu = 2 + + #объем RAM мастер-узла + #опциональный параметр + #тип - целое число + #используется при создании + #ram = 2048 + + #кол-во ВМ мастер-узла (1, 3 или 5) + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #num = 1 + + #размер диска мастер-узла + #опциональный параметр + #тип - целое число + #используется при создании + #disk = 10 + + #описание кластера + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc = "" + + #id extnet + #опциональный параметр + #тип - целое число + #используется при создании + #extnet_id = 0 + + #id vins + #опциональный параметр + #тип - целое число + #используется при создании + #vins_id = 1234 + + #sep ip + #опциональный параметр + #тип - целое число + #используется при создании + #sep_id = 0 + + #название пула + #опциональный параметр + #тип - строка + #используется при создании + #sep_pool = "pool" + + #старт/стоп кластера + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #start = true + + #включить/отключить кластер + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enabled = true + + #флаг для удаления k8s_cp, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = true + + #восстановить кластер из корзины + #опциональный параметр + #тип - булев + #используется при обновлении + #restore = true + + #создать кластер с/без балансировщика нагрузки + #опциональный параметр + #тип - булев + #используется при создании + #with_lb = true + + #создать схему отказоустройчивой LB + #опциональный параметр + #тип - булев + #используется при создании + #ha_mode = true + + #дополнительные SAN (Subject Alternative Names) для использования в процессе автоматического выписывания сертификата Кластера Kubernetes; + #возможность взаимодействовать с кластером по FQDN + #параметр получает список строк – IP-адреса и/или DNS (по формату RFC 1123 c поддержкой wildcard) + #опциональный параметр + #тип - массив строк + #используется при создании + #additional_sans = ["192.168.201.0","192.168.201.1"] + + #используется для определения настроек и действий, которые должны быть выполнены перед запуском любого другого компонента в кластере + #это позволяет вам настраивать такие вещи, как регистрация node, настройка network и другие задачи инициализации + #опциональный параметр + #тип - строка + #используется при создании + #init_config = "{JSON string}" + + #используется для определения глобальных настроек и конфигураций для всего кластера + #он включает в себя такие параметры, как имя кластера, настройки DNS, методы аутентификации и другие конфигурации в масштабах кластера + #опциональный параметр + #тип - строка + #используется при создании + #cluster_config = "{JSON string}" + + #используется для настройки поведения и параметров Kubelet, который является агентом primary node, запускаемым на каждом node кластера + #он включает в себя такие параметры, как IP-адрес node, распределение ресурсов, политики удаления модулей и другие конфигурации, специфичные для Kubelet + #опциональный параметр + #тип - строка + #используется при создании + #kubelet_config = "{JSON string}" + + #используется для настройки поведения и параметров присоединения node к кластеру + #он включает в себя такие параметры, как режим прокси-сервера, диапазоны IP-адресов кластера и другие конфигурации, специфичные для Kube-proxy + #опциональный параметр + #тип - строка + #используется при создании + #kube_proxy_config = "{JSON string}" + + #используется для настройки поведения и параметров присоединения node к кластеру + #он включает в себя такие параметры, как cluster's control plane endpoint, токен и ключ сертификата + #опциональный параметр + #тип - строка + #используется при создании + #join_config = "{JSON string}" + + #при создании кластере использовать подключение только к сети ExtNet + #опциональный параметр + #тип - булев + #используется при создании + #extnet_only = true + + #добавить ssl-сертификат в формате x509 pem + #опциональный параметр + #тип - файл с форматом в виде .crt + #используется при создании + #oidc_cert = file("ca.crt") + + #тип эмулируемой системы + #опциональный параметр + #тип - строка + #возможные значения: "i440fx", "Q35" + #по умолчанию - Q35 + #используется при создании + #chipset = "Q35" + + #пользовательские значения sysctl для LB + #опциональный параметр + #тип - массив мап + #используется при создании и обновлении + #lb_sysctl_params = [{ key1 = "value1", key2 = "value2" }] + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 +} + +output "cp_out" { + value = decort_cb_k8s_cp.cp +} diff --git a/samples/cloudbroker/k8s/resource_k8s_wg/initconfig.tftpl b/samples/cloudbroker/k8s/resource_k8s_wg/initconfig.tftpl new file mode 100644 index 00000000..06df7c0d --- /dev/null +++ b/samples/cloudbroker/k8s/resource_k8s_wg/initconfig.tftpl @@ -0,0 +1,9 @@ +--- +users: +- groups: users, wheel + name: user + plain_text_passwd: examplePassword + primary_group: user + ssh_authorized_keys: + - ssh-rsa EXAMPLE%id_rsa.pub + sudo: ALL=(ALL) NOPASSWD:ALL diff --git a/samples/cloudbroker/k8s/resource_k8s_wg/main.tf b/samples/cloudbroker/k8s/resource_k8s_wg/main.tf new file mode 100644 index 00000000..38c1e350 --- /dev/null +++ b/samples/cloudbroker/k8s/resource_k8s_wg/main.tf @@ -0,0 +1,126 @@ +/* +Пример использования +Получение информации о группе воркеров кластера Kubernetes(k8s) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_k8s_wg" "wg" { + #id экземпляра k8s + #обязательный параметр + #это значение должно быть и результат вызова decort_cb_k8s.cluster.k8s_id + #тип - целое число + #используется при создании + k8s_id = 1234 + + #имя worker group + #обязательный параметр + #тип - строка + #используется при создании + name = "workers-2" + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 111 + + #количество worker node для создания + #опциональный параметр + #тип - целое число + #по умолчанию - 1 + #используется при создании и обновлении + #num = 2 + + #количество cpu для 1 worker node + #опциональный параметр + #тип - целое число + #по умолчанию - 1 + #используется при создании + #cpu = 1 + + #количество RAM для одной worker node в МБ + #опциональный параметр + #тип - целое число + #по умолчанию - 1024 + #используется при создании + #ram = 1024 + + #размер загрузочного диска для worker node, в ГБ + #опциональный параметр + #по умолчанию - 0 + #если установлен параметр 0, то размер диска будет равен размеру образа + #тип - целое число + #используется при создании + #disk = 10 + + #список строк с labels для worker группы, в формате: ["label1=value1", "label2=value2"] + #опциональный параметр + #тип - массив строк + #используется при создании + #labels = ["label1=value1", "label2=value2"] + + #список строк с annotations для worker группы, в формате: ["key1=value1", "key2=value2"] + #опциональный параметр + #тип - массив строк + #используется при создании + #annotations = ["key1=value1", "key2=value2"] + + #список строк с taints для worker группы, в формате: ["key1=value1:NoSchedule", "key2=value2:NoExecute"] + #опциональный параметр + #тип - массив строк + #используется при создании + #taints = ["key1=value1", "key2=value2"] + + #id СХД для создания загрузочных дисков для Worker-групп по умолчанию. Использует sepId образа, если не указан. + #опциональный параметр + #тип - целое число + #используется при создании + #worker_sep_id = 1 + + #пул для хранения Workers. Если не заполнить, будет выбран системой + #опциональный параметр + #тип - целое число + #используется при создании + #worker_sep_pool = "worker_pool" + + #перечень аргументов для cloud-init для виртуальных машин worker групп + #опциональный параметр + #тип - файл в формате YAML + #используется при создании и обновлении + #cloud_init = file("initconfig.tftpl") + + #тип эмулируемой системы + #опциональный параметр + #тип - строка + #возможные значения: "i440fx", "Q35" + #по умолчанию - Q35 + #используется при создании + #chipset = "Q35" + +} + +output "test_wg" { + value = decort_cb_k8s_wg.wg +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm/main.tf new file mode 100644 index 00000000..851d8cad --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных о compute (виртуальной машине). +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm" "comp" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 11346 +} + +output "test" { + value = data.decort_cb_kvmvm.comp +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_affinity_relations/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_affinity_relations/main.tf new file mode 100644 index 00000000..f79f5d44 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_affinity_relations/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение словаря ВМ (виртуальных машин), разделенного по правилам affinity и anti-affinity. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_affinity_relations" "aff_rel" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 48 + +} + +output "output" { + value = data.decort_cb_kvmvm_affinity_relations.aff_rel +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_audits/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_audits/main.tf new file mode 100644 index 00000000..04e01861 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_audits/main.tf @@ -0,0 +1,92 @@ +/*Deprecated + +Данный datasource является **deprecated** и будет удалён в следующих версиях. Вместо него неоходимо использовать datasource **decort_cb_audit_list**. +*/ + +/* +Пример использования +Получение данных об аудитах compute (виртулаьной машине) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_audits" "kvmvm_audits" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 + + #найти все аудиты после определенного момента времени + #опциональный параметр + #тип - целое число + #timestamp_to = 11 + + #найти все аудиты до определенного момента времени + #опциональный параметр + #тип - целое число + #timestamp_at = 11 + + #фильтр по юзеру + #опциональный параметр + #тип - строка + #user = "user" + + #фильтр по эндпоинту апи + #опциональный параметр + #тип - строка + #call = "call" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #значение по умолчанию - 1 + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #значение по умолчанию - 100 + #size = 100 + + #найти по минимальному коду статуса HTTP + #опциональный параметр + #тип - целое число + #min_status_code = 1 + + #найти по максимальному коду статуса HTTP + #опциональный параметр + #тип - целое число + #max_status_code = 140 + +} + +output "output" { + value = data.decort_cb_kvmvm_audits.kvmvm_audits +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_boot_order_get/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_boot_order_get/main.tf new file mode 100644 index 00000000..248f625d --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_boot_order_get/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации о текущем порядке загрузки ВМ (виртуальной машины). +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_boot_order_get" "boot_order" { + #id виртуальной машины + #обязательный параметр + #тип - целое вчисло + compute_id = 48 + +} + +output "output" { + value = data.decort_cb_kvmvm_boot_order_get.boot_order +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_cpu_alignment_profile/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_cpu_alignment_profile/main.tf new file mode 100644 index 00000000..2aa6f44f --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_cpu_alignment_profile/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных о профиле CPU alignment виртуальной машины +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_cpu_alignment_profile" "cpu_alignment_profile" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 100 +} + +output "output" { + value = data.decort_cb_kvmvm_cpu_alignment_profile.cpu_alignment_profile +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_get_audits/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_get_audits/main.tf new file mode 100644 index 00000000..1a582685 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_get_audits/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение данных об аудитах compute (виртулаьной машины) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_get_audits" "kvmvm_get_audits" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 + +} + +output "output" { + value = data.decort_cb_kvmvm_get_audits.kvmvm_get_audits +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_get_console_url/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_get_console_url/main.tf new file mode 100644 index 00000000..67a02f4a --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_get_console_url/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение url compute (виртуальной машины) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_get_console_url" "kvmvm_get_console_url" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 + +} + +output "output" { + value = data.decort_cb_kvmvm_get_console_url.kvmvm_get_console_url +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_get_log/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_get_log/main.tf new file mode 100644 index 00000000..0d464338 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_get_log/main.tf @@ -0,0 +1,44 @@ +/* +Пример использования +Получение логов compute (виртуальной машины) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_get_log" "kvmvm_get_log" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 + + #путь до log файла + #обязательный параметр + #тип - строка + path = "/var/log/file.log" + +} + +output "output" { + value = data.decort_cb_kvmvm_get_log.kvmvm_get_log +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_list/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_list/main.tf new file mode 100644 index 00000000..1a9f3695 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_list/main.tf @@ -0,0 +1,129 @@ +/* +Пример использования +Получение данных о списке compute (виртуальных машин) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_list" "compute_list" { + #фильтр по id ВМ + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени ВМ + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка ВМ + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #rg_name = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #фильтр по названию ноды + #опциональный параметр + #тип - строка + #node_name = "node_name" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по ip + #опциональный параметр + #тип - строка + #ip_address = "test" + + #фильтр по node id + #опциональный параметр + #тип - целое число + #node_id = 123 + + #фильтр по cd image id + #опциональный параметр + #тип - целое число + #cd_image_id = 123 + + #фильтр по имени extnet + #опциональный параметр + #тип - строка + #extnet_name = "test" + + #фильтр по id extnet + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #флаг включения в результат удаленных балансировщиков нагрузки + #опциональный параметр + #если не задан - выводятся все доступные неудаленные балансировщики + #по умолчанию - false + #тип - булев + #includedeleted = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 1 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 + +} + +output "output" { + value = data.decort_cb_kvmvm_list.compute_list +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_list_deleted/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_list_deleted/main.tf new file mode 100644 index 00000000..f212bc46 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_list_deleted/main.tf @@ -0,0 +1,97 @@ +/* +Пример использования +Получение данных о списке удаленных compute (виртуальных машин) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_list_deleted" "compute_list" { + #фильтр по id виртуальной машины + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени виртуальной машины + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 100 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #rg_name = "test" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "some" + + #фильтр по ip + #опциональный параметр + #тип - строка + #ip_address = "test" + + #фильтр по имени extNet + #опциональный параметр + #тип - строка + #extnet_name = "test" + + #фильтр по id extNet + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 + +} + +output "output" { + value = data.decort_cb_kvmvm_list_deleted.compute_list +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_migrate_storage_info/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_migrate_storage_info/main.tf new file mode 100644 index 00000000..f9b01de0 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_migrate_storage_info/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации о последней (включая текущую) миграции хранилища. + +*/ +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_migrate_storage_info" "info" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 48 + +} + +output "output" { + value = data.decort_cb_kvmvm_migrate_storage_info.info +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_pci_device_list/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_pci_device_list/main.tf new file mode 100644 index 00000000..7d238224 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_pci_device_list/main.tf @@ -0,0 +1,77 @@ +/* +Пример использования +Получение данных о списке подключенных устройств (PCI) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_pci_device_list" "pci_device_list" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 100 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по id устройства + #опциональный параметр + #тип - целое число + #device_id = 100 + + #фильтр по имени устройства + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 1 + +} + +output "output" { + value = data.decort_cb_kvmvm_pci_device_list.pci_device_list +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_pfw_list/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_pfw_list/main.tf new file mode 100644 index 00000000..64260d70 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_pfw_list/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение данных об списке port forwarding compute (виртулаьных машин) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_pfw_list" "kvmvm_pfw_list" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 48 + +} + +output "output" { + value = data.decort_cb_kvmvm_pfw_list.kvmvm_pfw_list +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_snapshot_list/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_snapshot_list/main.tf new file mode 100644 index 00000000..4d96c5f1 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_snapshot_list/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение списка моментальных снимков ВМ (виртуальных машин). +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_snapshot_list" "kvmvm_snapshot_list" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 48 + +} + +output "output" { + value = data.decort_cb_kvmvm_snapshot_list.kvmvm_snapshot_list +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_snapshot_usage/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_snapshot_usage/main.tf new file mode 100644 index 00000000..c21087b1 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_snapshot_usage/main.tf @@ -0,0 +1,44 @@ +/* +Пример использования +Получение настоящего размера снимка ВМ (виртуальной машины) в хранилище. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_snapshot_usage" "snp_usage" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 48 + + #label снимка + #опциональный параметр + #тип - строка + #label = "test" + +} + +output "output" { + value = data.decort_cb_kvmvm_snapshot_usage.snp_usage +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_user_list/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_user_list/main.tf new file mode 100644 index 00000000..dd88f43f --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_user_list/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение данных об юзерах compute (виртуальной машины) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_user_list" "kvmvm_user_list" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 10154 + +} + +output "output" { + value = data.decort_cb_kvmvm_user_list.kvmvm_user_list +} diff --git a/samples/cloudbroker/kvmvm/data_kvmvm_vgpu_list/main.tf b/samples/cloudbroker/kvmvm/data_kvmvm_vgpu_list/main.tf new file mode 100644 index 00000000..b14b0f62 --- /dev/null +++ b/samples/cloudbroker/kvmvm/data_kvmvm_vgpu_list/main.tf @@ -0,0 +1,76 @@ +/* +Пример использования +Получение данных о списке подключенных графических процессоров +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_kvmvm_vgpu_list" "vgpu_list" { + #id виртуальной машины + #обязательный параметр + #тип - целое число + compute_id = 100 + + #фильтр по id графического процессора + #опциональный параметр + #тип - целое число + #gpu_id = 100 + + #фильтр по типу графического процессора + #опциональный параметр + #тип - строка + #type = "NVIDIA" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр "включая удаленные графические процессоры" + #опциональный параметр + #тип - булев + #includedeleted = false + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 1 + +} + +output "output" { + value = data.decort_cb_kvmvm_vgpu_list.vgpu_list +} diff --git a/samples/cloudbroker/kvmvm/resource_kvmvm/initconfig.tftpl b/samples/cloudbroker/kvmvm/resource_kvmvm/initconfig.tftpl new file mode 100644 index 00000000..587b59ce --- /dev/null +++ b/samples/cloudbroker/kvmvm/resource_kvmvm/initconfig.tftpl @@ -0,0 +1,14 @@ +{ +"users": [ + { + "groups": "users, wheel", + "name": "user", + "plain_text_passwd": "examplePassword", + "primary_group": "user", + "ssh_authorized_keys": [ + "ssh-rsa EXAMPLE%id_rsa.pub" + ], + "sudo": "ALL=(ALL) NOPASSWD:ALL" + } +] +} diff --git a/samples/cloudbroker/kvmvm/resource_kvmvm/main.tf b/samples/cloudbroker/kvmvm/resource_kvmvm/main.tf new file mode 100644 index 00000000..d8a7e666 --- /dev/null +++ b/samples/cloudbroker/kvmvm/resource_kvmvm/main.tf @@ -0,0 +1,750 @@ +/* +Пример использования +Работа с ресурсом kvmvm (compute) +Ресурс позволяет: +1. Создавать compute +2. Редактировать compute +3. Удалять compute +*/ +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "" + source = "basis/decort/decort" + } + } +} +*/ + + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_kvmvm" "comp" { + #имя compute + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "test-tf-compute-update-new" + + #id ресурсной группы + #обязательный параметр + #тип - целое число + #используется при создании + rg_id = 1111 + + #число cpu + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + cpu = 1 + + #кол-во оперативной памяти, МБ + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + ram = 2048 + + #id политики хранения + #обязательный параметр + #тип - целое число + #используется при создании + storage_policy_id = 1 + + #тип эмулируемой системы + #опциональный параметр + #тип - строка + #возможные значения: "i440fx", "Q35" + #по умолчанию - Q35 + #используется при создании и обновлении + #chipset = "Q35" + + #тип часов для ВМ + #опциональный параметр + #возможные значения: "default", "linux", "windows", "none" + #по умолчанию - "default" + #используется при создании и обновлении + #clock = "linux" + + #id образа диска для создания compute + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #image_id = 111 + + #создать вм без загрузочного диска + #если значение равно True, параметры image_id, boot_disk_size, sep_id, pool игнорируются + #компьютер создается без загрузочного диска в остановленном состоянии + #опциональный параметр + #тип - булев + #используется при создании + #without_boot_disk = true + + #создание без образа ОС + #опциональный параметр + #тип - булев + #используется при создании + #create_blank = false + + #размер загрузочного диска + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #boot_disk_size = 20 + + #установка режима кэширования для загрузочного диска + #опциональный параметр + #тип - строка + #значение по умолчанию - none + #возможные варианты: "none" или "writethrough" + #используется при создании и обновлении + #boot_disk_cache = "none" + + #id сепа для boot диска + #опциональный параметр + #тип - целое число + #используется при создании + #sep_id = 1 + + #название пула + #опциональный параметр + #тип - строка + #используется при создании + #pool = "data02" + + #конфигурация cloud init + #опциональный параметр + #тип - файл в формате JSON + #используется при создании + #cloud_init = file("initconfig.tftpl") + + #описание compute + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #description = "test update description in tf words update" + + #node id + #опциональный параметр + #тип - целое число + #используется при создании + #node_id = 1 + + #id образа CD-ROM для загрузки + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #alt_boot_id = 1 + + #необходимость выравнивать ВМ по NUMA + #опциональный параметр + #тип - строка + #возможные значения - "none, "strict", "loose" + #по умолчанию - "none" + #используется при создании и обновлении + #numa_affinity = "loose" + + #необходимость запускать ВМ на выделенных CPU ядрах + #опциональный параметр + #тип - булев + #по умолчанию - false + #используется при создании и обновлении + #cpu_pin = true + + #необходимость использовать для выделения RAM виртуальной машины Huge Pages + #опциональный параметр + #тип - булев + #по умолчанию - false + #используется при создании и обновлении + #hp_backed = true + + #установка режима "только для чтения", который позволяет лишь получать информацию о ВМ, ничего в ней не менять + #опциональный параметр + #тип - булев + #значение по умолчанию - false + #используется при создании и обновлении + #read_only = false + + #создание и добавление диска для compute + #при изменении параметров `pool` и `sep_id` для обновления ресурса может возникнуть необходимость синхронизации + #состояния при помощи команды `terraform refresh` + #опциональный параметр + #тип - список дисков + #используется при создании и обновлении + #disks { + #имя диска + #обязательный для диска параметр + #тип - строка + #disk_name = "disk_name" + + #размер диска + #обязательный для диска параметр + #тип - целое число + #size = 5 + + #id политики хранения + #обязательный для диска параметр + #тип - целое число + #storage_policy_id = 1 + + #установка режима кэширования + #опциональный параметр + #тип - строка + #значение по умолчанию - none + #возможные варианты: "none" или "writethrough" + #cache = "none" + + #опциональный параметр + #тип - целое число + #sep_id = 1 + + #название пула + #опциональный параметр + #тип - строка + #pool = "data01" + + #список node + #опциональный параметр + #тип - массив целых чисел + #node_ids = [10,11] + + #описание диска + #опциональный параметр + #тип - строка + #desc = "" + + #id образа + #опциональный параметр + #image_id = 378 + + #флаг для удаления диска, без возможности восстановления + #опциональный параметр + #тип - булев + #permanently = false + + #включение режима unmap для диска + #опциональный параметр + #тип - строка + #по умолчанию - "ignore" + #возможные варианты: "ignore" или "unmap" + #используется при создании и обновлении + #discard = "unmap" + + #размер блока диска + #опциональный параметр + #тип - строка + #возможные варианты: "512", "512e", "4k" + #block_size = "4k" + + #настройки лимитов операций ввода/вывода диска + #опциональный параметр + #тип - блок + #тип вложенных полей - целое число + #используется при создании и обновлении + #iotune { + #read_bytes_sec = 0 + #read_bytes_sec_max = 0 + #read_iops_sec = 0 + #read_iops_sec_max = 0 + #size_iops_sec = 0 + #total_bytes_sec = 0 + #total_bytes_sec_max = 0 + #total_iops_sec = 3000 + #total_iops_sec_max = 0 + #write_bytes_sec = 0 + #write_bytes_sec_max = 0 + #write_iops_sec = 0 + #write_iops_sec_max = 0 + #} + #} + + #правила affinity + #опциональный параметр + #может быть один, несколько или ни одного блока + #тип - блок + #используется при создании и обновлении + #affinity_rules { + #тип правила + #возможные значения - compute или node + #обязательный параметр + #тип - строка + #topology = "compute" + + #строгость правила + #возможные значения - RECOMMENDED и REQUIRED + #обязательный параметр + #тип - строка + #policy = "RECOMMENDED" + + #режим проверки + #возможные значения - ANY, EQ, NE + #обязательный параметр + #тип - строка + #mode = "ANY" + + #ключ правила + #обязательный параметр + #тип - строка + #key = "testkey" + + #ключ правила + #обязательный параметр + #тип - строка + #value = "testvalue" + #} + + #правила anti-affinity + #опциональный параметр + #может быть один, несколько или ни одного блока + #тип - блок + #используется при создании и обновлении + #anti_affinity_rules { + #тип правила + #возможные значения - compute или node + #обязательный параметр + #тип - строка + #topology = "compute" + + #строгость правила + #возможные значения - RECOMMENDED и REQUIRED + #обязательный параметр + #тип - строка + #policy = "RECOMMENDED" + + #режим проверки + #возможные значения - ANY, EQ, NE + #обязательный параметр + #тип - строка + #mode = "ANY" + + #ключ правила + #обязательный параметр + #тип - строка + #key = "testkey" + + #ключ правила + #обязательный параметр + #тип - строка + #value = "testvalue" + #} + + #установка метки для вм + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #affinity_label = "test4" + + #имя профиля CPU alignment + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #cpu_alignment_profile = "balanced" + + #id экстра дисков + #опциональный параметр + #тип - список чисел + #используется при создании и обновлении + #extra_disks = [1234, 4322, 1344] + + #управление XML виртуальной машины + #опциональный параметр + #тип - строка (json-encoded) + #используется при создании и обновлении + #custom_fields = "{`key`:`value`}" + + #присоединение сетей и удаление сетей в компьюте + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #network { + #тип сети + #обязательный параметр + #возможные значения - "VINS", "EXTNET", "VFNIC", "DPDK", "SDN", "TRUNK" (при выборе типа DPDK, необходимо указать hp_backed = true) + #тип - строка + #net_type = "VINS" + + #id сети + #обязательный параметр + #при использовании SDN необходимо указать любое значение отличное от 0 + #тип - целое число + #net_id = 1234 + + #ip адрес входящий в сеть + #опциональный параметр + #тип - строка + #ip_address = "127.0.0.1" + + #mac-адрес интерфейса компьюта + #опциональный параметр + #тип - строка + #mac = "52:54:01:12:34:60" + + #вес сети, указывается при необходимости указания порядка подключения сетей + #первой подключается сеть с наименьшим весом + #сеть с нулевым или неуказанным весом имеет наименьший приоритет + #опциональный параметр + #тип - целое число + #weight = 15 + + #максимальный объём данных, который может быть передан за одну итерацию + #используется с сетями типа "DPDK", "TRUNK", "EXTNET" + #возможные значения - 1500-9216 + #опциональный параметр + #тип - целое число + #mtu = 1500 + + #id sdn сети + #используется только с сетями типа "SDN" + #опциональный параметр + #тип - строка + #sdn_interface_id = "f2d87a70-ea35-468d-8aef-bb1ecbe2e476" + + #включение сетевого интерфейса + #используется с сетями типа "VINS", "EXTNET", "DPDK", "SDN", "TRUNK" + #по умолчанию - true + #опциональный параметр + #тип - булев + #enabled = true + + #маска подсети + #используется только с сетями типа "DPDK" и "VFNIC" + #опциональный параметр + #тип - целое число + #net_mask = 32 + #} + + #группы безопасности + #опциональный параметр + #тип - блок + #не применяется к сетям типа "VFNIC", "TRUNK", "SDN" + #используется при создании и обновлении + #security_groups { + #тип сети + #обязательный параметр + #тип - строка + #возможные значения - "VINS", "EXTNET", "DPDK" (при выборе типа DPDK, необходимо указать hp_backed = true) + #net_type = "VINS" + + #id сети + #обязательный параметр + #при использовании SDN необходимо указать любое значение отличное от 0 + #тип - целое число + #net_id = 1234 + + #список id групп безопасности + #обязательный параметр + #тип - массив целых чисел + #security_groups = [12, 34] + + #флаг, указывающий, включены ли группы безопасности + #опциональный параметр + #тип - булев + #по умолчанию: false + #enable_secgroups = false + #} + + #добавление и удаление тэгов + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #tags { + #ключ для тэга + #обязательный параметр + #тип - строка + #key = "key" + + #значения тэга + #обязательный параметр + #тип - строка + #value = "value" + #} + + #добавление и удаление port forwarding + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #port_forwarding { + #номер внешнего начального порта для правила + #обязательный параметр + #тип - целое число + #public_port_start = 2023 + + #номер внешнего последнего порта для правила + #опциональный параметр + #тип - целое число + #по умолчанию - -1 + #public_port_end = 2023 + + #номер внутреннего базового порта + #обязательный параметр + #тип - целое число + #local_port = 80 + + #сетевой протокол + #обязательный параметр + #тип - строка + #proto = "tcp" + #} + + #предоставить/забрать пользователю доступ к компьюту + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #user_access { + #имя юзера, которому предоставляем доступ + #обязательный параметр + #тип - строка + #username = "some@decs3o" + + #права: 'R' - только на чтение, 'RCX' - чтение/запись, 'ARCXDU' - админ + #обязательный параметр + #тип - строка + #access_type = "ARCXDU" + #} + + #создать/удалить снапшот компьюта + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #snapshot { + #лейбл снапшота + #обязательный параметр + #тип - строка + #label = "label1" + #} + + #флаг для удаления снапшотов в асинхронном режиме + #опциональный параметр + #тип - булев + #по умолчанию - false + #используется при обновлении + #snapshot_delete_async = true + + #rollback на нужный снапшот + #опциональный параметр + #не имеет смысла при отсутсвии снапшотов + #тип - блок + #используется при обновлении + #rollback { + #лейбл снапшота + #обязательный параметр + #тип - строка + #label = "label1" + #} + + #вставить/удалить СD rom + #опциональный параметр + #максимальное кол-во - 1 + #тип - блок + #используется при создании и обновлении + #cd { + #id образа диска CD rom + #обязательный параметр + #тип - целое число + #cdrom_id = 344 + #} + + #добавить компьют на ноду + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #pin_to_node = true + + #список ядер для использования в механизме vcpupinning. Количество указанных ядер должно быть равно количеству виртуальных процессоров ВМ + #игнорируется если cpu_pin=false или pin_to_node=false + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #preferred_cpu = [1234, 456] + + #флаг для старта компьюта при рестарте ноды + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #auto_start_w_node = true + + #флаг для принудительного добавления компьюта на ноду + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #force_pin = true + + #список PCI девайсов + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #pci_devices = [1,2] + + #флаг доступности компьюта для проведения с ним операций + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enabled = true + + #pause/resume компьюта + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #pause = true + + #сделать компьют заново + #опциональный параметр + #тип - булев + #используется при обновлении + #reset = true + + #восстановить удаленный компьют из корзины + #опциональный параметр + #тип - булев + #используется при обновлении + #restore = true + + #флаг для редеплоя компьюта + #опциональный параметр + #тип - булев + #используется при обновлении + #force_stop = true + + #флаг для ресайза компьюта + #опциональный параметр + #тип - булев + #используется при обновлении + #force_resize = true + + #запуск/стоп компьюта + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #started = true + + #detach диска при удалении компьюта + #опциональный параметр + #тип - булев + #используется при удалении + #detach_disks = true + + #флаг для удаления компьюта, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = false + + #конфигурация параметров libvirt virtio интерфейса + #опциональный параметр + #добавление блока возможно только при выключенной виртуальной машине, + #удаление блока удалит настройки только локально, состояние на платформе не изменится + #тип - блок + #используется при создании и обновлении + #libvirt_settings { + #тип сети + #обязательный параметр + #возможные значения - "VINS", "VFNIC", "DPDK" + #тип - строка + #net_type = "VINS" + + #id сети + #обязательный параметр + #тип - целое число + #net_id = 1234 + + #tx mode + #опциональный параметр + #возможные значения - 'iothread', 'timer' или 'selected by hypervisor' + #тип - строка + #txmode = "iothread" + + #io event + #опциональный параметр + #возможные значения - 'on', 'off' or 'selected by hypervisor' + #тип - строка + #ioeventfd = "on" + + #event ID + #опциональный параметр + #возможные значения - 'on', 'off' or 'selected by hypervisor' + #тип - строка + #event_idx = "off" + + #количество очередей + #опциональный параметр + #тип - целое число + #queues = "4" + + #длина очереди RX + #опциональный параметр + #тип - целое число + #rx_queue_size = "1024" + + #длина очереди TX + #опциональный параметр + #тип - целое число + #tx_queue_size = "1024" + #} + + #тип ВМ + #возможные значения - linux, windows, unknown + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #loader_type = "unknown" + + #тип загрузки образа + #возможные значения - bios, uefi + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #boot_type = "bios" + + #изменение размера ВМ + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #hot_resize = false + + #наименование сетевого интерфейса + #возможные значения - eth, ens + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #network_interface_naming = "ens" + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 + + #версия ОС, установленная на ВМ + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #os_version = "name" + + #вес ВМ + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #weight = 1 + + #включение режима unmap для boot диска + #опциональный параметр + #тип - строка + #по умолчанию - "ignore" + #используется при создании и обновлении + #возможные варианты: "ignore" или "unmap" + #boot_disk_discard = "unmap" +} + +output "test" { + value = decort_cb_kvmvm.comp +} diff --git a/samples/cloudbroker/lb/data_lb/main.tf b/samples/cloudbroker/lb/data_lb/main.tf new file mode 100644 index 00000000..c67049e6 --- /dev/null +++ b/samples/cloudbroker/lb/data_lb/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о load balancer (балансировщик нагрузки) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_lb" "lb" { + #id балансировщика нагрузки + #обязательный параметр + #тип - целое число + lb_id = 238 +} + +output "test" { + value = data.decort_cb_lb.lb +} diff --git a/samples/cloudbroker/lb/data_lb_list/main.tf b/samples/cloudbroker/lb/data_lb_list/main.tf new file mode 100644 index 00000000..e2d3242b --- /dev/null +++ b/samples/cloudbroker/lb/data_lb_list/main.tf @@ -0,0 +1,104 @@ +/* +Пример использования +Получение списка load balancer (балансировщиков нагрузки) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_lb_list" "lbl" { + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени балансировщика нагрузки + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка балансировщиков нагрузки + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по IP front + #опциональный параметр + #тип - строка + #front_ip = "ENABLED" + + #фильтр по IP back + #опциональный параметр + #тип - строка + #back_ip = "ENABLED" + + #флаг включения в результат удаленных балансировщиков нагрузки + #опциональный параметр + #тип - булев + #по умолчанию - false + #если не задан - выводятся все доступные неудаленные балансировщики + #includedeleted = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 +} + +output "test" { + value = data.decort_cb_lb_list.lbl +} diff --git a/samples/cloudbroker/lb/data_lb_list_deleted/main.tf b/samples/cloudbroker/lb/data_lb_list_deleted/main.tf new file mode 100644 index 00000000..336135f7 --- /dev/null +++ b/samples/cloudbroker/lb/data_lb_list_deleted/main.tf @@ -0,0 +1,86 @@ +/* +Пример использования +Получение списка удаленных load balancer (балансировщиков нагрузок) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "" + source = "basis/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_lb_list_deleted" "lbld" { + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени балансировщика нагрузки + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка балансировщиков нагрузки + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #фильтр по IP front + #опциональный параметр + #тип - строка + #front_ip = "ENABLED" + + #фильтр по IP back + #опциональный параметр + #тип - строка + #back_ip = "ENABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "test" { + value = data.decort_cb_lb_list_deleted.lbld +} diff --git a/samples/cloudbroker/lb/resource_lb/main.tf b/samples/cloudbroker/lb/resource_lb/main.tf new file mode 100644 index 00000000..ab440481 --- /dev/null +++ b/samples/cloudbroker/lb/resource_lb/main.tf @@ -0,0 +1,139 @@ +/* +Пример использования +Ресурса load balancer +Ресурс позволяет: +1. Создавать load balancer +2. Редактировать load balancer +3. Удалять load balancer +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_lb" "lb" { + #id ресурсной группы для создания балансировщика + #обязательный параметр + #тип - целое число + #используется при создании + rg_id = 1111 + + #наименование load balancer + #обязательный параметр + #тип - строка + #используется при создании + name = "tf-test-lb" + + #id внешней сети + #опциональный параметр + #id внешней сети и id виртуальной сети не могут быть одновременно = 0 + #тип - целое число + #используется при создании + #extnet_id = 6 + + #id виртуальной сети + #опциональный параметр + #id внешней сети и id виртуальной сети не могут быть одновременно = 0 + #тип - целое число + #используется при создании + #vins_id = 758 + + #флаг запуска load balancer + #опциональный параметр + #если load balancer был в статусе "stopped" (start = false), + #то для успешного старта, он должен быть доступен (enable = true) + #по умолчанию - true + #тип - булев + #используется при создании и обновлении + #start = true + + #создать схему отказоустойчивой LB + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #ha_mode = true + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #desc= "temp super lb for testing tf provider" + + #флаг доступности load balancer + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enable = true + + #флаг перезапуска load balancer + #опциональный параметр + #перезагрузка срабатывает только при изменении флага с false на true + #тип - булев + #используется при обновлении + #restart = false + + #флаг сброса конфигурации load balancer + #опциональный параметр + #сброс срабатывает только при изменении флага с false на true + #тип - булев + #используется при обновлении + #config_reset = false + + #флаг для удаления load balancer, без возможности восстановления + #опциональный параметр + #применяется при выполнении команды terraform destroy + #по умолчанию - false + #тип - булев + #используется при удалении + #permanently = false + + #флаг восстановления load balancer + #опциональный параметр + #восстановить можно load balancer, удаленным с флагом permanently = false + #тип - булев + #используется при обновлении + #restore = true + + #флаг используемый при рестарте load balancer + #опциональный параметр + #по умолчанию - true, при данном значении рестарт производится на обоих нодах в HA mode + #тип - булев + #используется при обновлении + #safe = true + + #пользовательские значения sysctl для LB + #опциональный параметр + #тип - список мап + #используется при создании и обновлении + #sysctl_params = [{ key1 = "value1", key2 = "value2" }] + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 + +} + +output "test" { + value = decort_cb_lb.lb +} diff --git a/samples/cloudbroker/lb/resource_lb_backend/main.tf b/samples/cloudbroker/lb/resource_lb_backend/main.tf new file mode 100644 index 00000000..74f5b238 --- /dev/null +++ b/samples/cloudbroker/lb/resource_lb_backend/main.tf @@ -0,0 +1,120 @@ +/* +Пример использования +Ресурса load balancer backend +Ресурс позволяет: +1. Создавать backend +2. Редактировать backend +3. Удалять backend +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_lb_backend" "lbb" { + #id балансировщика нагрузки + #обязательный параметр + #тип - целое число + #используется при создании + lb_id = 668 + + #имя бекенда для создания сервера + #обязательный параметр + #тип - строка + #используется при создании + name = "testBackend" + + #алгоритм балансировки + #опциональный параметр + #доступные значения - "roundrobin", "static-rr", "leastconn" + #по умолчанию - "roundrobin" + #тип - строка + #используется при создании и обновлении + #algorithm = "roundrobin" + + #------------------- + #настройки для серверов по умолчанию + #------------------- + + #интервал между проверками, в миллисекундах + #опциональный параметр + #по умолчанию - 5000 + #тип - целое число + #используется при создании и обновлении + #inter = 5000 + + #интервал между проверками доступности сервера после восстановления, в миллисекундах + #опциональный параметр + #по умолчанию - 10000 + #тип - целое число + #используется при создании и обновлении + #downinter = 1000 + + #кол-во проверок, которые сервер должен успешно пройти + #опциональный параметр + #тип - целое число + #по умолчанию - 2 + #используется при создании и обновлении + #rise = 2 + + #кол-во проверок, которые сервер может не пройти и после этого получить статус "unavailable" + #опциональный параметр + #по умолчанию - 2 + #тип - целое число + #используется при создании и обновлении + #fall = 2 + + #кол-во миллисекунд - время между получением сервера статуса "available" и открытием соединений + #опциональный параметр + #по умолчанию - 60000 + #тип - целое число + #используется при создании и обновлении + #slowstart = 60000 + + #максимальное кол-во соединений сервера, при достижении этого кол-ва, сервер выходит из схемы балансирования + #опциональный параметр + #по умолчанию - 250 + #тип - целое число + #используется при создании и обновлении + #maxconn = 250 + + #максимальное кол-во соединений в очереди сервера, при достижении этого кол-ва, соединения будут перенаправлены на другой сервер + #опциональный параметр + #по умолчанию - 256 + #тип - целое число + #используется при создании и обновлении + #maxqueue = 256 + + #вес сервера для балансировки + #опциональный параметр + #мин - 0 + #макс - 255 + #по умолчанию - 100 + #тип - целое число + #используется при создании и обновлении + #weight = 100 + +} + +output "test" { + value = decort_cb_lb_backend.lbb +} diff --git a/samples/cloudbroker/lb/resource_lb_backend_server/main.tf b/samples/cloudbroker/lb/resource_lb_backend_server/main.tf new file mode 100644 index 00000000..34c3036b --- /dev/null +++ b/samples/cloudbroker/lb/resource_lb_backend_server/main.tf @@ -0,0 +1,134 @@ +/* +Пример использования +Ресурса load balancer backend server +Ресурс позволяет: +1. Создавать server +2. Редактировать server +3. Удалять server +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_lb_backend_server" "lbbs" { + #id балансировщика нагрузки + #обязательный параметр + #тип - целое число + #используется при создании + lb_id = 668 + + #имя бекенда для создания сервера + #обязательный параметр + #тип - строка + #используется при создании + backend_name = "testBackend" + + #имя сервера + #обязательный параметр + #тип - строка + #используется при создании + name = "testServer" + + #ip адрес сервера + #обязательный параметр + #тип - строка + #используется при создании + address = "192.168.5.33" + + #порт сервера + #обязательный параметр + #тип - целое число + #используется при создании + port = 6553 + + #проверка доступности сервера + #опциональный параметр + #доступные значения - "disabled", "enabled" + #по умолчанию - "enabled" + #тип - строка + #используется при создании + #check = "enabled" + + #интервал между проверками, в миллисекундах + #опциональный параметр + #по умолчанию - 5000 + #тип - целое число + #используется при создании и обновлении + #inter = 5000 + + #интервал между проверками доступности сервера после восстановления, в миллисекундах + #опциональный параметр + #по умолчанию - 10000 + #тип - целое число + #используется при создании и обновлении + #downinter = 1000 + + #кол-во проверок, которые сервер должен успешно пройти + #опциональный параметр + #по умолчанию - 2 + #тип - целое число + #используется при создании и обновлении + #rise = 2 + + #кол-во проверок, которые сервер может не пройти и после этого получить статус "unavailable" + #опциональный параметр + #по умолчанию - 2 + #тип - целое число + #используется при создании и обновлении + #fall = 2 + + #кол-во миллисекунд - время между получением сервера статуса "available" и открытием соединений + #опциональный параметр + #по умолчанию - 60000 + #тип - целое число + #используется при создании и обновлении + #slowstart = 60000 + + #максимальное кол-во соединений сервера, при достижении этого кол-ва, сервер выходит из схемы балансирования + #опциональный параметр + #по умолчанию - 250 + #тип - целое число + #используется при создании и обновлении + #maxconn = 250 + + #максимальное кол-во соединений в очереди серевера, при достижении этого кол-ва, соединения будут перенаправлены на другой сервер + #опциональный параметр + #по умолчанию - 256 + #тип - целое число + #используется при создании и обновлении + #maxqueue = 256 + + #вес сервера для балансировки + #опциональный параметр + #мин - 0 + #макс - 255 + #по умолчанию - 100 + #тип - целое число + #используется при создании и обновлении + #weight = 100 + +} + +output "test" { + value = decort_cb_lb_backend_server.lbbs +} diff --git a/samples/cloudbroker/lb/resource_lb_frontend/main.tf b/samples/cloudbroker/lb/resource_lb_frontend/main.tf new file mode 100644 index 00000000..3f217769 --- /dev/null +++ b/samples/cloudbroker/lb/resource_lb_frontend/main.tf @@ -0,0 +1,55 @@ +/* +Пример использования +Ресурса load balancer frontend +Ресурс позволяет: +1. Создавать frontend +2. Удалять frontend +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_lb_frontend" "lb" { + #id балансировщика нагрузки + #обязательный параметр + #тип - целое число + #используется при создании + lb_id = 668 + + #имя бекенда для создания фронтенда + #обязательный параметр + #тип - строка + #используется при создании + backend_name = "testBackend" + + #имя фронтенда + #обязательный параметр + #тип - строка + #используется при создании + name = "testFrontend" + +} + +output "test" { + value = decort_cb_lb_frontend.lb +} diff --git a/samples/cloudbroker/lb/resource_lb_frontend_bind/main.tf b/samples/cloudbroker/lb/resource_lb_frontend_bind/main.tf new file mode 100644 index 00000000..ee8802f6 --- /dev/null +++ b/samples/cloudbroker/lb/resource_lb_frontend_bind/main.tf @@ -0,0 +1,68 @@ +/* +Пример использования +Ресурса load balancer frontend bind (привязка фронтенда балансировщика нагрузки) +Ресурс позволяет: +1. Создавать привязку +2. Редактировать привязку +3. Удалять привязку +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_lb_frontend_bind" "lbfb" { + #id балансировщика нагрузки + #обязательный параметр + #тип - целое число + #используется при создании + lb_id = 668 + + #имя фронтенда для создания привязки + #обязательный параметр + #тип - строка + #используется при создании + frontend_name = "testFrontend" + + #наименование привязки + #обязательный параметр + #тип - строка + #используется при создании + name = "testBinding" + + #адрес привязки фронтенда + #обязательный параметр + #тип - строка + #используется при создании и обновлении + address = "111.111.111.111" + + #порт для привязки фронтенда + #обязательный параметр + #тип - целое число + #используется при создании и обновлении + port = 1111 + +} + +output "test" { + value = decort_cb_lb_frontend_bind.lbfb +} diff --git a/samples/cloudbroker/node/data_node/main.tf b/samples/cloudbroker/node/data_node/main.tf new file mode 100644 index 00000000..b8bcffd6 --- /dev/null +++ b/samples/cloudbroker/node/data_node/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о ноде платформы +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_node" "node" { + #id ноды + #обязательный параметр + #тип - целое число + node_id = 12 +} + +output "test" { + value = data.decort_cb_node.node +} diff --git a/samples/cloudbroker/node/data_node_list/main.tf b/samples/cloudbroker/node/data_node_list/main.tf new file mode 100644 index 00000000..a195b805 --- /dev/null +++ b/samples/cloudbroker/node/data_node_list/main.tf @@ -0,0 +1,90 @@ +/* +Пример использования +Получение списка нод платформы +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_node_list" "nodes" { + #фильтр по id ноды + #опциональный параметр + #тип - целое число + #by_id = 1234 + + #фильтр по имени ноды + #опциональный параметр + #тип - строка + #name = "node1" + + #фильтр по версии ноды + #опциональный параметр + #тип - строка + #version = "version1" + + #фильтр по релизу ноды + #опциональный параметр + #тип - строка + #release = "release1" + + #фильтр по sep id + #опциональный параметр + #тип - целое число + #sep_id = 12 + + #фильтр по ролям ноды + #опциональный параметр + #тип - строка + #role = "service" + + #фильтр по статусу ноды + #опциональный параметр + #тип - строка + #status = "disabled" + + #фильтр по id зоны + #опциональный параметр + #значение по умолчанию - 0 + #тип - целое число + #zone_id = 54 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 3 +} + +output "test" { + value = data.decort_cb_node_list.nodes +} diff --git a/samples/cloudbroker/node/data_node_network_info/main.tf b/samples/cloudbroker/node/data_node_network_info/main.tf new file mode 100644 index 00000000..f81d4c9a --- /dev/null +++ b/samples/cloudbroker/node/data_node_network_info/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение сетевой информации ноды +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_node_network_info" "network_info" { + #id ноды + #обязательный параметр + #тип - целое число + node_id = 100 +} + +output "output" { + value = data.decort_cb_node_network_info.network_info +} diff --git a/samples/cloudbroker/node/data_node_pci_devices/main.tf b/samples/cloudbroker/node/data_node_pci_devices/main.tf new file mode 100644 index 00000000..710afd46 --- /dev/null +++ b/samples/cloudbroker/node/data_node_pci_devices/main.tf @@ -0,0 +1,58 @@ +/* +Пример использования +Получение списка PCI-устройств ноды +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_node_pci_devices" "pci_devices" { + #id ноды + #обязательный параметр + #тип - целое число + node_id = 100 + + #строка поиска + #опциональный параметр + #тип - строка + #search = "nvidia" + + #сортировка по полю, формат +|-(поле) + #опциональный параметр + #тип - строка + #sort_by = "+product_name" + + #номер страницы + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 10 +} + +output "output" { + value = data.decort_cb_node_pci_devices.pci_devices +} diff --git a/samples/cloudbroker/pcidevice/data_pcidevice/main.tf b/samples/cloudbroker/pcidevice/data_pcidevice/main.tf new file mode 100644 index 00000000..2026fe2d --- /dev/null +++ b/samples/cloudbroker/pcidevice/data_pcidevice/main.tf @@ -0,0 +1,40 @@ +/* +Пример использования +Получение информации об устройстве +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +data "decort_cb_pcidevice" "pd" { + #id устройства + #обязательный параметр + #тип - целое число + device_id = 85 + +} + +output "test" { + value = data.decort_cb_pcidevice.pd +} diff --git a/samples/cloudbroker/pcidevice/data_pcidevice_list/main.tf b/samples/cloudbroker/pcidevice/data_pcidevice_list/main.tf new file mode 100644 index 00000000..8290fbe0 --- /dev/null +++ b/samples/cloudbroker/pcidevice/data_pcidevice_list/main.tf @@ -0,0 +1,69 @@ +/* +Пример использования +Получение информации обо всех доступных устройствах +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_pcidevice_list" "pdl" { + #фильтр по id устройства + #опциональный параметр + #тип - целое число + #by_id = 111 + + #фильтр по id compute + #опциональный параметр + #тип - целое число + #compute_id = 123 + + #фильтр по имени устройства + #опциональный параметр + #тип - строка + #name = "name" + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 111 + + #фильтр по статусу устройства + #опциональный параметр + #тип - строка + #status = "status" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 3 + +} + +output "test" { + value = data.decort_cb_pcidevice_list.pdl.items +} diff --git a/samples/cloudbroker/pcidevice/resource_pcidevice/main.tf b/samples/cloudbroker/pcidevice/resource_pcidevice/main.tf new file mode 100644 index 00000000..4b799f9d --- /dev/null +++ b/samples/cloudbroker/pcidevice/resource_pcidevice/main.tf @@ -0,0 +1,92 @@ +/* +Пример использования +Ресурса pdidevice +Ресурс позволяет: +1. Создавать устройство +2. Редактировать устройство +3. Удалять устройство +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_pcidevice" "pd" { + #имя устройства + #обязательный параметр + #тип - строка + #используется при создании + name = "test_device" + + #путь до устройства + #обязательный параметр + #тип - строка + #используется при создании + hw_path = "0000:01:00.0" + + #описание устройства + #опциональный параметр + #тип - строка + #используется при создании + #description = "test desc" + + #id ресурсной группы устройства + #обязательный параметр + #тип - целое число + #используется при создании + rg_id = 1111 + + #id ноды устройства + #обязательный параметр + #тип - целое число + #используется при создании + node_id = 11 + + #доступность устройства + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enable = false + + #принудительное отключение устройства + #опциональный параметр + #может использоваться на созданном ресурсе + #тип - булев + #используется при обновлении + #force_disable = true + + #принудительное удаление устройства + #опциональный параметр + #тип - булев + #используется при удалении + #force_delete = true + + #id устройства + #опциональный параметр + #позволяет "восстановить" состояние ресурса терраформа на локальной машине + #тип - целое число + #device_id = 86 +} + +output "test" { + value = decort_cb_pcidevice.pd +} diff --git a/samples/cloudbroker/rg/data_rg/main.tf b/samples/cloudbroker/rg/data_rg/main.tf new file mode 100644 index 00000000..d58d281b --- /dev/null +++ b/samples/cloudbroker/rg/data_rg/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации о ресурсной группе (RG) +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg" "rg" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 1022 +} + +output "output" { + value = data.decort_cb_rg.rg +} diff --git a/samples/cloudbroker/rg/data_rg_affinity_group_computes/main.tf b/samples/cloudbroker/rg/data_rg_affinity_group_computes/main.tf new file mode 100644 index 00000000..04d585a9 --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_affinity_group_computes/main.tf @@ -0,0 +1,42 @@ +/* +Пример использования +Получение информации о специальной группе компьютов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} */ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_affinity_group_computes" "lc" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #название специальной группы компьютов + #обязательный параметр + #тип - строка + affinity_group = "TEST" +} + +output "output" { + value = data.decort_cb_rg_affinity_group_computes.lc +} diff --git a/samples/cloudbroker/rg/data_rg_affinity_groups_get/main.tf b/samples/cloudbroker/rg/data_rg_affinity_groups_get/main.tf new file mode 100644 index 00000000..2745847e --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_affinity_groups_get/main.tf @@ -0,0 +1,42 @@ +/* +Пример использования +Получение информации о списке компьютов из определенной группы +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} */ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_affinity_groups_get" "get_groups" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #название специальной группы компьютов + #обязательный параметр + #тип - строка + affinity_group = "TEST" +} + +output "output" { + value = data.decort_cb_rg_affinity_groups_get.get_groups +} diff --git a/samples/cloudbroker/rg/data_rg_affinity_groups_list/main.tf b/samples/cloudbroker/rg/data_rg_affinity_groups_list/main.tf new file mode 100644 index 00000000..5208435e --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_affinity_groups_list/main.tf @@ -0,0 +1,49 @@ +/* +Пример использования +Получение информации о списке специальных групп компьютов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} */ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_affinity_groups_list" "list_groups" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output" { + value = data.decort_cb_rg_affinity_groups_list.list_groups +} diff --git a/samples/cloudbroker/rg/data_rg_audits/main.tf b/samples/cloudbroker/rg/data_rg_audits/main.tf new file mode 100644 index 00000000..09a863c3 --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_audits/main.tf @@ -0,0 +1,42 @@ +/*Deprecated + +Данный datasource является **deprecated** и будет удалён в следующих версиях. Вместо него неоходимо использовать datasource **decort_cb_audit_list**. +*/ + +/* +Пример использования +Получение информации о списке аудитов ресурсной группы +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} */ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_audits" "rg_audits" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 1022 +} + +output "output" { + value = data.decort_cb_rg_audits.rg_audits +} diff --git a/samples/cloudbroker/rg/data_rg_get_resource_consumption/main.tf b/samples/cloudbroker/rg/data_rg_get_resource_consumption/main.tf new file mode 100644 index 00000000..5e48e70f --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_get_resource_consumption/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение списка текущего потребления ресурсов ресурсной группы +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://alpha.dev.decs.online" + #oauth2_url = + oauth2_url = "https://sso-alpha.dev.decs.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_resource_consumption_get" "rc_get" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 111 +} + +output "test" { + value = data.decort_cb_rg_resource_consumption_get.rc_get +} + diff --git a/samples/cloudbroker/rg/data_rg_list/main.tf b/samples/cloudbroker/rg/data_rg_list/main.tf new file mode 100644 index 00000000..7930252b --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_list/main.tf @@ -0,0 +1,89 @@ +/* +Пример использования +Получение информации о списке всех ресурсных групп к которым есть доступ +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} */ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_list" "rg_list" { + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка ресурсных групп + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "test" + + #фильтр по времени создания (после указанного времени) + #опциональный параметр + #тип - целое число + #created_after = 123 + + #фильтр по времени создания (перед указанным временем) + #опциональный параметр + #тип - целое число + #created_before = 123 + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #отображать удаленные ресурсные группы или нет + #опциональный параметр + #тип - булев + #по умолчанию - false + #includedeleted = false + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 2 +} + +output "output" { + value = data.decort_cb_rg_list.rg_list +} diff --git a/samples/cloudbroker/rg/data_rg_list_computes/main.tf b/samples/cloudbroker/rg/data_rg_list_computes/main.tf new file mode 100644 index 00000000..e5eb7c6d --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_list_computes/main.tf @@ -0,0 +1,96 @@ +/* +Пример использования +Получение информации о списке компьютов в ресурсной группе +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_list_computes" "list_computes" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #фильтр по id compute + #опциональный параметр + #тип - целое число + #compute_id = 100 + + #фильтр по имени compute + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 100 + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STARTED" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по ip address + #опциональный параметр + #тип - строка + #ip_address = "1.1.1.1.1" + + #фильтр по имени внешней сети + #опциональный параметр + #тип - строка + #extnet_name = "test" + + #фильтр по id внешней сети + #опциональный параметр + #тип - целое число + #extnet_id = 100 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output" { + value = data.decort_cb_rg_list_computes.list_computes +} diff --git a/samples/cloudbroker/rg/data_rg_list_deleted/main.tf b/samples/cloudbroker/rg/data_rg_list_deleted/main.tf new file mode 100644 index 00000000..27c7fed2 --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_list_deleted/main.tf @@ -0,0 +1,85 @@ +/* +Пример использования +Получение информации о списке удаленных ресурсных групп +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_list_deleted" "list_deleted" { + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени ресурсной группы + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка ресурсных групп + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по имени аккаунта + #опциональный параметр + #тип - строка + #account_name = "test" + + #фильтр по времени создания (после указанного времени) + #опциональный параметр + #тип - целое число + #created_after = 123 + + #фильтр по времени создания (перед указанным временем) + #опциональный параметр + #тип - целое число + #created_before = 123 + + #фильтр по lock status + #опциональный параметр + #тип - строка + #lock_status = "UNLOCKED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 2 +} + +output "output" { + value = data.decort_cb_rg_list_deleted.list_deleted +} diff --git a/samples/cloudbroker/rg/data_rg_list_lb/main.tf b/samples/cloudbroker/rg/data_rg_list_lb/main.tf new file mode 100644 index 00000000..b3ec00b9 --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_list_lb/main.tf @@ -0,0 +1,87 @@ +/* +Пример использования +Получение информации о списке балансировщиков в ресурсной группе +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_list_lb" "list_lb" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #фильтр по id балансировщика нагрузки + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени балансировщика нагрузки + #опциональный параметр + #тип - строка + #name = "test" + + #фильтр по техническому статусу + #опциональный параметр + #тип - строка + #tech_status = "STOPPED" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтр по IP front + #опциональный параметр + #тип - строка + #front_ip = "1.1.1.1" + + #фильтр по IP back + #опциональный параметр + #тип - строка + #back_ip = "1.1.1.1" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 +} + +output "output" { + value = data.decort_cb_rg_list_lb.list_lb +} diff --git a/samples/cloudbroker/rg/data_rg_list_pfw/main.tf b/samples/cloudbroker/rg/data_rg_list_pfw/main.tf new file mode 100644 index 00000000..7a25155c --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_list_pfw/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации о списке правил переадресации портов для ресурсной группы. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_list_pfw" "list_pfw" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 +} + +output "output" { + value = data.decort_cb_rg_list_pfw.list_pfw +} diff --git a/samples/cloudbroker/rg/data_rg_list_vins/main.tf b/samples/cloudbroker/rg/data_rg_list_vins/main.tf new file mode 100644 index 00000000..5d44dfcb --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_list_vins/main.tf @@ -0,0 +1,77 @@ +/* +Пример использования +Получение информации о списке винсов в ресурсной группе +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_list_vins" "list_vins" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 + + #фильтр по id vins + #опциональный параметр + #тип - целое число + #vins_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка балансировщиков нагрузки + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по IP внешней сети + #опциональный параметр + #тип - строка + #ext_ip = "test" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 +} + +output "output" { + value = data.decort_cb_rg_list_vins.list_vins +} diff --git a/samples/cloudbroker/rg/data_rg_resource_consumption_list/main.tf b/samples/cloudbroker/rg/data_rg_resource_consumption_list/main.tf new file mode 100644 index 00000000..774a38f8 --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_resource_consumption_list/main.tf @@ -0,0 +1,37 @@ +/* +Пример использования +Получение списка текущего потребления ресурсов +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://alpha.dev.decs.online" + #oauth2_url = + oauth2_url = "https://sso-alpha.dev.decs.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_resource_consumption_list" "rc_list" { + #нет входных параметров +} + +output "test" { + value = data.decort_cb_rg_resource_consumption_list.rc_list +} + diff --git a/samples/cloudbroker/rg/data_rg_usage/main.tf b/samples/cloudbroker/rg/data_rg_usage/main.tf new file mode 100644 index 00000000..e27020ef --- /dev/null +++ b/samples/cloudbroker/rg/data_rg_usage/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации об использовании ресурсов в ресурсной группе +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_rg_usage" "rg_usage" { + #id ресурсной группы + #обязательный параметр + #тип - целое число + rg_id = 123 +} + +output "output" { + value = data.decort_cb_rg_usage.rg_usage +} diff --git a/samples/cloudbroker/rg/resource_rg/main.tf b/samples/cloudbroker/rg/resource_rg/main.tf new file mode 100644 index 00000000..3848d083 --- /dev/null +++ b/samples/cloudbroker/rg/resource_rg/main.tf @@ -0,0 +1,228 @@ +/* +Пример использования +Ресурсов RG +Ресурс позволяет: +1. Создавать RG +2. Редактировать RG +3. Удалять RG +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_rg" "rg" { + #имя ресурсной группы + #обязательный параметр + #тип - строка + #используется при создании и обновлении + rg_name = "testing_rg_1" + + #id аккаунта которому будет принадлежать ресурсная группа + #обязательный параметр + #тип - целое число + #используется при создании + account_id = 123 + + #id сети + #обязательный параметр + #тип - целое число + #используется при создании + gid = 1234 + + #лимиты ресурсов + #опциональные параметры + #тип - блок лимитов на ресурсы + #используется при создании и обновлении + #resource_limits { + #максимальное количество ядер cpu + #опциональный параметр + #тип - целое число + #cu_c = 12 + + #максимальный размер агрегированных виртуальных дисков в ГБ + #опциональный параметр + #тип - целое число + #cu_dm = 12 + + #максимальное количество назначенных общедоступных IP-адресов + #опциональный параметр + #тип - целое число + #cu_i = 12 + + #максимальный объем памяти в МБ + #опциональный параметр + #тип - целое число + #cu_m = 12 + #} + + #имя владельца ресурсной группы + #опциональный параметр + #тип - строка + #используется при создании + #owner = "owner name" + + #тип сети по умолчанию для этой ресурсной группы. + #виртуальные машины, созданные в этой RG, по умолчанию будут подключены к этой сети. + #допустимые значения: PRIVATE, PUBLIC, NONE. + #опциональный параметр + #по умолчанию: PRIVATE + #тип - строка + #используется при создании + #def_net_type = "NONE" + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #description = "qwerty" + + #id внешней сети + #опциональный параметр + #тип - целое число + #используется при создании + #ext_net_id = 123 + + #ip внешней сети + #опциональный параметр + #тип - строка + #используется при создании + #ext_ip = "1.1.1.1" + + #список названий pools + #опциональный параметр + #тип - массив строк + #используется при создании и обновлении + #uniq_pools = ["sep1_poolName1", "sep2_poolName2"] + + #блок для предоставления прав на ресурсную группу + #опциональный параметр + #тип - блок прав пользователя + #используется при создании и обновлении + #access { + #имя юзера предоставляемому права + #обязательный параметр при использовании блока + #тип - строка + #user = "kasim_baybikov_1@decs3o" + + #тип прав + #обязательный параметр + #тип - строка + #разрешенные значения: "R", "RCX" or "ARCXDU" + #right = "RCX" + #} + + #установить сеть по умолчанию + #опциональный параметр + #тип - блок конфигурации сети + #при добавлении блока, удалять его нельзя + #используется при создании + #def_net { + #тип сети + #обязательный параметр при использовании блока + #тип - строка + #net_type = "PUBLIC" + + #id сети + #идентификатор сегмента сети. Если net_type — PUBLIC, а net_id — 0, + #то будет выбран сегмент внешней сети по умолчанию. Если net_type + #имеет значение PRIVATE и net_id=0, будет выбран первый vins, определенный для этой ресурсной группы. + #в противном случае net_id идентифицирует либо существующий сегмент внешней сети, либо vins. + #опциональный параметр + #тип - целое число + #net_id = 1234 + #} + + #может ли запуститься ВМ, если ресурсов CPU недостаточно + #опциональный параметр + #допустимые значения: strict, loose. + #тип - строка + #используется при создании и обновлении + #cpu_allocation_parameter = "loose" + + #cpu allocation ratio + #опциональный параметр + #one pCPU = ratio*vCPU (zero or positive value) + #тип - целое число + #используется при создании и обновлении + #cpu_allocation_ratio = 1 + + #флаг доступности ресурсной группы + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enable = true + + #флаг для восстановления удаленной ресурсной группы + #опциональный параметр + #тип - булев + #используется при обновлении + #restore = false + + #флаг для принудительного удаления ресурсной группы + #опциональный параметр + #тип - булев + #перед удалением следует перевести ресурсную группу в статус disabled, выставив enable = false + #используется при удалении + #force = true + + #флаг для удаления ресурсной группы, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = true + + #доступ к дополнительным функциям управления ВМ + #опциональный параметр + #возможные значенния - "hugepages", "numa", "cpupin", "vfnic", "dpdk, "changemac", "trunk" + #тип - массив строк + #внимание - требуется указывать итоговое желаемое состояние для ресурсной группы (рг), так как поле compute_features не будет автоматически + #наследоваться от аккаунта, в котором создается рг. + #используется при создании и обновлении + #compute_features = ["hugepages", "numa", "cpupin", "vfnic"] + + #идентификатор группы доступа SDN + #опциональный параметр + #тип - строка + #используется при создании + #sdn_access_group_id = "64e039f4-3705-4feb-84ff-a59fbdb1ebfe" + + #добавление/удаление политик хранения + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #storage_policy { + #id политики хранения + #обязательный параметр + #тип - целое число + #id = 8 + #лимит ресурсов хранения в ГБ + #опциональный параметр + #тип - целое число + #значение по умолчанию - -1 + #limit = 111 + #} +} + +output "output" { + value = decort_cb_rg.rg +} diff --git a/samples/cloudbroker/secgroup/data_security_group/main.tf b/samples/cloudbroker/secgroup/data_security_group/main.tf new file mode 100644 index 00000000..8797f4cb --- /dev/null +++ b/samples/cloudbroker/secgroup/data_security_group/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение списка security group +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_security_group" "sc" { + #идентификатор группы безопасности + #обязательный параметр + #тип - целое число + security_group_id = 1111 +} + +output "test" { + value = data.decort_cb_security_group.sc +} \ No newline at end of file diff --git a/samples/cloudbroker/secgroup/data_security_group_list/main.tf b/samples/cloudbroker/secgroup/data_security_group_list/main.tf new file mode 100644 index 00000000..937808d7 --- /dev/null +++ b/samples/cloudbroker/secgroup/data_security_group_list/main.tf @@ -0,0 +1,89 @@ +/* +Пример использования +Получение списка security group +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_security_group_list" "lsc" { + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы результата + #опциональный параметр + #тип - целое число + #size = 1 + + #фильтр по id + #опциональный параметр + #тип - целое число + #by_id = 1111 + + #фильтр по имени + #опциональный параметр + #тип - строка + #name = "storage_policy_name" + + #фильтр по описанию + #опциональный параметр + #тип - строка + #desc = "desc" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 1111 + + #фильтр по созданию до временной метки + #опциональный параметр + #тип - целое число + #created_min = 1111 + + #фильтр по созданию после временной метки + #опциональный параметр + #тип - целое число + #created_max = 1111 + + #фильтр по обновлению после временной метки + #опциональный параметр + #тип - целое число + #updated_min = 1111 + + #фильтр по обновлению до временной метки + #опциональный параметр + #тип - целое число + #updated_max = 1111 +} + +output "test" { + value = data.decort_cb_security_group_list.lsc +} diff --git a/samples/cloudbroker/secgroup/resource_security_group/main.tf b/samples/cloudbroker/secgroup/resource_security_group/main.tf new file mode 100644 index 00000000..d9aaaac6 --- /dev/null +++ b/samples/cloudbroker/secgroup/resource_security_group/main.tf @@ -0,0 +1,96 @@ +/* +Пример использования +Ресурса группы безопасности: +1. Создание ресурса +2. Изменение ресурса +3. Удаление ресурса +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_security_group" "name" { + #id аккаунта, которому принадлежит группа безопасности + #обязательный параметр + #тип - целое число + #используется при создании + account_id = 111 + + #название группы безопасности + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "NAME" + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #description = "desc" + + #правила + #опциональный параметр + #тип - блок + #используется при обновлении + #rules { + #направление движения + #обязательный параметр + #тип - строка + #возможные значения - inbound, outbound + #direction = "inbound" + + #версия протокола IP + #опциональный параметр + #тип - строка + #возможные значения - IPv4, IPv6 + #значение по умолчанию - IPv4 + #ethertype = "IPv4" + + #сетевой протокол + #опциональный параметр + #тип - строка + #возможные значения - icmp, tcp, udp + #protocol = "icmp" + + #номер начального порта (для TCP/UDP) + #опциональный параметр + #тип - целое число + #port_range_min = 11 + + #номер конечного порта (для TCP/UDP) + #опциональный параметр + #тип - целое число + #port_range_max = 15 + + #удаленный IP префикс в нотации CIDR + #опциональный параметр + #тип - строка + #remote_ip_prefix = "192.168.1.0/24" + + #} +} + +output "test" { + value = decort_cb_security_group.name +} \ No newline at end of file diff --git a/samples/cloudbroker/sep/data_available_sep_and_pools_list/main.tf b/samples/cloudbroker/sep/data_available_sep_and_pools_list/main.tf new file mode 100644 index 00000000..af42113f --- /dev/null +++ b/samples/cloudbroker/sep/data_available_sep_and_pools_list/main.tf @@ -0,0 +1,44 @@ +/* +Пример использования +Получение данных доступных sep и pools +*/ + +#Раскомментируйте код ниже, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_sep_and_pools_available_list" "ap" { + #идентификатор аккаунта + #обязательный параметр + #тип - целое число + account_id = 1111 + + #идентификатор ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 1111 +} + +output "test" { + value = data.decort_cb_sep_and_pools_available_list.ap +} + diff --git a/samples/cloudbroker/sep/data_sep/main.tf b/samples/cloudbroker/sep/data_sep/main.tf new file mode 100644 index 00000000..2360b313 --- /dev/null +++ b/samples/cloudbroker/sep/data_sep/main.tf @@ -0,0 +1,42 @@ +/* +Пример использования +Получение данных sep +*/ + +#Раскомментируйте код ниже, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_sep" "sd" { + #id sep + #обязательный параметр + #тип - целое число + sep_id = 1111 +} + +output "test" { + value = data.decort_cb_sep.sd +} + +output "config" { + value = jsondecode(data.decort_cb_sep.sd.config) +} diff --git a/samples/cloudbroker/sep/data_sep_config/main.tf b/samples/cloudbroker/sep/data_sep_config/main.tf new file mode 100644 index 00000000..7c06d3bf --- /dev/null +++ b/samples/cloudbroker/sep/data_sep_config/main.tf @@ -0,0 +1,42 @@ +/* +Пример использования +Получение данных конфигурации sep +*/ + +#Раскомментируйте код ниже, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_sep_config" "sc" { + #id sep + #обязательный параметр + #тип - целое число + sep_id = 1111 +} + +output "test" { + value = data.decort_cb_sep_config.sc +} + +output "config" { + value = jsondecode(data.decort_cb_sep_config.sc.config) +} diff --git a/samples/cloudbroker/sep/data_sep_consumption/main.tf b/samples/cloudbroker/sep/data_sep_consumption/main.tf new file mode 100644 index 00000000..9279bf50 --- /dev/null +++ b/samples/cloudbroker/sep/data_sep_consumption/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение общих данных об использовании sep +*/ + +#Раскомментируйте код ниже, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_sep_consumption" "scons" { + #id sep + #обязательный параметр + #тип - целое число + sep_id = 1111 +} + +output "test" { + value = data.decort_cb_sep_consumption.scons +} diff --git a/samples/cloudbroker/sep/data_sep_disk_list/main.tf b/samples/cloudbroker/sep/data_sep_disk_list/main.tf new file mode 100644 index 00000000..af572c57 --- /dev/null +++ b/samples/cloudbroker/sep/data_sep_disk_list/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение данных об используемых sep дисках +*/ + +#Раскомментируйте код ниже, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_sep_disk_list" "sdl" { + #id sep + #обязательный параметр + #тип - целое число + sep_id = 1111 + + #sep pool name + #опциональный параметр + #тип - строка + #pool_name = "sep_pool" +} + +output "test" { + value = data.decort_cb_sep_disk_list.sdl +} diff --git a/samples/cloudbroker/sep/data_sep_list/main.tf b/samples/cloudbroker/sep/data_sep_list/main.tf new file mode 100644 index 00000000..0a6b8669 --- /dev/null +++ b/samples/cloudbroker/sep/data_sep_list/main.tf @@ -0,0 +1,89 @@ +/* +Пример использования +Получение списка sep +*/ + +#Раскомментируйте код ниже, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_sep_list" "sl" { + #фильтр по sep id + #опциональный параметр + #тип - целое число + #by_id = 3 + + #фильтр по sep name + #опциональный параметр + #тип - строка + #name = "name" + + #фильтр по gid + #опциональный параметр + #тип - целое число + #gid = 1 + + #фильтр по sep type + #опциональный параметр + #тип - строка + #type = "type" + + #фильтр по provided physical node id + #опциональный параметр + #тип - целое число + #provided_by = 1 + + #фильтр по тех статусу + #опциональный параметр + #тип - строка + #tech_status = "status" + + #фильтр по consumed physical node id + #опциональный параметр + #тип - целое число + #consumed_by = 1 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #страница + #опциональный параметр + #тип - целое число + #page = 3 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 2 + + #сортировка по списку идентификаторов SEP + #опциональный параметр + #тип - массив целых чисел + #sep_ids = [2, 4, 5] +} + +output "test" { + value = data.decort_cb_sep_list.sl +} diff --git a/samples/cloudbroker/sep/data_sep_pool/main.tf b/samples/cloudbroker/sep/data_sep_pool/main.tf new file mode 100644 index 00000000..33384327 --- /dev/null +++ b/samples/cloudbroker/sep/data_sep_pool/main.tf @@ -0,0 +1,45 @@ +/* +Пример использования +Получение данных sep pool +*/ + +#Раскомментируйте код ниже, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_sep_pool" "sp" { + #id sep + #обязательный параметр + #тип - целое число + sep_id = 1111 + + #sep pool name + #обязательный параметр + #тип - строка + pool_name = "sep_pool" +} + +output "pool" { + value = { + for k, v in data.decort_cb_sep_pool.sp.pool : k => v + } +} \ No newline at end of file diff --git a/samples/cloudbroker/sep/data_sep_template/main.tf b/samples/cloudbroker/sep/data_sep_template/main.tf new file mode 100644 index 00000000..666ffb1f --- /dev/null +++ b/samples/cloudbroker/sep/data_sep_template/main.tf @@ -0,0 +1,45 @@ +/* +Пример использования +Получение данных конфигурации sep +*/ + +#Раскомментируйте код ниже, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_sep_template" "compute_template" { + #тип сеп + #возможные значения - des, hitachi, dorado, tatlin, shared, local, ustor + #обязательный параметр + #тип - строка + sep_type = "dorado" + + #язык + #возможные значения - ru, en + #обязательный параметр + #тип - строка + lang = "en" +} + +output "output" { + value = data.decort_cb_sep_template.compute_template +} diff --git a/samples/cloudbroker/sep/resource_sep/main.tf b/samples/cloudbroker/sep/resource_sep/main.tf new file mode 100644 index 00000000..4bc5c21d --- /dev/null +++ b/samples/cloudbroker/sep/resource_sep/main.tf @@ -0,0 +1,167 @@ +/* +Пример использования +Ресурса sep +Ресурс позволяет: +1. Создавать sep. +2. Удалять sep. +*/ + +#Раскомментируйте код ниже, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_sep" "s" { + #grid id + #обязательный параметр + #тип - целое число + #используется при создании + gid = 212 + + #sep name + #обязательный параметр + #тип - строка + #используется при создании + name = "test sep" + + #тип sep + #обязательный параметр + #возможные значения - des, dorado, tatlin, hitachi, local, shared, ustor + #тип - строка + #используется при создании + type = "des" + + #конфигурация sep + #обязательный параметр + #представляет собой json-строку + #тип - строка + #используется при создании + config = file("./config.json") + + #описание sep + #опциональный параметр + #тип - строка + #используется при создании + #desc = "rrrrr" + + #предоставление/отключение доступа указанных аккаунтов к sep + #deprecated, поле скоро будет удалено + #опциональный параметр + #тип - массив целых чисел + #используется при создании + #account_ids = [12, 245] + + #предоставление/отключение доступа к пулу на sep + #deprecated, поле скоро будет удалено + #опциональный параметр + #тип - блок доступа к пулу + #используется при создании + #access_to_pool { + #имя pool + #обязательный параметр + #тип - строка + #pool_name = "pool name" + + #id аккаунта + #опциональный параметр + #тип - целое число + #account_id_pool = 123 + + #id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 1234 + #} + + #доступность sep + #опциональный параметр + #по умолчанию - false + #тип - булев + #используется при создании + #enable = false + + #использование нодами + #опциональный параметр + #тип - массив целых чисел + #используется при создании + #consumed_by = [] + + #id provided nodes + #опциональный параметр + #тип - массив целых чисел + #используется при создании + #provided_by = [16, 14, 15] + + #добавление/удаление pools к/из sep + #опциональный параметр + #тип - блок pools + #используется при создании + #pools { + #идентификаторы учетных записей доступа + #обязательный параметр + #тип - массив целых чисел + #access_account_ids = [1, 2, 3] + + #идентификаторы групп ресурсов доступа + #обязательный параметр + #тип - массив целых чисел + #access_res_group_ids = [10, 20, 30] + + #имя пула + #опциональный параметр + #тип - строка + #name = "example_pool_name" + + #тип пула + #опциональный параметр + #тип - массив строк + #types = ["type1", "type2"] + + #адреса узлов хранения + #опциональный параметр + #тип - блок ip адресов + #uris { + #ip адрес узла + #обязательный параметр + #тип - строка + #ip = "192.168.1.1" + + #порт узла + #обязательный параметр + #тип - целое число + #port = 8080 + #} + + #доступный объем пула + #обязательный параметр + #тип - целое число + #usage_limit = 1000 + #} + +} + +output "test" { + value = decort_cb_sep.s +} + +output "config" { + value = jsondecode(decort_cb_sep.s.config) +} diff --git a/samples/cloudbroker/sep/resource_sep_config/main.tf b/samples/cloudbroker/sep/resource_sep_config/main.tf new file mode 100644 index 00000000..333a6e52 --- /dev/null +++ b/samples/cloudbroker/sep/resource_sep_config/main.tf @@ -0,0 +1,76 @@ +/* +Пример использования +Ресурс конфигурации sep +Ресурс позволяет: +1. Получить конфигурацию +2. Изменять конфигурацию +3. Изменять отдельные поля конфигурации +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_sep_config" "sc" { + #id sep + #обязательный параметр + #тип - целое число + #используется при создании + sep_id = 1111 + + #конфигурация + #опциональный параметр + #тип - json строка + #используется при обновлении + #config = file("./config.json") + + #редактирование поля + #опциональный параметр + #тип - блок полей + #используется при обновлении + #field_edit { + #имя поля + #обязательный параметр + #тип - строка + #field_name = "edgeuser_password" + + #значение поля + #обязательный параметр + #тип - строка + #field_value = "shshs" + + #тип поля + #обязательный параметр + #возможные значения - int,bool, str, dict, list + #тип - строка + #field_type = "str" + #} + +} + +output "sep_config" { + value = decort_cb_sep_config.sc +} + +output "sep_config_json" { + value = jsondecode(decort_cb_sep_config.sc.config) +} diff --git a/samples/cloudbroker/stpolicy/data_storage_policy/main.tf b/samples/cloudbroker/stpolicy/data_storage_policy/main.tf new file mode 100644 index 00000000..df7442bf --- /dev/null +++ b/samples/cloudbroker/stpolicy/data_storage_policy/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о storage policy по её id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_storage_policy" "sp" { + #идентификатор политики хранения + #обязательный параметр + #тип - целое число + storage_policy_id = 1111 +} + +output "test" { + value = data.decort_cb_storage_policy.sp +} \ No newline at end of file diff --git a/samples/cloudbroker/stpolicy/data_storage_policy_list/main.tf b/samples/cloudbroker/stpolicy/data_storage_policy_list/main.tf new file mode 100644 index 00000000..8eb5487a --- /dev/null +++ b/samples/cloudbroker/stpolicy/data_storage_policy_list/main.tf @@ -0,0 +1,100 @@ +/* +Пример использования +Получение списка storage policy +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_storage_policy_list" "lsp" { + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы результата + #опциональный параметр + #тип - целое число + #size = 1 + + #фильтр по id + #опциональный параметр + #тип - целое число + #by_id = 1111 + + #фильтр по имени + #опциональный параметр + #тип - строка + #name = "storage_policy_name" + + #фильтр по статусу + #опциональный параметр + #тип - строка + #status = "status" + + #фильтр по описанию + #опциональный параметр + #тип - строка + #desc = "desc" + + #фильтр по лимиту iops + #опциональный параметр + #тип - целое число + #limit_iops = 1111 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #фильтр по id аккаунта + #опциональный параметр + #тип - целое число + #account_id = 1111 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #resgroup_id = 1111 + + #фильтр по id сеп + #опциональный параметр + #тип - целое число + #sep_id = 1111 + + #фильтр по имени пула + #опциональный параметр + #тип - строка + #pool_name = "name" + + #сортировка по статусу SEP + #опциональный параметр + #тип - строка + #возможные значения - ENABLED, DISABLED + #sep_tech_status = "ENABLED" +} + +output "test" { + value = data.decort_cb_storage_policy_list.lsp +} \ No newline at end of file diff --git a/samples/cloudbroker/stpolicy/resource_storage_policy/main.tf b/samples/cloudbroker/stpolicy/resource_storage_policy/main.tf new file mode 100644 index 00000000..654f9182 --- /dev/null +++ b/samples/cloudbroker/stpolicy/resource_storage_policy/main.tf @@ -0,0 +1,79 @@ +/* +Пример использования +Ресурса политики хранения: +1. Создание ресурса +2. Изменение ресурса +3. Удаление ресурса +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_storage_policy" "name" { + #название политики хранения + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "policy_name" + + #список доступов + #обязательный параметр + #тип - блок + #используется при создании и обновлении + access_seps_pools { + #id сепа + #обязательный параметр + #тип - целое число + sep_id = 11 + + #имя пула + #обязательный параметр + #тип - строка + pool_name = "name" + } + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #description = "desc" + + #максимальный лимит iops для дисков, использующих данную политику хранения + #опциональный параметр + #тип - целое число + #значение по умолчанию - 2000 + #используется при создании и обновлении + #limit_iops = 2000 + + #сделать доступной или отключить + #опциональный параметр + #тип - булев + #значение по умолчанию - true + #используется при обновлении + #enabled = true +} + +output "test" { + value = decort_cb_storage_policy.name +} \ No newline at end of file diff --git a/samples/cloudbroker/trunk/data_trunk/main.tf b/samples/cloudbroker/trunk/data_trunk/main.tf new file mode 100644 index 00000000..d14a7065 --- /dev/null +++ b/samples/cloudbroker/trunk/data_trunk/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных транка +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_trunk" "name" { + #идентификатор транка + #обязательный параметр + #тип - целое число + trunk_id = 1111 +} + +output "test" { + value = data.decort_cb_trunk.name +} \ No newline at end of file diff --git a/samples/cloudbroker/trunk/data_trunk_list/main.tf b/samples/cloudbroker/trunk/data_trunk_list/main.tf new file mode 100644 index 00000000..37d127ff --- /dev/null +++ b/samples/cloudbroker/trunk/data_trunk_list/main.tf @@ -0,0 +1,62 @@ +/* +Пример использования +Получение списка транковых портов. +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +data "decort_cb_trunk_list" "name" { + #фильтр по id транка + #опциональный параметр + #тип - массив целых чисел + #trunk_ids = [10,11] + + #фильтр по id учетных записей с доступом к транку + #опциональный параметр + #тип - массив целых чисел + #account_ids = [10,11] + + #фильтр по тегам транка (значение от 1 до 4095) + #опциональный параметр + #тип - строка + #trunk_tags = "4095" + + #сортировка по статусу + #опциональный параметр + #тип - строка + #status = "DISABLED" + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_cb_trunk_list.name +} \ No newline at end of file diff --git a/samples/cloudbroker/trunk/resource_trunk/main.tf b/samples/cloudbroker/trunk/resource_trunk/main.tf new file mode 100644 index 00000000..f354e685 --- /dev/null +++ b/samples/cloudbroker/trunk/resource_trunk/main.tf @@ -0,0 +1,87 @@ +/* +Пример использования +Ресурса транкового порта: +1. Создание ресурса +2. Изменение ресурса +3. Удаление ресурса +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_trunk" "name" { + #имя транка + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "trunk_name" + + #список тегов транка (значения от 1 до 4095) + #обязательный параметр + #тип - строка + #используется при создании и обновлении + trunk_tags = "4095" + + #имя моста ovs + #обязательный параметр + #тип - строка + #используется при создании + ovs_bridge = "ovs_bridge_name" + + #описание + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #description = "desc" + + #список идентификаторов учетных записей с доступом к этому транку + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #account_ids = [10,11] + + #идентификатор vlan + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #native_vlan_id = 123 + + #сделать доступным или отключить + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #по умолчанию - true + #enable = true + + #максимальная единица передачи + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #по умолчанию - 1500 + #mtu = 1500 +} + +output "test" { + value = decort_cb_trunk.name +} \ No newline at end of file diff --git a/samples/cloudbroker/user/data_user/main.tf b/samples/cloudbroker/user/data_user/main.tf new file mode 100644 index 00000000..782a7f45 --- /dev/null +++ b/samples/cloudbroker/user/data_user/main.tf @@ -0,0 +1,40 @@ +/* +Пример использования +Получение данных user по id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_user" "user" { + #id user + #обязательный параметр + #тип - строка + user_id = "" + +} + +output "test" { + value = data.decort_cb_user.user +} + diff --git a/samples/cloudbroker/user/data_user_get_audit/main.tf b/samples/cloudbroker/user/data_user_get_audit/main.tf new file mode 100644 index 00000000..af4e0e5b --- /dev/null +++ b/samples/cloudbroker/user/data_user_get_audit/main.tf @@ -0,0 +1,77 @@ +/* +Пример использования +Получение списка аудитов пользователя +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_user_get_audit" "audits" { + #имя пользователя + #опциональный параметр + #если не указано, выводит данные по текущему пользователю + #тип - строка + #username = "test_user" + + #фильтр по вызову api + #опциональный параметр + #тип - строка + #call = "restapi/user/get" + + #фильтр по статус коду ответа + #опциональный параметр + #тип - целое число + #status_code = 200 + + #фильтр по временной метке, после которой были сделаны запросы + #опциональный параметр + #тип - целое число + #timestamp_at = 123456 + + #фильтр по временной метке, до которой были сделаны запросы + #опциональный параметр + #тип - целое число + #timestamp_to = 123456 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #значение по умолчанию - -timestamp + #тип - строка + #sort_by = "-timestamp" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 3 + +} + +output "test" { + value = data.decort_cb_user_get_audit.audits +} diff --git a/samples/cloudbroker/user/data_user_list/main.tf b/samples/cloudbroker/user/data_user_list/main.tf new file mode 100644 index 00000000..fb50414c --- /dev/null +++ b/samples/cloudbroker/user/data_user_list/main.tf @@ -0,0 +1,70 @@ +/* +Пример использования +Получение списка пользователей +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_user_list" "users" { + #фильтр по id пользователя + #опциональный параметр + #тип - строка + #by_id = "test_user" + + #фильтр по активным пользователям + #опциональный параметр + #тип - булев + #active = true + + #фильтр по электронной почте + #опциональный параметр + #тип - строка + #email = "user@site.domen" + + #фильтр по сервисным аккаунтам + #опциональный параметр + #тип - булев + #service_account = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 3 + +} + +output "test" { + value = data.decort_cb_user_list.users +} diff --git a/samples/cloudbroker/user/resource_user/main.tf b/samples/cloudbroker/user/resource_user/main.tf new file mode 100644 index 00000000..a7a0afaa --- /dev/null +++ b/samples/cloudbroker/user/resource_user/main.tf @@ -0,0 +1,77 @@ +/* +Пример использования +Ресурса user +Ресурс позволяет: +1. Создавать пользователя +2. Изменять список apiaccess групп пользователя +3. Удалять пользователя +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://mr4.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_user" "user" { + #id пользователя + #обязательный параметр + #тип - строка + #используется при создании + username = "user1" + + #email адрес пользователя + #обязательный параметр + #тип - строка + #используется при создании + emailaddress = "user1@example.com" + + #пароль пользователя + #обязательный параметр + #тип - строка + #используется при создании + password = "user1Password" + + #список групп доступа к api, к которым принадлежит этот пользователь + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #apiaccess = [1,2] + + #заблокировать пользователя + #значение по умолчанию - false + #опциональный параметр + #тип - булев + #используется при обновлении + #blocked = false + + #провайдер + #опциональный параметр + #возможные значения - bvs, decs3o + #тип - строка + #используется при создании + #provider_name = "bvs" + +} + +output "test" { + value = decort_cb_user.user +} + diff --git a/samples/cloudbroker/vfpool/data_vfpool/main.tf b/samples/cloudbroker/vfpool/data_vfpool/main.tf new file mode 100644 index 00000000..5f09ff2d --- /dev/null +++ b/samples/cloudbroker/vfpool/data_vfpool/main.tf @@ -0,0 +1,40 @@ +/* +Пример использования +Получение информации о vfpool по его id +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vfpool" "vfpool" { + #идентификатор vfpool + #обязательный параметр + #тип - целое число + vfpool_id = 2 + +} + +output "test" { + value = data.decort_cb_vfpool.vfpool +} + diff --git a/samples/cloudbroker/vfpool/data_vfpool_list/main.tf b/samples/cloudbroker/vfpool/data_vfpool_list/main.tf new file mode 100644 index 00000000..d4ccb8bd --- /dev/null +++ b/samples/cloudbroker/vfpool/data_vfpool_list/main.tf @@ -0,0 +1,88 @@ +/* +Пример использования +Получение списка vfpool +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vfpool_list" "vfpool_list" { + #фильтрация списка для получения информации о конкретном vfpool по его id + #опциональный параметр + #тип - целое число + #by_id = 1 + + #фильтрация списка для получения информации о vfpool, которые принадлежат к определенному GRID + #опциональный параметр + #тип - целое число + #gid = 1 + + #фильтрация списка для получения информации о конкретном vfpool по его имени + #опциональный параметр + #тип - строка + #name = "alpha-cpu-04" + + #фильтрация списка для получения информации о конкретном vfpool по его описанию + #опциональный параметр + #тип - строка + #description = "some" + + #фильтрация списка для получения информации о vfpool, которые имеют соответствующий статус + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтрация списка для получения информации о vfpool, которые доступны конкретному аккаунту + #опциональный параметр + #тип - целое число + #account_access = 1 + + #фильтрация списка для получения информации о vfpool, которые доступны конкретной ресурсной группе + #опциональный параметр + #тип - целое число + #rg_access = 1 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #формат - "+поле" по возрастанию / "-поле" по убыванию + #тип - строка + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #page = 2 + + #размер страницы + #опциональный параметр + #если не задан - выводятся все доступные данные + #тип - целое число + #size = 3 + +} + +output "test" { + value = data.decort_cb_vfpool_list.vfpool_list +} + diff --git a/samples/cloudbroker/vfpool/resource_vfpool/main.tf b/samples/cloudbroker/vfpool/resource_vfpool/main.tf new file mode 100644 index 00000000..555b4fb5 --- /dev/null +++ b/samples/cloudbroker/vfpool/resource_vfpool/main.tf @@ -0,0 +1,90 @@ +/* +Пример использования +Ресурс позволяет: +1. Создавать пул виртуальных сетевых функций +2. Изменять список аккаунтов, которым доступен пул +3. Изменять список ресурсных групп, которым доступен пул +4. Изменять статус пула +5. Изменять наименование или описание пула +6. Изменять конфигурацию пула +7. Удалять пул +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_vfpool" "vfpool" { + #наименование vfpool + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "test" + + #описание vfpool + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #description = "some" + + #список для предоставления доступа к vfpool перечисленным аккаунтам + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #account_access = [1,2] + + #список для предоставления доступа к vfpool перечисленным ресурсным группам + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #rg_access = [1,2] + + #блок для указания списка конфигурации + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #config { + #идентификатор узла + #обязательный параметр + #тип - целое число + #node_id = 1 + + #имя верхнеуровневого сетевого интерфейса, VF которого входят в пул + #обязательный параметр + #тип - строка + #nic_name = "eth0" + + #список идентификаторов VF для NIC узла + #обязательный параметр + #тип - массив целых чисел + #vf_ids = [1,2] + #} + + #ручное подключение и отключение ресурса + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enable = true +} + + + diff --git a/samples/cloudbroker/vins/data_vins/main.tf b/samples/cloudbroker/vins/data_vins/main.tf new file mode 100644 index 00000000..d96a2aa9 --- /dev/null +++ b/samples/cloudbroker/vins/data_vins/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение данных о vins +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vins" "vins" { + #id желаемого vins + #обязательный параметр + #тип - целое число + vins_id = 10101 +} + +output "test" { + value = data.decort_cb_vins.vins +} diff --git a/samples/cloudbroker/vins/data_vins_audits/main.tf b/samples/cloudbroker/vins/data_vins_audits/main.tf new file mode 100644 index 00000000..643816ec --- /dev/null +++ b/samples/cloudbroker/vins/data_vins_audits/main.tf @@ -0,0 +1,43 @@ +/*Deprecated + +Данный datasource является **deprecated** и будет удалён в следующих версиях. Вместо него неоходимо использовать datasource **decort_cb_audit_list**. +*/ + +/* +Пример использования +Получение списка vins audits +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "" + source = "basis/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vins_audits" "vins_audits" { + #id желаемого vins + #обязательный параметр + #тип - целое число + vins_id = 10101 +} + +output "test" { + value = data.decort_cb_vins_audits.vins_audits +} diff --git a/samples/cloudbroker/vins/data_vins_ext_net_list/main.tf b/samples/cloudbroker/vins/data_vins_ext_net_list/main.tf new file mode 100644 index 00000000..43fe268a --- /dev/null +++ b/samples/cloudbroker/vins/data_vins_ext_net_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение списка vins extnet +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vins_ext_net_list" "vins_ext_net_list" { + #id желаемого vins + #обязательный параметр + #тип - целое число + vins_id = 10101 +} + +output "test" { + value = data.decort_cb_vins_ext_net_list.vins_ext_net_list +} diff --git a/samples/cloudbroker/vins/data_vins_ip_list/main.tf b/samples/cloudbroker/vins/data_vins_ip_list/main.tf new file mode 100644 index 00000000..24188026 --- /dev/null +++ b/samples/cloudbroker/vins/data_vins_ip_list/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение списка vins_ip +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vins_ip_list" "vins_ip_list" { + #id желаемого vins + #обязательный параметр + #тип - целое число + vins_id = 10101 +} + +output "test" { + value = data.decort_cb_vins_ip_list.vins_ip_list +} + diff --git a/samples/cloudbroker/vins/data_vins_list/main.tf b/samples/cloudbroker/vins/data_vins_list/main.tf new file mode 100644 index 00000000..7500d7cd --- /dev/null +++ b/samples/cloudbroker/vins/data_vins_list/main.tf @@ -0,0 +1,98 @@ +/* +Пример использования +Получение списка vins +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vins_list" "vl" { + #фильтр по id vins + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка vins + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по IP внешней сети + #опциональный параметр + #тип - строка + #ext_ip = "test" + + #фильтр по id vnfDevices + #опциональный параметр + #тип - целое число + #vnfdev_id = 11111 + + #включение удаленных vins в результат + #опциональный параметр + #тип - булев + #если не задан - выводятся все неудаленные данные + #include_deleted = true + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #поиск по статусу + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 1 + + #id зоны + #опциональный параметр + #тип - целое число + #значение по умолчанию - 0 + #zone_id = 11 +} + +output "test" { + value = data.decort_cb_vins_list.vl +} diff --git a/samples/cloudbroker/vins/data_vins_list_deleted/main.tf b/samples/cloudbroker/vins/data_vins_list_deleted/main.tf new file mode 100644 index 00000000..a77ccbe7 --- /dev/null +++ b/samples/cloudbroker/vins/data_vins_list_deleted/main.tf @@ -0,0 +1,79 @@ +/* +Пример использования +Получение списка удаленных vins +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vins_list_deleted" "vins_list_deleted" { + #фильтр по id vins + #опциональный параметр + #тип - целое число + #by_id = 100 + + #фильтр по имени vins + #опциональный параметр + #тип - строка + #name = "test" + + #id аккаунта для получения списка vins + #опциональный параметр + #тип - целое число + #account_id = 11111 + + #фильтр по id ресурсной группы + #опциональный параметр + #тип - целое число + #rg_id = 100 + + #фильтр по IP внешней сети + #опциональный параметр + #тип - строка + #ext_ip = "test" + + #фильтр по VNF Device id + #опциональный параметр + #тип - целое число + #vnf_dev_id = 14 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #page = 1 + + #размер страницы + #опциональный параметр + #тип - целое число + #size = 1 +} + +output "test" { + value = data.decort_cb_vins_list_deleted.vins_list_deleted +} diff --git a/samples/cloudbroker/vins/data_vins_nat_rule_list/main.tf b/samples/cloudbroker/vins/data_vins_nat_rule_list/main.tf new file mode 100644 index 00000000..77c9c130 --- /dev/null +++ b/samples/cloudbroker/vins/data_vins_nat_rule_list/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение списка natRule vins +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vins_nat_rule_list" "vins_nat_rule_list" { + #id желаемого vins + #обязательный параметр + #тип - целое число + vins_id = 10101 +} + +output "test" { + value = data.decort_cb_vins_nat_rule_list.vins_nat_rule_list +} + diff --git a/samples/cloudbroker/vins/data_vins_static_route/main.tf b/samples/cloudbroker/vins/data_vins_static_route/main.tf new file mode 100644 index 00000000..6b96c655 --- /dev/null +++ b/samples/cloudbroker/vins/data_vins_static_route/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о static route в данном Vins +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://mr4.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vins_static_route" "route" { + #id vins в котором добавлены routes + #обязательный параметр + #тип - целое число + vins_id = 1111 + + #id route + #обязательный параметр + #тип - целое число + route_id = 1 +} + +output "route" { + value = data.decort_cb_vins_static_route.route +} diff --git a/samples/cloudbroker/vins/data_vins_static_route_list/main.tf b/samples/cloudbroker/vins/data_vins_static_route_list/main.tf new file mode 100644 index 00000000..2f1c0b0f --- /dev/null +++ b/samples/cloudbroker/vins/data_vins_static_route_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о всех static routes в данном Vins +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://mr4.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_vins_static_route_list" "route" { + #id vins в котором добавлены routes + #обязательный параметр + #тип - целое число + vins_id = 111 +} + +output "route" { + value = data.decort_cb_vins_static_route_list.route +} diff --git a/samples/cloudbroker/vins/resource_vins/main.tf b/samples/cloudbroker/vins/resource_vins/main.tf new file mode 100644 index 00000000..5240334f --- /dev/null +++ b/samples/cloudbroker/vins/resource_vins/main.tf @@ -0,0 +1,262 @@ +/* +Пример использования +Ресурса vins +Ресурс позволяет: +1. Создавать vins +2. Удалять vins +3. Восстанвливать vins +4. Добавлять и убирать подключение к внешней сети +5. Резервировать и освобождать ip для vins +6. Добавлять и удалять natrule +7. Перезапускать и редеплоить vnfdev +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://mr4.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_vins" "vins" { + #обязательный параметр + #имя создаваемого ресурса + #тип - строка + #используется при создании + name = "test_name" + + #id аккаунта для создания ресурса + #опциональный параметр + #внимание, для создания ресурса обязательно должен быть указан или rg_id, или account_id + #тип - целое число + #используется при создании + account_id = 2023 + + #id ресурсной группы для создаения ресурса + #опциональный параметр + #внимание, для создания ресурса обязательно должен быть указан или rg_id, или account_id + #тип - целое число + #используется при создании + rg_id = 10101 + + #id внешней сети для подключения к ней ресурса + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #ext_net_id = 2222 + + #ip внешней сети для подключения к нему ресурса + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #ext_ip = "1.1.1.1" + + #приватная сеть IP CIDR + #опциональный параметр + #тип - строка + #используется при создании + #ipcidr = "192.168.0.1" + + #количество зарезервированных адресов на момент создания + #опциональный параметр + #тип - целое число + #используется при создании + #pre_reservations_num = 2 + + #grid (platform) ID + #опциональный параметр + #тип - целое число + #используется при создании + #gid = 2002 + + #описание + #опциональный параметр + #тип - строка + #используется при создании + #description = "Description" + + #блок для указания списка routes + #опциональный параметр + #тип - список routes + #используется при создании + #routes = [{ + #ip целевой сети + #опциональный параметр + #тип - строка + #destination = "DHCP" + + #сетевая маска в формате 255.255.255.255 + #опциональный параметр + #тип - строка + #netmask = "192.168.5.5" + + #шлюз по умолчанию + #опциональный параметр + #тип - строка + #gateway = "192.168.5.5" + #}] + + #default qos + #опциональный параметр + #блок для указания default_qos + #тип - список qos + #используется при обновлении + #default_qos = { + #внутренний трафик, Кбит + #опциональный параметр + #тип - целое число + #in_rate = 1 + + #burst внутреннего трафика, Кбит + #опциональный параметр + #тип - целое число + #in_burst = 1 + + #rate внешнего трафика, Кбит + #опциональный параметр + #тип - целое число + #e_rate = 1 + #} + + #ручное подключение и отключение ресурса + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #enable = true + + #флаг для удаления VINS, без возможности восстановления + #опциональный параметр + #тип - булев + #используется при удалении + #permanently = true + + #удаляет за собой все зависимые ресурсы + #опциональный параметр + #тип - булев + #используется при удалении + #force = true + + #блок для резервирования ip + #опциональный параметр + #тип - список параметров ip + #используется при создании и обновлении + #ip { + #тип подключения + #обязательный параметр + #тип - строка + #type = "DHCP" + + #ip который необходимо зарезервировать + #опциональный параметр + #тип - строка + #ip_addr = "192.168.5.5" + + #mac который необходимо зарезервировать + #опциональный параметр + #тип - строка + #mac = "ff:ff:ff:ff:ff:ff" + + #compute_id, ассоциируемый с типом DHCP + #опциональный параметр + #тип - целое число + #compute_id = 1234 + #} + + #блок для добавления natRule + #опциональный параметр + #тип - список параметров natRule + #используется при создании и обновлении + #nat_rule { + #ip внутренний + #обязательный параметр + #тип - строка + #int_ip = "192.168.0.28" + + #внутренний порт + #опциональный параметр + #тип - целое число + #int_port = 80 + + #начало диапазона внешних портов + #обязательный параметр + #тип - целое число + #ext_port_start = 8001 + + #конец диапазона внешних портов + #опциональный параметр + #тип - целое число + #ext_port_end = 8001 + + #протокол natRule: разрешенные значения "tcp", "udp" + #опциональный параметр + #тип - строка + #proto = "tcp" + #} + + #vnf dev start, stop + #опциональный параметр + #true: старт vnfDev; false: стоп vnfDev + #тип - булев + #используется при обновлении + #vnfdev_start = true + + #перезапуск vnfDev + #опциональный параметр + #тип - булев + #используется при обновлении + #vnfdev_restart = true + + #сброс vnfDev + #опциональный параметр + #тип - булев + #используется при обновлении + #vnfdev_reset = true + + #редеплой vnfDev + #опциональный параметр + #тип - булев + #используется при обновлении + #vnfdev_redeploy = true + + #список dns + #опциональный параметр + #если при создании указать пустой список, то ресурс создается с полем vnfs.dhcp.config.dns, имеющим значение по умолчанию + #если при обновлении указать пустой список, то ресурс обновит в модели поле vnfs.dhcp.config.dns с текущего значения на пустой список + #тип - список строк + #используется при создании и обновлении + #dns = ["1.1.1.1", "2.2.2.2"] + + #идентификатор экземпляра zone + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #zone_id = 1111 + + #флаг, указывающий, включены ли группы безопасности для этой сети + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #значение по умолчанию - false + #enable_secgroups = false + +} + +output "test" { + value = decort_cb_vins.vins +} diff --git a/samples/cloudbroker/vins/resource_vins_static_route/main.tf b/samples/cloudbroker/vins/resource_vins_static_route/main.tf new file mode 100644 index 00000000..f9901372 --- /dev/null +++ b/samples/cloudbroker/vins/resource_vins_static_route/main.tf @@ -0,0 +1,58 @@ +/* +Пример использования +Ресурса vins static routes +Ресурс позволяет: +1. Создавать static routes +2. Удалять static routes +3. Предоставлять доступ виртуальным машинам к static routes +4. Удалять доступ виртуальным машинам к static routes +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_vins_static_route" "sr" { + #id vins + #обязательный параметр + #тип - целое число + vins_id = 385 + + #ip целевой сети + #обязательный параметр + #тип - строка + destination = "192.168.201.0" + + #сетевая маска + #обязательный параметр + #тип - строка + netmask = "255.255.255.255" + + #ip-адрес из пула свободных IP-адресов ViNS ID + #обязательный параметр + #тип - строка + gateway = "192.168.201.40" +} + +output "sr" { + value = decort_cb_vins_static_route.sr +} diff --git a/samples/cloudbroker/zone/data_zone/main.tf b/samples/cloudbroker/zone/data_zone/main.tf new file mode 100644 index 00000000..d5f1fa10 --- /dev/null +++ b/samples/cloudbroker/zone/data_zone/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о zone по ее id +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_zone" "zone" { + #идентификатор zone + #обязательный параметр + #тип - целое число + zone_id = 2 +} + +output "test" { + value = data.decort_cb_zone.zone +} + diff --git a/samples/cloudbroker/zone/data_zone_cpu_alignment_profile/main.tf b/samples/cloudbroker/zone/data_zone_cpu_alignment_profile/main.tf new file mode 100644 index 00000000..52918c7c --- /dev/null +++ b/samples/cloudbroker/zone/data_zone_cpu_alignment_profile/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение профиля выравнивания CPU зоны по её id +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_zone_cpu_alignment_profile" "cap" { + #идентификатор зоны + #обязательный параметр + #тип - целое число + zone_id = 1 +} + +output "test" { + value = data.decort_cb_zone_cpu_alignment_profile.cap +} diff --git a/samples/cloudbroker/zone/data_zone_cpu_alignment_profile_list/main.tf b/samples/cloudbroker/zone/data_zone_cpu_alignment_profile_list/main.tf new file mode 100644 index 00000000..82a08ddf --- /dev/null +++ b/samples/cloudbroker/zone/data_zone_cpu_alignment_profile_list/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение списка профилей выравнивания CPU зон +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_zone_cpu_alignment_profile_list" "cap_list" { + #фильтрация по идентификатору зоны + #опциональный параметр + #тип - целое число + #zone_id = 1 +} + +output "test" { + value = data.decort_cb_zone_cpu_alignment_profile_list.cap_list +} diff --git a/samples/cloudbroker/zone/data_zone_cpu_alignment_profile_test/main.tf b/samples/cloudbroker/zone/data_zone_cpu_alignment_profile_test/main.tf new file mode 100644 index 00000000..8de34e23 --- /dev/null +++ b/samples/cloudbroker/zone/data_zone_cpu_alignment_profile_test/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Тестирование профиля выравнивания CPU зоны +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_zone_cpu_alignment_profile_test" "cap_test" { + #идентификатор зоны + #обязательный параметр + #тип - целое число + zone_id = 1 + + #схожесть гипервизоров в процентах + #опциональный параметр + #тип - целое число + #hypervisor_similarity_in_percentage = 70 +} + +output "test" { + value = data.decort_cb_zone_cpu_alignment_profile_test.cap_test +} diff --git a/samples/cloudbroker/zone/data_zone_list/main.tf b/samples/cloudbroker/zone/data_zone_list/main.tf new file mode 100644 index 00000000..cacbaf57 --- /dev/null +++ b/samples/cloudbroker/zone/data_zone_list/main.tf @@ -0,0 +1,87 @@ +/* +Пример использования +Получение списка zone +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_cb_zone_list" "zone_list" { + #фильтрация списка для получения информации о конкретном zone по его id + #опциональный параметр + #тип - целое число + #by_id = 1 + + #фильтрация списка для получения информации о zone, которые принадлежат к определенному GRID + #опциональный параметр + #тип - целое число + #gid = 1 + + #фильтрация списка для получения информации о конкретном zone по его имени + #опциональный параметр + #тип - строка + #name = "alpha-cpu-04" + + #фильтрация списка для получения информации о конкретном zone по его описанию + #опциональный параметр + #тип - строка + #description = "some" + + #фильтрация списка для получения информации о zone, которые имеют соответствующий статус + #опциональный параметр + #тип - строка + #status = "ENABLED" + + #фильтрация списка для получения информации о zone, которые удалены + #опциональный параметр + #тип - булев + #deletable = false + + #фильтрация списка для получения информации о zone с конкретными nodeId + #опциональный параметр + #тип - целое число + #node_id = 1 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #формат - "+поле" по возрастанию / "-поле" по убыванию + #sort_by = "+name" + + #номер страницы для отображения + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #page = 2 + + #размер страницы + #опциональный параметр + #тип - целое число + #если не задан - выводятся все доступные данные + #size = 3 +} + +output "test" { + value = data.decort_cb_zone_list.zone_list +} + diff --git a/samples/cloudbroker/zone/resource_zone/main.tf b/samples/cloudbroker/zone/resource_zone/main.tf new file mode 100644 index 00000000..7730de13 --- /dev/null +++ b/samples/cloudbroker/zone/resource_zone/main.tf @@ -0,0 +1,76 @@ +/* +Пример использования +Ресурс позволяет: +1. Создавать зону +2. Изменять зону +3. Добавлять новые узлы в зону +4. Удалять узлы из зоны +5. Удалять зону +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_cb_zone" "zone" { + #наименование зоны + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "test" + + #описание зоны + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #description = "desc" + + #прикрепленные узлы + #опциональный параметр + #тип - массив целых чисел + #используется при создании и обновлении + #node_ids = [1,2,3] + + #автостарт ноды + #опциональный параметр + #тип - булев + #по умолчанию - false + #используется при создании и обновлении + #auto_start = false + + #включение/отключение drs + #опциональный параметр + #тип - булев + #значение по умолчанию - false + #используется при создании + #drs = false + + #профиль выравнивания CPU + #опциональный параметр + #тип - целое число + #используется при создании и обновлении + #hypervisor_similarity_in_percentage = 70 +} + +output "test" { + value = decort_cb_zone.zone +} diff --git a/samples/sdn/access_group/data_decort_sdn_access_group/main.tf b/samples/sdn/access_group/data_decort_sdn_access_group/main.tf new file mode 100644 index 00000000..622ee9ca --- /dev/null +++ b/samples/sdn/access_group/data_decort_sdn_access_group/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о access group по ее id +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sdn_access_group" "name" { + #идентификатор группы доступа + #обязательный параметр + #тип - строка + access_group_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" +} + +output "test" { + value = data.decort_sdn_access_group.name +} + diff --git a/samples/sdn/access_group/data_decort_sdn_access_group_list/main.tf b/samples/sdn/access_group/data_decort_sdn_access_group_list/main.tf new file mode 100644 index 00000000..f43107c0 --- /dev/null +++ b/samples/sdn/access_group/data_decort_sdn_access_group_list/main.tf @@ -0,0 +1,85 @@ +/* +Пример использования +Получение информации о списке групп доступа +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sdn_access_group_list" "name" { + #фильтр по включенной\выключенной группе + #опциональный параметр + #тип - булев + #enabled = false + + #фильтр по удаленной/не удаленной группе + #опциональный параметр + #тип - булев + #deleted = true + + #фильтр по отображаемому имени + #опциональный параметр + #тип - строка + #display_name = "name" + + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #количество результатов на странице + #опциональный параметр + #тип - целое число + #per_page = 2 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #возможные значения - display_name, created_at, updated_at, deleted_at, owner_login + #sort_by = "created_at" + + #порядок сортировки + #опциональный параметр + #тип - строка + #возможные значения - asc, desc + #sort_order = "asc" + + #фильтр по нижней границе даты создания + #опциональный параметр + #тип - строка + #created_from = "2023-01-01T00:00:00Z" + + #фильтр по верхней границе даты создания + #опциональный параметр + #тип - строка + #created_to = "2023-01-01T00:00:00Z" + + #фильтр по отображаемому имени владельца группы доступа + #опциональный параметр + #тип - строка + #owner_display_name = "owner_name" +} + +output "test" { + value = data.decort_sdn_access_group_list.name +} + diff --git a/samples/sdn/access_group/data_decort_sdn_access_group_user_list/main.tf b/samples/sdn/access_group/data_decort_sdn_access_group_user_list/main.tf new file mode 100644 index 00000000..6b03dd38 --- /dev/null +++ b/samples/sdn/access_group/data_decort_sdn_access_group_user_list/main.tf @@ -0,0 +1,120 @@ +/* +Пример использования +Получение информации о списке пользователей группы доступа +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sdn_access_group_user_list" "name" { + #фильтр по идентификатору группы доступа + #обязательный параметр + #тип - строка + access_group_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" + + #фильтр по глобальной роли + #опциональный параметр + #тип - строка + #global_role = "global_role" + + #фильтр по роли группы доступа + #опциональный параметр + #тип - строка + #access_group_role = "access_group_role" + + #фильтр по включению + #опциональный параметр + #тип - булев + #enabled = false + + #фильтр по удалению + #опциональный параметр + #тип - булев + #deleted = true + + #фильтр по отображаемому имени + #опциональный параметр + #тип - строка + #display_name = "name" + + #фильтр по логину пользователя + #опциональный параметр + #тип - строка + #login = "login" + + #кто создал пользователя + #опциональный параметр + #тип - строка + #created_by = "name" + + #кто обновил пользователя + #опциональный параметр + #тип - строка + #updated_by = "name" + + #кто удалил пользователя + #опциональный параметр + #тип - строка + #deleted_by = "name" + + #кто отключил пользователя + #опциональный параметр + #тип - строка + #disabled_by = "name" + + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #количество результатов на странице + #опциональный параметр + #тип - целое число + #per_page = 2 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #возможные значения - display_name, email, phone, created_at, updated_at, deleted_at + #sort_by = "created_at" + + #порядок сортировки + #опциональный параметр + #тип - строка + #возможные значения - asc, desc + #sort_order = "asc" + + #фильтр по нижней границе даты создания + #опциональный параметр + #тип - строка + #created_from = "2023-01-01T00:00:00Z" + + #фильтр по верхней границе даты создания + #опциональный параметр + #тип - строка + #created_to = "2023-01-01T00:00:00Z" +} + +output "test" { + value = data.decort_sdn_access_group_user_list.name +} + diff --git a/samples/sdn/access_group/resource_decort_sdn_access_group/main.tf b/samples/sdn/access_group/resource_decort_sdn_access_group/main.tf new file mode 100644 index 00000000..fcdc440a --- /dev/null +++ b/samples/sdn/access_group/resource_decort_sdn_access_group/main.tf @@ -0,0 +1,81 @@ +/* +Пример использования +Ресурс позволяет: +1. Создавать группу доступа +2. Изменять группу доступа +3. Удалять группу доступа +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +resource "decort_sdn_access_group" "name" { + #название группы + #обязательный параметр + #тип - строка + #используется при создании и обновлении + display_name = "name" + + #описание (комментарий) к группе + #обязательный параметр + #тип - строка + #используется при создании и обновлении + comment = "comment" + + #управление пользователями, входящими в группу + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #users { + #id назначаемой роли + #обязательный параметр + #тип - строка + #access_group_role_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" + + #id пользователя + #обязательный параметр + #тип - строка + #user_id = "jkf-jfi-456fn5-kks" + #} + + #определение политик безопасности по умолчанию + #опциональный параметр + #может быть один или ни одного + #тип - блок + #используется при создании и обновлении ресурса + #default_security_policy { + #начальные права доступа + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #default_acl_drop = "default_acl_drop" + + #флаг сброса открытых сессий + #опциональный параметр + #тип - булев + #используется при создании и обновлении + #default_open_session_drop = true + #} +} + diff --git a/samples/sdn/default_security_policy/data_decort_sdn_default_security_policy_list/main.tf b/samples/sdn/default_security_policy/data_decort_sdn_default_security_policy_list/main.tf new file mode 100644 index 00000000..b5477938 --- /dev/null +++ b/samples/sdn/default_security_policy/data_decort_sdn_default_security_policy_list/main.tf @@ -0,0 +1,61 @@ +/* +Пример использования +Получение списка политик безопасности по умолчанию +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sdn_default_security_policy_list" "policy_list" { + #id группы доступа + #опциональный параметр + #тип - строка + #access_group_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" + + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #количество результатов на странице + #опциональный параметр + #тип - целое число + #per_page = 2 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #возможные значения - created_at, updated_at + #sort_by = "created_at" + + #порядок сортировки + #опциональный параметр + #тип - строка + #возможные значения - asc, desc + #sort_order = "asc" +} + +output "test" { + value = data.decort_sdn_default_security_policy_list.policy_list +} + diff --git a/samples/sdn/hypervisors/data_decort_sdn_hypervisor/main.tf b/samples/sdn/hypervisors/data_decort_sdn_hypervisor/main.tf new file mode 100644 index 00000000..a27dca98 --- /dev/null +++ b/samples/sdn/hypervisors/data_decort_sdn_hypervisor/main.tf @@ -0,0 +1,44 @@ +/* +Пример использования +Получение информации о hypervisor по его id +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sdn_hypervisor" "test" { + #имя гипервизора + #обязательный параметр + #тип - строка + name = "name" + + #объем информации + #опциональный параметр + #тип - строка + #возможные значения - detailed, general + #port_info = "detailed" +} + +output "test" { + value = data.decort_sdn_hypervisor.test +} \ No newline at end of file diff --git a/samples/sdn/hypervisors/data_decort_sdn_hypervisor_list/main.tf b/samples/sdn/hypervisors/data_decort_sdn_hypervisor_list/main.tf new file mode 100644 index 00000000..db9e7dd1 --- /dev/null +++ b/samples/sdn/hypervisors/data_decort_sdn_hypervisor_list/main.tf @@ -0,0 +1,96 @@ +/* +Пример использования +Получение информации о списке гипервизоров +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sdn_hypervisor_list" "test" { + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #количество результатов на странице + #опциональный параметр + #тип - целое число + #per_page = 2 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #возможные значения - name, hostname, last_sync, display_name, ip, created_at, updated_at + #sort_by = "created_at" + + #порядок сортировки + #опциональный параметр + #тип - строка + #возможные значения - asc, desc + #sort_order = "asc" + + #объем информации + #опциональный параметр + #тип - строка + #возможные значения - detailed, general + #port_info = "detailed" + + #хостнейм + #опциональный параметр + #тип - строка + #hostname = "hostname" + + #фильтр по отображаемому имени + #опциональный параметр + #тип - строка + #display_name = "name" + + #IP + #опциональный параметр + #тип - строка + #ip = "192.168. 123.132" + + #фильтр по нижней границе даты создания + #опциональный параметр + #тип - строка + #created_from = "2023-01-01T00:00:00Z" + + #фильтр по верхней границе даты создания + #опциональный параметр + #тип - строка + #created_to = "2023-01-01T00:00:00Z" + + #фильтр по нижней границе даты обновления + #опциональный параметр + #тип - строка + #updated_from = "2023-01-01T00:00:00Z" + + #фильтр по верхней границе даты обновления + #опциональный параметр + #тип - строка + #updated_to = "2023-01-01T00:00:00Z" +} + +output "test" { + value = data.decort_sdn_hypervisor_list.test +} diff --git a/samples/sdn/hypervisors/resource_hypervisor/main.tf b/samples/sdn/hypervisors/resource_hypervisor/main.tf new file mode 100644 index 00000000..aca52273 --- /dev/null +++ b/samples/sdn/hypervisors/resource_hypervisor/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования ресурса гипервизора +Ресурс позволяет: +1. Редактировать гипервизор +2. Удалять гипервизор +*/ + +#Раскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +resource "decort_sdn_hypervisor" "test" { + #имя гипервизора (текущее) + #обязательный параметр + #тип - строка + #используется при обновлении + name = "name" + + #отображаемое имя гипервизора (новое) + #обязательный параметр + #тип - строка + #используется при обновлении + display_name = "name" +} + +output "test" { + value = decort_sdn_hypervisor.test +} diff --git a/samples/sdn/logicalports/data_logical_port/main.tf b/samples/sdn/logicalports/data_logical_port/main.tf new file mode 100644 index 00000000..8ae137f6 --- /dev/null +++ b/samples/sdn/logicalports/data_logical_port/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о логическом порте по его id +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +data "decort_sdn_logical_port" "test" { + #идентификатор логического порта + #обязательный параметр + #тип - строка + logical_port_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" +} + +output "test" { + value = data.decort_sdn_logical_port.test +} \ No newline at end of file diff --git a/samples/sdn/logicalports/data_logical_port_by_unique_id/main.tf b/samples/sdn/logicalports/data_logical_port_by_unique_id/main.tf new file mode 100644 index 00000000..fd539844 --- /dev/null +++ b/samples/sdn/logicalports/data_logical_port_by_unique_id/main.tf @@ -0,0 +1,38 @@ +/* +Пример использования +Получение информации о логическом порте по его уникальному идентификатору +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +data "decort_sdn_logical_port_get_by_unique_identifier" "test" { + #уникальный идентификатор логического порта + #обязательный параметр + #тип - строка + unique_identifier = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" +} + +output "test" { + value = data.decort_sdn_logical_port_get_by_unique_identifier.test +} \ No newline at end of file diff --git a/samples/sdn/logicalports/data_logical_port_list/main.tf b/samples/sdn/logicalports/data_logical_port_list/main.tf new file mode 100644 index 00000000..3d8553fa --- /dev/null +++ b/samples/sdn/logicalports/data_logical_port_list/main.tf @@ -0,0 +1,139 @@ +/* +Пример использования +Получение информации о списке логических портов +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +data "decort_sdn_logical_port_list" "test" { + #фильтр по id группы доступа + #опциональный параметр + #тип - строка + #access_group_id = "b2c3d4e5-f6g7-8901-h2i3-j4k5l6m7n8o9" + + #фильтр по id сегмента + #опциональный параметр + #тип - строка + #segment_id = "b2c3d4e5-f6g7-8901-h2i3-j4k5l6m7n8o9" + + #фильтр по отображаемому имени сегмента + #опциональный параметр + #тип - строка + #segment_display_name = "name" + + #фильтр по id внешней сети + #опциональный параметр + #тип - строка + #external_network_id = "b2c3d4e5-f6g7-8901-h2i3-j4k5l6m7n8o9" + + #фильтр по уникальному идентификатору + #опциональный параметр + #тип - строка + #unique_identifier = "ca9d66f0-63b3-4709-98c7-5bc99247c4d3" + + #фильтр по отображаемому имени логического порта + #опциональный параметр + #тип - строка + #display_name = "name" + + #фильтр по MAC адресу адаптера + #опциональный параметр + #тип - строка + #adapter_mac = "12:1f:00:2f:00:14" + + #фильтр по гипервизору + #опциональный параметр + #тип - строка + #hypervisor = "hypervisor" + + #фильтр по отображаемому имени гипервизора + #опциональный параметр + #тип - строка + #hypervisor_display_name = "name" + + #фильтр по live migration target hv + #опциональный параметр + #тип - строка + #live_migration_target_hv = "" + + #фильтр по защите порта + #опциональный параметр + #тип - булев + #port_security = true + + #фильтр по обнаружению адреса + #опциональный параметр + #тип - булев + #address_detection = true + + #фильтр по включенному\выключенному порту + #опциональный параметр + #тип - булев + #enabled = false + + #фильтр по статусу операции + #опциональный параметр + #тип - строка + #operation_status = "Synchronized" + + #фильтр по статусу гипервизора + #опциональный параметр + #тип - строка + #hypervisor_status = "Warning" + + #фильтр по нижней границе даты создания + #опциональный параметр + #тип - строка + #created_from = "2023-01-01T00:00:00Z" + + #фильтр по верхней границе даты создания + #опциональный параметр + #тип - строка + #created_to = "2023-01-01T00:00:00Z" + + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #количество результатов на странице + #опциональный параметр + #тип - целое число + #per_page = 2 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #возможные значения - display_name, created_at, updated_at, deleted_at, segment_id, hypervisor, port_security, segment_display_name, primary_address, hypervisor_display_name + #sort_by = "created_at" + + #порядок сортировки + #опциональный параметр + #тип - строка + #возможные значения - asc, desc + #sort_order = "asc" +} +output "test" { + value = data.decort_sdn_logical_port_list.test +} \ No newline at end of file diff --git a/samples/sdn/logicalports/resource_logical_port/main.tf b/samples/sdn/logicalports/resource_logical_port/main.tf new file mode 100644 index 00000000..f3f1fb71 --- /dev/null +++ b/samples/sdn/logicalports/resource_logical_port/main.tf @@ -0,0 +1,154 @@ +/* +Пример использования + +Функция позволяет: +- Создать логический порт +- Изменять логический порт +- Удалить логический порт +- Включить/отключить логический порт +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_sdn_logical_port" "test" { + #id группы доступа + #обязательный параметр + #тип - строка + #используется при создании + access_group_id = "b2c3d4e5-f6g7-8901-h2i3-j4k5l6m7n8o9" + + #описание логического порта + #обязательный параметр + #тип - строка + #используется при создании и обновлении + description = "description" + + #отображаемое имя логического порта + #обязательный параметр + #тип - строка + #используется при создании и обновлении + display_name = "name" + + #включенение порта + #обязательный параметр + #тип - булев + #используется при создании и обновлении + enabled = true + + #связанный гипервизор + #обязательный параметр + #тип - строка + #используется при создании и обновлении + hypervisor = "hypervisor" + + #статус безопасности порта + #обязательный параметр + #тип - булев + #используется при создании и обновлении + port_security = true + + #id сегмента сети + #обязательный параметр + #тип - строка + #используется при создании и обновлении + segment_id = "a866059a-1900-4f7f-89c1-0f98880f5f4c" + + #MAC адрес адаптера + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #adapter_mac = "^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$ default: null" + + #уникальный идентификатор порта + #опциональный параметр + #тип - строка + #используется при создании + #unique_identifier = "b2c3d4e5-f6g7-8901-h2i3-j4k5l6m7n8o9" + + #управление списком адресов логических портов + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #logical_port_addresses { + #ip + #обязательный параметр + #тип - строка + #ip = "192.168.0.1" + + #тип ip + #обязательный параметр + #тип - строка + #возможные значения - IPv4, IPv6 + #ip_type = IPv4" + + #обнаружен/не обнаружен + #опциональный параметр + #тип - булев + #значение по умолчанию - false + #is_discovered = false + + #является ли основным + #обязательный параметр + #тип - булев + #значение по умолчанию - true + #is_primary = true + + #MAC адрес + #опциональный параметр + #тип - строка + #mac = "^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$" + #} + + #метки + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #labels { + # #идентификатор виртуальной машины + # #опциональный параметр + # #тип - строка + # #vm_id = "vmid-420" + + # #имя виртуальной машины + # #опциональный параметр + # #тип - строка + # #vm_name = "my-vm" + #} + + #флаг инициации миграции на гипервизор из поля hypervisor + #опциональный параметр + #тип - булев + #значение по умолчанию - false + #используется при обновлении + #migrate = true + + #флаг принудительного удаления + #опциональный параметр + #тип - булев + #используется при обновлении + #force = true +} + +output "test" { + value = decort_sdn_logical_port.test +} diff --git a/samples/sdn/netobjgroups/data_decort_sdn_network_object_group/main.tf b/samples/sdn/netobjgroups/data_decort_sdn_network_object_group/main.tf new file mode 100644 index 00000000..014a5d4a --- /dev/null +++ b/samples/sdn/netobjgroups/data_decort_sdn_network_object_group/main.tf @@ -0,0 +1,37 @@ +/* +Пример использования +Получение информации о группе сетевых объектов по её id +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sdn_network_object_group" "name" { + #идентификатор группы сетевых объектов + #обязательный параметр + #тип - строка + net_object_group_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" +} + +output "test" { + value = data.decort_sdn_network_object_group.name +} diff --git a/samples/sdn/netobjgroups/data_decort_sdn_network_object_group_list/main.tf b/samples/sdn/netobjgroups/data_decort_sdn_network_object_group_list/main.tf new file mode 100644 index 00000000..da8f2539 --- /dev/null +++ b/samples/sdn/netobjgroups/data_decort_sdn_network_object_group_list/main.tf @@ -0,0 +1,88 @@ +/* +Пример использования +Получение списка групп сетевых объектов +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sdn_network_object_group_list" "name" { + #фильтр по имени группы сетевых объектов + #опциональный параметр + #тип - строка + #name = "my-group" + + #фильтр по id группы доступа + #опциональный параметр + #тип - строка + #access_group_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" + + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #количество результатов на странице + #опциональный параметр + #тип - целое число + #per_page = 10 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #возможные значения - name, created_at, updated_at + #sort_by = "name" + + #порядок сортировки + #опциональный параметр + #тип - строка + #возможные значения - asc, desc + #sort_order = "asc" + + #фильтр по нижней границе даты создания + #опциональный параметр + #тип - строка + #значение по умолчанию - null + #created_from = "2024-01-01T00:00:00Z" + + #фильтр по верхней границе даты создания + #опциональный параметр + #тип - строка + #значение по умолчанию - null + #created_to = "2025-01-01T00:00:00Z" + + #фильтр по нижней границе даты обновления + #опциональный параметр + #тип - строка + #значение по умолчанию - null + #updated_from = "2024-01-01T00:00:00Z" + + #фильтр по верхней границе даты обновления + #опциональный параметр + #тип - строка + #значение по умолчанию - null + #updated_to = "2025-01-01T00:00:00Z" +} + +output "test" { + value = data.decort_sdn_network_object_group_list.name +} diff --git a/samples/sdn/netobjgroups/resource_decort_sdn_network_object_group/main.tf b/samples/sdn/netobjgroups/resource_decort_sdn_network_object_group/main.tf new file mode 100644 index 00000000..7661de64 --- /dev/null +++ b/samples/sdn/netobjgroups/resource_decort_sdn_network_object_group/main.tf @@ -0,0 +1,101 @@ +/* +Пример использования +Ресурс позволяет: +1. Создавать группу сетевых объектов +2. Изменять группу сетевых объектов +3. Удалять группу сетевых объектов +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_sdn_network_object_group" "name" { + #имя группы сетевых объектов + #обязательный параметр + #тип - строка + #используется при создании и обновлении + name = "my-net-obj-group" + + #id группы доступа + #обязательный параметр + #тип - строка + #используется при создании и обновлении + access_group_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" + + #описание группы сетевых объектов + #обязательный параметр + #тип - строка + #используется при создании и обновлении + description = "description" + + #привязка и отвязка l2 портов + #опциональный параметр + #тип - блок + #используется при создании + #l2_connection_ports_bindings { + #id порта + #обязательный параметр + #тип - строка + #port_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" + + #версия порта + #обязательный параметр + #тип - целое число + #port_version = 1747141621952 + #} + + #список сетевых адресов + #опциональный параметр + #тип - блок (может быть несколько) + #используется при создании и обновлении + #addresses { + #тип сетевого адреса + #обязательный параметр + #тип - строка + #net_address_type = "ip" + + #IP-адрес + #опциональный параметр + #тип - строка + #ip_addr = "192.168.1.10" + + #конец диапазона IP-адресов + #опциональный параметр + #тип - строка + #ip_addr_range_end = "192.168.1.20" + + #IP-префикс (CIDR) + #опциональный параметр + #тип - строка + #ip_prefix = "192.168.1.0/24" + + #MAC-адрес + #опциональный параметр + #тип - строка + #mac_addr = "aa:bb:cc:dd:ee:ff" + #} +} + +output "test" { + value = decort_sdn_network_object_group.name +} diff --git a/samples/sdn/segments/data_segment/main.tf b/samples/sdn/segments/data_segment/main.tf new file mode 100644 index 00000000..53439c5d --- /dev/null +++ b/samples/sdn/segments/data_segment/main.tf @@ -0,0 +1,43 @@ +/* +Пример использования +Получение информации о segment по ее id +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sdn_segment" "name" { + #идентификатор сегмента + #обязательный параметр + #тип - строка + segment_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" + + #идентификатор группы доступа + #опциональный параметр + #тип - строка + #access_group_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" +} + +output "test" { + value = data.decort_sdn_segment.name +} + diff --git a/samples/sdn/segments/data_segment_list/main.tf b/samples/sdn/segments/data_segment_list/main.tf new file mode 100644 index 00000000..77096e17 --- /dev/null +++ b/samples/sdn/segments/data_segment_list/main.tf @@ -0,0 +1,106 @@ +/* +Пример использования +Получение списка segments +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_sdn_segment_list" "name" { + #номер страницы результата + #опциональный параметр + #тип - целое число + #page = 1 + + #количество результатов на странице + #опциональный параметр + #тип - целое число + #per_page = 2 + + #сортировка по одному из поддерживаемых полей + #опциональный параметр + #тип - строка + #возможные значения - display_name, subnet, created_at, updated_at + #sort_by = "created_at" + + #порядок сортировки + #опциональный параметр + #тип - строка + #возможные значения - asc, desc + #sort_order = "asc" + + #фильтр по включенному/выключенному сегменту + #опциональный параметр + #тип - булев + #enabled = false + + #считает ли Core в настоящее время, что его данные синхронизированы с данными в OVN? + #опциональный параметр + #тип - булев + #is_synced = true + + #фильтр по отображаемому имени + #опциональный параметр + #тип - строка + #display_name = "name" + + #фильтр по подсети IPv4 или IPv6 + #опциональный параметр + #тип - строка + #subnet = "192.168.1.0/24" + + #фильтр по id группы доступа + #опциональный параметр + #тип - строка + #access_group_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" + + #фильтр по нижней границе даты создания + #опциональный параметр + #тип - строка + #created_from = "2023-01-01T00:00:00Z" + + #фильтр по верхней границе даты создания + #опциональный параметр + #тип - строка + #created_to = "2023-01-01T00:00:00Z" + + #фильтр по нижней границе даты обновления + #опциональный параметр + #тип - строка + #updated_from = "2023-01-01T00:00:00Z" + + #фильтр по верхней границе даты обновления + #опциональный параметр + #тип - строка + #updated_to = "2023-01-01T00:00:00Z" + + #фильтр по статусу операции + #опциональный параметр + #тип - строка + #возможные значения - Idle, SynchronizingAtCore, SynchronizingAtOVN, Synchronized, NoHypervisorAtOVN, FailedAtCore, TemporaryFailedAtCore + #operation_status = "Idle" +} + +output "test" { + value = data.decort_sdn_segment_list.name +} + diff --git a/samples/sdn/segments/resource_segment/main.tf b/samples/sdn/segments/resource_segment/main.tf new file mode 100644 index 00000000..4f4be0e3 --- /dev/null +++ b/samples/sdn/segments/resource_segment/main.tf @@ -0,0 +1,160 @@ +/* +Пример использования +Ресурс позволяет: +1. Создавать сегмент +2. Изменять сегмент +3. Удалять сегмент +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + source = "basis/decort/decort" + version = "" + } + } +} +*/ + +provider "decort" { + authenticator = "decs3o" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_sdn_segment" "name" { + #id группы доступа + #обязательный параметр + #тип - строка + #используется при создании и обновлении + access_group_id = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" + + #описание сегмента + #обязательный параметр + #тип - строка + #используется при создании и обновлении + description = "description" + + #отображаемое имя сегмента + #обязательный параметр + #тип - строка + #используется при создании и обновлении + display_name = "name" + + #включение/отключение сегмента + #обязательный параметр + #тип - булев + #используется при создании и обновлении + enabled = true + + #подсеть IPv4 для текущего сегмента + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #subnet_v4 = "192.168.1.0/24" + + #подсеть IPv6 для текущего сегмента + #опциональный параметр + #тип - строка + #используется при создании и обновлении + #subnet_v6 = "aef0::/64" + + #настройка DHCPv4 + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #dhcp_v4 { + #DNS + #опциональный параметр + #тип - массив строк + #dns = ["198.51.100.42","8.8.8.8"] + + #исключенные диапазоны адресов + #опциональный параметр + #тип - массив строк + #excluded_address_ranges = ["198.51.100.42","8.8.8.8"] + + #шлюз + #обязательный параметр + #тип - строка + #gateway = "192.168.0.1" + + #время аренды + #опциональный параметр + #тип - целое число + #lease_time = 86400 + + #ip сервера + #обязательный параметр + #тип - строка + #server_ip = "192.168.1.100" + + #MAC адрес сервера + #опциональный параметр + #тип - строка + #server_mac = "^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$" + + #включение/отключение + #обязательный параметр + #тип - булев + #enabled = true + #} + + #настройка DHCPv6 + #опциональный параметр + #тип - блок + #используется при создании и обновлении + #dhcp_v6 { + #префикс IPv6 + #обязательный параметр + #тип - строка + #address_prefix = "2001:db8::/64" + + #DNS + #опциональный параметр + #тип - массив строк + #dns = ["198.51.100.42","8.8.8.8"] + + #время аренды + #опциональный параметр + #тип - целое число + #lease_time = 86400 + + #MAC адрес сервера + #опциональный параметр + #тип - строка + #server_mac = "^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$" + + #включение/отключение + #обязательный параметр + #тип - булев + #enabled = true + #} + + #тип сегмента + #опциональный параметр + #тип - строка + #возможные значения - User, ExtNet + #используется при создании и обновлении + #type = "User" + + #флаг принудительного удаления + #опциональный параметр + #тип - булев + #используется при обновлении + #force = true +} + +output "test" { + value = decort_sdn_segment.name +} + + + diff --git a/scripts/install.bat b/scripts/install.bat new file mode 100644 index 00000000..686beb11 --- /dev/null +++ b/scripts/install.bat @@ -0,0 +1,74 @@ +:: Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +:: Authors: +:: Tim Tkachev, +:: +:: Licensed under the Apache License, Version 2.0 (the "License"); +:: you may not use this file except in compliance with the License. +:: You may obtain a copy of the License at +:: +:: http://www.apache.org/licenses/LICENSE-2.0 +:: +:: Unless required by applicable law or agreed to in writing, software +:: distributed under the License is distributed on an "AS IS" BASIS, +:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +:: See the License for the specific language governing permissions and +:: limitations under the License. +:: +:: Installer uses basis/decort/decort as path value to provider executable. + +@echo off + +cd /d "%~dp0" +pushd .\bin\ +for %%f in (*.exe) do ( + set filename=%%~nf +) + +for /F "tokens=1,2,3,4 delims=_" %%a in ("%filename%") do ( + set version=%%b + set os=%%c + set arch=%%d +) + +set provider_path=%appdata%\terraform.d\plugins\basis\decort\decort\%version%\%os%_%arch%\ + +if exist %provider_path% ( + echo Provider directory already exists, checking for decort provider executable.. + copy /y %filename%.exe %provider_path% + if errorlevel 1 ( + pause + exit /b + ) + call :print_success + pause + exit /b +) else ( + echo Creating provider directory.. + mkdir %provider_path% + if errorlevel 1 ( + pause + exit /b + ) + copy %filename%.exe %provider_path% + if errorlevel 1 ( + pause + exit /b + ) + call :print_success + pause + exit /b +) + +:print_success +echo DECORT provider version %version% has been successfully installed +echo: +echo Copy this provider configuration to main.tf file: +echo terraform { +echo required_providers { +echo decort = { +echo version = "%version%" +echo source = "basis/decort/decort" +echo } +echo } +echo } +goto:eof \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 00000000..bb32dd2f --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,71 @@ +# Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved. +# Authors: +# Tim Tkachev, +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Installer uses basis/decort/decort as path value to provider binary. + +set -e + +filename="bin"/* + +version=$(basename $filename | cut -d '_' -f 2) +os=$(basename $filename | cut -d '_' -f 3) +arch=$(basename $filename | cut -d '_' -f 4) + +plugins_dir=~/.terraform.d/plugins/ +provider_path=basis/decort/decort/$version/$os\_$arch/ + +print_info () { +cat <