Compare commits

...

16 Commits
4.3.2 ... 4.5.1

Author SHA1 Message Date
20050bc169 4.5.1 2023-12-18 18:55:52 +03:00
e2ee45ee14 4.5.1 2023-12-18 18:36:55 +03:00
Nikita Sorokin
294680282e 4.5.0 2023-11-13 00:59:02 +03:00
Nikita Sorokin
2bc0fbae9a 4.5.0-alpha 2023-11-07 18:26:09 +03:00
Nikita Sorokin
2453a32d01 4.4.2 2023-10-18 08:30:37 +03:00
Nikita Sorokin
0602a4b693 4.4.1 2023-10-13 13:28:19 +03:00
Nikita Sorokin
28b60de115 4.4.0-static-route-updated 2023-10-09 13:15:11 +03:00
Nikita Sorokin
b705ce4aab 4.4.0 2023-09-28 19:41:26 +03:00
Nikita Sorokin
83ca627cea 4.4.0 2023-09-28 16:08:15 +03:00
Nikita Sorokin
739289fbb8 4.3.8 2023-09-27 16:17:35 +03:00
Nikita Sorokin
c89574c3e6 4.3.7 2023-09-22 12:49:22 +03:00
Nikita Sorokin
a1e61674c8 4.3.6 2023-09-04 11:15:01 +03:00
Nikita Sorokin
cb9ff26bb0 4.3.5 2023-08-29 16:26:37 +03:00
Nikita Sorokin
6932f9d305 4.3.5 2023-08-28 13:02:41 +03:00
Nikita Sorokin
712f8edf9e 4.3.4 2023-08-23 16:32:48 +03:00
Nikita Sorokin
805ffe1f29 4.3.3 2023-08-22 13:15:17 +03:00
647 changed files with 64899 additions and 15328 deletions

2
.gitignore vendored
View File

@@ -3,3 +3,5 @@ examples/
url_scrapping/ url_scrapping/
terraform-provider-decort* terraform-provider-decort*
.vscode/ .vscode/
.DS_Store

View File

@@ -1,5 +1,24 @@
## Version 4.3.2 ## Version 4.5.1
## Bugfixes ## Feature
- Fixed bootdisk flattens - Refactoring BVS config
- Updated golang-decort-sdk version with fixed permamently field in cloudapi/cloudbroker/compute/diskDel - Added and updated data sources and resources for cloudbroker groups:
* account
* audit
* disks
* extnet
* flipgroup
* grid
* image
* k8ci
* k8s
* kvmvm (compute)
* lb (load balancer)
* pcidevice
* rg (resource group)
* sep
* stack
* vins
### Bugfix
- Fixed description update for compute in cloudapi/kvmvm

View File

@@ -7,11 +7,8 @@ ZIPDIR = ./zip
BINARY=${NAME} BINARY=${NAME}
WORKPATH= ./examples/terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH} WORKPATH= ./examples/terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH}
MAINPATH = ./cmd/decort/ MAINPATH = ./cmd/decort/
VERSION=4.3.2 VERSION=4.5.1
OS_ARCH=$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH) OS_ARCH=$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH)
# OS_ARCH=darwin_arm64
# OS_ARCH=windows_amd64
# OS_ARCH=linux_amd64
FILES = ${BINARY}_${VERSION}_darwin_amd64\ FILES = ${BINARY}_${VERSION}_darwin_amd64\
${BINARY}_${VERSION}_darwin_arm64\ ${BINARY}_${VERSION}_darwin_arm64\

View File

@@ -6,6 +6,8 @@ Terraform provider для платформы Digital Energy Cloud Orchestration
| Версия DECORT API | Версия провайдера Terraform | | Версия DECORT API | Версия провайдера Terraform |
| ------ | ------ | | ------ | ------ |
| 3.8.9 | 4.5.x |
| 3.8.8 | 4.4.x |
| 3.8.7 | 4.3.x | | 3.8.7 | 4.3.x |
| 3.8.6 | 4.0.x, 4.1.x, 4.2.x | | 3.8.6 | 4.0.x, 4.1.x, 4.2.x |
| 3.8.5 | 3.4.x | | 3.8.5 | 3.4.x |
@@ -25,21 +27,42 @@ Terraform provider для платформы Digital Energy Cloud Orchestration
## Возможности провайдера ## Возможности провайдера
- Работа с Compute instances, - Режим пользователя:
- Работа с disks, - Работа с accounts,
- Работа с k8s, - Работа с bservice,
- Работа с image, - Работа с disks,
- Работа с reource groups, - Работа с extnets,
- Работа с VINS, - Работа с flipgroups,
- Работа с pfw, - Работа с image,
- Работа с accounts, - Работа с k8s,
- Работа с snapshots, - Работа с Compute instances,
- Работа с bservice, - Работа с load balancer,
- Работа с extnets, - Работа с locations,
- Работа с locations, - Работа с pfw,
- Работа с load balancer. - Работа с resource groups,
- Работа с snapshots,
- Работа с stacks,
- Работа с VINS.
Вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki - Режим администратора:
- Работа с accounts,
- Работа с audits,
- Работа с disks,
- Работа с extnets,
- Работа с flipgroups,
- Работа с grids,
- Работа с images,
- Работа с k8ci,
- Работа с k8s,
- Работа с Compute instances,
- Работа с load balancer,
- Работа с pci device,
- Работа с resource groups,
- Работа с seps,
- Работа с stacks,
- Работа с VINS.
Со списком и описанием функционала всех групп можно ознамоиться на Вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
## Установка ## Установка
Начиная с версии провайдера `4.3.0` в релизном архиве находятся скрипты-инсталляторы. Начиная с версии провайдера `4.3.0` в релизном архиве находятся скрипты-инсталляторы.
@@ -86,7 +109,7 @@ terraform {
9. Добавьте в файл блок с инициализацией провайдера. 9. Добавьте в файл блок с инициализацией провайдера.
```terraform ```terraform
provider "decort" { provider "decort" {
authenticator = "oauth2" authenticator = "decs3o"
controller_url = "https://mr4.digitalenergy.online" controller_url = "https://mr4.digitalenergy.online"
oauth2_url = "https://sso.digitalenergy.online" oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true allow_unverified_ssl = true
@@ -172,7 +195,7 @@ ${host_name}/${namespace}/${type}
8. Добавьте в файл блок с инициализацией провайдера. 8. Добавьте в файл блок с инициализацией провайдера.
```terraform ```terraform
provider "decort" { provider "decort" {
authenticator = "oauth2" authenticator = "decs3o"
controller_url = "https://mr4.digitalenergy.online" controller_url = "https://mr4.digitalenergy.online"
oauth2_url = "https://sso.digitalenergy.online" oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true allow_unverified_ssl = true

View File

@@ -58,7 +58,7 @@ Two ways for starting:
```terraform ```terraform
provider "decort" { provider "decort" {
authenticator = "oauth2" authenticator = "decs3o"
#controller_url = <DECORT_CONTROLLER_URL> #controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online" controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL> #oauth2_url = <DECORT_SSO_URL>

16
go.mod
View File

@@ -8,8 +8,8 @@ require (
github.com/hashicorp/terraform-plugin-docs v0.13.0 github.com/hashicorp/terraform-plugin-docs v0.13.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1
github.com/sirupsen/logrus v1.9.0 github.com/sirupsen/logrus v1.9.0
golang.org/x/net v0.12.0 golang.org/x/net v0.16.0
repository.basistech.ru/BASIS/decort-golang-sdk v1.5.3 repository.basistech.ru/BASIS/decort-golang-sdk v1.7.2
) )
require ( require (
@@ -24,8 +24,8 @@ require (
github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.1 // indirect github.com/go-playground/validator/v10 v10.15.4 // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
@@ -67,12 +67,12 @@ require (
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/vmihailenco/tagparser v0.1.2 // indirect
github.com/zclconf/go-cty v1.12.1 // indirect github.com/zclconf/go-cty v1.12.1 // indirect
golang.org/x/crypto v0.11.0 // indirect golang.org/x/crypto v0.15.0 // indirect
golang.org/x/sys v0.10.0 // indirect golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.11.0 // indirect golang.org/x/text v0.14.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 // indirect google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 // indirect
google.golang.org/grpc v1.51.0 // indirect google.golang.org/grpc v1.51.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

32
go.sum
View File

@@ -55,8 +55,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 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 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= github.com/go-playground/validator/v10 v10.15.4 h1:zMXza4EpOdooxPel5xDqXEdXG5r+WggpvnAKMsalBjs=
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-playground/validator/v10 v10.15.4/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU= github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
@@ -65,8 +65,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 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.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -249,8 +249,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -265,8 +265,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 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.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -293,8 +293,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@@ -304,8 +304,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@@ -322,8 +322,8 @@ google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 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.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -339,5 +339,5 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
repository.basistech.ru/BASIS/decort-golang-sdk v1.5.3 h1:Rt5tE4EZcUr4ONK9u/XYe2mG1CC37xLUnNuCLYKDwYs= repository.basistech.ru/BASIS/decort-golang-sdk v1.7.2 h1:Ll8MBcmDcElxxgxOUUaYbbafTSbIm4dcPEDLl4fdF8Q=
repository.basistech.ru/BASIS/decort-golang-sdk v1.5.3/go.mod h1:szsTGa73O75ckCWVGJPvTtRbhA/ubuYrYhMkPjvHlmE= repository.basistech.ru/BASIS/decort-golang-sdk v1.7.2/go.mod h1:7fj8sgGZFiiExewQeqckCS4WxwOmU0oP6BO6mi1Lpkw=

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
@@ -24,14 +24,13 @@ import (
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"io/ioutil" "io"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
// "time"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
decort "repository.basistech.ru/BASIS/decort-golang-sdk" decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/config" "repository.basistech.ru/BASIS/decort-golang-sdk/config"
@@ -46,24 +45,32 @@ import (
// enumerated constants that define authentication modes // enumerated constants that define authentication modes
const ( const (
MODE_UNDEF = iota // this is the invalid mode - it should never be seen MODE_UNDEF = iota // this is the invalid mode - it should never be seen
MODE_LEGACY = iota MODE_LEGACY
MODE_OAUTH2 = iota MODE_DECS3O
MODE_JWT = iota MODE_JWT
MODE_BVS
) )
type ControllerCfg struct { type ControllerCfg struct {
controller_url string // always required controller_url string // always required
auth_mode_code int // always required auth_mode_code int // always required
auth_mode_txt string // always required, it is a text representation of auth mode 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_user string // required for legacy mode
legacy_password 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 legacy_sid string // obtained from DECORT controller on successful login in legacy mode
jwt string // obtained from Outh2 provider on successful login in oauth2 mode, required in jwt mode jwt string // obtained from Outh2 provider on successful login in decs3o mode, required in jwt mode
app_id string // required for oauth2 mode app_id string // required for decs3o and bvs mode
app_secret string // required for oauth2 mode app_secret string // required for decs3o and bvs mode
oauth2_url string // always required oauth2_url string // required for decs3o and bvs mode
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification 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 cc_client *http.Client // assigned when all initial checks successfully passed
caller interfaces.Caller caller interfaces.Caller
} }
@@ -86,17 +93,24 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
legacy_user: d.Get("user").(string), legacy_user: d.Get("user").(string),
legacy_password: d.Get("password").(string), legacy_password: d.Get("password").(string),
legacy_sid: "", 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), jwt: d.Get("jwt").(string),
app_id: d.Get("app_id").(string), app_id: d.Get("app_id").(string),
app_secret: d.Get("app_secret").(string), app_secret: d.Get("app_secret").(string),
oauth2_url: d.Get("oauth2_url").(string), oauth2_url: d.Get("oauth2_url").(string),
decort_username: "", 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) allow_unverified_ssl := d.Get("allow_unverified_ssl").(bool)
if ret_config.controller_url == "" { if ret_config.controller_url == "" {
return nil, fmt.Errorf("Empty DECORT cloud controller URL provided.") 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 // this should have already been done by StateFunc defined in Schema, but we want to be sure
@@ -105,33 +119,53 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
switch ret_config.auth_mode_txt { switch ret_config.auth_mode_txt {
case "jwt": case "jwt":
if ret_config.jwt == "" { if ret_config.jwt == "" {
return nil, fmt.Errorf("Authenticator mode 'jwt' specified but no JWT provided.") return nil, fmt.Errorf("authenticator mode 'jwt' specified but no JWT provided")
} }
ret_config.auth_mode_code = MODE_JWT ret_config.auth_mode_code = MODE_JWT
case "oauth2": case "decs3o":
if ret_config.oauth2_url == "" { if ret_config.oauth2_url == "" {
return nil, fmt.Errorf("Authenticator mode 'oauth2' specified but no OAuth2 URL provided.") return nil, fmt.Errorf("authenticator mode 'decs3o' specified but no OAuth2 URL provided")
} }
if ret_config.app_id == "" { if ret_config.app_id == "" {
return nil, fmt.Errorf("Authenticator mode 'oauth2' specified but no Application ID provided.") return nil, fmt.Errorf("authenticator mode 'decs3o' specified but no Application ID provided")
} }
if ret_config.app_secret == "" { if ret_config.app_secret == "" {
return nil, fmt.Errorf("Authenticator mode 'oauth2' specified but no Secret ID provided.") return nil, fmt.Errorf("authenticator mode 'decs3o' specified but no Secret ID provided")
} }
ret_config.auth_mode_code = MODE_OAUTH2 ret_config.auth_mode_code = MODE_DECS3O
case "legacy": case "legacy":
// //
ret_config.legacy_user = d.Get("user").(string) ret_config.legacy_user = d.Get("user").(string)
if ret_config.legacy_user == "" { if ret_config.legacy_user == "" {
return nil, fmt.Errorf("Authenticator mode 'legacy' specified but no user provided.") return nil, fmt.Errorf("authenticator mode 'legacy' specified but no user provided")
} }
ret_config.legacy_password = d.Get("password").(string) ret_config.legacy_password = d.Get("password").(string)
if ret_config.legacy_password == "" { if ret_config.legacy_password == "" {
return nil, fmt.Errorf("Authenticator mode 'legacy' specified but no password provided.") return nil, fmt.Errorf("authenticator mode 'legacy' specified but no password provided")
} }
ret_config.auth_mode_code = MODE_LEGACY 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: default:
return nil, fmt.Errorf("Unknown authenticator mode %q provided.", ret_config.auth_mode_txt) return nil, fmt.Errorf("unknown authenticator mode %q provided", ret_config.auth_mode_txt)
} }
if allow_unverified_ssl { if allow_unverified_ssl {
@@ -167,10 +201,10 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
if !ok { if !ok {
return nil, err return nil, err
} }
case MODE_OAUTH2: case MODE_DECS3O:
// on success getOAuth2JWT will set config.jwt to the obtained JWT, so there is no // on success getDECS3OJWT will set config.jwt to the obtained JWT, so there is no
// need to set it once again here // need to set it once again here
_, err := ret_config.getOAuth2JWT() _, err := ret_config.getDECS3OJWT()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -189,7 +223,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
tbuf.WriteString(claims["iss"].(string)) tbuf.WriteString(claims["iss"].(string))
ret_config.decort_username = tbuf.String() ret_config.decort_username = tbuf.String()
} else { } else {
return nil, fmt.Errorf("Failed to extract user and iss fields from JWT token in oauth2 mode.") return nil, fmt.Errorf("failed to extract user and iss fields from JWT token in oauth2 mode")
} }
sdkConf := config.Config{ sdkConf := config.Config{
@@ -201,10 +235,27 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
} }
ret_config.caller = decort.New(sdkConf) 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: default:
// FYI, this should never happen due to all above checks, but we want to be fool proof // 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) 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 // All checks passed successfully, credentials corresponding to the selected authenticator mode
@@ -216,13 +267,13 @@ func (config *ControllerCfg) GetDecortUsername() string {
return config.decort_username return config.decort_username
} }
func (config *ControllerCfg) getOAuth2JWT() (string, error) { func (config *ControllerCfg) getDECS3OJWT() (string, error) {
// Obtain JWT from the Oauth2 provider using application ID and application secret provided in config. // Obtain JWT from the Oauth2 provider using application ID and application secret provided in config.
if config.auth_mode_code == MODE_UNDEF { if config.auth_mode_code == MODE_UNDEF {
return "", fmt.Errorf("getOAuth2JWT method called for undefined authorization mode.") return "", fmt.Errorf("getOAuth2JWT method called for undefined authorization mode")
} }
if config.auth_mode_code != MODE_OAUTH2 { if config.auth_mode_code != MODE_DECS3O {
return "", fmt.Errorf("getOAuth2JWT method called for incompatible authorization mode %q.", config.auth_mode_txt) return "", fmt.Errorf("getOAuth2JWT method called for incompatible authorization mode %q", config.auth_mode_txt)
} }
params := url.Values{} params := url.Values{}
@@ -253,7 +304,7 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
} }
defer resp.Body.Close() defer resp.Body.Close()
responseData, err := ioutil.ReadAll(resp.Body) responseData, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return "", err return "", err
} }
@@ -273,13 +324,13 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
*/ */
if jwt == "" { if jwt == "" {
if config.jwt == "" { if config.jwt == "" {
return false, fmt.Errorf("validateJWT method called, but no meaningful JWT provided.") return false, fmt.Errorf("validateJWT method called, but no meaningful JWT provided")
} }
jwt = config.jwt jwt = config.jwt
} }
if config.oauth2_url == "" { if config.oauth2_url == "" {
return false, fmt.Errorf("validateJWT method called, but no OAuth2 URL provided.") 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) req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/account/list", nil)
@@ -296,7 +347,7 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
return false, err return false, err
} }
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q.", return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q",
resp.StatusCode, req.URL) resp.StatusCode, req.URL)
} }
defer resp.Body.Close() defer resp.Body.Close()
@@ -312,10 +363,10 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
reason, the method will return false and error. reason, the method will return false and error.
*/ */
if config.auth_mode_code == MODE_UNDEF { if config.auth_mode_code == MODE_UNDEF {
return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode.") return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode")
} }
if config.auth_mode_code != MODE_LEGACY { if config.auth_mode_code != MODE_LEGACY {
return false, fmt.Errorf("validateLegacyUser method called for incompatible authorization mode %q.", config.auth_mode_txt) return false, fmt.Errorf("validateLegacyUser method called for incompatible authorization mode %q", config.auth_mode_txt)
} }
params := url.Values{} params := url.Values{}
@@ -336,12 +387,12 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
return false, err return false, err
} }
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q.", return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q",
resp.StatusCode, config.legacy_user, config.controller_url) resp.StatusCode, config.legacy_user, config.controller_url)
} }
defer resp.Body.Close() defer resp.Body.Close()
responseData, err := ioutil.ReadAll(resp.Body) responseData, err := io.ReadAll(req.Body)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@@ -353,21 +404,32 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
} }
func (config *ControllerCfg) CloudAPI() *cloudapi.CloudAPI { func (config *ControllerCfg) CloudAPI() *cloudapi.CloudAPI {
if config.auth_mode_code == MODE_LEGACY { switch config.auth_mode_code {
case MODE_LEGACY:
client, _ := config.caller.(*decort.LegacyDecortClient) client, _ := config.caller.(*decort.LegacyDecortClient)
return client.CloudAPI() 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{}
} }
client, _ := config.caller.(*decort.DecortClient)
return client.CloudAPI()
} }
func (config *ControllerCfg) CloudBroker() *cloudbroker.CloudBroker { func (config *ControllerCfg) CloudBroker() *cloudbroker.CloudBroker {
if config.auth_mode_code == MODE_LEGACY { switch config.auth_mode_code {
case MODE_LEGACY:
client, _ := config.caller.(*decort.LegacyDecortClient) client, _ := config.caller.(*decort.LegacyDecortClient)
return client.CloudBroker() 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{}
} }
client, _ := config.caller.(*decort.DecortClient)
return client.CloudBroker()
} }

View File

@@ -1,37 +1,65 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Authors:
Stanislav Solovev, <spsolovev@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License"); Kasim Baybikov, <kmbaybikov@basistech.ru>
you may not use this file except in compliance with the License. Nikita Sorokin, <nesorokin@basistech.ru>
You may obtain a copy of the License at Tim Tkachev, <tvtkachev@basistech.ru>
http://www.apache.org/licenses/LICENSE-2.0 Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Unless required by applicable law or agreed to in writing, software You may obtain a copy of the License at
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. http://www.apache.org/licenses/LICENSE-2.0
See the License for the specific language governing permissions and
limitations under the License. Unless required by applicable law or agreed to in writing, software
*/ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/* See the License for the specific language governing permissions and
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud limitations under the License.
Orchestration Technology) with Terraform by Hashicorp. */
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Please see README.md to learn where to place source code so that it Orchestration Technology) with Terraform by Hashicorp.
builds seamlessly.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ Please see README.md to learn where to place source code so that it
builds seamlessly.
package snapshot
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
const snapshotCreateAPI = "/restmachine/cloudbroker/compute/snapshotCreate" */
const snapshotDeleteAPI = "/restmachine/cloudbroker/compute/snapshotDelete"
const snapshotRollbackAPI = "/restmachine/cloudbroker/compute/snapshotRollback" package dc
const snapshotListAPI = "/restmachine/cloudbroker/compute/snapshotList"
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
}

View File

@@ -1,159 +1,254 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package provider package provider
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "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/account"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/bservice" "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/disks"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/extnet" "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/flipgroup"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/image" "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/k8s"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm" "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/lb"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/locations" "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/rg"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/snapshot" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/snapshot"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/stack"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vins"
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_account "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/account"
cb_extnet "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/extnet" cb_audit "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/audit"
cb_grid "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/grid" cb_disks "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/disks"
cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image" cb_extnet "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/extnet"
cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice" cb_flipgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/flipgroup"
cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg" cb_grid "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/grid"
cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep" cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image"
cb_vgpu "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vgpu" 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"
func newDataSourcesMap() map[string]*schema.Resource { cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg"
return map[string]*schema.Resource{ cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep"
"decort_account": account.DataSourceAccount(), cb_stack "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/stack"
"decort_resgroup": rg.DataSourceResgroup(), cb_vins "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins"
"decort_kvmvm": kvmvm.DataSourceCompute(),
"decort_kvmvm_list": kvmvm.DataSourceComputeList(), // cb_vgpu "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vgpu"
"decort_kvmvm_audits": kvmvm.DataSourceComputeAudits(), cb_k8ci "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8ci"
"decort_kvmvm_get_audits": kvmvm.DataSourceComputeGetAudits(), cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s"
"decort_kvmvm_get_console_url": kvmvm.DataSourceComputeGetConsoleUrl(), )
"decort_kvmvm_get_log": kvmvm.DataSourceComputeGetLog(),
"decort_kvmvm_pfw_list": kvmvm.DataSourceComputePfwList(), func newDataSourcesMap() map[string]*schema.Resource {
"decort_kvmvm_user_list": kvmvm.DataSourceComputeUserList(), return map[string]*schema.Resource{
"decort_kvmvm_snapshot_usage": kvmvm.DataSourceComputeSnapshotUsage(), "decort_account": account.DataSourceAccount(),
"decort_k8s": k8s.DataSourceK8s(), "decort_resgroup": rg.DataSourceResgroup(),
"decort_k8s_list": k8s.DataSourceK8sList(), "decort_kvmvm": kvmvm.DataSourceCompute(),
"decort_k8s_list_deleted": k8s.DataSourceK8sListDeleted(), "decort_kvmvm_list": kvmvm.DataSourceComputeList(),
"decort_k8s_wg": k8s.DataSourceK8sWg(), "decort_kvmvm_audits": kvmvm.DataSourceComputeAudits(),
"decort_k8s_wg_list": k8s.DataSourceK8sWgList(), "decort_kvmvm_get_audits": kvmvm.DataSourceComputeGetAudits(),
"decort_k8s_computes": k8s.DataSourceK8sComputes(), "decort_kvmvm_get_console_url": kvmvm.DataSourceComputeGetConsoleUrl(),
"decort_k8ci_list": k8s.DataSourceK8CIList(), "decort_kvmvm_get_log": kvmvm.DataSourceComputeGetLog(),
"decort_vins": vins.DataSourceVins(), "decort_kvmvm_pfw_list": kvmvm.DataSourceComputePfwList(),
"decort_vins_list": vins.DataSourceVinsList(), "decort_kvmvm_user_list": kvmvm.DataSourceComputeUserList(),
"decort_vins_audits": vins.DataSourceVinsAudits(), "decort_kvmvm_snapshot_usage": kvmvm.DataSourceComputeSnapshotUsage(),
"decort_vins_ip_list": vins.DataSourceVinsIpList(), "decort_k8s": k8s.DataSourceK8s(),
"decort_vins_list_deleted": vins.DataSourceVinsListDeleted(), "decort_k8s_list": k8s.DataSourceK8sList(),
"decort_vins_ext_net_list": vins.DataSourceVinsExtNetList(), "decort_k8s_list_deleted": k8s.DataSourceK8sListDeleted(),
"decort_vins_nat_rule_list": vins.DataSourceVinsNatRuleList(), "decort_k8s_wg": k8s.DataSourceK8sWg(),
"decort_snapshot_list": snapshot.DataSourceSnapshotList(), "decort_k8s_wg_list": k8s.DataSourceK8sWgList(),
"decort_disk": disks.DataSourceDisk(), "decort_k8s_computes": k8s.DataSourceK8sComputes(),
"decort_disk_list": disks.DataSourceDiskList(), "decort_k8ci_list": k8s.DataSourceK8CIList(),
"decort_rg_list": rg.DataSourceRgList(), "decort_vins": vins.DataSourceVins(),
"decort_rg_affinity_group_computes": rg.DataSourceRgAffinityGroupComputes(), "decort_vins_list": vins.DataSourceVinsList(),
"decort_rg_affinity_groups_list": rg.DataSourceRgAffinityGroupsList(), "decort_vins_audits": vins.DataSourceVinsAudits(),
"decort_rg_affinity_groups_get": rg.DataSourceRgAffinityGroupsGet(), "decort_vins_ip_list": vins.DataSourceVinsIpList(),
"decort_rg_audits": rg.DataSourceRgAudits(), "decort_vins_list_deleted": vins.DataSourceVinsListDeleted(),
"decort_rg_list_computes": rg.DataSourceRgListComputes(), "decort_vins_ext_net_list": vins.DataSourceVinsExtNetList(),
"decort_rg_list_deleted": rg.DataSourceRgListDeleted(), "decort_vins_nat_rule_list": vins.DataSourceVinsNatRuleList(),
"decort_rg_list_lb": rg.DataSourceRgListLb(), "decort_vins_static_route_list": vins.DataSourceStaticRouteList(),
"decort_rg_list_pfw": rg.DataSourceRgListPfw(), "decort_vins_static_route": vins.DataSourceStaticRoute(),
"decort_rg_list_vins": rg.DataSourceRgListVins(), "decort_snapshot_list": snapshot.DataSourceSnapshotList(),
"decort_rg_usage": rg.DataSourceRgUsage(), "decort_disk": disks.DataSourceDisk(),
"decort_disk_list_types_detailed": disks.DataSourceDiskListTypesDetailed(), "decort_disk_list": disks.DataSourceDiskList(),
"decort_disk_list_types": disks.DataSourceDiskListTypes(), "decort_rg_list": rg.DataSourceRgList(),
"decort_disk_list_deleted": disks.DataSourceDiskListDeleted(), "decort_rg_affinity_group_computes": rg.DataSourceRgAffinityGroupComputes(),
"decort_disk_list_unattached": disks.DataSourceDiskListUnattached(), "decort_rg_affinity_groups_list": rg.DataSourceRgAffinityGroupsList(),
"decort_disk_snapshot": disks.DataSourceDiskSnapshot(), "decort_rg_affinity_groups_get": rg.DataSourceRgAffinityGroupsGet(),
"decort_disk_snapshot_list": disks.DataSourceDiskSnapshotList(), "decort_rg_audits": rg.DataSourceRgAudits(),
"decort_account_list": account.DataSourceAccountList(), "decort_rg_list_computes": rg.DataSourceRgListComputes(),
"decort_account_computes_list": account.DataSourceAccountComputesList(), "decort_rg_list_deleted": rg.DataSourceRgListDeleted(),
"decort_account_disks_list": account.DataSourceAccountDisksList(), "decort_rg_list_lb": rg.DataSourceRgListLb(),
"decort_account_vins_list": account.DataSourceAccountVinsList(), "decort_rg_list_pfw": rg.DataSourceRgListPfw(),
"decort_account_audits_list": account.DataSourceAccountAuditsList(), "decort_rg_list_vins": rg.DataSourceRgListVins(),
"decort_account_rg_list": account.DataSourceAccountRGList(), "decort_rg_usage": rg.DataSourceRgUsage(),
"decort_account_consumed_units": account.DataSourceAccountConsumedUnits(), "decort_disk_list_types_detailed": disks.DataSourceDiskListTypesDetailed(),
"decort_account_consumed_units_by_type": account.DataSourceAccountConsumedUnitsByType(), "decort_disk_list_types": disks.DataSourceDiskListTypes(),
"decort_account_reserved_units": account.DataSourceAccountReservedUnits(), "decort_disk_list_deleted": disks.DataSourceDiskListDeleted(),
"decort_account_templates_list": account.DataSourceAccountTemplatessList(), "decort_disk_list_unattached": disks.DataSourceDiskListUnattached(),
"decort_account_deleted_list": account.DataSourceAccountDeletedList(), "decort_disk_snapshot": disks.DataSourceDiskSnapshot(),
"decort_account_flipgroups_list": account.DataSourceAccountFlipGroupsList(), "decort_disk_snapshot_list": disks.DataSourceDiskSnapshotList(),
"decort_bservice_list": bservice.DataSourceBasicServiceList(), "decort_account_list": account.DataSourceAccountList(),
"decort_bservice": bservice.DataSourceBasicService(), "decort_account_computes_list": account.DataSourceAccountComputesList(),
"decort_bservice_snapshot_list": bservice.DataSourceBasicServiceSnapshotList(), "decort_account_disks_list": account.DataSourceAccountDisksList(),
"decort_bservice_group": bservice.DataSourceBasicServiceGroup(), "decort_account_vins_list": account.DataSourceAccountVinsList(),
"decort_bservice_deleted_list": bservice.DataSourceBasicServiceDeletedList(), "decort_account_audits_list": account.DataSourceAccountAuditsList(),
"decort_extnet_list": extnet.DataSourceExtnetList(), "decort_account_rg_list": account.DataSourceAccountRGList(),
"decort_extnet_computes_list": extnet.DataSourceExtnetComputesList(), "decort_account_consumed_units": account.DataSourceAccountConsumedUnits(),
"decort_extnet": extnet.DataSourceExtnet(), "decort_account_consumed_units_by_type": account.DataSourceAccountConsumedUnitsByType(),
"decort_extnet_default": extnet.DataSourceExtnetDefault(), "decort_account_reserved_units": account.DataSourceAccountReservedUnits(),
"decort_locations_list": locations.DataSourceLocationsList(), "decort_account_templates_list": account.DataSourceAccountTemplatessList(),
"decort_location_url": locations.DataSourceLocationUrl(), "decort_account_deleted_list": account.DataSourceAccountDeletedList(),
"decort_image_list": image.DataSourceImageList(), "decort_account_flipgroups_list": account.DataSourceAccountFlipGroupsList(),
"decort_image": image.DataSourceImage(), "decort_bservice_list": bservice.DataSourceBasicServiceList(),
"decort_lb": lb.DataSourceLB(), "decort_bservice": bservice.DataSourceBasicService(),
"decort_lb_list": lb.DataSourceLBList(), "decort_bservice_snapshot_list": bservice.DataSourceBasicServiceSnapshotList(),
"decort_lb_list_deleted": lb.DataSourceLBListDeleted(), "decort_bservice_group": bservice.DataSourceBasicServiceGroup(),
"decort_flipgroup": flipgroup.DataSourceFlipgroup(), "decort_bservice_deleted_list": bservice.DataSourceBasicServiceDeletedList(),
"decort_flipgroup_list": flipgroup.DataSourceFlipGroupList(), "decort_extnet_list": extnet.DataSourceExtnetList(),
"decort_extnet_computes_list": extnet.DataSourceExtnetComputesList(),
"decort_cb_account": cb_account.DataSourceAccount(), "decort_extnet": extnet.DataSourceExtnet(),
"decort_cb_account_list": cb_account.DataSourceAccountList(), "decort_extnet_default": extnet.DataSourceExtnetDefault(),
"decort_cb_account_computes_list": cb_account.DataSourceAccountComputesList(), "decort_locations_list": locations.DataSourceLocationsList(),
"decort_cb_account_deleted_list": cb_account.DataSourceAccountDeletedList(), "decort_location_url": locations.DataSourceLocationUrl(),
"decort_cb_account_disks_list": cb_account.DataSourceAccountDisksList(), "decort_image_list": image.DataSourceImageList(),
"decort_cb_account_flipgroups_list": cb_account.DataSourceAccountFlipGroupsList(), "decort_image": image.DataSourceImage(),
"decort_cb_account_rg_list": cb_account.DataSourceAccountRGList(), "decort_lb": lb.DataSourceLB(),
"decort_cb_account_vins_list": cb_account.DataSourceAccountVinsList(), "decort_lb_list": lb.DataSourceLBList(),
"decort_cb_account_audits_list": cb_account.DataSourceAccountAuditsList(), "decort_lb_list_deleted": lb.DataSourceLBListDeleted(),
"decort_cb_extnet": cb_extnet.DataSourceExtnetCB(), "decort_flipgroup": flipgroup.DataSourceFlipgroup(),
"decort_cb_extnet_list": cb_extnet.DataSourceExtnetListCB(), "decort_flipgroup_list": flipgroup.DataSourceFlipGroupList(),
"decort_cb_extnet_default": cb_extnet.DataSourceExtnetDefaultCB(), "decort_stack": stack.DataSourceStack(),
"decort_cb_disk": cb_disks.DataSourceDisk(), "decort_stack_list": stack.DataSourceStackList(),
"decort_cb_disk_list": cb_disks.DataSourceDiskList(), "decort_account_resource_consumption_list": account.DataSourceAccountResourceConsumptionList(),
"decort_cb_image": cb_image.DataSourceImage(), "decort_account_resource_consumption_get": account.DataSourceAccountResourceConsumptionGet(),
"decort_cb_grid": cb_grid.DataSourceGrid(), "decort_kvmvm_list_deleted": kvmvm.DataSourceComputeListDeleted(),
"decort_cb_grid_list": cb_grid.DataSourceGridList(), "decort_kvmvm_vgpu_list": kvmvm.DataSourceComputeVGPUList(),
"decort_cb_image_list": cb_image.DataSourceImageList(), "decort_kvmvm_pci_device_list": kvmvm.DataSourceComputePCIDeviceList(),
"decort_cb_image_list_stacks": cb_image.DataSourceImageListStacks(), "decort_k8s_wg_cloud_init": k8s.DataSourceK8sWgCloudInit(),
"decort_cb_pcidevice": cb_pcidevice.DataSourcePcidevice(), "decort_rg_resource_consumption_list": rg.DataSourceRGResourceConsumptionList(),
"decort_cb_pcidevice_list": cb_pcidevice.DataSourcePcideviceList(), "decort_rg_resource_consumption_get": rg.DataSourceRGResourceConsumptionGet(),
"decort_cb_sep_list": cb_sep.DataSourceSepList(),
"decort_cb_sep": cb_sep.DataSourceSep(), "decort_cb_account": cb_account.DataSourceAccount(),
"decort_cb_sep_consumption": cb_sep.DataSourceSepConsumption(), "decort_cb_account_list": cb_account.DataSourceAccountList(),
"decort_cb_sep_disk_list": cb_sep.DataSourceSepDiskList(), "decort_cb_account_computes_list": cb_account.DataSourceAccountComputesList(),
"decort_cb_sep_config": cb_sep.DataSourceSepConfig(), "decort_cb_account_list_deleted": cb_account.DataSourceAccountDeletedList(),
"decort_cb_sep_pool": cb_sep.DataSourceSepPool(), "decort_cb_account_disks_list": cb_account.DataSourceAccountDisksList(),
"decort_cb_vgpu": cb_vgpu.DataSourceVGPU(), "decort_cb_account_flipgroups_list": cb_account.DataSourceAccountFlipGroupsList(),
"decort_cb_rg_list": cb_rg.DataSourceRgList(), "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_audit": cb_audit.DataSourceAudit(),
"decort_cb_audit_list": cb_audit.DataSourceAuditList(),
"decort_cb_audit_linked_jobs": cb_audit.DataSourceAuditLinkedJobs(),
"decort_cb_extnet": cb_extnet.DataSourceExtnetCB(),
"decort_cb_extnet_list": cb_extnet.DataSourceExtnetListCB(),
"decort_cb_extnet_default": cb_extnet.DataSourceExtnetDefaultCB(),
"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_post_diagnosis": cb_grid.DataSourceGridPostDiagnosis(),
"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_image_list_stacks": cb_image.DataSourceImageListStacks(),
"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_disk": cb_disks.DataSourceDisk(),
"decort_cb_disk_list": cb_disks.DataSourceDiskList(),
"decort_cb_disk_list_deleted": cb_disks.DataSourceDiskListDeleted(),
"decort_cb_disk_list_types": cb_disks.DataSourceDiskListTypes(),
"decort_cb_disk_list_types_detailed": cb_disks.DataSourceDiskListTypesDetailed(),
"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_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_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_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_stack_list": cb_stack.DataSourceStacksList(),
"decort_cb_stack": cb_stack.DataSourceStack(),
"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(),
}
}

View File

@@ -1,129 +1,168 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package provider package provider
import ( import (
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "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/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"golang.org/x/net/context" "golang.org/x/net/context"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "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/location"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs"
) )
func Provider() *schema.Provider { func Provider() *schema.Provider {
return &schema.Provider{ return &schema.Provider{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"authenticator": { "authenticator": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
StateFunc: statefuncs.StateFuncToLower, StateFunc: statefuncs.StateFuncToLower,
ValidateFunc: validation.StringInSlice([]string{"oauth2", "legacy", "jwt"}, true), // ignore case while validating 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 'oauth2', 'legacy' or 'jwt'.", Description: "Authentication mode to use when connecting to DECORT cloud API. Should be one of 'decs3o', 'legacy', 'jwt' or 'bvs'.",
}, },
"oauth2_url": { "oauth2_url": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
StateFunc: statefuncs.StateFuncToLower, StateFunc: statefuncs.StateFuncToLower,
DefaultFunc: schema.EnvDefaultFunc("DECORT_OAUTH2_URL", nil), DefaultFunc: schema.EnvDefaultFunc("DECORT_OAUTH2_URL", nil),
Description: "OAuth2 application URL in 'oauth2' authentication mode.", Description: "OAuth2 application URL in 'decs3o' and 'bvs' authentication mode.",
}, },
"controller_url": { "controller_url": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true, ForceNew: true,
StateFunc: statefuncs.StateFuncToLower, StateFunc: statefuncs.StateFuncToLower,
Description: "URL of DECORT Cloud controller to use. API calls will be directed to this URL.", Description: "URL of DECORT Cloud controller to use. API calls will be directed to this URL.",
}, },
"user": { "user": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_USER", nil), DefaultFunc: schema.EnvDefaultFunc("DECORT_USER", nil),
Description: "User name for DECORT cloud API operations in 'legacy' authentication mode.", Description: "User name for DECORT cloud API operations in 'legacy' authentication mode.",
}, },
"password": { "password": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_PASSWORD", nil), DefaultFunc: schema.EnvDefaultFunc("DECORT_PASSWORD", nil),
Description: "User password for DECORT cloud API operations in 'legacy' authentication mode.", Description: "User password for DECORT cloud API operations in 'legacy' authentication mode.",
}, },
"app_id": { "bvs_user": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_ID", nil), DefaultFunc: schema.EnvDefaultFunc("DECORT_BVS_USER", nil),
Description: "Application ID to access DECORT cloud API in 'oauth2' authentication mode.", Description: "User name for DECORT cloud API operations in 'bvs' authentication mode.",
}, },
"app_secret": { "bvs_password": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_SECRET", nil), DefaultFunc: schema.EnvDefaultFunc("DECORT_BVS_PASSWORD", nil),
Description: "Application secret to access DECORT cloud API in 'oauth2' authentication mode.", Description: "User password for DECORT cloud API operations in 'bvs' authentication mode.",
}, },
"jwt": { "domain": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_JWT", nil), DefaultFunc: schema.EnvDefaultFunc("DECORT_DOMAIN", nil),
Description: "JWT to access DECORT cloud API in 'jwt' authentication mode.", Description: "User password for DECORT cloud API operations in 'bvs' authentication mode.",
}, },
"allow_unverified_ssl": { "app_id": {
Type: schema.TypeBool, Type: schema.TypeString,
Optional: true, Optional: true,
Default: false, DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_ID", nil),
Description: "If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only!", Description: "Application ID to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode.",
}, },
},
"app_secret": {
ResourcesMap: newResourcesMap(), Type: schema.TypeString,
Optional: true,
DataSourcesMap: newDataSourcesMap(), DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_SECRET", nil),
Description: "Application secret to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode.",
ConfigureContextFunc: providerConfigure, },
}
} "jwt": {
Type: schema.TypeString,
func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { Optional: true,
decsController, err := controller.ControllerConfigure(d) DefaultFunc: schema.EnvDefaultFunc("DECORT_JWT", nil),
if err != nil { Description: "JWT to access DECORT cloud API in 'jwt' authentication mode.",
return nil, diag.FromErr(err) },
}
"allow_unverified_ssl": {
gridId, err := location.UtilityLocationGetDefaultGridID(ctx, decsController) Type: schema.TypeBool,
if err != nil { Optional: true,
return nil, diag.FromErr(err) Default: false,
} Description: "If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only!",
if gridId == 0 { },
return nil, diag.FromErr(fmt.Errorf("providerConfigure: invalid default Grid ID = 0"))
} "path_cfg": {
Type: schema.TypeString,
return decsController, nil 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
}

View File

@@ -1,94 +1,103 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package provider package provider
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "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/account"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/bservice" "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/disks"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/flipgroup" "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/image"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/k8s" "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/kvmvm"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/lb" "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/pfw"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/rg"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/snapshot" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/snapshot"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vins"
cb_account "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/account" 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_disks "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/disks"
cb_extnet "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/extnet" cb_extnet "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/extnet"
cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image" cb_flipgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/flipgroup"
cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s" cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image"
cb_kvmvm "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/kvmvm" cb_k8ci "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8ci"
cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice" cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s"
cb_pfw "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pfw" cb_kvmvm "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/kvmvm"
cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg" cb_lb "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/lb"
cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep" cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice"
cb_snapshot "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/snapshot" cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg"
cb_vins "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins" cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep"
) cb_vins "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins"
)
func newResourcesMap() map[string]*schema.Resource {
return map[string]*schema.Resource{ func newResourcesMap() map[string]*schema.Resource {
"decort_resgroup": rg.ResourceResgroup(), return map[string]*schema.Resource{
"decort_kvmvm": kvmvm.ResourceCompute(), "decort_resgroup": rg.ResourceResgroup(),
"decort_disk": disks.ResourceDisk(), "decort_kvmvm": kvmvm.ResourceCompute(),
"decort_disk_snapshot": disks.ResourceDiskSnapshot(), "decort_disk": disks.ResourceDisk(),
"decort_vins": vins.ResourceVins(), "decort_disk_snapshot": disks.ResourceDiskSnapshot(),
"decort_pfw": pfw.ResourcePfw(), "decort_vins": vins.ResourceVins(),
"decort_k8s": k8s.ResourceK8s(), "decort_pfw": pfw.ResourcePfw(),
"decort_k8s_wg": k8s.ResourceK8sWg(), "decort_k8s": k8s.ResourceK8s(),
"decort_k8s_cp": k8s.ResourceK8sCP(), "decort_k8s_wg": k8s.ResourceK8sWg(),
"decort_snapshot": snapshot.ResourceSnapshot(), "decort_k8s_cp": k8s.ResourceK8sCP(),
"decort_account": account.ResourceAccount(), "decort_snapshot": snapshot.ResourceSnapshot(),
"decort_bservice": bservice.ResourceBasicService(), "decort_account": account.ResourceAccount(),
"decort_bservice_group": bservice.ResourceBasicServiceGroup(), "decort_bservice": bservice.ResourceBasicService(),
"decort_image": image.ResourceImage(), "decort_bservice_group": bservice.ResourceBasicServiceGroup(),
"decort_image_virtual": image.ResourceImageVirtual(), "decort_image": image.ResourceImage(),
"decort_lb": lb.ResourceLB(), "decort_image_virtual": image.ResourceImageVirtual(),
"decort_lb_backend": lb.ResourceLBBackend(), "decort_lb": lb.ResourceLB(),
"decort_lb_backend_server": lb.ResourceLBBackendServer(), "decort_lb_backend": lb.ResourceLBBackend(),
"decort_lb_frontend": lb.ResourceLBFrontend(), "decort_lb_backend_server": lb.ResourceLBBackendServer(),
"decort_lb_frontend_bind": lb.ResourceLBFrontendBind(), "decort_lb_frontend": lb.ResourceLBFrontend(),
"decort_flipgroup": flipgroup.ResourceFlipgroup(), "decort_lb_frontend_bind": lb.ResourceLBFrontendBind(),
"decort_flipgroup": flipgroup.ResourceFlipgroup(),
"decort_cb_account": cb_account.ResourceAccount(), "decort_vins_static_route": vins.ResourceStaticRoute(),
"decort_cb_extnet": cb_extnet.ResourceExtnetCB(),
"decort_cb_disk": cb_disks.ResourceDisk(), "decort_cb_account": cb_account.ResourceAccount(),
"decort_cb_image": cb_image.ResourceImage(), "decort_cb_extnet": cb_extnet.ResourceExtnetCB(),
"decort_cb_virtual_image": cb_image.ResourceVirtualImage(), "decort_cb_extnet_static_route": cb_extnet.ResourceStaticRoute(),
"decort_cb_cdrom_image": cb_image.ResourceCDROMImage(), "decort_cb_disk": cb_disks.ResourceDisk(),
"decort_cb_delete_images": cb_image.ResourceDeleteImages(), "decort_cb_disk_snapshot": cb_disks.ResourceDiskSnapshot(),
"decort_cb_pcidevice": cb_pcidevice.ResourcePcidevice(), "decort_cb_image": cb_image.ResourceImage(),
"decort_cb_sep": cb_sep.ResourceSep(), "decort_cb_virtual_image": cb_image.ResourceVirtualImage(),
"decort_cb_sep_config": cb_sep.ResourceSepConfig(), "decort_cb_cdrom_image": cb_image.ResourceCDROMImage(),
"decort_cb_resgroup": cb_rg.ResourceResgroup(), "decort_cb_pcidevice": cb_pcidevice.ResourcePcidevice(),
"decort_cb_kvmvm": cb_kvmvm.ResourceCompute(), "decort_cb_sep": cb_sep.ResourceSep(),
"decort_cb_vins": cb_vins.ResourceVins(), "decort_cb_sep_config": cb_sep.ResourceSepConfig(),
"decort_cb_pfw": cb_pfw.ResourcePfw(), "decort_cb_kvmvm": cb_kvmvm.ResourceCompute(),
"decort_cb_k8s": cb_k8s.ResourceK8s(), "decort_cb_vins": cb_vins.ResourceVins(),
"decort_cb_k8s_wg": cb_k8s.ResourceK8sWg(), "decort_cb_k8ci": cb_k8ci.ResourceK8CI(),
"decort_cb_snapshot": cb_snapshot.ResourceSnapshot(), "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(),
}
}

View File

@@ -0,0 +1,136 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 {
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,
},
"cu_np": {
Type: schema.TypeFloat,
Computed: true,
},
"gpu_units": {
Type: schema.TypeFloat,
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(),
}
}

View File

@@ -0,0 +1,169 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 {
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,
},
"ext_traffic": {
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 DataSourceAccountResourceConsumptionList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceAccountResourceConsumptionListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceAccountResourceConsumptionListSchemaMake(),
}
}

View File

@@ -43,7 +43,7 @@ import (
) )
func flattenAccountTemplatesList(atl *account.ListTemplates) []map[string]interface{} { func flattenAccountTemplatesList(atl *account.ListTemplates) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(atl.Data))
for _, at := range atl.Data { for _, at := range atl.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"unc_path": at.UNCPath, "unc_path": at.UNCPath,
@@ -72,7 +72,7 @@ func dataSourceAccountTemplatesListRead(ctx context.Context, d *schema.ResourceD
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenAccountTemplatesList(accountTemplatesList)) d.Set("items", flattenAccountTemplatesList(accountTemplatesList))
d.Set("entry_count", accountTemplatesList.EntryCount)
return nil return nil
} }
@@ -87,6 +87,31 @@ func dataSourceAccountTemplatesListSchemaMake() map[string]*schema.Schema {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, 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",
},
"page": {
Type: schema.TypeInt,
Optional: true,
Description: "Page number",
},
"size": {
Type: schema.TypeInt,
Optional: true,
Description: "Page size",
},
"items": { "items": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -136,6 +161,10 @@ func dataSourceAccountTemplatesListSchemaMake() map[string]*schema.Schema {
}, },
}, },
}, },
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
} }
return res return res
} }

View File

@@ -21,7 +21,7 @@ func flattenAccount(d *schema.ResourceData, acc account.RecordAccount) error {
d.Set("guid", acc.GUID) d.Set("guid", acc.GUID)
d.Set("account_id", acc.ID) d.Set("account_id", acc.ID)
d.Set("account_name", acc.Name) d.Set("account_name", acc.Name)
d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits)) d.Set("resource_limits", flattenAccResourceLimits(acc.ResourceLimits))
d.Set("send_access_emails", acc.SendAccessEmails) d.Set("send_access_emails", acc.SendAccessEmails)
d.Set("status", acc.Status) d.Set("status", acc.Status)
d.Set("updated_time", acc.UpdatedTime) d.Set("updated_time", acc.UpdatedTime)
@@ -79,11 +79,19 @@ func flattenAccAcl(acls []account.RecordACL) []map[string]interface{} {
return res return res
} }
func flattenRgResourceLimits(rl account.ResourceLimits) []map[string]interface{} { 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) res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{ temp := map[string]interface{}{
"cu_c": rl.CUC, "cu_c": rl.CUC,
"cu_d": rl.CUD, "cu_d": rl.CUD,
"cu_dm": rl.CUDM,
"cu_i": rl.CUI, "cu_i": rl.CUI,
"cu_m": rl.CUM, "cu_m": rl.CUM,
"cu_np": rl.CUNP, "cu_np": rl.CUNP,
@@ -124,14 +132,28 @@ func flattenAccountSeps(seps map[string]map[string]account.DiskUsage) []map[stri
func flattenAccResource(r account.Resource) []map[string]interface{} { func flattenAccResource(r account.Resource) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{ temp := map[string]interface{}{
"cpu": r.CPU, "cpu": r.CPU,
"disksize": r.DiskSize, "disk_size": r.DiskSize,
"extips": r.ExtIPs, "disk_size_max": r.DiskSizeMax,
"exttraffic": r.ExtTraffic, "ext_ips": r.ExtIPs,
"gpu": r.GPU, "ext_traffic": r.ExtTraffic,
"ram": r.RAM, "gpu": r.GPU,
"seps": flattenAccountSeps(r.SEPs), "ram": r.RAM,
"seps": flattenAccountSeps(r.SEPs),
} }
res = append(res, temp) res = append(res, temp)
return res 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
}

View File

@@ -54,7 +54,7 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interf
func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceAccountRead: called for account with ID: %v", d.Id()) log.Debugf("resourceAccountRead: called for account with ID: %v", d.Id())
c := m.(*controller.ControllerCfg) // c := m.(*controller.ControllerCfg)
acc, err := utilityAccountCheckPresence(ctx, d, m) acc, err := utilityAccountCheckPresence(ctx, d, m)
if err != nil { if err != nil {
@@ -67,22 +67,23 @@ func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interfac
switch acc.Status { switch acc.Status {
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceAccountCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceAccountCreate(ctx, d, m)
case status.Destroying: case status.Destroying:
return diag.Errorf("The account is in progress with status: %s", acc.Status) return diag.Errorf("The account is in progress with status: %s", acc.Status)
case status.Deleted: case status.Deleted:
id, _ := strconv.ParseUint(d.Id(), 10, 64) // id, _ := strconv.ParseUint(d.Id(), 10, 64)
req := account.RestoreRequest{ // req := account.RestoreRequest{
AccountID: id, // AccountID: id,
} // }
_, err := c.CloudAPI().Account().Restore(ctx, req) // _, err := c.CloudAPI().Account().Restore(ctx, req)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
hasChanged = true // hasChanged = true
case status.Disabled: case status.Disabled:
log.Debugf("The account is in status: %s, troubles may occur with update. Please, enable account first.", acc.Status) log.Debugf("The account is in status: %s, troubles may occur with update. Please, enable account first.", acc.Status)
case status.Confirmed: case status.Confirmed:
@@ -142,7 +143,8 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf
switch acc.Status { switch acc.Status {
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceAccountCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceAccountCreate(ctx, d, m)
case status.Destroying: case status.Destroying:
return diag.Errorf("The account is in progress with status: %s", acc.Status) return diag.Errorf("The account is in progress with status: %s", acc.Status)
case status.Deleted: case status.Deleted:

View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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
}

View File

@@ -0,0 +1,55 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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
}

View File

@@ -44,9 +44,8 @@ import (
func utilityAccountTemplatesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListTemplates, error) { func utilityAccountTemplatesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ListTemplates, error) {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
var id uint64
id = uint64(d.Get("account_id").(int)) id := uint64(d.Get("account_id").(int))
req := account.ListTemplatesRequest{ req := account.ListTemplatesRequest{
AccountID: id, AccountID: id,
@@ -55,6 +54,21 @@ func utilityAccountTemplatesListCheckPresence(ctx context.Context, d *schema.Res
if include_deleted, ok := d.GetOk("include_deleted"); ok { if include_deleted, ok := d.GetOk("include_deleted"); ok {
req.IncludeDeleted = include_deleted.(bool) 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 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") log.Debugf("utilityAccountTemplatesListCheckPresence: load")
accountTemplatesList, err := c.CloudAPI().Account().ListTemplates(ctx, req) accountTemplatesList, err := c.CloudAPI().Account().ListTemplates(ctx, req)

View File

@@ -146,7 +146,7 @@ func dataSourceBasicServiceSchemaMake() map[string]*schema.Schema {
Computed: true, Computed: true,
}, },
"disk_total": { "disk_total": {
Type: schema.TypeString, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"gid": { "gid": {
@@ -185,13 +185,13 @@ func dataSourceBasicServiceSchemaMake() map[string]*schema.Schema {
}, },
}, },
}, },
"groups_name": { // "groups_name": {
Type: schema.TypeList, // Type: schema.TypeList,
Computed: true, // Computed: true,
Elem: &schema.Schema{ // Elem: &schema.Schema{
Type: schema.TypeString, // Type: schema.TypeString,
}, // },
}, // },
"guid": { "guid": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,

View File

@@ -49,8 +49,8 @@ func dataSourceBasicServiceSnapshotListRead(ctx context.Context, d *schema.Resou
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenBasicServiceSnapshots(basicServiceSnapshotList)) d.Set("items", flattenBasicServiceSnapshotsList(basicServiceSnapshotList))
d.Set("entry_count", basicServiceSnapshotList.EntryCount)
return nil return nil
} }

View File

@@ -30,6 +30,7 @@ func flattenResourceBasicServiceGroup(d *schema.ResourceData, bsg *bservice.Reco
d.Set("rg_name", bsg.RGName) d.Set("rg_name", bsg.RGName)
d.Set("role", bsg.Role) d.Set("role", bsg.Role)
d.Set("sep_id", bsg.SEPID) d.Set("sep_id", bsg.SEPID)
d.Set("sep_pool", bsg.PoolName)
d.Set("seq_no", bsg.SeqNo) d.Set("seq_no", bsg.SeqNo)
d.Set("status", bsg.Status) d.Set("status", bsg.Status)
d.Set("tech_status", bsg.TechStatus) d.Set("tech_status", bsg.TechStatus)
@@ -110,7 +111,7 @@ func flattenBasicServiceComputes(bscs bservice.ListComputes) []map[string]interf
} }
func flattenBasicServiceSnapshots(bsrvss bservice.ListSnapshots) []map[string]interface{} { func flattenBasicServiceSnapshots(bsrvss bservice.ListSnapshots) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(bsrvss))
for _, bsrvs := range bsrvss { for _, bsrvs := range bsrvss {
temp := map[string]interface{}{ temp := map[string]interface{}{
"guid": bsrvs.GUID, "guid": bsrvs.GUID,
@@ -122,3 +123,17 @@ func flattenBasicServiceSnapshots(bsrvss bservice.ListSnapshots) []map[string]in
} }
return res 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
}

View File

@@ -77,13 +77,40 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i
d.SetId(strconv.FormatUint(serviceId, 10)) d.SetId(strconv.FormatUint(serviceId, 10))
d.Set("service_id", serviceId) d.Set("service_id", serviceId)
service, err := utilityBasicServiceCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
if d.Get("enable").(bool) && (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 {
return diag.FromErr(err)
}
}
if d.Get("start").(bool) && d.Get("enable").(bool) {
log.Debugf("trying to start bservice %v", serviceId)
_, err := c.CloudAPI().BService().Enable(ctx, bservice.EnableRequest{
ServiceID: serviceId,
})
if err != nil {
return diag.FromErr(err)
}
}
return resourceBasicServiceRead(ctx, d, m) return resourceBasicServiceRead(ctx, d, m)
} }
func resourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceBasicServiceRead") log.Debugf("resourceBasicServiceRead")
c := m.(*controller.ControllerCfg) // c := m.(*controller.ControllerCfg)
bs, err := utilityBasicServiceCheckPresence(ctx, d, m) bs, err := utilityBasicServiceCheckPresence(ctx, d, m)
if err != nil { if err != nil {
@@ -104,29 +131,30 @@ func resourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m int
case status.Disabling: case status.Disabling:
log.Debugf("The basic service is in status: %s, troubles can occur with the update.", bs.Status) log.Debugf("The basic service is in status: %s, troubles can occur with the update.", bs.Status)
case status.Deleted: case status.Deleted:
id, _ := strconv.ParseUint(d.Id(), 10, 64) // id, _ := strconv.ParseUint(d.Id(), 10, 64)
restoreReq := bservice.RestoreRequest{ // restoreReq := bservice.RestoreRequest{
ServiceID: id, // ServiceID: id,
} // }
enableReq := bservice.EnableRequest{ // enableReq := bservice.EnableRequest{
ServiceID: id, // ServiceID: id,
} // }
_, err := c.CloudAPI().BService().Restore(ctx, restoreReq) // _, err := c.CloudAPI().BService().Restore(ctx, restoreReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
_, err = c.CloudAPI().BService().Enable(ctx, enableReq) // _, err = c.CloudAPI().BService().Enable(ctx, enableReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
hasChanged = true // hasChanged = true
case status.Deleting: case status.Deleting:
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceBasicServiceCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceBasicServiceCreate(ctx, d, m)
case status.Destroying: case status.Destroying:
return diag.Errorf("The basic service is in progress with status: %s", bs.Status) return diag.Errorf("The basic service is in progress with status: %s", bs.Status)
case status.Restoring: case status.Restoring:
@@ -224,7 +252,8 @@ func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m i
case status.Deleting: case status.Deleting:
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceBasicServiceCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceBasicServiceCreate(ctx, d, m)
case status.Destroying: case status.Destroying:
return diag.Errorf("The basic service is in progress with status: %s", bs.Status) return diag.Errorf("The basic service is in progress with status: %s", bs.Status)
case status.Restoring: case status.Restoring:
@@ -533,7 +562,7 @@ func resourceBasicServiceSchemaMake() map[string]*schema.Schema {
Computed: true, Computed: true,
}, },
"disk_total": { "disk_total": {
Type: schema.TypeString, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"gid": { "gid": {

View File

@@ -68,6 +68,20 @@ func resourceBasicServiceGroupCreate(ctx context.Context, d *schema.ResourceData
req.TimeoutStart = uint64(timeoutStart.(int)) 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 { if vinses, ok := d.GetOk("vinses"); ok {
res := []uint64{} res := []uint64{}
for _, vins := range vinses.([]interface{}) { for _, vins := range vinses.([]interface{}) {
@@ -93,6 +107,20 @@ func resourceBasicServiceGroupCreate(ctx context.Context, d *schema.ResourceData
d.SetId(strconv.FormatUint(compgroupId, 10)) d.SetId(strconv.FormatUint(compgroupId, 10))
d.Set("compgroup_id", compgroupId) 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) return resourceBasicServiceGroupRead(ctx, d, m)
} }
@@ -362,6 +390,25 @@ func resourceBasicServiceGroupSchemaMake() map[string]*schema.Schema {
Required: true, Required: true,
Description: "compute driver like a KVM_X86, KVM_PPC, etc.", Description: "compute driver like a KVM_X86, KVM_PPC, etc.",
}, },
///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.",
},
///
"role": { "role": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@@ -524,10 +571,6 @@ func resourceBasicServiceGroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"sep_id": {
Type: schema.TypeInt,
Computed: true,
},
"seq_no": { "seq_no": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,

View File

@@ -42,7 +42,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
func utilityBasicServiceSnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (bservice.ListSnapshots, error) { func utilityBasicServiceSnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*bservice.ListInfoSnapshots, error) {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
var id uint64 var id uint64

View File

@@ -97,6 +97,16 @@ func dataSourceDiskListSchemaMake() map[string]*schema.Schema {
Optional: true, Optional: true,
Description: "type of the disks", Description: "type of the disks",
}, },
"sep_id": {
Type: schema.TypeInt,
Optional: true,
Description: "find by sep ID",
},
"pool_name": {
Type: schema.TypeString,
Optional: true,
Description: "find by pool name",
},
"page": { "page": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,

View File

@@ -49,12 +49,23 @@ func dataSourceDiskListTypesRead(ctx context.Context, d *schema.ResourceData, m
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("types", listTypes) d.Set("types", listTypes.Data)
d.Set("entry_count", listTypes.EntryCount)
return nil return nil
} }
func dataSourceDiskListTypesSchemaMake() map[string]*schema.Schema { func dataSourceDiskListTypesSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{ res := map[string]*schema.Schema{
"page": {
Type: schema.TypeInt,
Optional: true,
Description: "Page number",
},
"size": {
Type: schema.TypeInt,
Optional: true,
Description: "Page size",
},
"types": { "types": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -63,6 +74,10 @@ func dataSourceDiskListTypesSchemaMake() map[string]*schema.Schema {
}, },
Description: "The types of disk in terms of its role in compute: 'B=Boot, D=Data, T=Temp'", Description: "The types of disk in terms of its role in compute: 'B=Boot, D=Data, T=Temp'",
}, },
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
} }
return res return res
} }

View File

@@ -49,6 +49,7 @@ func flattenDiskListTypesDetailed(tld *disks.ListTypes) []map[string]interface{}
temp := map[string]interface{}{ temp := map[string]interface{}{
"pools": flattenListTypesDetailedPools(toMap["pools"].([]interface{})), "pools": flattenListTypesDetailedPools(toMap["pools"].([]interface{})),
"sep_id": toMap["sepId"].(float64), "sep_id": toMap["sepId"].(float64),
"sep_name": toMap["sepName"].(string),
} }
res = append(res, temp) res = append(res, temp)
} }
@@ -61,6 +62,7 @@ func flattenListTypesDetailedPools(pools []interface{}) []interface{} {
toMap := pool.(map[string]interface{}) toMap := pool.(map[string]interface{})
temp := map[string]interface{}{ temp := map[string]interface{}{
"name": toMap["name"].(string), "name": toMap["name"].(string),
"system": toMap["system"].(string),
"types": toMap["types"].([]interface{}), "types": toMap["types"].([]interface{}),
} }
res = append(res, temp) res = append(res, temp)
@@ -78,11 +80,22 @@ func dataSourceDiskListTypesDetailedRead(ctx context.Context, d *schema.Resource
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenDiskListTypesDetailed(listTypesDetailed)) d.Set("items", flattenDiskListTypesDetailed(listTypesDetailed))
d.Set("entry_count", listTypesDetailed.EntryCount)
return nil return nil
} }
func dataSourceDiskListTypesDetailedSchemaMake() map[string]*schema.Schema { func dataSourceDiskListTypesDetailedSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{ res := map[string]*schema.Schema{
"page": {
Type: schema.TypeInt,
Optional: true,
Description: "Page number",
},
"size": {
Type: schema.TypeInt,
Optional: true,
Description: "Page size",
},
"items": { "items": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -98,6 +111,10 @@ func dataSourceDiskListTypesDetailedSchemaMake() map[string]*schema.Schema {
Computed: true, Computed: true,
Description: "Pool name", Description: "Pool name",
}, },
"system": {
Type: schema.TypeString,
Computed: true,
},
"types": { "types": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -114,9 +131,17 @@ func dataSourceDiskListTypesDetailedSchemaMake() map[string]*schema.Schema {
Computed: true, Computed: true,
Description: "Storage endpoint provider ID to create disk", Description: "Storage endpoint provider ID to create disk",
}, },
"sep_name": {
Type: schema.TypeString,
Computed: true,
},
}, },
}, },
}, },
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
} }
return res return res
} }

View File

@@ -97,6 +97,16 @@ func dataSourceDiskListUnattachedSchemaMake() map[string]*schema.Schema {
Optional: true, Optional: true,
Description: "ID of the account the disks belong to", 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",
},
"type": { "type": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,

View File

@@ -17,7 +17,7 @@ func flattenDiskSnapshot(d *schema.ResourceData, snapshot disks.ItemSnapshot) {
} }
func flattenDiskListUnattached(ul *disks.ListDisksUnattached) []map[string]interface{} { func flattenDiskListUnattached(ul *disks.ListDisksUnattached) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(ul.Data))
for _, unattachedDisk := range ul.Data { for _, unattachedDisk := range ul.Data {
unattachedDiskAcl, _ := json.Marshal(unattachedDisk.ACL) unattachedDiskAcl, _ := json.Marshal(unattachedDisk.ACL)
tmp := map[string]interface{}{ tmp := map[string]interface{}{
@@ -120,7 +120,7 @@ func flattenDisk(d *schema.ResourceData, disk *disks.RecordDisk) {
} }
func flattenDiskSnapshotList(sl disks.ListSnapshots) []interface{} { func flattenDiskSnapshotList(sl disks.ListSnapshots) []interface{} {
res := make([]interface{}, 0) res := make([]interface{}, 0, len(sl))
for _, snapshot := range sl { for _, snapshot := range sl {
temp := map[string]interface{}{ temp := map[string]interface{}{
"guid": snapshot.GUID, "guid": snapshot.GUID,
@@ -137,7 +137,7 @@ func flattenDiskSnapshotList(sl disks.ListSnapshots) []interface{} {
} }
func flattenDiskList(dl *disks.ListDisks) []map[string]interface{} { func flattenDiskList(dl *disks.ListDisks) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(dl.Data))
for _, disk := range dl.Data { for _, disk := range dl.Data {
diskAcl, _ := json.Marshal(disk.ACL) diskAcl, _ := json.Marshal(disk.ACL)
temp := map[string]interface{}{ temp := map[string]interface{}{

View File

@@ -142,7 +142,7 @@ func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface
} }
func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
c := m.(*controller.ControllerCfg) // c := m.(*controller.ControllerCfg)
warnings := dc.Warnings{} warnings := dc.Warnings{}
disk, err := utilityDiskCheckPresence(ctx, d, m) disk, err := utilityDiskCheckPresence(ctx, d, m)
@@ -157,23 +157,24 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}
case status.Destroyed, status.Purged: case status.Destroyed, status.Purged:
d.Set("disk_id", 0) d.Set("disk_id", 0)
d.SetId("") d.SetId("")
return resourceDiskCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceDiskCreate(ctx, d, m)
case status.Deleted: case status.Deleted:
hasChangeState = true // hasChangeState = true
req := disks.RestoreRequest{ // req := disks.RestoreRequest{
DiskID: disk.ID, // DiskID: disk.ID,
} // }
if reason, ok := d.GetOk("reason"); ok { // if reason, ok := d.GetOk("reason"); ok {
req.Reason = reason.(string) // req.Reason = reason.(string)
} else { // } else {
req.Reason = "Terraform automatic restore" // req.Reason = "Terraform automatic restore"
} // }
_, err := c.CloudAPI().Disks().Restore(ctx, req) // _, err := c.CloudAPI().Disks().Restore(ctx, req)
if err != nil { // if err != nil {
warnings.Add(err) // warnings.Add(err)
} // }
case status.Assigned: case status.Assigned:
case status.Modeled: case status.Modeled:
return diag.Errorf("The disk is in status: %s, please, contact support for more information", disk.Status) return diag.Errorf("The disk is in status: %s, please, contact support for more information", disk.Status)
@@ -227,7 +228,8 @@ func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface
case status.Destroyed, status.Purged: case status.Destroyed, status.Purged:
d.Set("disk_id", 0) d.Set("disk_id", 0)
d.SetId("") d.SetId("")
return resourceDiskCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceDiskCreate(ctx, d, m)
case status.Deleted: case status.Deleted:
hasChangeState = true hasChangeState = true
req := disks.RestoreRequest{ req := disks.RestoreRequest{
@@ -271,7 +273,7 @@ func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface
Size: uint64(newSize.(int)), Size: uint64(newSize.(int)),
} }
_, err := c.CloudAPI().Disks().Resize(ctx, req) _, err := c.CloudAPI().Disks().Resize2(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -47,18 +47,6 @@ func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := disks.ListRequest{} req := disks.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 diskType, ok := d.GetOk("type"); ok {
req.Type = strings.ToUpper(diskType.(string))
}
if accountId, ok := d.GetOk("accountId"); ok {
req.AccountID = uint64(accountId.(int))
}
if by_id, ok := d.GetOk("by_id"); ok { if by_id, ok := d.GetOk("by_id"); ok {
req.ByID = uint64(by_id.(int)) req.ByID = uint64(by_id.(int))
} }
@@ -77,6 +65,24 @@ func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m
if shared, ok := d.GetOk("shared"); ok { if shared, ok := d.GetOk("shared"); ok {
req.Shared = shared.(bool) req.Shared = shared.(bool)
} }
if accountId, ok := d.GetOk("account_id"); ok {
req.AccountID = uint64(accountId.(int))
}
if diskType, ok := d.GetOk("type"); ok {
req.Type = strings.ToUpper(diskType.(string))
}
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 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("utilityDiskListCheckPresence: load disk list") log.Debugf("utilityDiskListCheckPresence: load disk list")
diskList, err := c.CloudAPI().Disks().List(ctx, req) diskList, err := c.CloudAPI().Disks().List(ctx, req)

View File

@@ -13,15 +13,6 @@ func utilityDiskListUnattachedCheckPresence(ctx context.Context, d *schema.Resou
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := disks.ListUnattachedRequest{} req := disks.ListUnattachedRequest{}
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("accountId"); ok {
req.AccountID = uint64(accountId.(int))
}
if by_id, ok := d.GetOk("by_id"); ok { if by_id, ok := d.GetOk("by_id"); ok {
req.ByID = uint64(by_id.(int)) req.ByID = uint64(by_id.(int))
} }
@@ -34,6 +25,24 @@ func utilityDiskListUnattachedCheckPresence(ctx context.Context, d *schema.Resou
if status, ok := d.GetOk("status"); ok { if status, ok := d.GetOk("status"); ok {
req.Status = status.(string) req.Status = status.(string)
} }
if diskType, ok := d.GetOk("type"); ok {
req.Type = diskType.(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 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("utilityDiskListUnattachedCheckPresence: load disk Unattached list") log.Debugf("utilityDiskListUnattachedCheckPresence: load disk Unattached list")
unattachedList, err := c.CloudAPI().Disks().ListUnattached(ctx, req) unattachedList, err := c.CloudAPI().Disks().ListUnattached(ctx, req)

View File

@@ -46,6 +46,13 @@ func utilityDiskListTypesDetailedCheckPresence(ctx context.Context, d *schema.Re
req := disks.ListTypesRequest{ req := disks.ListTypesRequest{
Detailed: true, Detailed: true,
} }
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("utilityDiskListTypesDetailedCheckPresence: load disk list Types Detailed") log.Debugf("utilityDiskListTypesDetailedCheckPresence: load disk list Types Detailed")
listTypesDetailed, err := c.CloudAPI().Disks().ListTypes(ctx, req) listTypesDetailed, err := c.CloudAPI().Disks().ListTypes(ctx, req)

View File

@@ -47,6 +47,13 @@ func utilityDiskListTypesCheckPresence(ctx context.Context, d *schema.ResourceDa
Detailed: false, Detailed: false,
} }
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("utilityDiskListTypesCheckPresence: load disk list Types Detailed") log.Debugf("utilityDiskListTypesCheckPresence: load disk list Types Detailed")
typesList, err := c.CloudAPI().Disks().ListTypes(ctx, req) typesList, err := c.CloudAPI().Disks().ListTypes(ctx, req)
if err != nil { if err != nil {

View File

@@ -50,7 +50,7 @@ func dataSourceExtnetComputesListRead(ctx context.Context, d *schema.ResourceDat
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenExtnetComputesList(extnetComputesList)) d.Set("items", flattenExtnetComputesList(extnetComputesList))
d.Set("entry_count", extnetComputesList.EntryCount)
return nil return nil
} }
@@ -61,6 +61,26 @@ func dataSourceExtnetComputesListSchemaMake() map[string]*schema.Schema {
Required: true, Required: true,
Description: "filter by account ID", 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",
},
"page": {
Type: schema.TypeInt,
Optional: true,
Description: "Page number",
},
"size": {
Type: schema.TypeInt,
Optional: true,
Description: "Page size",
},
"items": { "items": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -117,6 +137,10 @@ func dataSourceExtnetComputesListSchemaMake() map[string]*schema.Schema {
}, },
}, },
}, },
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
} }
return res return res
} }

View File

@@ -35,7 +35,7 @@ func flattenExtnet(d *schema.ResourceData, e *extnet.RecordExtNet) {
} }
func flattenExcluded(ex []extnet.Excluded) []map[string]interface{} { func flattenExcluded(ex []extnet.Excluded) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(ex))
for _, item := range ex { for _, item := range ex {
temp := map[string]interface{}{ temp := map[string]interface{}{
"client_type": item.ClientType, "client_type": item.ClientType,
@@ -51,7 +51,7 @@ func flattenExcluded(ex []extnet.Excluded) []map[string]interface{} {
} }
func flattenExtnetReservations(ers extnet.ListReservations) []map[string]interface{} { func flattenExtnetReservations(ers extnet.ListReservations) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(ers))
for _, er := range ers { for _, er := range ers {
temp := map[string]interface{}{ temp := map[string]interface{}{
"client_type": er.ClientType, "client_type": er.ClientType,
@@ -92,7 +92,7 @@ func flattenExtnetVNFS(evnfs extnet.VNFs) []map[string]interface{} {
} }
func flattenExtnetsComputes(ecs extnet.ListExtNetExtends) []map[string]interface{} { func flattenExtnetsComputes(ecs extnet.ListExtNetExtends) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len (ecs))
for _, ec := range ecs { for _, ec := range ecs {
temp := map[string]interface{}{ temp := map[string]interface{}{
"net_id": ec.ID, "net_id": ec.ID,
@@ -106,7 +106,7 @@ func flattenExtnetsComputes(ecs extnet.ListExtNetExtends) []map[string]interface
} }
func flattenExtnetComputesList(ecl *extnet.ListExtNetComputes) []map[string]interface{} { func flattenExtnetComputesList(ecl *extnet.ListExtNetComputes) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(ecl.Data))
for _, ec := range ecl.Data { for _, ec := range ecl.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"account_id": ec.AccountID, "account_id": ec.AccountID,
@@ -123,7 +123,7 @@ func flattenExtnetComputesList(ecl *extnet.ListExtNetComputes) []map[string]inte
} }
func flattenExtnetList(el *extnet.ListExtNets) []map[string]interface{} { func flattenExtnetList(el *extnet.ListExtNets) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(el.Data))
for _, e := range el.Data { for _, e := range el.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"net_id": e.ID, "net_id": e.ID,

View File

@@ -48,6 +48,20 @@ func utilityExtnetComputesListCheckPresence(ctx context.Context, d *schema.Resou
AccountID: uint64(d.Get("account_id").(int)), 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 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") log.Debugf("utilityExtnetComputesListCheckPresence")
extnetComputesList, err := c.CloudAPI().ExtNet().ListComputes(ctx, req) extnetComputesList, err := c.CloudAPI().ExtNet().ListComputes(ctx, req)
if err != nil { if err != nil {

View File

@@ -144,7 +144,8 @@ func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{
case status.Created: case status.Created:
case status.Destroyed, status.Purged: case status.Destroyed, status.Purged:
d.SetId("") d.SetId("")
return resourceImageCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceImageCreate(ctx, d, m)
} }
flattenImage(d, img) flattenImage(d, img)
@@ -233,7 +234,8 @@ func resourceImageUpdate(ctx context.Context, d *schema.ResourceData, m interfac
case status.Created: case status.Created:
case status.Destroyed, status.Purged: case status.Destroyed, status.Purged:
d.SetId("") d.SetId("")
return resourceImageCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceImageCreate(ctx, d, m)
} }
if d.HasChange("name") { if d.HasChange("name") {

View File

@@ -50,7 +50,7 @@ func resourceImageVirtualCreate(ctx context.Context, d *schema.ResourceData, m i
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := image.CreateVirtualRequest{ req := image.CreateVirtualRequest{
Name: d.Get("name").(string), Name: d.Get("name").(string),
TargetID: uint64(d.Get("target_id").(int)), TargetID: uint64(d.Get("link_to").(int)),
} }
imageId, err := c.CloudAPI().Image().CreateVirtual(ctx, req) imageId, err := c.CloudAPI().Image().CreateVirtual(ctx, req)

View File

@@ -80,10 +80,6 @@ func computesSchemaMake() map[string]*schema.Schema {
} }
} }
func workerComputesSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{}
}
func dataSourceK8sComputesSchemaMake() map[string]*schema.Schema { func dataSourceK8sComputesSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{ return map[string]*schema.Schema{
"k8s_id": { "k8s_id": {

View File

@@ -58,6 +58,7 @@ func dataSourceK8sListDeletedRead(ctx context.Context, d *schema.ResourceData, m
func dataSourceK8sListDeletedSchemaMake() map[string]*schema.Schema { func dataSourceK8sListDeletedSchemaMake() map[string]*schema.Schema {
k8sListDeleted := createK8sListSchema() k8sListDeleted := createK8sListSchema()
delete(k8sListDeleted, "includedeleted") delete(k8sListDeleted, "includedeleted")
delete(k8sListDeleted, "status")
return k8sListDeleted return k8sListDeleted
} }

View File

@@ -0,0 +1,93 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 {
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(),
}
}

View File

@@ -42,7 +42,7 @@ import (
) )
func flattenK8CIItems(list *k8ci.ListK8CI) []map[string]interface{} { func flattenK8CIItems(list *k8ci.ListK8CI) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(list.Data))
for _, item := range list.Data { for _, item := range list.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"k8ci_id": item.ID, "k8ci_id": item.ID,
@@ -72,7 +72,7 @@ func flattenK8sDataComputes(d *schema.ResourceData, cluster *k8s.RecordK8S) {
} }
func flattenMasterComputes(cluster *k8s.RecordK8S) []map[string]interface{} { func flattenMasterComputes(cluster *k8s.RecordK8S) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(cluster.K8SGroups.Masters.DetailedInfo))
for _, comp := range cluster.K8SGroups.Masters.DetailedInfo { for _, comp := range cluster.K8SGroups.Masters.DetailedInfo {
temp := map[string]interface{}{ temp := map[string]interface{}{
"id": comp.ID, "id": comp.ID,
@@ -88,7 +88,7 @@ func flattenMasterComputes(cluster *k8s.RecordK8S) []map[string]interface{} {
} }
func flattenWorkerComputes(cluster *k8s.RecordK8S) []map[string]interface{} { func flattenWorkerComputes(cluster *k8s.RecordK8S) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(cluster.K8SGroups.Workers))
for _, wg := range cluster.K8SGroups.Workers { for _, wg := range cluster.K8SGroups.Workers {
for _, comp := range wg.DetailedInfo { for _, comp := range wg.DetailedInfo {
temp := map[string]interface{}{ temp := map[string]interface{}{
@@ -106,7 +106,7 @@ func flattenWorkerComputes(cluster *k8s.RecordK8S) []map[string]interface{} {
} }
func flattenAclList(aclList k8s.ListACL) []map[string]interface{} { func flattenAclList(aclList k8s.ListACL) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len (aclList))
for _, acl := range aclList { for _, acl := range aclList {
temp := map[string]interface{}{ temp := map[string]interface{}{
"explicit": acl.Explicit, "explicit": acl.Explicit,
@@ -134,7 +134,7 @@ func flattenAcl(acl k8s.RecordACL) []map[string]interface{} {
} }
func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface{} { func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len (interfaces))
for _, interfaceCompute := range interfaces { for _, interfaceCompute := range interfaces {
temp := map[string]interface{}{ temp := map[string]interface{}{
"def_gw": interfaceCompute.DefGW, "def_gw": interfaceCompute.DefGW,
@@ -147,7 +147,7 @@ func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface
} }
func flattenDetailedInfo(detailedInfoList k8s.ListDetailedInfo, computes []compute.RecordCompute) []map[string]interface{} { func flattenDetailedInfo(detailedInfoList k8s.ListDetailedInfo, computes []compute.RecordCompute) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len (detailedInfoList))
if computes != nil { if computes != nil {
for i, detailedInfo := range detailedInfoList { for i, detailedInfo := range detailedInfoList {
temp := map[string]interface{}{ temp := map[string]interface{}{
@@ -193,7 +193,7 @@ func flattenMasterGroup(mastersGroup k8s.MasterGroup, masters []compute.RecordCo
} }
func flattenK8sGroup(k8SGroupList k8s.ListK8SGroups, workers []compute.RecordCompute) []map[string]interface{} { func flattenK8sGroup(k8SGroupList k8s.ListK8SGroups, workers []compute.RecordCompute) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(k8SGroupList))
for _, k8sGroup := range k8SGroupList { for _, k8sGroup := range k8SGroupList {
labels := make([]string, 0) labels := make([]string, 0)
for _, label := range k8sGroup.Labels { for _, label := range k8sGroup.Labels {
@@ -222,15 +222,15 @@ func flattenK8sGroup(k8SGroupList k8s.ListK8SGroups, workers []compute.RecordCom
return res return res
} }
func flattenK8sGroups(k8sGroups k8s.RecordK8SGroups, masters []compute.RecordCompute, workers []compute.RecordCompute) []map[string]interface{} { // func flattenK8sGroups(k8sGroups k8s.RecordK8SGroups, masters []compute.RecordCompute, workers []compute.RecordCompute) []map[string]interface{} {
res := make([]map[string]interface{}, 0) // res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{ // temp := map[string]interface{}{
"masters": flattenMasterGroup(k8sGroups.Masters, masters), // "masters": flattenMasterGroup(k8sGroups.Masters, masters),
"workers": flattenK8sGroup(k8sGroups.Workers, workers), // "workers": flattenK8sGroup(k8sGroups.Workers, workers),
} // }
res = append(res, temp) // res = append(res, temp)
return res // return res
} // }
func flattenK8sData(d *schema.ResourceData, cluster k8s.RecordK8S, masters []compute.RecordCompute, workers []compute.RecordCompute) { func flattenK8sData(d *schema.ResourceData, cluster k8s.RecordK8S, masters []compute.RecordCompute, workers []compute.RecordCompute) {
d.Set("acl", flattenAcl(cluster.ACL)) d.Set("acl", flattenAcl(cluster.ACL))
@@ -267,7 +267,7 @@ func flattenServiceAccount(serviceAccount k8s.RecordServiceAccount) []map[string
} }
func flattenWorkersGroup(workersGroups k8s.ListK8SGroups) []map[string]interface{} { func flattenWorkersGroup(workersGroups k8s.ListK8SGroups) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len (workersGroups))
for _, worker := range workersGroups { for _, worker := range workersGroups {
temp := map[string]interface{}{ temp := map[string]interface{}{
"annotations": worker.Annotations, "annotations": worker.Annotations,
@@ -288,7 +288,7 @@ func flattenWorkersGroup(workersGroups k8s.ListK8SGroups) []map[string]interface
} }
func flattenK8sItems(k8sItems *k8s.ListK8SClusters) []map[string]interface{} { func flattenK8sItems(k8sItems *k8s.ListK8SClusters) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len (k8sItems.Data))
for _, item := range k8sItems.Data { for _, item := range k8sItems.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"account_id": item.AccountID, "account_id": item.AccountID,
@@ -396,7 +396,7 @@ func flattenResourceK8s(d *schema.ResourceData, k8s k8s.RecordK8S, masters []com
} }
func flattenWg(d *schema.ResourceData, wg k8s.ItemK8SGroup, computes []compute.RecordCompute) { func flattenWg(d *schema.ResourceData, wg k8s.ItemK8SGroup, computes []compute.RecordCompute) {
labels := make([]string, 0) labels := make([]string, 0, len(wg.Labels))
for _, label := range wg.Labels { for _, label := range wg.Labels {
if strings.HasPrefix(label, "workersGroupName") { if strings.HasPrefix(label, "workersGroupName") {
continue continue
@@ -418,7 +418,7 @@ func flattenWg(d *schema.ResourceData, wg k8s.ItemK8SGroup, computes []compute.R
} }
func flattenWgList(wgList k8s.ListK8SGroups, computesMap map[uint64][]compute.RecordCompute) []map[string]interface{} { func flattenWgList(wgList k8s.ListK8SGroups, computesMap map[uint64][]compute.RecordCompute) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(wgList))
for _, wg := range wgList { for _, wg := range wgList {
computes := computesMap[wg.ID] computes := computesMap[wg.ID]
temp := map[string]interface{}{ temp := map[string]interface{}{

View File

@@ -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.",
},
},
}
}

View File

@@ -145,12 +145,66 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{
createReq.WithLB = d.Get("with_lb").(bool) 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 {
createReq.LbSysctlParams = lbSysctlParams.(string)
}
if oidcCertificate, ok := d.GetOk("oidc_cert"); ok {
createReq.OidcCertificate = oidcCertificate.(string)
}
///
createReq.ExtNetOnly = d.Get("extnet_only").(bool)
if extNet, ok := d.GetOk("extnet_id"); ok { if extNet, ok := d.GetOk("extnet_id"); ok {
createReq.ExtNetID = uint64(extNet.(int)) createReq.ExtNetID = uint64(extNet.(int))
} else { } else {
createReq.ExtNetID = 0 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 { if desc, ok := d.GetOk("desc"); ok {
createReq.Description = desc.(string) createReq.Description = desc.(string)
} }
@@ -181,7 +235,7 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{
break break
} }
time.Sleep(time.Second * 10) time.Sleep(time.Second * 20)
} }
return resourceK8sRead(ctx, d, m) return resourceK8sRead(ctx, d, m)
@@ -205,31 +259,32 @@ func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{})
case status.Created: case status.Created:
case status.Deleting: case status.Deleting:
case status.Deleted: case status.Deleted:
id, _ := strconv.ParseUint(d.Id(), 10, 64) // id, _ := strconv.ParseUint(d.Id(), 10, 64)
restoreReq := k8s.RestoreRequest{ // restoreReq := k8s.RestoreRequest{
K8SID: id, // K8SID: id,
} // }
_, err := c.CloudAPI().K8S().Restore(ctx, restoreReq) // _, err := c.CloudAPI().K8S().Restore(ctx, restoreReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
enableReq := k8s.DisableEnableRequest{ // enableReq := k8s.DisableEnableRequest{
K8SID: id, // K8SID: id,
} // }
_, err = c.CloudAPI().K8S().Enable(ctx, enableReq) // _, err = c.CloudAPI().K8S().Enable(ctx, enableReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
hasChanged = true // hasChanged = true
case status.Destroying: case status.Destroying:
return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status) return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status)
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceK8sCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceK8sCreate(ctx, d, m)
case status.Enabling: case status.Enabling:
case status.Enabled: case status.Enabled:
case status.Disabling: case status.Disabling:
@@ -388,7 +443,8 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{
return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status) return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status)
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceK8sCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceK8sCreate(ctx, d, m)
case status.Enabling: case status.Enabling:
case status.Enabled: case status.Enabled:
case status.Disabling: case status.Disabling:
@@ -561,6 +617,12 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
Default: true, Default: true,
Description: "Create k8s with load balancer if 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": { "extnet_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
@@ -568,6 +630,63 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
ForceNew: true, ForceNew: true,
Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.", Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.",
}, },
///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",
},
////
"desc": { "desc": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@@ -660,6 +779,7 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
}, },
"vins_id": { "vins_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true,
Computed: true, Computed: true,
Description: "ID of default vins for this instace.", Description: "ID of default vins for this instace.",
}, },

View File

@@ -129,12 +129,68 @@ func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interfac
createReq.WithLB = d.Get("with_lb").(bool) 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 {
createReq.LbSysctlParams = lbSysctlParams.(string)
}
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 { if extNet, ok := d.GetOk("extnet_id"); ok {
createReq.ExtNetID = uint64(extNet.(int)) createReq.ExtNetID = uint64(extNet.(int))
} else { } else {
createReq.ExtNetID = 0 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 { if desc, ok := d.GetOk("desc"); ok {
createReq.Description = desc.(string) createReq.Description = desc.(string)
} }
@@ -165,7 +221,7 @@ func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interfac
break break
} }
time.Sleep(time.Second * 10) time.Sleep(time.Second * 20)
} }
cluster, err := utilityK8sCheckPresence(ctx, d, m) cluster, err := utilityK8sCheckPresence(ctx, d, m)
@@ -204,31 +260,32 @@ func resourceK8sCPRead(ctx context.Context, d *schema.ResourceData, m interface{
case status.Created: case status.Created:
case status.Deleting: case status.Deleting:
case status.Deleted: case status.Deleted:
id, _ := strconv.ParseUint(d.Id(), 10, 64) // id, _ := strconv.ParseUint(d.Id(), 10, 64)
restoreReq := k8s.RestoreRequest{ // restoreReq := k8s.RestoreRequest{
K8SID: id, // K8SID: id,
} // }
_, err := c.CloudAPI().K8S().Restore(ctx, restoreReq) // _, err := c.CloudAPI().K8S().Restore(ctx, restoreReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
enableReq := k8s.DisableEnableRequest{ // enableReq := k8s.DisableEnableRequest{
K8SID: id, // K8SID: id,
} // }
_, err = c.CloudAPI().K8S().Enable(ctx, enableReq) // _, err = c.CloudAPI().K8S().Enable(ctx, enableReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
hasChanged = true // hasChanged = true
case status.Destroying: case status.Destroying:
return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status) return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status)
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceK8sCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceK8sCreate(ctx, d, m)
case status.Enabling: case status.Enabling:
case status.Enabled: case status.Enabled:
case status.Disabling: case status.Disabling:
@@ -291,7 +348,7 @@ func resourceK8sCPRead(ctx context.Context, d *schema.ResourceData, m interface{
if _, ok := d.GetOk("k8s_id"); !ok { if _, ok := d.GetOk("k8s_id"); !ok {
for _, worker := range cluster.K8SGroups.Workers { 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) 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) warnings.Add(err)
} }
} }
@@ -387,7 +444,8 @@ func resourceK8sCPUpdate(ctx context.Context, d *schema.ResourceData, m interfac
return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status) return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status)
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceK8sCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceK8sCreate(ctx, d, m)
case status.Enabling: case status.Enabling:
case status.Enabled: case status.Enabled:
case status.Disabling: case status.Disabling:
@@ -567,6 +625,61 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
Default: true, Default: true,
Description: "Create k8s with load balancer if 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.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": { "extnet_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
@@ -681,6 +794,7 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
}, },
"vins_id": { "vins_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true,
Computed: true, Computed: true,
Description: "ID of default vins for this instace.", Description: "ID of default vins for this instace.",
}, },
@@ -689,7 +803,7 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
func ResourceK8sCP() *schema.Resource { func ResourceK8sCP() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 2,
CreateContext: resourceK8sCPCreate, CreateContext: resourceK8sCPCreate,
ReadContext: resourceK8sCPRead, ReadContext: resourceK8sCPRead,
@@ -709,5 +823,12 @@ func ResourceK8sCP() *schema.Resource {
}, },
Schema: resourceK8sCPSchemaMake(), Schema: resourceK8sCPSchemaMake(),
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceK8sCPSchemaV1().CoreConfigSchema().ImpliedType(),
Upgrade: resourceK8sCPStateUpgradeV1,
Version: 1,
},
},
} }
} }

View File

@@ -92,6 +92,10 @@ func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interfac
req.WorkerDisk = uint64(d.Get("disk").(int)) 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) resp, err := c.CloudAPI().K8S().WorkersGroupAdd(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
@@ -110,7 +114,7 @@ func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{
return diag.FromErr(err) return diag.FromErr(err)
} }
workersComputeList := make([]compute.RecordCompute, 0, 0) workersComputeList := make([]compute.RecordCompute, 0)
for _, info := range wg.DetailedInfo { for _, info := range wg.DetailedInfo {
compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID)
if err != nil { if err != nil {
@@ -184,6 +188,19 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac
} }
} }
if d.HasChange("cloud_init") {
req := k8s.UpdateWorkerNodesMetaDataRequest{
K8SID: uint64(d.Get("k8s_id").(int)),
WorkersGroupID: wgId,
UserData: d.Get("cloud_init").(string),
}
_, err := c.CloudAPI().K8S().UpdateWorkerNodesMetaData(ctx, req)
if err != nil {
return diag.FromErr(err)
}
}
return nil return nil
} }
@@ -286,6 +303,11 @@ func resourceK8sWgSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
"cloud_init": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: cloudInitDiffSupperss,
},
"wg_id": { "wg_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,

View File

@@ -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
}

View File

@@ -261,6 +261,19 @@ func utilityK8sListCheckPresence(ctx context.Context, d *schema.ResourceData, m
req.TechStatus = tech_status.(string) req.TechStatus = tech_status.(string)
} }
if includedeleted, ok := d.GetOk("includedeleted"); ok {
req.IncludeDeleted = includedeleted.(bool)
}
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().List(ctx, req) k8sList, err := c.CloudAPI().K8S().List(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -297,14 +310,18 @@ func utilityK8sListDeletedCheckPresence(ctx context.Context, d *schema.ResourceD
req.BasicServiceID = uint64(bservice_id.(int)) 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 { if tech_status, ok := d.GetOk("tech_status"); ok {
req.TechStatus = tech_status.(string) req.TechStatus = tech_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))
}
k8sList, err := c.CloudAPI().K8S().ListDeleted(ctx, req) k8sList, err := c.CloudAPI().K8S().ListDeleted(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -39,6 +39,7 @@ import (
"strings" "strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "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/compute"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
@@ -70,7 +71,7 @@ func utilityDataK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData,
return nil, nil, fmt.Errorf("WG with id %v in k8s cluster %v not found", wgId, k8sId) return nil, nil, fmt.Errorf("WG with id %v in k8s cluster %v not found", wgId, k8sId)
} }
workersComputeList := make([]compute.RecordCompute, 0, 0) workersComputeList := make([]compute.RecordCompute, 0)
for _, info := range curWg.DetailedInfo { for _, info := range curWg.DetailedInfo {
compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID)
if err != nil { if err != nil {
@@ -121,7 +122,7 @@ func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m in
} }
} }
return nil, fmt.Errorf("Not found wg with id: %v in k8s cluster: %v", wgId, cluster.ID) 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) { func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (k8s.ListK8SGroups, error) {
@@ -137,3 +138,27 @@ func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData,
return cluster.K8SGroups.Workers, nil 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
}

View File

@@ -637,10 +637,10 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
// "custom_fields": { "custom_fields": {
// Type: schema.TypeString, Type: schema.TypeString,
// Computed: true, Computed: true,
// }, },
"deleted_by": { "deleted_by": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,

View File

@@ -154,10 +154,10 @@ func itemComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
// "custom_fields": { //NEED "custom_fields": { //NEED
// Type: schema.TypeString, Type: schema.TypeString,
// Computed: true, Computed: true,
// }, },
"deleted_by": { "deleted_by": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,

View File

@@ -0,0 +1,153 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 {
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",
},
"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(),
}
}

View File

@@ -1,132 +1,119 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. Licensed under the Apache License, Version 2.0 (the "License");
You may obtain a copy of the License at you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, Unless required by applicable law or agreed to in writing, software
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. distributed under the License is distributed on an "AS IS" BASIS,
See the License for the specific language governing permissions and WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
limitations under the License. See the License for the specific language governing permissions and
*/ limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud /*
Orchestration Technology) with Terraform by Hashicorp. Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly. Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package snapshot
package kvmvm
import (
"context" import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" "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/constants"
) )
func flattenSnapshotList(gl compute.ListSnapshots) []map[string]interface{} { func dataSourceComputePCIDeviceListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
res := make([]map[string]interface{}, 0) computePCIDeviceList, err := utilityComputePCIDeviceListCheckPresence(ctx, d, m)
for _, item := range gl { if err != nil {
temp := map[string]interface{}{ return diag.FromErr(err)
"label": item.Label, }
"guid": item.GUID, id := uuid.New()
"disks": item.Disks, d.SetId(id.String())
"timestamp": item.Timestamp, d.Set("items", flattenPCIDevice(computePCIDeviceList.Data))
} d.Set("entry_count", computePCIDeviceList.EntryCount)
return nil
res = append(res, temp) }
}
return res func dataSourceComputePCIDeviceListSchemaMake() map[string]*schema.Schema {
} return map[string]*schema.Schema{
"compute_id": {
func dataSourceSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { Type: schema.TypeInt,
snapshotList, err := utilitySnapshotListCheckPresence(ctx, d, m) Required: true,
if err != nil { },
return diag.FromErr(err) "rg_id": {
} Type: schema.TypeInt,
id := uuid.New() Optional: true,
d.SetId(id.String()) Description: "Find by RG id",
d.Set("items", flattenSnapshotList(snapshotList)) },
"device_id": {
return nil Type: schema.TypeInt,
} Optional: true,
Description: "Find by device id",
func dataSourceSnapshotListSchemaMake() map[string]*schema.Schema { },
rets := map[string]*schema.Schema{ "name": {
"compute_id": { Type: schema.TypeString,
Type: schema.TypeInt, Computed: true,
Required: true, Description: "Find by name",
ForceNew: true, },
Description: "ID of the compute instance to create snapshot for.", "status": {
}, Type: schema.TypeString,
"items": { Computed: true,
Type: schema.TypeList, Description: "Find by status",
Computed: true, },
Description: "snapshot list", "page": {
Elem: &schema.Resource{ Type: schema.TypeInt,
Schema: dataSourceSnapshotSchemaMake(), Optional: true,
}, Description: "Page number",
}, },
} "size": {
Type: schema.TypeInt,
return rets Optional: true,
} Description: "Page size",
},
func dataSourceSnapshotSchemaMake() map[string]*schema.Schema { "items": {
return map[string]*schema.Schema{ Type: schema.TypeList,
"label": { Computed: true,
Type: schema.TypeString, Elem: &schema.Schema{
Computed: true, Type: schema.TypeString,
Description: "text label for snapshot. Must be unique among this compute snapshots.", },
}, },
"disks": { "entry_count": {
Type: schema.TypeList, Type: schema.TypeInt,
Computed: true, Computed: true,
Elem: &schema.Schema{ },
Type: schema.TypeInt, }
}, }
},
"guid": { func DataSourceComputePCIDeviceList() *schema.Resource {
Type: schema.TypeString, return &schema.Resource{
Computed: true, SchemaVersion: 1,
Description: "guid of the snapshot",
}, ReadContext: dataSourceComputePCIDeviceListRead,
"timestamp": {
Type: schema.TypeInt, Timeouts: &schema.ResourceTimeout{
Computed: true, Read: &constants.Timeout30s,
Description: "timestamp", Default: &constants.Timeout60s,
}, },
}
} Schema: dataSourceComputePCIDeviceListSchemaMake(),
}
func DataSourceSnapshotList() *schema.Resource { }
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceSnapshotListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceSnapshotListSchemaMake(),
}
}

View File

@@ -49,6 +49,7 @@ func dataSourceComputePfwListRead(ctx context.Context, d *schema.ResourceData, m
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenPfwList(computePfwList)) d.Set("items", flattenPfwList(computePfwList))
d.Set("entry_count", computePfwList.EntryCount)
return nil return nil
} }
@@ -94,6 +95,10 @@ func dataSourceComputePfwListSchemaMake() map[string]*schema.Schema {
}, },
}, },
}, },
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
} }
} }

View File

@@ -0,0 +1,120 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 {
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",
},
"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.Schema{
Type: schema.TypeString,
},
},
"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(),
}
}

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
@@ -36,7 +36,6 @@ import (
"encoding/json" "encoding/json"
"sort" "sort"
"strconv" "strconv"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@@ -67,7 +66,7 @@ func flattenQOS(qos compute.QOS) []map[string]interface{} {
return res return res
} }
func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface{} { func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(interfaces))
for _, interfaceItem := range interfaces { for _, interfaceItem := range interfaces {
temp := map[string]interface{}{ temp := map[string]interface{}{
"conn_id": interfaceItem.ConnID, "conn_id": interfaceItem.ConnID,
@@ -93,7 +92,7 @@ func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface
return res return res
} }
func flattenSnapSets(snapSets compute.ListSnapSets) []map[string]interface{} { func flattenSnapSets(snapSets compute.ListSnapSets) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(snapSets))
for _, snapSet := range snapSets { for _, snapSet := range snapSets {
temp := map[string]interface{}{ temp := map[string]interface{}{
"disks": snapSet.Disks, "disks": snapSet.Disks,
@@ -106,7 +105,7 @@ func flattenSnapSets(snapSets compute.ListSnapSets) []map[string]interface{} {
return res return res
} }
func flattenTags(tags map[string]string) []map[string]interface{} { func flattenTags(tags map[string]string) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(tags))
for key, val := range tags { for key, val := range tags {
temp := map[string]interface{}{ temp := map[string]interface{}{
"key": key, "key": key,
@@ -118,7 +117,7 @@ func flattenTags(tags map[string]string) []map[string]interface{} {
} }
func flattenListRules(listRules compute.ListRules) []map[string]interface{} { func flattenListRules(listRules compute.ListRules) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(listRules))
for _, rule := range listRules { for _, rule := range listRules {
temp := map[string]interface{}{ temp := map[string]interface{}{
"guid": rule.GUID, "guid": rule.GUID,
@@ -133,7 +132,7 @@ func flattenListRules(listRules compute.ListRules) []map[string]interface{} {
return res return res
} }
func flattenListACL(listAcl compute.ListACL) []map[string]interface{} { func flattenListACL(listAcl compute.ListACL) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(listAcl))
for _, acl := range listAcl { for _, acl := range listAcl {
temp := map[string]interface{}{ temp := map[string]interface{}{
"explicit": acl.Explicit, "explicit": acl.Explicit,
@@ -149,9 +148,9 @@ func flattenListACL(listAcl compute.ListACL) []map[string]interface{} {
} }
func flattenComputeList(computes *compute.ListComputes) []map[string]interface{} { func flattenComputeList(computes *compute.ListComputes) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(computes.Data))
for _, compute := range computes.Data { for _, compute := range computes.Data {
// customFields, _ := json.Marshal(compute.CustomFields) customFields, _ := json.Marshal(compute.CustomFields)
devices, _ := json.Marshal(compute.Devices) devices, _ := json.Marshal(compute.Devices)
temp := map[string]interface{}{ temp := map[string]interface{}{
"acl": flattenListACL(compute.ACL), "acl": flattenListACL(compute.ACL),
@@ -170,44 +169,44 @@ func flattenComputeList(computes *compute.ListComputes) []map[string]interface{}
"cpus": compute.CPU, "cpus": compute.CPU,
"created_by": compute.CreatedBy, "created_by": compute.CreatedBy,
"created_time": compute.CreatedTime, "created_time": compute.CreatedTime,
// "custom_fields": string(customFields), "custom_fields": string(customFields),
"deleted_by": compute.DeletedBy, "deleted_by": compute.DeletedBy,
"deleted_time": compute.DeletedTime, "deleted_time": compute.DeletedTime,
"desc": compute.Description, "desc": compute.Description,
"devices": string(devices), "devices": string(devices),
"disks": flattenDisks(compute.Disks), "disks": flattenDisks(compute.Disks),
"driver": compute.Driver, "driver": compute.Driver,
"gid": compute.GID, "gid": compute.GID,
"guid": compute.GUID, "guid": compute.GUID,
"compute_id": compute.ID, "compute_id": compute.ID,
"image_id": compute.ImageID, "image_id": compute.ImageID,
"interfaces": flattenInterfaces(compute.Interfaces), "interfaces": flattenInterfaces(compute.Interfaces),
"lock_status": compute.LockStatus, "lock_status": compute.LockStatus,
"manager_id": compute.ManagerID, "manager_id": compute.ManagerID,
"manager_type": compute.ManagerType, "manager_type": compute.ManagerType,
"migrationjob": compute.MigrationJob, "migrationjob": compute.MigrationJob,
"milestones": compute.Milestones, "milestones": compute.Milestones,
"name": compute.Name, "name": compute.Name,
"pinned": compute.Pinned, "pinned": compute.Pinned,
"ram": compute.RAM, "ram": compute.RAM,
"reference_id": compute.ReferenceID, "reference_id": compute.ReferenceID,
"registered": compute.Registered, "registered": compute.Registered,
"res_name": compute.ResName, "res_name": compute.ResName,
"rg_id": compute.RGID, "rg_id": compute.RGID,
"rg_name": compute.RGName, "rg_name": compute.RGName,
"snap_sets": flattenSnapSets(compute.SnapSets), "snap_sets": flattenSnapSets(compute.SnapSets),
"stateless_sep_id": compute.StatelessSepID, "stateless_sep_id": compute.StatelessSepID,
"stateless_sep_type": compute.StatelessSepType, "stateless_sep_type": compute.StatelessSepType,
"status": compute.Status, "status": compute.Status,
"tags": flattenTags(compute.Tags), "tags": flattenTags(compute.Tags),
"tech_status": compute.TechStatus, "tech_status": compute.TechStatus,
"total_disk_size": compute.TotalDiskSize, "total_disk_size": compute.TotalDiskSize,
"updated_by": compute.UpdatedBy, "updated_by": compute.UpdatedBy,
"updated_time": compute.UpdatedTime, "updated_time": compute.UpdatedTime,
"user_managed": compute.UserManaged, "user_managed": compute.UserManaged,
"vgpus": compute.VGPUs, "vgpus": compute.VGPUs,
"vins_connected": compute.VINSConnected, "vins_connected": compute.VINSConnected,
"virtual_image_id": compute.VirtualImageID, "virtual_image_id": compute.VirtualImageID,
} }
res = append(res, temp) res = append(res, temp)
} }
@@ -237,10 +236,10 @@ func flattenBootDisk(bootDisk *compute.ItemComputeDisk) []map[string]interface{}
return res return res
} }
func flattenComputeDisksDemo(disksList compute.ListComputeDisks, extraDisks []interface{}) []map[string]interface{} { func flattenComputeDisksDemo(disksList compute.ListComputeDisks, extraDisks []interface{}, bootDiskId uint64) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(disksList)) res := make([]map[string]interface{}, 0, len(disksList))
for _, disk := range disksList { for _, disk := range disksList {
if strings.Contains(disk.Name, "bootdisk") || findInExtraDisks(uint(disk.ID), extraDisks) { //skip main bootdisk and extraDisks if disk.ID == bootDiskId || findInExtraDisks(uint(disk.ID), extraDisks) { //skip main bootdisk and extraDisks
continue continue
} }
temp := map[string]interface{}{ temp := map[string]interface{}{
@@ -261,6 +260,7 @@ func flattenComputeDisksDemo(disksList compute.ListComputeDisks, extraDisks []in
sort.Slice(res, func(i, j int) bool { sort.Slice(res, func(i, j int) bool {
return res[i]["disk_id"].(uint64) < res[j]["disk_id"].(uint64) return res[i]["disk_id"].(uint64) < res[j]["disk_id"].(uint64)
}) })
return res return res
} }
@@ -281,7 +281,7 @@ func flattenNetwork(interfaces compute.ListInterfaces) []map[string]interface{}
func findBootDisk(disks compute.ListComputeDisks) *compute.ItemComputeDisk { func findBootDisk(disks compute.ListComputeDisks) *compute.ItemComputeDisk {
for _, disk := range disks { for _, disk := range disks {
if strings.Contains(disk.Name, "bootdisk") { if disk.Type == "B" {
return &disk return &disk
} }
} }
@@ -301,7 +301,7 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute) er
//check extraDisks, ipa_type, is, //check extraDisks, ipa_type, is,
d.SetId(strconv.FormatUint(computeRec.ID, 10)) d.SetId(strconv.FormatUint(computeRec.ID, 10))
d.Set("acl", flattenACL(computeRec.ACL)) // d.Set("acl", flattenACL(computeRec.ACL))
d.Set("account_id", computeRec.AccountID) d.Set("account_id", computeRec.AccountID)
d.Set("account_name", computeRec.AccountName) d.Set("account_name", computeRec.AccountName)
d.Set("affinity_weight", computeRec.AffinityWeight) d.Set("affinity_weight", computeRec.AffinityWeight)
@@ -317,11 +317,12 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute) er
d.Set("computeci_id", computeRec.ComputeCIID) d.Set("computeci_id", computeRec.ComputeCIID)
d.Set("created_by", computeRec.CreatedBy) d.Set("created_by", computeRec.CreatedBy)
d.Set("created_time", computeRec.CreatedTime) d.Set("created_time", computeRec.CreatedTime)
// d.Set("custom_fields", flattenCustomFields(computeRec.CustomFields))
d.Set("deleted_by", computeRec.DeletedBy) d.Set("deleted_by", computeRec.DeletedBy)
d.Set("deleted_time", computeRec.DeletedTime) d.Set("deleted_time", computeRec.DeletedTime)
d.Set("description", computeRec.Description) d.Set("description", computeRec.Description)
d.Set("devices", string(devices)) d.Set("devices", string(devices))
err := d.Set("disks", flattenComputeDisksDemo(computeRec.Disks, d.Get("extra_disks").(*schema.Set).List())) err := d.Set("disks", flattenComputeDisksDemo(computeRec.Disks, d.Get("extra_disks").(*schema.Set).List(), bootDisk.ID))
if err != nil { if err != nil {
return err return err
} }
@@ -397,7 +398,7 @@ func flattenACL(acl compute.RecordACL) []map[string]interface{} {
} }
func flattenAffinityRules(affinityRules compute.ListRules) []map[string]interface{} { func flattenAffinityRules(affinityRules compute.ListRules) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(affinityRules))
for _, affinityRule := range affinityRules { for _, affinityRule := range affinityRules {
temp := map[string]interface{}{ temp := map[string]interface{}{
"guid": affinityRule.GUID, "guid": affinityRule.GUID,
@@ -436,7 +437,7 @@ func flattenIotune(iotune compute.IOTune) []map[string]interface{} {
} }
func flattenSnapshots(snapshots compute.SnapshotExtendList) []map[string]interface{} { func flattenSnapshots(snapshots compute.SnapshotExtendList) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(snapshots))
for _, snapshot := range snapshots { for _, snapshot := range snapshots {
temp := map[string]interface{}{ temp := map[string]interface{}{
"guid": snapshot.GUID, "guid": snapshot.GUID,
@@ -454,7 +455,7 @@ func flattenSnapshots(snapshots compute.SnapshotExtendList) []map[string]interfa
} }
func flattenListComputeDisks(disks compute.ListComputeDisks) []map[string]interface{} { func flattenListComputeDisks(disks compute.ListComputeDisks) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(disks))
for _, disk := range disks { for _, disk := range disks {
acl, _ := json.Marshal(disk.ACL) acl, _ := json.Marshal(disk.ACL)
temp := map[string]interface{}{ temp := map[string]interface{}{
@@ -510,7 +511,7 @@ func flattenCustomFields(customFields map[string]interface{}) string {
} }
func flattenOsUsers(osUsers compute.ListOSUser) []map[string]interface{} { func flattenOsUsers(osUsers compute.ListOSUser) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(osUsers))
for _, user := range osUsers { for _, user := range osUsers {
temp := map[string]interface{}{ temp := map[string]interface{}{
"guid": user.GUID, "guid": user.GUID,
@@ -542,7 +543,7 @@ func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute
d.Set("cpus", computeRec.CPU) d.Set("cpus", computeRec.CPU)
d.Set("created_by", computeRec.CreatedBy) d.Set("created_by", computeRec.CreatedBy)
d.Set("created_time", computeRec.CreatedTime) d.Set("created_time", computeRec.CreatedTime)
// d.Set("custom_fields", flattenCustomFields(computeRec.CustomFields)) d.Set("custom_fields", flattenCustomFields(computeRec.CustomFields))
d.Set("deleted_by", computeRec.DeletedBy) d.Set("deleted_by", computeRec.DeletedBy)
d.Set("deleted_time", computeRec.DeletedTime) d.Set("deleted_time", computeRec.DeletedTime)
d.Set("desc", computeRec.Description) d.Set("desc", computeRec.Description)
@@ -589,7 +590,7 @@ func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute
} }
func flattenComputeAudits(computeAudits compute.ListAudits) []map[string]interface{} { func flattenComputeAudits(computeAudits compute.ListAudits) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(computeAudits))
for _, computeAudit := range computeAudits { for _, computeAudit := range computeAudits {
temp := map[string]interface{}{ temp := map[string]interface{}{
"call": computeAudit.Call, "call": computeAudit.Call,
@@ -604,7 +605,7 @@ func flattenComputeAudits(computeAudits compute.ListAudits) []map[string]interfa
} }
func flattenPfwList(computePfws *compute.ListPFWs) []map[string]interface{} { func flattenPfwList(computePfws *compute.ListPFWs) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(computePfws.Data))
for _, computePfw := range computePfws.Data { for _, computePfw := range computePfws.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"pfw_id": computePfw.ID, "pfw_id": computePfw.ID,
@@ -627,7 +628,7 @@ func flattenUserList(d *schema.ResourceData, userList *compute.ListUsers) {
} }
func flattenComputeGetAudits(computeAudits compute.ListShortAudits) []map[string]interface{} { func flattenComputeGetAudits(computeAudits compute.ListShortAudits) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(computeAudits))
for _, computeAudit := range computeAudits { for _, computeAudit := range computeAudits {
temp := map[string]interface{}{ temp := map[string]interface{}{
"epoch": computeAudit.Epoch, "epoch": computeAudit.Epoch,
@@ -639,7 +640,7 @@ func flattenComputeGetAudits(computeAudits compute.ListShortAudits) []map[string
} }
func flattenSnapshotUsage(computeSnapshotUsages compute.ListUsageSnapshots) []map[string]interface{} { func flattenSnapshotUsage(computeSnapshotUsages compute.ListUsageSnapshots) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(computeSnapshotUsages))
for _, computeUsage := range computeSnapshotUsages { for _, computeUsage := range computeSnapshotUsages {
temp := map[string]interface{}{ temp := map[string]interface{}{
"count": computeUsage.Count, "count": computeUsage.Count,
@@ -651,3 +652,55 @@ func flattenSnapshotUsage(computeSnapshotUsages compute.ListUsageSnapshots) []ma
} }
return res 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(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 flattenPCIDevice(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
}

File diff suppressed because it is too large Load Diff

View File

@@ -63,14 +63,16 @@ func existRgID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool
func existImageId(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { func existImageId(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
imageId := uint64(d.Get("image_id").(int)) imageId := uint64(d.Get("image_id").(int))
req := image.ListRequest{} req := image.ListRequest{
ByID: imageId,
}
imageList, err := c.CloudAPI().Image().List(ctx, req) imageList, err := c.CloudAPI().Image().List(ctx, req)
if err != nil { if err != nil {
return false, err return false, err
} }
return len(imageList.FilterByID(imageId).Data) != 0, nil return len(imageList.Data) != 0, nil
} }
func existVinsIdInList(vinsId uint64, vinsList *vins.ListVINS) bool { func existVinsIdInList(vinsId uint64, vinsList *vins.ListVINS) bool {

View File

@@ -129,9 +129,7 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
createReqX86.IS = IS.(string) createReqX86.IS = IS.(string)
} }
if !d.Get("with_default_vins").(bool) { createReqX86.Interfaces = make([]kvmx86.Interface, 0)
createReqX86.Interfaces = make([]kvmx86.Interface, 0)
}
if networks, ok := d.GetOk("network"); ok { if networks, ok := d.GetOk("network"); ok {
if networks.(*schema.Set).Len() > 0 { if networks.(*schema.Set).Len() > 0 {
@@ -192,6 +190,16 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
createReqX86.Driver = driver createReqX86.Driver = driver
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
}
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86") log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
apiResp, err := c.CloudAPI().KVMX86().Create(ctx, createReqX86) apiResp, err := c.CloudAPI().KVMX86().Create(ctx, createReqX86)
if err != nil { if err != nil {
@@ -226,7 +234,7 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
argVal, ok = d.GetOk("extra_disks") argVal, ok = d.GetOk("extra_disks")
if ok && argVal.(*schema.Set).Len() > 0 { if ok && argVal.(*schema.Set).Len() > 0 {
log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len()) log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len())
err = utilityComputeExtraDisksConfigure(ctx, d, m, false) err = utilityComputeExtraDisksConfigure(ctx, d, m, false, nil)
if err != nil { if err != nil {
log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", computeId, err) log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", computeId, err)
cleanup = true cleanup = true
@@ -247,13 +255,13 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
if enabled, ok := d.GetOk("enabled"); ok { if enabled, ok := d.GetOk("enabled"); ok {
if enabled.(bool) { if enabled.(bool) {
req := compute.EnableRequest{ComputeID: computeId} req := compute.EnableRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", computeId, enabled) 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 { if _, err := c.CloudAPI().Compute().Enable(ctx, req); err != nil {
warnings.Add(err) warnings.Add(err)
} }
} else { } else {
req := compute.DisableRequest{ComputeID: computeId} req := compute.DisableRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", computeId, enabled) 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 { if _, err := c.CloudAPI().Compute().Disable(ctx, req); err != nil {
warnings.Add(err) warnings.Add(err)
} }
@@ -486,7 +494,7 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
log.Debugf("resourceComputeRead: called for Compute name %s, RG ID %d", log.Debugf("resourceComputeRead: called for Compute name %s, RG ID %d",
d.Get("name").(string), d.Get("rg_id").(int)) d.Get("name").(string), d.Get("rg_id").(int))
c := m.(*controller.ControllerCfg) // c := m.(*controller.ControllerCfg)
computeRec, err := utilityComputeCheckPresence(ctx, d, m) computeRec, err := utilityComputeCheckPresence(ctx, d, m)
if err != nil { if err != nil {
@@ -497,23 +505,24 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
switch computeRec.Status { switch computeRec.Status {
case status.Deleted: case status.Deleted:
restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID} // restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID}
enableReq := compute.EnableRequest{ComputeID: computeRec.ID} // enableReq := compute.EnableRequest{ComputeID: computeRec.ID}
_, err := c.CloudAPI().Compute().Restore(ctx, restoreReq) // _, err := c.CloudAPI().Compute().Restore(ctx, restoreReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
_, err = c.CloudAPI().Compute().Enable(ctx, enableReq) // _, err = c.CloudAPI().Compute().Enable(ctx, enableReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
hasChanged = true // hasChanged = true
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceComputeCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceComputeCreate(ctx, d, m)
case status.Disabled: case status.Disabled:
log.Debugf("The compute is in status: %s, troubles may occur with update. Please, enable compute first.", computeRec.Status) log.Debugf("The compute is in status: %s, troubles may occur with update. Please, enable compute first.", computeRec.Status)
case status.Redeploying: case status.Redeploying:
@@ -574,11 +583,11 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
switch networkData["net_type"].(string) { switch networkData["net_type"].(string) {
case "VINS": case "VINS":
if vinsId, ok := existVinsId(ctx, m, networkData["net_id"].(int)); !ok { 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) return diag.Errorf("resourceComputeCreate: can't update compute because vins ID %d is not allowed or does not exist", vinsId)
} }
case "EXTNET": case "EXTNET":
if extNetId, ok := existExtNetId(ctx, m, networkData["net_id"].(int)); !ok { 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) return diag.Errorf("resourceComputeCreate: can't update compute because extnet ID %d is not allowed or does not exist", extNetId)
} }
default: default:
@@ -632,7 +641,8 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceComputeCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceComputeCreate(ctx, d, m)
case status.Disabled: case status.Disabled:
log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", computeRec.Status) 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.Redeploying:
@@ -706,7 +716,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
} }
if d.HasChange("extra_disks") { if d.HasChange("extra_disks") {
err := utilityComputeExtraDisksConfigure(ctx, d, m, true) // pass do_delta = true to apply changes, if any err := utilityComputeExtraDisksConfigure(ctx, d, m, true, computeRec.Disks) // pass do_delta = true to apply changes, if any
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -725,7 +735,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
Name: d.Get("name").(string), Name: d.Get("name").(string),
} }
if desc, ok := d.GetOk("desc"); ok { if desc, ok := d.GetOk("description"); ok {
req.Description = desc.(string) req.Description = desc.(string)
} }
@@ -745,7 +755,23 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
for _, el := range oldConv { for _, el := range oldConv {
if !isContainsDisk(newConv, el) { if !isContainsDisk(newConv, el) {
deletedDisks = append(deletedDisks, 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)
}
} }
} }
@@ -772,7 +798,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
for _, disk := range deletedDisks { for _, disk := range deletedDisks {
diskConv := disk.(map[string]interface{}) diskConv := disk.(map[string]interface{})
if strings.Contains(diskConv["disk_name"].(string), "bootdisk") { if diskConv["disk_type"].(string) == "B" {
continue continue
} }
@@ -782,6 +808,8 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
Permanently: diskConv["permanently"].(bool), Permanently: diskConv["permanently"].(bool),
} }
log.Debugf("trying to delete disk %d", req.DiskID)
_, err := c.CloudAPI().Compute().DiskDel(ctx, req) _, err := c.CloudAPI().Compute().DiskDel(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
@@ -800,7 +828,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if len(addedDisks) > 0 { if len(addedDisks) > 0 {
for _, disk := range addedDisks { for _, disk := range addedDisks {
diskConv := disk.(map[string]interface{}) diskConv := disk.(map[string]interface{})
if strings.Contains(diskConv["disk_name"].(string), "bootdisk") { if diskConv["disk_type"].(string) == "B" {
continue continue
} }
req := compute.DiskAddRequest{ req := compute.DiskAddRequest{
@@ -832,7 +860,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if len(updatedDisks) > 0 { if len(updatedDisks) > 0 {
for _, disk := range updatedDisks { for _, disk := range updatedDisks {
diskConv := disk.(map[string]interface{}) diskConv := disk.(map[string]interface{})
if strings.Contains(diskConv["disk_name"].(string), "bootdisk") { if diskConv["disk_type"].(string) == "B" {
continue continue
} }
req := compute.DiskResizeRequest{ req := compute.DiskResizeRequest{
@@ -1335,6 +1363,35 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
} }
} }
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)
}
}
}
// we may reuse dataSourceComputeRead here as we maintain similarity // we may reuse dataSourceComputeRead here as we maintain similarity
// between Compute resource and Compute data source schemas // between Compute resource and Compute data source schemas
defer resourceComputeRead(ctx, d, m) defer resourceComputeRead(ctx, d, m)
@@ -1556,16 +1613,16 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.", Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.",
}, },
"rg_id": { "rg_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, // ForceNew: true,
ValidateFunc: validation.IntAtLeast(1), ValidateFunc: validation.IntAtLeast(1),
Description: "ID of the resource group where this compute should be deployed.", Description: "ID of the resource group where this compute should be deployed.",
}, },
"driver": { "driver": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true, // ForceNew: true,
StateFunc: statefuncs.StateFuncToUpper, StateFunc: statefuncs.StateFuncToUpper,
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86", "KVM_PPC"}, false), // observe case while validating ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86", "KVM_PPC"}, false), // observe case while validating
Description: "Hardware architecture of this compute instance.", Description: "Hardware architecture of this compute instance.",
@@ -1678,18 +1735,17 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Schema: disksSubresourceSchemaMake(), Schema: disksSubresourceSchemaMake(),
}, },
}, },
"custom_fields": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"stateless": { "stateless": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
Default: false, Default: false,
Description: "Compute will be stateless (SVA_KVM_X86) if set to True", 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": { "boot_disk": {
Type: schema.TypeSet, Type: schema.TypeSet,
Computed: true, Computed: true,
@@ -1698,23 +1754,24 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
}, },
}, },
"sep_id": { "sep_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, // ForceNew: true,
Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.", Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.",
}, },
"pool": { "pool": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, // ForceNew: true,
Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.", Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.",
}, },
"extra_disks": { "extra_disks": {
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
Computed: true,
MaxItems: constants.MaxExtraDisksPerCompute, MaxItems: constants.MaxExtraDisksPerCompute,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
@@ -2075,7 +2132,7 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
func ResourceCompute() *schema.Resource { func ResourceCompute() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 3,
CreateContext: resourceComputeCreate, CreateContext: resourceComputeCreate,
ReadContext: resourceComputeRead, ReadContext: resourceComputeRead,
@@ -2095,5 +2152,17 @@ func ResourceCompute() *schema.Resource {
}, },
Schema: ResourceComputeSchemaMake(), Schema: ResourceComputeSchemaMake(),
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceComputeResourceV1().CoreConfigSchema().ImpliedType(),
Upgrade: resourceCompueteStateUpgradeV1,
Version: 1,
},
{
Type: resourceComputeResourceV2().CoreConfigSchema().ImpliedType(),
Upgrade: resourceComputeStateUpgradeV2,
Version: 2,
},
},
} }
} }

View File

@@ -0,0 +1,41 @@
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
}

View File

@@ -54,7 +54,7 @@ func matchComputes(computeList *compute.ListComputes) *compute.ListComputes {
return &result return &result
} }
func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool) error { func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool, disks compute.ListComputeDisks) error {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %t", d.Id(), do_delta) log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %t", d.Id(), do_delta)
@@ -138,6 +138,22 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa
DiskID: uint64(diskId.(int)), 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) _, err := c.CloudAPI().Compute().DiskAttach(ctx, req)
if err != nil { if err != nil {
log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err) log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err)
@@ -165,6 +181,7 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
Force: true, Force: true,
} }
log.Debugf("utilityComputeNetworksConfigure: stopping compute %d", computeID)
_, err := c.CloudAPI().Compute().Stop(ctx, req) _, err := c.CloudAPI().Compute().Stop(ctx, req)
if err != nil { if err != nil {
return err return err
@@ -255,6 +272,7 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
startReq := compute.StartRequest{ComputeID: computeID} startReq := compute.StartRequest{ComputeID: computeID}
log.Debugf("utilityComputeNetworksConfigure: starting compute %d", computeID)
_, err = c.CloudAPI().Compute().Start(ctx, startReq) _, err = c.CloudAPI().Compute().Start(ctx, startReq)
if err != nil { if err != nil {
apiErrCount++ apiErrCount++
@@ -279,7 +297,7 @@ func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m
computeRecord, err := c.CloudAPI().Compute().Get(ctx, req) computeRecord, err := c.CloudAPI().Compute().Get(ctx, req)
if err != nil { if err != nil {
return *computeRecord, err return compute.RecordCompute{}, err
} }
return *computeRecord, nil return *computeRecord, nil

View File

@@ -0,0 +1,87 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 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
}

View File

@@ -0,0 +1,74 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 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
}

View File

@@ -0,0 +1,74 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 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
}

View File

@@ -91,6 +91,7 @@ func flattenResourceLBBackend(d *schema.ResourceData, b *lb.ItemBackend, lbId in
func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) { func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) {
d.Set("ha_mode", lb.HAMode) d.Set("ha_mode", lb.HAMode)
d.Set("backend_haip", lb.BackendHAIP)
d.Set("backends", flattenLBBackends(lb.Backends)) d.Set("backends", flattenLBBackends(lb.Backends))
d.Set("created_by", lb.CreatedBy) d.Set("created_by", lb.CreatedBy)
d.Set("created_time", lb.CreatedTime) d.Set("created_time", lb.CreatedTime)
@@ -99,6 +100,7 @@ func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) {
d.Set("desc", lb.Description) d.Set("desc", lb.Description)
d.Set("dp_api_user", lb.DPAPIUser) d.Set("dp_api_user", lb.DPAPIUser)
d.Set("extnet_id", lb.ExtNetID) d.Set("extnet_id", lb.ExtNetID)
d.Set("frontend_haip", lb.FrontendHAIP)
d.Set("frontends", flattenFrontends(lb.Frontends)) d.Set("frontends", flattenFrontends(lb.Frontends))
d.Set("gid", lb.GID) d.Set("gid", lb.GID)
d.Set("guid", lb.GUID) d.Set("guid", lb.GUID)
@@ -106,6 +108,7 @@ func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) {
d.Set("image_id", lb.ImageID) d.Set("image_id", lb.ImageID)
d.Set("milestones", lb.Milestones) d.Set("milestones", lb.Milestones)
d.Set("name", lb.Name) d.Set("name", lb.Name)
d.Set("part_k8s", lb.PartK8s)
d.Set("primary_node", flattenNode(lb.PrimaryNode)) d.Set("primary_node", flattenNode(lb.PrimaryNode))
d.Set("rg_id", lb.RGID) d.Set("rg_id", lb.RGID)
d.Set("rg_name", lb.RGName) d.Set("rg_name", lb.RGName)
@@ -120,6 +123,7 @@ func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) {
func flattenLB(d *schema.ResourceData, lb *lb.RecordLB) { func flattenLB(d *schema.ResourceData, lb *lb.RecordLB) {
d.Set("ha_mode", lb.HAMode) d.Set("ha_mode", lb.HAMode)
d.Set("backend_haip", lb.BackendHAIP)
d.Set("backends", flattenLBBackends(lb.Backends)) d.Set("backends", flattenLBBackends(lb.Backends))
d.Set("created_by", lb.CreatedBy) d.Set("created_by", lb.CreatedBy)
d.Set("created_time", lb.CreatedTime) d.Set("created_time", lb.CreatedTime)
@@ -128,12 +132,14 @@ func flattenLB(d *schema.ResourceData, lb *lb.RecordLB) {
d.Set("desc", lb.Description) d.Set("desc", lb.Description)
d.Set("dp_api_user", lb.DPAPIUser) d.Set("dp_api_user", lb.DPAPIUser)
d.Set("extnet_id", lb.ExtNetID) d.Set("extnet_id", lb.ExtNetID)
d.Set("frontend_haip", lb.FrontendHAIP)
d.Set("frontends", flattenFrontends(lb.Frontends)) d.Set("frontends", flattenFrontends(lb.Frontends))
d.Set("gid", lb.GID) d.Set("gid", lb.GID)
d.Set("guid", lb.GUID) d.Set("guid", lb.GUID)
d.Set("image_id", lb.ImageID) d.Set("image_id", lb.ImageID)
d.Set("milestones", lb.Milestones) d.Set("milestones", lb.Milestones)
d.Set("name", lb.Name) d.Set("name", lb.Name)
d.Set("part_k8s", lb.PartK8s)
d.Set("primary_node", flattenNode(lb.PrimaryNode)) d.Set("primary_node", flattenNode(lb.PrimaryNode))
d.Set("rg_id", lb.RGID) d.Set("rg_id", lb.RGID)
d.Set("rg_name", lb.RGName) d.Set("rg_name", lb.RGName)
@@ -246,6 +252,7 @@ func flattenLBList(lbl *lb.ListLB) []map[string]interface{} {
for _, lb := range lbl.Data { for _, lb := range lbl.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"ha_mode": lb.HAMode, "ha_mode": lb.HAMode,
"backend_haip": lb.BackendHAIP,
"backends": flattenLBBackends(lb.Backends), "backends": flattenLBBackends(lb.Backends),
"created_by": lb.CreatedBy, "created_by": lb.CreatedBy,
"created_time": lb.CreatedTime, "created_time": lb.CreatedTime,
@@ -255,6 +262,7 @@ func flattenLBList(lbl *lb.ListLB) []map[string]interface{} {
"dp_api_user": lb.DPAPIUser, "dp_api_user": lb.DPAPIUser,
"dp_api_password": lb.DPAPIPassword, "dp_api_password": lb.DPAPIPassword,
"extnet_id": lb.ExtNetID, "extnet_id": lb.ExtNetID,
"frontend_haip": lb.FrontendHAIP,
"frontends": flattenFrontends(lb.Frontends), "frontends": flattenFrontends(lb.Frontends),
"gid": lb.GID, "gid": lb.GID,
"guid": lb.GUID, "guid": lb.GUID,

View File

@@ -181,5 +181,6 @@ func dsLBItemSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
} }
delete(sch, "part_k8s")
return sch return sch
} }

View File

@@ -47,12 +47,12 @@ func lbResourceSchemaMake() map[string]*schema.Schema {
sch["extnet_id"] = &schema.Schema{ sch["extnet_id"] = &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Optional: true,
} }
sch["vins_id"] = &schema.Schema{ sch["vins_id"] = &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Optional: true,
} }
sch["start"] = &schema.Schema{ sch["start"] = &schema.Schema{
Type: schema.TypeBool, Type: schema.TypeBool,
@@ -83,7 +83,18 @@ func lbResourceSchemaMake() map[string]*schema.Schema {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
} }
///4.4.0
sch["ha_mode"] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,
}
sch["lb_sysctl_params"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
}
///
sch["permanently"] = &schema.Schema{ sch["permanently"] = &schema.Schema{
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,

View File

@@ -40,6 +40,10 @@ func createLBSchema() map[string]*schema.Schema {
Type: schema.TypeBool, Type: schema.TypeBool,
Computed: true, Computed: true,
}, },
"backend_haip": {
Type: schema.TypeString,
Computed: true,
},
"backends": { "backends": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -204,6 +208,10 @@ func createLBSchema() map[string]*schema.Schema {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"frontend_haip": {
Type: schema.TypeString,
Computed: true,
},
"frontends": { "frontends": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -272,6 +280,10 @@ func createLBSchema() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"part_k8s": {
Type: schema.TypeBool,
Computed: true,
},
"primary_node": { "primary_node": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,

View File

@@ -43,6 +43,11 @@ func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
extNetID := uint64(d.Get("extnet_id").(int)) 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{} req := extnet.ListRequest{}
extNetList, err := c.CloudAPI().ExtNet().List(ctx, req) extNetList, err := c.CloudAPI().ExtNet().List(ctx, req)
@@ -57,6 +62,11 @@ func existViNSID(ctx context.Context, d *schema.ResourceData, m interface{}) (bo
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
vinsID := uint64(d.Get("vins_id").(int)) 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{} req := vins.ListRequest{}
vinsList, err := c.CloudAPI().VINS().List(ctx, req) vinsList, err := c.CloudAPI().VINS().List(ctx, req)

View File

@@ -88,15 +88,19 @@ func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}
req.Description = desc.(string) req.Description = desc.(string)
} }
if haMode, ok := d.GetOk("ha_mode"); ok {
req.HighlyAvailable = haMode.(bool)
}
lbId, err := c.CloudAPI().LB().Create(ctx, req) lbId, err := c.CloudAPI().LB().Create(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
lbIdParsed, _ := strconv.ParseInt(lbId, 10, 64) lbIdParsed := strconv.Itoa(int(lbId))
d.SetId(lbId) d.SetId(lbIdParsed)
d.Set("lb_id", lbIdParsed) d.Set("lb_id", lbId)
_, err = utilityLBCheckPresence(ctx, d, m) _, err = utilityLBCheckPresence(ctx, d, m)
if err != nil { if err != nil {
@@ -128,7 +132,7 @@ func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}
func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBRead") log.Debugf("resourceLBRead")
c := m.(*controller.ControllerCfg) // c := m.(*controller.ControllerCfg)
lbRec, err := utilityLBCheckPresence(ctx, d, m) lbRec, err := utilityLBCheckPresence(ctx, d, m)
if lbRec == nil { if lbRec == nil {
@@ -145,25 +149,26 @@ func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{})
case status.Created: case status.Created:
case status.Deleting: case status.Deleting:
case status.Deleted: case status.Deleted:
lbId, _ := strconv.ParseUint(d.Id(), 10, 64) // lbId, _ := strconv.ParseUint(d.Id(), 10, 64)
restoreReq := lb.RestoreRequest{LBID: lbId} // restoreReq := lb.RestoreRequest{LBID: lbId}
enableReq := lb.DisableEnableRequest{LBID: lbId} // enableReq := lb.DisableEnableRequest{LBID: lbId}
_, err := c.CloudAPI().LB().Restore(ctx, restoreReq) // _, err := c.CloudAPI().LB().Restore(ctx, restoreReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
_, err = c.CloudAPI().LB().Enable(ctx, enableReq) // _, err = c.CloudAPI().LB().Enable(ctx, enableReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
hasChanged = true // hasChanged = true
case status.Destroying: case status.Destroying:
return diag.Errorf("The LB is in progress with status: %s", lbRec.Status) return diag.Errorf("The LB is in progress with status: %s", lbRec.Status)
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceLBCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceLBCreate(ctx, d, m)
case status.Enabled: case status.Enabled:
case status.Enabling: case status.Enabling:
case status.Disabling: case status.Disabling:
@@ -276,7 +281,8 @@ func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}
return diag.Errorf("The LB is in progress with status: %s", lbRec.Status) return diag.Errorf("The LB is in progress with status: %s", lbRec.Status)
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceLBCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceLBCreate(ctx, d, m)
case status.Enabled: case status.Enabled:
case status.Enabling: case status.Enabling:
case status.Disabling: case status.Disabling:
@@ -286,13 +292,26 @@ func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}
} }
if hasChanged { if hasChanged {
lbRec, err = utilityLBCheckPresence(ctx, d, m) _, err = utilityLBCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) 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("enable") { if d.HasChange("enable") {
enable := d.Get("enable").(bool) enable := d.Get("enable").(bool)
req := lb.DisableEnableRequest{ req := lb.DisableEnableRequest{

View File

@@ -34,6 +34,7 @@ package pfw
import ( import (
"context" "context"
"fmt"
"strconv" "strconv"
"strings" "strings"
@@ -65,5 +66,5 @@ func utilityPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m inte
} }
} }
return nil, nil return nil, fmt.Errorf("PFW not found")
} }

View File

@@ -393,7 +393,7 @@ func dataSourceRgSchemaMake() map[string]*schema.Schema {
} }
func dataSourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
rg, err := utilityDataResgroupCheckPresence(ctx, d, m) rg, err := utilityResgroupCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") // ensure ID is empty in this case d.SetId("") // ensure ID is empty in this case
return diag.FromErr(err) return diag.FromErr(err)

View File

@@ -49,6 +49,7 @@ func dataSourceRgAffinityGroupsListRead(ctx context.Context, d *schema.ResourceD
d.SetId(strconv.Itoa(d.Get("rg_id").(int))) d.SetId(strconv.Itoa(d.Get("rg_id").(int)))
d.Set("affinity_groups", flattenRgListGroups(list)) d.Set("affinity_groups", flattenRgListGroups(list))
d.Set("entry_count", list.EntryCount)
return nil return nil
} }
@@ -59,6 +60,16 @@ func dataSourceRgAffinityGroupsListSchemaMake() map[string]*schema.Schema {
Required: true, Required: true,
Description: "ID of the RG", 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": { "affinity_groups": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -71,13 +82,26 @@ func dataSourceRgAffinityGroupsListSchemaMake() map[string]*schema.Schema {
"ids": { "ids": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Schema{ Elem: &schema.Resource{
Type: schema.TypeInt, 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 return res

View File

@@ -0,0 +1,101 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 {
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(),
}
}

View File

@@ -78,17 +78,17 @@ func dataSourceRgListVinsSchemaMake() map[string]*schema.Schema {
}, },
"vins_id": { "vins_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Optional: true,
Description: "Filter by ViNS ID", Description: "Filter by ViNS ID",
}, },
"page": { "page": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Optional: true,
Description: "Page number", Description: "Page number",
}, },
"size": { "size": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Optional: true,
Description: "Page size", Description: "Page size",
}, },
"items": { "items": {

View File

@@ -0,0 +1,211 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 {
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,
},
"exttraffic": {
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,
},
"cu_np": {
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(),
}
}

View File

@@ -40,7 +40,7 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg"
) )
func flattenAccountSeps(seps map[string]map[string]DiskUsage) []map[string]interface{} { func flattenRGSeps(seps map[string]map[string]rg.DiskUsage) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0)
for sepKey, sepVal := range seps { for sepKey, sepVal := range seps {
for dataKey, dataVal := range sepVal { for dataKey, dataVal := range sepVal {
@@ -57,31 +57,31 @@ func flattenAccountSeps(seps map[string]map[string]DiskUsage) []map[string]inter
return res return res
} }
func flattenAccResource(r Resource) []map[string]interface{} { // func flattenAccResource(r Resource) []map[string]interface{} {
res := make([]map[string]interface{}, 0) // res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{ // temp := map[string]interface{}{
"cpu": r.CPU, // "cpu": r.CPU,
"disksize": r.DiskSize, // "disksize": r.DiskSize,
"extips": r.ExtIPs, // "extips": r.ExtIPs,
"exttraffic": r.ExtTraffic, // "exttraffic": r.ExtTraffic,
"gpu": r.GPU, // "gpu": r.GPU,
"ram": r.RAM, // "ram": r.RAM,
"seps": flattenAccountSeps(r.SEPs), // "seps": flattenRgSeps(r.SEPs),
} // }
res = append(res, temp) // res = append(res, temp)
return res // return res
} // }
func flattenRgResources(r Resources) []map[string]interface{} { // func flattenRgResources(r Resources) []map[string]interface{} {
res := make([]map[string]interface{}, 0) // res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{ // temp := map[string]interface{}{
"current": flattenAccResource(r.Current), // "current": flattenAccResource(r.Current),
"reserved": flattenAccResource(r.Reserved), // "reserved": flattenAccResource(r.Reserved),
} // }
res = append(res, temp) // res = append(res, temp)
return res // return res
} // }
func flattenResgroup(d *schema.ResourceData, details rg.RecordResourceGroup) error { func flattenResgroup(d *schema.ResourceData, details rg.RecordResourceGroup) error {
log.Debugf("flattenResgroup: decoded RG name %q / ID %d, account ID %d", log.Debugf("flattenResgroup: decoded RG name %q / ID %d, account ID %d",
@@ -122,7 +122,7 @@ func flattenResgroup(d *schema.ResourceData, details rg.RecordResourceGroup) err
} }
func flattenRgSeps(seps map[string]map[string]rg.DiskUsage) []map[string]interface{} { func flattenRgSeps(seps map[string]map[string]rg.DiskUsage) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(seps))
for sepKey, sepVal := range seps { for sepKey, sepVal := range seps {
SepMap := map[string]interface{}{} SepMap := map[string]interface{}{}
for dataKey, dataVal := range sepVal { for dataKey, dataVal := range sepVal {
@@ -140,7 +140,6 @@ func flattenRgSeps(seps map[string]map[string]rg.DiskUsage) []map[string]interfa
func flattenResource(resource rg.Resource) []map[string]interface{} { func flattenResource(resource rg.Resource) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{ temp := map[string]interface{}{
"cpu": resource.CPU, "cpu": resource.CPU,
"disk_size": resource.DiskSize, "disk_size": resource.DiskSize,
@@ -149,7 +148,7 @@ func flattenResource(resource rg.Resource) []map[string]interface{} {
"exttraffic": resource.ExtTraffic, "exttraffic": resource.ExtTraffic,
"gpu": resource.GPU, "gpu": resource.GPU,
"ram": resource.RAM, "ram": resource.RAM,
"seps": flattenRgSeps(resource.SEPs), "seps": flattenRGSeps(resource.SEPs),
} }
res = append(res, temp) res = append(res, temp)
@@ -191,7 +190,7 @@ func flattenRg(d *schema.ResourceData, itemRg rg.RecordResourceGroup) {
} }
func flattenRgAudits(rgAudits rg.ListAudits) []map[string]interface{} { func flattenRgAudits(rgAudits rg.ListAudits) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(rgAudits))
for _, rgAudit := range rgAudits { for _, rgAudit := range rgAudits {
temp := map[string]interface{}{ temp := map[string]interface{}{
"call": rgAudit.Call, "call": rgAudit.Call,
@@ -208,7 +207,7 @@ func flattenRgAudits(rgAudits rg.ListAudits) []map[string]interface{} {
} }
func flattenRgList(rgl *rg.ListResourceGroups) []map[string]interface{} { func flattenRgList(rgl *rg.ListResourceGroups) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(rgl.Data))
for _, rg := range rgl.Data { for _, rg := range rgl.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"account_acl": flattenRgAcl(rg.ACL), "account_acl": flattenRgAcl(rg.ACL),
@@ -249,7 +248,7 @@ func flattenRgList(rgl *rg.ListResourceGroups) []map[string]interface{} {
} }
func flattenRgAcl(rgAcls rg.ListACL) []map[string]interface{} { func flattenRgAcl(rgAcls rg.ListACL) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(rgAcls))
for _, rgAcl := range rgAcls { for _, rgAcl := range rgAcls {
temp := map[string]interface{}{ temp := map[string]interface{}{
"explicit": rgAcl.Explicit, "explicit": rgAcl.Explicit,
@@ -281,7 +280,7 @@ func flattenRgResourceLimits(rl rg.ResourceLimits) []map[string]interface{} {
} }
func flattenRules(list rg.ListRules) []map[string]interface{} { func flattenRules(list rg.ListRules) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(list))
for _, rule := range list { for _, rule := range list {
temp := map[string]interface{}{ temp := map[string]interface{}{
"guid": rule.GUID, "guid": rule.GUID,
@@ -299,7 +298,7 @@ func flattenRules(list rg.ListRules) []map[string]interface{} {
} }
func flattenRgListComputes(lc *rg.ListComputes) []map[string]interface{} { func flattenRgListComputes(lc *rg.ListComputes) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(lc.Data))
for _, compute := range lc.Data { for _, compute := range lc.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"account_id": compute.AccountID, "account_id": compute.AccountID,
@@ -351,7 +350,7 @@ func flattenServerSettings(settings rg.RecordServerSettings) []map[string]interf
} }
func flattenListServers(list rg.ListServers) []map[string]interface{} { func flattenListServers(list rg.ListServers) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(list))
for _, serv := range list { for _, serv := range list {
temp := map[string]interface{}{ temp := map[string]interface{}{
"address": serv.Address, "address": serv.Address,
@@ -368,7 +367,7 @@ func flattenListServers(list rg.ListServers) []map[string]interface{} {
} }
func flattenBackends(b rg.ListBackends) []map[string]interface{} { func flattenBackends(b rg.ListBackends) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(b))
for _, item := range b { for _, item := range b {
temp := map[string]interface{}{ temp := map[string]interface{}{
"algorithm": item.Algorithm, "algorithm": item.Algorithm,
@@ -383,7 +382,7 @@ func flattenBackends(b rg.ListBackends) []map[string]interface{} {
} }
func flattenBindings(list rg.ListBindings) []map[string]interface{} { func flattenBindings(list rg.ListBindings) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(list))
for _, bind := range list { for _, bind := range list {
temp := map[string]interface{}{ temp := map[string]interface{}{
"address": bind.Address, "address": bind.Address,
@@ -398,7 +397,7 @@ func flattenBindings(list rg.ListBindings) []map[string]interface{} {
} }
func flattenFrontends(list rg.ListFrontends) []map[string]interface{} { func flattenFrontends(list rg.ListFrontends) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(list))
for _, front := range list { for _, front := range list {
temp := map[string]interface{}{ temp := map[string]interface{}{
"backend": front.Backend, "backend": front.Backend,
@@ -427,7 +426,7 @@ func flattenNode(node rg.RecordNode) []map[string]interface{} {
} }
func flattenRgListLb(listLb *rg.ListLB) []map[string]interface{} { func flattenRgListLb(listLb *rg.ListLB) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(listLb.Data))
for _, lb := range listLb.Data { for _, lb := range listLb.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"ha_mode": lb.HAMode, "ha_mode": lb.HAMode,
@@ -462,7 +461,7 @@ func flattenRgListLb(listLb *rg.ListLB) []map[string]interface{} {
} }
func flattenRgListPfw(listPfw *rg.ListPortForwards) []map[string]interface{} { func flattenRgListPfw(listPfw *rg.ListPortForwards) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(listPfw.Data))
for _, pfw := range listPfw.Data { for _, pfw := range listPfw.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"public_port_end": pfw.PublicPortEnd, "public_port_end": pfw.PublicPortEnd,
@@ -481,7 +480,7 @@ func flattenRgListPfw(listPfw *rg.ListPortForwards) []map[string]interface{} {
} }
func flattenRgListVins(lv *rg.ListVINS) []map[string]interface{} { func flattenRgListVins(lv *rg.ListVINS) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(lv.Data))
for _, vins := range lv.Data { for _, vins := range lv.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"account_id": vins.AccountID, "account_id": vins.AccountID,
@@ -509,7 +508,7 @@ func flattenRgListVins(lv *rg.ListVINS) []map[string]interface{} {
} }
func flattenRgAffinityGroupComputes(list rg.ListAffinityGroupsComputes) []map[string]interface{} { func flattenRgAffinityGroupComputes(list rg.ListAffinityGroupsComputes) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(list))
for _, item := range list { for _, item := range list {
temp := map[string]interface{}{ temp := map[string]interface{}{
@@ -527,22 +526,37 @@ func flattenRgAffinityGroupComputes(list rg.ListAffinityGroupsComputes) []map[st
return res return res
} }
func flattenRgAffinityGroupsGet(list []uint64) []map[string]interface{} { // func flattenRgAffinityGroupsGet(list []uint64) []map[string]interface{} {
res := make([]map[string]interface{}, 0) // res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{ // temp := map[string]interface{}{
"items": list, // "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)
}
} }
res = append(res, temp)
return res return res
} }
func flattenRgListGroups(list *rg.ListAffinityGroups) []map[string]interface{} { func flattenRgAffinityListGroup(list rg.ListAffinityGroup) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(list))
for groupKey, groupVal := range list.Data { for _, ag := range list {
temp := map[string]interface{}{ temp := map[string]interface{}{
"label": groupKey, "id": ag.ID,
"ids": groupVal, "node_id": ag.NodeID,
} }
res = append(res, temp) res = append(res, temp)
} }
@@ -560,3 +574,24 @@ func flattenRgUsageResource(d *schema.ResourceData, usage rg.RecordResourceUsage
d.Set("ram", usage.RAM) d.Set("ram", usage.RAM)
d.Set("seps", flattenRgSeps(usage.SEPs)) 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)
}

View File

@@ -185,7 +185,6 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter
} }
} }
} }
} }
if defNet, ok := d.GetOk("def_net"); ok { if defNet, ok := d.GetOk("def_net"); ok {
@@ -256,7 +255,7 @@ func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interfa
log.Debugf("resourceResgroupRead: called for RG name %s, account ID %d", log.Debugf("resourceResgroupRead: called for RG name %s, account ID %d",
d.Get("name").(string), d.Get("account_id").(int)) d.Get("name").(string), d.Get("account_id").(int))
c := m.(*controller.ControllerCfg) // c := m.(*controller.ControllerCfg)
rgData, err := utilityResgroupCheckPresence(ctx, d, m) rgData, err := utilityResgroupCheckPresence(ctx, d, m)
if err != nil { if err != nil {
@@ -272,24 +271,25 @@ func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interfa
case status.Created: case status.Created:
case status.Enabled: case status.Enabled:
case status.Deleted: case status.Deleted:
restoreReq := rg.RestoreRequest{RGID: rgData.ID} // restoreReq := rg.RestoreRequest{RGID: rgData.ID}
enableReq := rg.EnableRequest{RGID: rgData.ID} // enableReq := rg.EnableRequest{RGID: rgData.ID}
_, err := c.CloudAPI().RG().Restore(ctx, restoreReq) // _, err := c.CloudAPI().RG().Restore(ctx, restoreReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
_, err = c.CloudAPI().RG().Enable(ctx, enableReq) // _, err = c.CloudAPI().RG().Enable(ctx, enableReq)
if err != nil { // if err != nil {
return diag.FromErr(err) // return diag.FromErr(err)
} // }
hasChanged = true // hasChanged = true
case status.Deleting: case status.Deleting:
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceResgroupCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceResgroupCreate(ctx, d, m)
case status.Destroying: case status.Destroying:
case status.Disabled: case status.Disabled:
case status.Disabling: case status.Disabling:
@@ -369,7 +369,8 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
case status.Deleting: case status.Deleting:
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return resourceResgroupCreate(ctx, d, m) return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceResgroupCreate(ctx, d, m)
case status.Destroying: case status.Destroying:
case status.Disabled: case status.Disabled:
case status.Disabling: case status.Disabling:
@@ -378,7 +379,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
} }
if hasChanged { if hasChanged {
rgData, err = utilityDataResgroupCheckPresence(ctx, d, m) rgData, err = utilityResgroupCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
@@ -787,14 +788,6 @@ func ResourceRgSchemaMake() map[string]*schema.Schema {
Schema: aclSchemaMake(), Schema: aclSchemaMake(),
}, },
}, },
"created_by": {
Type: schema.TypeString,
Computed: true,
},
"created_time": {
Type: schema.TypeInt,
Computed: true,
},
"deleted_by": { "deleted_by": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,

View File

@@ -63,21 +63,3 @@ func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m
return rgData, nil return rgData, nil
} }
func utilityDataResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.RecordResourceGroup, error) {
c := m.(*controller.ControllerCfg)
req := rg.GetRequest{
RGID: uint64(d.Get("rg_id").(int)),
}
if reason, ok := d.GetOk("reason"); ok {
req.Reason = reason.(string)
}
rgData, err := c.CloudAPI().RG().Get(ctx, req)
if err != nil {
return nil, err
}
return rgData, nil
}

View File

@@ -46,6 +46,14 @@ func utilityRgAffinityGroupsListCheckPresence(ctx context.Context, d *schema.Res
RGID: uint64(d.Get("rg_id").(int)), 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) groups, err := c.CloudAPI().RG().AffinityGroupsList(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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
}

View File

@@ -0,0 +1,55 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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
}

View File

@@ -49,7 +49,7 @@ func dataSourceSnapshotListRead(ctx context.Context, d *schema.ResourceData, m i
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenSnapshotList(snapshotList)) d.Set("items", flattenSnapshotList(snapshotList))
d.Set("entry_count", snapshotList.EntryCount)
return nil return nil
} }
@@ -69,6 +69,10 @@ func dataSourceSnapshotListSchemaMake() map[string]*schema.Schema {
Schema: dataSourceSnapshotSchemaMake(), Schema: dataSourceSnapshotSchemaMake(),
}, },
}, },
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
} }
return rets return rets

View File

@@ -6,7 +6,7 @@ import (
) )
func flattenSnapshotList(gl *compute.ListSnapShots) []map[string]interface{} { func flattenSnapshotList(gl *compute.ListSnapShots) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(gl.Data))
for _, item := range gl.Data { for _, item := range gl.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"label": item.Label, "label": item.Label,

View File

@@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -29,65 +30,44 @@ builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package account package stack
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" import (
"context"
"strconv"
func dataSourceAccountVinsSchema() map[string]*schema.Schema { "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
return map[string]*schema.Schema{
"account_id": { "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func dataSourceStackSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"stack_id": {
Type: schema.TypeInt,
Required: true,
},
"cpu_allocation_ratio": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"account_name": { "descr": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"computes": { "drivers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"mem_allocation_ratio": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"created_by": { "name": {
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,
},
"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, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
@@ -95,13 +75,36 @@ func dataSourceAccountVinsSchema() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"updated_by": { "type": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"updated_time": { }
Type: schema.TypeInt, return res
Computed: true, }
func dataSourceStackRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
stack, err := utilityStackCheckPresence(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("stack_id").(int)))
flattenStack(d, *stack)
return nil
}
func DataSourceStack() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceStackRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
}, },
Schema: dataSourceStackSchemaMake(),
} }
} }

View File

@@ -0,0 +1,136 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package stack
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 dataSourceStackListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
stackList, err := utilityStackListCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenStackList(stackList))
d.Set("entry_count", stackList.EntryCount)
return nil
}
func dataSourceStackListSchemaMake() 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",
},
"type": {
Type: schema.TypeString,
Optional: true,
Description: "Find by type",
},
"status": {
Type: schema.TypeString,
Optional: true,
Description: "Find by 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,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"stack_id": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
}
return res
}
func DataSourceStackList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceStackListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceStackListSchemaMake(),
}
}

View File

@@ -0,0 +1,69 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package stack
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stack"
)
func flattenStackList(stackl *stack.ListStacks) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, stack := range stackl.Data {
temp := map[string]interface{}{
"stack_id": stack.ID,
"name": stack.Name,
"status": stack.Status,
"type": stack.Type,
}
res = append(res, temp)
}
return res
}
func flattenStack(d *schema.ResourceData, details stack.InfoStack) error {
log.Debugf("flattenStack: decoded Stack name %q / ID %d",
details.Name, details.ID)
d.Set("stack_id", details.ID)
d.Set("cpu_allocation_ratio", details.CPUAllocationRatio)
d.Set("name", details.Name)
d.Set("descr", details.Descr)
d.Set("mem_allocation_ratio", details.MemAllocationRatio)
d.Set("status", details.Status)
d.Set("type", details.Type)
d.Set("drivers", details.Drivers)
return nil
}

View File

@@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -29,21 +30,33 @@ builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package k8s package stack
const K8sCreateAPI = "/restmachine/cloudbroker/k8s/create" import (
const K8sGetAPI = "/restmachine/cloudbroker/k8s/get" "context"
const K8sUpdateAPI = "/restmachine/cloudbroker/k8s/update" "strconv"
const K8sDeleteAPI = "/restmachine/cloudbroker/k8s/delete"
const K8sWgCreateAPI = "/restmachine/cloudbroker/k8s/workersGroupAdd" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stack"
const K8sWgDeleteAPI = "/restmachine/cloudbroker/k8s/workersGroupDelete" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
const K8sWorkerAddAPI = "/restmachine/cloudbroker/k8s/workerAdd" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
const K8sWorkerDeleteAPI = "/restmachine/cloudbroker/k8s/deleteWorkerFromGroup" )
const K8sGetConfigAPI = "/restmachine/cloudbroker/k8s/getConfig" func utilityStackCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*stack.InfoStack, error) {
c := m.(*controller.ControllerCfg)
req := stack.GetRequest{}
const LbGetAPI = "/restmachine/cloudbroker/lb/get" if d.Id() != "" {
stackId, _ := strconv.ParseUint(d.Id(), 10, 64)
req.StackId = stackId
} else {
req.StackId = uint64(d.Get("stack_id").(int))
}
const AsyncTaskGetAPI = "/restmachine/cloudbroker/tasks/get" stackData, err := c.CloudAPI().Stack().Get(ctx, req)
if err != nil {
return nil, err
}
return stackData, nil
}

View File

@@ -0,0 +1,77 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package stack
import (
"context"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stack"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func utilityStackListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*stack.ListStacks, error) {
c := m.(*controller.ControllerCfg)
req := stack.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 status, ok := d.GetOk("status"); ok {
req.Status = status.(string)
}
if stackType, ok := d.GetOk("type"); ok {
req.Type = stackType.(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("utilityStackListCheckPresence: load stack list")
stackList, err := c.CloudAPI().Stack().List(ctx, req)
if err != nil {
return nil, err
}
return stackList, nil
}

View File

@@ -3,6 +3,7 @@ Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -29,77 +30,78 @@ builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package image package vins
import ( import (
"context" "context"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "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/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
) )
func resourceCreateListImages(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
staticRoute, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
d.SetId(strconv.FormatUint(staticRoute.ID, 10))
flattenStaticRouteData(d, staticRoute)
return nil return nil
} }
func resourceDeleteListImages(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceStaticRouteSchemaMake() map[string]*schema.Schema {
return nil rets := map[string]*schema.Schema{
} "vins_id": {
Type: schema.TypeInt,
func resourceReadListImages(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { Required: true,
return nil Description: "Unique ID of the ViNS",
} },
"route_id": {
func resourceDeleteImagesSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt,
return map[string]*schema.Schema{ Required: true,
"image_ids": { Description: "Unique ID of the static route",
},
"compute_ids": {
Type: schema.TypeList, Type: schema.TypeList,
Required: true, Computed: true,
ForceNew: true,
MinItems: 1,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
}, },
Description: "images ids for deleting",
}, },
"reason": { "destination": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Computed: true,
ForceNew: true,
Description: "reason for deleting the images",
}, },
"permanently": { "gateway": {
Type: schema.TypeBool, Type: schema.TypeString,
Optional: true, Computed: true,
ForceNew: true, },
Default: false, "guid": {
Description: "whether to completely delete the images", Type: schema.TypeString,
Computed: true,
},
"netmask": {
Type: schema.TypeString,
Computed: true,
}, },
} }
return rets
} }
func ResourceDeleteImages() *schema.Resource { func DataSourceStaticRoute() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
CreateContext: resourceCreateListImages, ReadContext: dataSourceStaticRouteRead,
ReadContext: resourceReadListImages,
DeleteContext: resourceDeleteListImages,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout60s,
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Update: &constants.Timeout60s,
Delete: &constants.Timeout60s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: resourceDeleteImagesSchemaMake(), Schema: dataSourceStaticRouteSchemaMake(),
} }
} }

View File

@@ -0,0 +1,121 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.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 {
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(),
}
}

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
@@ -34,8 +34,8 @@ package vins
import ( import (
"context" "context"
"strconv"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "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/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
@@ -47,8 +47,9 @@ func dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.FormatUint(vins.ID, 10)) id := uuid.New()
flattenVinsData(d, *vins) d.SetId(id.String())
flattenVinsData(d, vins)
return nil return nil
} }
@@ -640,7 +641,7 @@ func rulesSchemaMake() map[string]*schema.Schema {
} }
} }
func configSchrmaMake() map[string]*schema.Schema { func natConfigSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{ return map[string]*schema.Schema{
"net_mask": { "net_mask": {
Type: schema.TypeInt, Type: schema.TypeInt,
@@ -678,7 +679,7 @@ func natSchemaMake() map[string]*schema.Schema {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: configSchrmaMake(), Schema: natConfigSchemaMake(),
}, },
}, },
"devices": { "devices": {
@@ -768,7 +769,6 @@ func dataSourceVinsSchemaMake() map[string]*schema.Schema {
Required: true, Required: true,
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
}, },
"vnf_dev": { "vnf_dev": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -776,10 +776,6 @@ func dataSourceVinsSchemaMake() map[string]*schema.Schema {
Schema: vnfDevSchemaMake(), Schema: vnfDevSchemaMake(),
}, },
}, },
"_ckey": {
Type: schema.TypeString,
Computed: true,
},
"account_id": { "account_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
@@ -797,6 +793,14 @@ func dataSourceVinsSchemaMake() map[string]*schema.Schema {
Schema: vinsComputeSchemaMake(), Schema: vinsComputeSchemaMake(),
}, },
}, },
"created_by": {
Type: schema.TypeString,
Computed: true,
},
"created_time": {
Type: schema.TypeInt,
Computed: true,
},
"default_gw": { "default_gw": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
@@ -808,6 +812,14 @@ func dataSourceVinsSchemaMake() map[string]*schema.Schema {
Schema: qosSchemaMake(), Schema: qosSchemaMake(),
}, },
}, },
"deleted_by": {
Type: schema.TypeString,
Computed: true,
},
"deleted_time": {
Type: schema.TypeInt,
Computed: true,
},
"desc": { "desc": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
@@ -874,6 +886,14 @@ func dataSourceVinsSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
"user_managed": { "user_managed": {
Type: schema.TypeBool, Type: schema.TypeBool,
Computed: true, Computed: true,

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
@@ -49,7 +49,7 @@ func dataSourceVinsExtNetListRead(ctx context.Context, d *schema.ResourceData, m
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenVinsExtNetList(extNetList)) d.Set("items", flattenVinsExtNetList(extNetList))
d.Set("entry_count", extNetList.EntryCount)
return nil return nil
} }
@@ -92,6 +92,10 @@ func DataSourceVinsExtNetListchemaMake() map[string]*schema.Schema {
}, },
}, },
}, },
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
} }
return rets return rets
} }

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
@@ -49,7 +49,7 @@ func dataSourceVinsIpListRead(ctx context.Context, d *schema.ResourceData, m int
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenVinsIpList(ips)) d.Set("items", flattenVinsIpList(ips))
d.Set("entry_count", ips.EntryCount)
return nil return nil
} }
@@ -96,6 +96,10 @@ func DataSourceVinsIpListSchemaMake() map[string]*schema.Schema {
}, },
}, },
}, },
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
} }
return rets return rets
} }

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>

Some files were not shown because too many files have changed in this diff Show More