Compare commits

...

5 Commits

Author SHA1 Message Date
91ba361af9 4.5.3 2024-03-26 12:17:33 +03:00
f49d9f8860 4.5.2 2023-12-19 16:37:50 +03:00
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
626 changed files with 56472 additions and 27797 deletions

View File

@@ -1,5 +1,31 @@
## Version 4.5.0-alfa ## Version 4.5.3
### Bugfix ### Bugfix
- Fixed bservice and rg schema and flatten - Change field Value in schema resource kvmvm in blocks affinity_rules and anti_affinity_rules from required to optional in cloudapi and cloudbroker
- Add stateUpgrader for k8s_cp - Change the format ID in resource k8s_wg from wg_id to k8s_id#wg_id
- Fix scripts intall.bat and intall.sh
- Increased timeouts for resources account, disk, cdrom_image, image, virtual_image, k8s_wg, vins, rg in cloudbroker so that they match the same from cloudapi
- Increased timeouts for resources pcidevice, sep, sep_config in cloudbroker
- Fix bug in affinity_rules in cloudbroker/kvmvm
- Add field NeedReboot in cloudapi/kvmvm in data_source, data_source_list and resource schemas
- Fix bug with field ExtNetID in CreateInRGRequest in cloudapi/vins and cloudbroker/vins
- Add boolean field Safe in Restart func in resource cloudapi/lb
- Add field force_resize in Resize func in resource cloudapi/kvmvm and cloudbroker/kvmvm
- Fix bug in cloudBroker/kvmvm with disk and extra_disks
- Change logic from disk delete and disk add to disk rename when disk.disk_name field is changed in resource cloudapi/kvmvm and cloudbroker/kvmvm
- Fix allowed network plugin value from "weawenet" to "weavenet" for k8ci, k8s resources in cloudbroker and for k8s resource in cloudapi
- Fix bug with deleting decort_bservice resource when setting enable=false in cloudapi/bservice
- Fix panic in data source decort_bservice_snapshot_list in cloudapi/bservice
- Fix panic in data source decort_rg_affinity_groups_list in cloudapi/rg
- Fix change description in resource decort_cb_kvmvm in cloudbroker
- Computed field bootdisk_size has been renamed to boot_disk_size in data sources decort_kvmvm, decort_kvmvm_list, decort_cb_kvmvm_list in cloudapi and cloudbroker
- Change request logic for delete resource decort_cb_k8s_cp in cloudbroker
- Fix schema in datasource decort_cb_kvmvm in cloudbroker, fields boot_disk_id, sep_id, pool, extra_disks, network, net_id, net_type, ip_address, mac have been removes
- Fix panic with RG in cloudapi
- Fix permanently field for disks delete in decort_kvmvm in cloudapi/kvmvm and decort_cb_kvmvm in cloudbroker/kvmvm
- Fix bug with enable request duplication
### Feature
- Add RAM divisibility validation in compute, k8s, k8s_cp and k8s_wg resources in cloudapi and cloudbroker
- Add "permanently" flag in k8s, k8s_cp in cloudapi

View File

@@ -7,7 +7,7 @@ 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.5.0-alfa VERSION=4.5.3
OS_ARCH=$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH) OS_ARCH=$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH)
FILES = ${BINARY}_${VERSION}_darwin_amd64\ FILES = ${BINARY}_${VERSION}_darwin_amd64\

View File

@@ -6,6 +6,7 @@ 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.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 |
@@ -26,23 +27,42 @@ Terraform provider для платформы Digital Energy Cloud Orchestration
## Возможности провайдера ## Возможности провайдера
- Работа с Compute instances, - Режим пользователя:
- Работа с disks, - Работа с accounts,
- Работа с k8s, - Работа с bservice,
- Работа с image, - Работа с disks,
- Работа с flipgroups, - Работа с extnets,
- Работа с stacks, - Работа с flipgroups,
- Работа с reource groups, - Работа с image,
- Работа с VINS, - Работа с k8s,
- Работа с pfw, - Работа с Compute instances,
- Работа с accounts, - Работа с load balancer,
- Работа с snapshots, - Работа с locations,
- Работа с bservice, - Работа с pfw,
- Работа с extnets, - Работа с resource groups,
- Работа с locations, - Работа с snapshots,
- Работа с load balancer. - Работа с 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` в релизном архиве находятся скрипты-инсталляторы.
@@ -89,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
@@ -175,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>

53
go.mod
View File

@@ -3,52 +3,53 @@ module repository.basistech.ru/BASIS/terraform-provider-decort
go 1.18 go 1.18
require ( require (
github.com/golang-jwt/jwt/v4 v4.4.3
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
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.30.0
github.com/sirupsen/logrus v1.9.0 github.com/sirupsen/logrus v1.9.0
golang.org/x/net v0.16.0 golang.org/x/net v0.17.0
repository.basistech.ru/BASIS/decort-golang-sdk v1.6.9 repository.basistech.ru/BASIS/decort-golang-sdk v1.7.7
) )
require ( require (
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/agext/levenshtein v1.2.3 // indirect github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/armon/go-radix v1.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/fatih/color v1.13.0 // indirect github.com/fatih/color v1.13.0 // indirect
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.15.4 // indirect github.com/go-playground/validator/v10 v10.15.4 // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-cmp v0.6.0 // 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
github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect
github.com/hashicorp/go-hclog v1.4.0 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-plugin v1.4.8 // indirect github.com/hashicorp/go-plugin v1.5.1 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hc-install v0.4.0 // indirect github.com/hashicorp/hc-install v0.6.1 // indirect
github.com/hashicorp/hcl/v2 v2.15.0 // indirect github.com/hashicorp/hcl/v2 v2.19.1 // indirect
github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/terraform-exec v0.17.3 // indirect github.com/hashicorp/terraform-exec v0.19.0 // indirect
github.com/hashicorp/terraform-json v0.14.0 // indirect github.com/hashicorp/terraform-json v0.17.1 // indirect
github.com/hashicorp/terraform-plugin-go v0.14.2 // indirect github.com/hashicorp/terraform-plugin-go v0.19.0 // indirect
github.com/hashicorp/terraform-plugin-log v0.7.0 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
github.com/hashicorp/terraform-registry-address v0.1.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.2 // indirect
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect
github.com/huandu/xstrings v1.4.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.13 // indirect github.com/imdario/mergo v0.3.15 // indirect
github.com/leodido/go-urn v1.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-isatty v0.0.16 // indirect
@@ -64,16 +65,16 @@ require (
github.com/shopspring/decimal v1.3.1 // indirect github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.5.0 // indirect github.com/spf13/cast v1.5.0 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/zclconf/go-cty v1.12.1 // indirect github.com/zclconf/go-cty v1.14.1 // indirect
golang.org/x/crypto v0.14.0 // indirect golang.org/x/crypto v0.15.0 // indirect
golang.org/x/oauth2 v0.13.0 // indirect golang.org/x/mod v0.13.0 // indirect
golang.org/x/sys v0.13.0 // indirect golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.13.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/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
google.golang.org/grpc v1.51.0 // indirect google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.31.0 // 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
) )

228
go.sum
View File

@@ -1,4 +1,4 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
@@ -7,49 +7,38 @@ github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYr
github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I=
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-git/v5 v5.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrObY=
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
@@ -58,22 +47,17 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
github.com/go-playground/validator/v10 v10.15.4 h1:zMXza4EpOdooxPel5xDqXEdXG5r+WggpvnAKMsalBjs= github.com/go-playground/validator/v10 v10.15.4 h1:zMXza4EpOdooxPel5xDqXEdXG5r+WggpvnAKMsalBjs=
github.com/go-playground/validator/v10 v10.15.4/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/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/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.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.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.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/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.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=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -86,47 +70,44 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-plugin v1.4.8 h1:CHGwpxYDOttQOY7HOWgETU9dyVjOXzniXDqJcYJE1zM= github.com/hashicorp/go-plugin v1.5.1 h1:oGm7cWBaYIp3lJpx1RUEfLWophprE2EV/KUeqBYo+6k=
github.com/hashicorp/go-plugin v1.4.8/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-plugin v1.5.1/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk= github.com/hashicorp/hc-install v0.6.1 h1:IGxShH7AVhPaSuSJpKtVi/EFORNjO+OYVJJrAtGG2mY=
github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI= github.com/hashicorp/hc-install v0.6.1/go.mod h1:0fW3jpg+wraYSnFDJ6Rlie3RvLf1bIqVIkzoon4KoVE=
github.com/hashicorp/hcl/v2 v2.15.0 h1:CPDXO6+uORPjKflkWCCwoWc9uRp+zSIPcCQ+BrxV7m8= github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI=
github.com/hashicorp/hcl/v2 v2.15.0/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng= github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/terraform-exec v0.17.3 h1:MX14Kvnka/oWGmIkyuyvL6POx25ZmKrjlaclkx3eErU= github.com/hashicorp/terraform-exec v0.19.0 h1:FpqZ6n50Tk95mItTSS9BjeOVUb4eg81SpgVtZNNtFSM=
github.com/hashicorp/terraform-exec v0.17.3/go.mod h1:+NELG0EqQekJzhvikkeQsOAZpsw0cv/03rbeQJqscAI= github.com/hashicorp/terraform-exec v0.19.0/go.mod h1:tbxUpe3JKruE9Cuf65mycSIT8KiNPZ0FkuTE3H4urQg=
github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s= github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA=
github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM= github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o=
github.com/hashicorp/terraform-plugin-docs v0.13.0 h1:6e+VIWsVGb6jYJewfzq2ok2smPzZrt1Wlm9koLeKazY= github.com/hashicorp/terraform-plugin-docs v0.13.0 h1:6e+VIWsVGb6jYJewfzq2ok2smPzZrt1Wlm9koLeKazY=
github.com/hashicorp/terraform-plugin-docs v0.13.0/go.mod h1:W0oCmHAjIlTHBbvtppWHe8fLfZ2BznQbuv8+UD8OucQ= github.com/hashicorp/terraform-plugin-docs v0.13.0/go.mod h1:W0oCmHAjIlTHBbvtppWHe8fLfZ2BznQbuv8+UD8OucQ=
github.com/hashicorp/terraform-plugin-go v0.14.2 h1:rhsVEOGCnY04msNymSvbUsXfRLKh9znXZmHlf5e8mhE= github.com/hashicorp/terraform-plugin-go v0.19.0 h1:BuZx/6Cp+lkmiG0cOBk6Zps0Cb2tmqQpDM3iAtnhDQU=
github.com/hashicorp/terraform-plugin-go v0.14.2/go.mod h1:Q12UjumPNGiFsZffxOsA40Tlz1WVXt2Evh865Zj0+UA= github.com/hashicorp/terraform-plugin-go v0.19.0/go.mod h1:EhRSkEPNoylLQntYsk5KrDHTZJh9HQoumZXbOGOXmec=
github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 h1:zHcMbxY0+rFO9gY99elV/XC/UnQVg7FhRCbj1i5b7vM= github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 h1:X7vB6vn5tON2b49ILa4W7mFAsndeqJ7bZFOGbVO+0Cc=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1/go.mod h1:+tNlb0wkfdsDJ7JEiERLz4HzM19HyiuIoGzTsM7rPpw= github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0/go.mod h1:ydFcxbdj6klCqYEPkPvdvFKiNGKZLUs+896ODUXCyao=
github.com/hashicorp/terraform-registry-address v0.1.0 h1:W6JkV9wbum+m516rCl5/NjKxCyTVaaUBbzYcMzBDO3U= github.com/hashicorp/terraform-registry-address v0.2.2 h1:lPQBg403El8PPicg/qONZJDC6YlgCVbWDtNmmZKtBno=
github.com/hashicorp/terraform-registry-address v0.1.0/go.mod h1:EnyO2jYO6j29DTHbJcm00E5nQTFeTtyZH3H5ycydQ5A= github.com/hashicorp/terraform-registry-address v0.2.2/go.mod h1:LtwNbCihUoUZ3RYriyS2wF/lGPB6gF9ICLRtuDk7hSo=
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
@@ -135,28 +116,19 @@ github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
@@ -172,8 +144,6 @@ github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2c
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
@@ -183,11 +153,9 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
@@ -196,24 +164,20 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -226,66 +190,46 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY=
github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA=
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
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.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
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/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
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.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -295,51 +239,51 @@ 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.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
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=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 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.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.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
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=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 h1:jmIfw8+gSvXcZSgaFAGyInDXeWzUhvYH57G/5GKMn70= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM=
google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg=
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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.6.9 h1:FaQQol7gx4i/IzaScGbiVxJpLkBOgG2bOp+De1kW0hY= repository.basistech.ru/BASIS/decort-golang-sdk v1.7.7 h1:VIF+NXXfYec8DtlTcPae+CjB0fhH8ovBQxKMwEnLgE8=
repository.basistech.ru/BASIS/decort-golang-sdk v1.6.9/go.mod h1:mwcpnw0dT/PQf6AOJShjlbDNDfNitr0WM77LNKL1qjo= repository.basistech.ru/BASIS/decort-golang-sdk v1.7.7/go.mod h1:7fj8sgGZFiiExewQeqckCS4WxwOmU0oP6BO6mi1Lpkw=

View File

@@ -37,3 +37,6 @@ const MaxCpusPerCompute = 128
// MinRamPerCompute sets minimum amount of RAM per compute in MB // MinRamPerCompute sets minimum amount of RAM per compute in MB
const MinRamPerCompute = 128 const MinRamPerCompute = 128
// RAMDivisibility sets divisibility of RAM value
const RAMDivisibility = 128

View File

@@ -28,5 +28,6 @@ var Timeout60s = time.Second * 60
var Timeout180s = time.Second * 180 var Timeout180s = time.Second * 180
var Timeout300s = time.Second * 300 var Timeout300s = time.Second * 300
var Timeout600s = time.Second * 600 var Timeout600s = time.Second * 600
var Timeout900s = time.Second * 900
var Timeout20m = time.Minute * 20 var Timeout20m = time.Minute * 20
var Timeout30m = time.Minute * 30 var Timeout30m = time.Minute * 30

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>
@@ -21,17 +21,15 @@ limitations under the License.
package controller package controller
import ( import (
"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"
@@ -39,31 +37,37 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker"
jwt "github.com/golang-jwt/jwt/v4"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// 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 +90,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 +116,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,30 +198,30 @@ 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
} // }
// we are not verifying the JWT when parsing because actual verification is done on the // we are not verifying the JWT when parsing because actual verification is done on the
// OVC controller side. Here we do parsing solely to extract Oauth2 user name (claim "user") // OVC controller side. Here we do parsing solely to extract Oauth2 user name (claim "user")
// and JWT issuer name (claim "iss") // and JWT issuer name (claim "iss")
parser := jwt.Parser{} // parser := jwt.Parser{}
token, _, err := parser.ParseUnverified(ret_config.jwt, jwt.MapClaims{}) // token, _, err := parser.ParseUnverified(ret_config.jwt, jwt.MapClaims{})
if err != nil { // if err != nil {
return nil, err // return nil, err
} // }
if claims, ok := token.Claims.(jwt.MapClaims); ok { // if claims, ok := token.Claims.(jwt.MapClaims); ok {
var tbuf bytes.Buffer // var tbuf bytes.Buffer
tbuf.WriteString(claims["username"].(string)) // tbuf.WriteString(claims["username"].(string))
tbuf.WriteString("@") // tbuf.WriteString("@")
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{
AppID: ret_config.app_id, AppID: ret_config.app_id,
@@ -201,10 +232,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
@@ -212,57 +260,57 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
return ret_config, nil return ret_config, nil
} }
func (config *ControllerCfg) GetDecortUsername() string { // 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{}
params.Add("grant_type", "client_credentials") // params.Add("grant_type", "client_credentials")
params.Add("client_id", config.app_id) // params.Add("client_id", config.app_id)
params.Add("client_secret", config.app_secret) // params.Add("client_secret", config.app_secret)
params.Add("response_type", "id_token") // params.Add("response_type", "id_token")
params.Add("validity", "3600") // params.Add("validity", "3600")
params_str := params.Encode() // params_str := params.Encode()
req, err := http.NewRequest("POST", config.oauth2_url+"/v1/oauth/access_token", strings.NewReader(params_str)) // req, err := http.NewRequest("POST", config.oauth2_url+"/v1/oauth/access_token", strings.NewReader(params_str))
if err != nil { // if err != nil {
return "", err // return "", err
} // }
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Content-Length", strconv.Itoa(len(params_str))) // req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
resp, err := config.cc_client.Do(req) // resp, err := config.cc_client.Do(req)
if err != nil { // if err != nil {
return "", err // return "", err
} // }
if resp.StatusCode != http.StatusOK { // if resp.StatusCode != http.StatusOK {
// fmt.Println("response Status:", resp.Status) // // fmt.Println("response Status:", resp.Status)
// fmt.Println("response Headers:", resp.Header) // // fmt.Println("response Headers:", resp.Header)
// fmt.Println("response Headers:", req.URL) // // fmt.Println("response Headers:", req.URL)
return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q", // return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q",
resp.StatusCode, req.URL, config.app_id, params_str) // resp.StatusCode, req.URL, config.app_id, params_str)
} // }
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
} // }
// validation successful - store JWT in the corresponding field of the ControllerCfg structure // // validation successful - store JWT in the corresponding field of the ControllerCfg structure
config.jwt = strings.TrimSpace(string(responseData)) // config.jwt = strings.TrimSpace(string(responseData))
return config.jwt, nil // return config.jwt, nil
} // }
func (config *ControllerCfg) validateJWT(jwt string) (bool, error) { func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
/* /*
@@ -273,13 +321,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 +344,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 +360,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 +384,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 +401,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

@@ -38,17 +38,23 @@ import (
"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_audit "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/audit"
cb_disks "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/disks"
cb_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_flipgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/flipgroup" cb_flipgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/flipgroup"
// cb_grid "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/grid" cb_grid "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/grid"
// cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image" cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image"
// cb_lb "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/lb" cb_kvmvm "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/kvmvm"
// cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice" cb_lb "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/lb"
// cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg" cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice"
// cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep" cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg"
// cb_stack "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/stack" cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep"
cb_stack "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/stack"
cb_vins "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins"
// cb_vgpu "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vgpu" // cb_vgpu "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vgpu"
cb_k8ci "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8ci"
cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s"
) )
func newDataSourcesMap() map[string]*schema.Resource { func newDataSourcesMap() map[string]*schema.Resource {
@@ -144,7 +150,7 @@ func newDataSourcesMap() map[string]*schema.Resource {
"decort_cb_account": cb_account.DataSourceAccount(), "decort_cb_account": cb_account.DataSourceAccount(),
"decort_cb_account_list": cb_account.DataSourceAccountList(), "decort_cb_account_list": cb_account.DataSourceAccountList(),
"decort_cb_account_computes_list": cb_account.DataSourceAccountComputesList(), "decort_cb_account_computes_list": cb_account.DataSourceAccountComputesList(),
"decort_cb_account_deleted_list": cb_account.DataSourceAccountDeletedList(), "decort_cb_account_list_deleted": cb_account.DataSourceAccountDeletedList(),
"decort_cb_account_disks_list": cb_account.DataSourceAccountDisksList(), "decort_cb_account_disks_list": cb_account.DataSourceAccountDisksList(),
"decort_cb_account_flipgroups_list": cb_account.DataSourceAccountFlipGroupsList(), "decort_cb_account_flipgroups_list": cb_account.DataSourceAccountFlipGroupsList(),
"decort_cb_account_rg_list": cb_account.DataSourceAccountRGList(), "decort_cb_account_rg_list": cb_account.DataSourceAccountRGList(),
@@ -152,10 +158,97 @@ func newDataSourcesMap() map[string]*schema.Resource {
"decort_cb_account_resource_consumption_get": cb_account.DataSourceAccountResourceConsumptionGet(), "decort_cb_account_resource_consumption_get": cb_account.DataSourceAccountResourceConsumptionGet(),
"decort_cb_account_resource_consumption_list": cb_account.DataSourceAccountResourceConsumptionList(), "decort_cb_account_resource_consumption_list": cb_account.DataSourceAccountResourceConsumptionList(),
"decort_cb_account_audits_list": cb_account.DataSourceAccountAuditsList(), "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": cb_extnet.DataSourceExtnetCB(),
"decort_cb_extnet_list": cb_extnet.DataSourceExtnetListCB(), "decort_cb_extnet_list": cb_extnet.DataSourceExtnetListCB(),
"decort_cb_extnet_default": cb_extnet.DataSourceExtnetDefaultCB(), "decort_cb_extnet_default": cb_extnet.DataSourceExtnetDefaultCB(),
"decort_cb_extnet_static_route_list": cb_extnet.DataSourceStaticRouteList(), "decort_cb_extnet_static_route_list": cb_extnet.DataSourceStaticRouteList(),
"decort_cb_extnet_static_route": cb_extnet.DataSourceStaticRoute(), "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

@@ -40,8 +40,8 @@ func Provider() *schema.Provider {
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": {
@@ -49,7 +49,7 @@ func Provider() *schema.Provider {
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": {
@@ -74,18 +74,39 @@ func Provider() *schema.Provider {
Description: "User password for DECORT cloud API operations in 'legacy' authentication mode.", Description: "User password for DECORT cloud API operations in 'legacy' authentication mode.",
}, },
"bvs_user": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_BVS_USER", nil),
Description: "User name for DECORT cloud API operations in 'bvs' authentication mode.",
},
"bvs_password": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_BVS_PASSWORD", nil),
Description: "User password for DECORT cloud API operations in 'bvs' authentication mode.",
},
"domain": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_DOMAIN", nil),
Description: "User password for DECORT cloud API operations in 'bvs' authentication mode.",
},
"app_id": { "app_id": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_ID", nil), DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_ID", nil),
Description: "Application ID to access DECORT cloud API in 'oauth2' authentication mode.", Description: "Application ID to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode.",
}, },
"app_secret": { "app_secret": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_SECRET", nil), DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_SECRET", nil),
Description: "Application secret to access DECORT cloud API in 'oauth2' authentication mode.", Description: "Application secret to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode.",
}, },
"jwt": { "jwt": {
@@ -101,6 +122,25 @@ func Provider() *schema.Provider {
Default: false, Default: false,
Description: "If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only!", Description: "If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only!",
}, },
"path_cfg": {
Type: schema.TypeString,
Optional: true,
Description: "The path of the configuration file entry",
},
"path_token": {
Type: schema.TypeString,
Optional: true,
Description: "The path of the token file entry",
},
"time_to_refresh": {
Type: schema.TypeInt,
Optional: true,
Description: "The number of minutes before the expiration of the token, a refresh will be made",
},
}, },
ResourcesMap: newResourcesMap(), ResourcesMap: newResourcesMap(),

View File

@@ -36,19 +36,18 @@ import (
"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_flipgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/flipgroup" cb_flipgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/flipgroup"
// cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image" cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image"
// cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s" cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s"
// cb_kvmvm "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/kvmvm" cb_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_lb "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/lb"
// cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice" cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice"
// cb_pfw "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pfw" cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg"
// cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg" cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep"
// cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep" cb_k8ci "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8ci"
// cb_snapshot "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/snapshot" cb_vins "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins"
// cb_vins "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins"
) )
func newResourcesMap() map[string]*schema.Resource { func newResourcesMap() map[string]*schema.Resource {
@@ -76,29 +75,29 @@ func newResourcesMap() map[string]*schema.Resource {
"decort_flipgroup": flipgroup.ResourceFlipgroup(), "decort_flipgroup": flipgroup.ResourceFlipgroup(),
"decort_vins_static_route": vins.ResourceStaticRoute(), "decort_vins_static_route": vins.ResourceStaticRoute(),
"decort_cb_account": cb_account.ResourceAccount(), "decort_cb_account": cb_account.ResourceAccount(),
"decort_cb_extnet": cb_extnet.ResourceExtnetCB(), "decort_cb_extnet": cb_extnet.ResourceExtnetCB(),
// "decort_cb_disk": cb_disks.ResourceDisk(),
// "decort_cb_image": cb_image.ResourceImage(),
// "decort_cb_virtual_image": cb_image.ResourceVirtualImage(),
// "decort_cb_cdrom_image": cb_image.ResourceCDROMImage(),
// "decort_cb_delete_images": cb_image.ResourceDeleteImages(),
// "decort_cb_pcidevice": cb_pcidevice.ResourcePcidevice(),
// "decort_cb_sep": cb_sep.ResourceSep(),
// "decort_cb_sep_config": cb_sep.ResourceSepConfig(),
// "decort_cb_resgroup": cb_rg.ResourceResgroup(),
// "decort_cb_kvmvm": cb_kvmvm.ResourceCompute(),
// "decort_cb_vins": cb_vins.ResourceVins(),
// "decort_cb_pfw": cb_pfw.ResourcePfw(),
// "decort_cb_k8s": cb_k8s.ResourceK8s(),
// "decort_cb_k8s_wg": cb_k8s.ResourceK8sWg(),
// "decort_cb_snapshot": cb_snapshot.ResourceSnapshot(),
// "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_extnet_static_route": cb_extnet.ResourceStaticRoute(), "decort_cb_extnet_static_route": cb_extnet.ResourceStaticRoute(),
"decort_cb_disk": cb_disks.ResourceDisk(),
"decort_cb_disk_snapshot": cb_disks.ResourceDiskSnapshot(),
"decort_cb_image": cb_image.ResourceImage(),
"decort_cb_virtual_image": cb_image.ResourceVirtualImage(),
"decort_cb_cdrom_image": cb_image.ResourceCDROMImage(),
"decort_cb_pcidevice": cb_pcidevice.ResourcePcidevice(),
"decort_cb_sep": cb_sep.ResourceSep(),
"decort_cb_sep_config": cb_sep.ResourceSepConfig(),
"decort_cb_kvmvm": cb_kvmvm.ResourceCompute(),
"decort_cb_vins": cb_vins.ResourceVins(),
"decort_cb_k8ci": cb_k8ci.ResourceK8CI(),
"decort_cb_k8s_cp": cb_k8s.ResourceK8sCP(),
"decort_cb_k8s_wg": cb_k8s.ResourceK8sWg(),
"decort_cb_vins_static_route": cb_vins.ResourceStaticRoute(),
"decort_cb_flipgroup": cb_flipgroup.ResourceFlipgroup(),
"decort_cb_lb": cb_lb.ResourceLB(),
"decort_cb_lb_backend": cb_lb.ResourceLBBackend(),
"decort_cb_lb_backend_server": cb_lb.ResourceLBBackendServer(),
"decort_cb_lb_frontend": cb_lb.ResourceLBFrontend(),
"decort_cb_lb_frontend_bind": cb_lb.ResourceLBFrontendBind(),
"decort_cb_rg": cb_rg.ResourceResgroup(),
} }
} }

View File

@@ -45,6 +45,7 @@ import (
func dataSourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
acc, err := utilityAccountCheckPresence(ctx, d, m) acc, err := utilityAccountCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -99,6 +100,10 @@ func resourceLimitsSchemaMake() map[string]*schema.Schema {
Type: schema.TypeFloat, Type: schema.TypeFloat,
Computed: true, Computed: true,
}, },
"cu_dm": {
Type: schema.TypeFloat,
Computed: true,
},
"cu_i": { "cu_i": {
Type: schema.TypeFloat, Type: schema.TypeFloat,
Computed: true, Computed: true,

View File

@@ -61,6 +61,7 @@ func flattenAccountAuditsList(aal account.ListAudits) []map[string]interface{} {
func dataSourceAccountAuditsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountAuditsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountAuditsList, err := utilityAccountAuditsListCheckPresence(ctx, d, m) accountAuditsList, err := utilityAccountAuditsListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -76,6 +76,7 @@ func flattenAccountComputesList(acl *account.ListComputes) []map[string]interfac
func dataSourceAccountComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountComputesList, err := utilityAccountComputesListCheckPresence(ctx, d, m) accountComputesList, err := utilityAccountComputesListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceAccountConsumedUnitsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountConsumedUnitsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountConsumedUnits, err := utilityAccountConsumedUnitsCheckPresence(ctx, d, m) accountConsumedUnits, err := utilityAccountConsumedUnitsCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -51,6 +52,7 @@ func dataSourceAccountConsumedUnitsRead(ctx context.Context, d *schema.ResourceD
d.SetId(id.String()) d.SetId(id.String())
d.Set("cu_c", accountConsumedUnits.CUC) d.Set("cu_c", accountConsumedUnits.CUC)
d.Set("cu_d", accountConsumedUnits.CUD) d.Set("cu_d", accountConsumedUnits.CUD)
d.Set("cu_dm", accountConsumedUnits.CUDM)
d.Set("cu_i", accountConsumedUnits.CUI) d.Set("cu_i", accountConsumedUnits.CUI)
d.Set("cu_m", accountConsumedUnits.CUM) d.Set("cu_m", accountConsumedUnits.CUM)
d.Set("cu_np", accountConsumedUnits.CUNP) d.Set("cu_np", accountConsumedUnits.CUNP)
@@ -74,6 +76,10 @@ func dataSourceAccountConsumedUnitsSchemaMake() map[string]*schema.Schema {
Type: schema.TypeFloat, Type: schema.TypeFloat,
Computed: true, Computed: true,
}, },
"cu_dm": {
Type: schema.TypeFloat,
Computed: true,
},
"cu_i": { "cu_i": {
Type: schema.TypeFloat, Type: schema.TypeFloat,
Computed: true, Computed: true,

View File

@@ -44,6 +44,7 @@ import (
func dataSourceAccountConsumedUnitsByTypeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountConsumedUnitsByTypeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
result, err := utilityAccountConsumedUnitsByTypeCheckPresence(ctx, d, m) result, err := utilityAccountConsumedUnitsByTypeCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceAccountDeletedListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountDeletedListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountDeletedList, err := utilityAccountDeletedListCheckPresence(ctx, d, m) accountDeletedList, err := utilityAccountDeletedListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -62,6 +62,7 @@ func flattenAccountDisksList(adl *account.ListDisks) []map[string]interface{} {
func dataSourceAccountDisksListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountDisksListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountDisksList, err := utilityAccountDisksListCheckPresence(ctx, d, m) accountDisksList, err := utilityAccountDisksListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -77,6 +77,7 @@ func flattenAccountFlipGroupsList(afgl *account.ListFLIPGroups) []map[string]int
func dataSourceAccountFlipGroupsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountFlipGroupsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountFlipGroupsList, err := utilityAccountFlipGroupsListCheckPresence(ctx, d, m) accountFlipGroupsList, err := utilityAccountFlipGroupsListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceAccountResourceConsumptionGetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountResourceConsumptionGetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountResourceConsumptionRec, err := utilityAccountResourceConsumptionGetCheckPresence(ctx, d, m) accountResourceConsumptionRec, err := utilityAccountResourceConsumptionGetCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -78,6 +78,7 @@ func flattenRgAcl(rgAcls []account.RecordACL) []map[string]interface{} {
func dataSourceAccountListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountList, err := utilityAccountListCheckPresence(ctx, d, m) accountList, err := utilityAccountListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceAccountReservedUnitsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountReservedUnitsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountReservedUnits, err := utilityAccountReservedUnitsCheckPresence(ctx, d, m) accountReservedUnits, err := utilityAccountReservedUnitsCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -51,6 +52,7 @@ func dataSourceAccountReservedUnitsRead(ctx context.Context, d *schema.ResourceD
d.SetId(id.String()) d.SetId(id.String())
d.Set("cu_c", accountReservedUnits.CUC) d.Set("cu_c", accountReservedUnits.CUC)
d.Set("cu_d", accountReservedUnits.CUD) d.Set("cu_d", accountReservedUnits.CUD)
d.Set("cu_dm", accountReservedUnits.CUDM)
d.Set("cu_i", accountReservedUnits.CUI) d.Set("cu_i", accountReservedUnits.CUI)
d.Set("cu_m", accountReservedUnits.CUM) d.Set("cu_m", accountReservedUnits.CUM)
d.Set("cu_np", accountReservedUnits.CUNP) d.Set("cu_np", accountReservedUnits.CUNP)
@@ -74,6 +76,10 @@ func dataSourceAccountReservedUnitsSchemaMake() map[string]*schema.Schema {
Type: schema.TypeFloat, Type: schema.TypeFloat,
Computed: true, Computed: true,
}, },
"cu_dm": {
Type: schema.TypeFloat,
Computed: true,
},
"cu_i": { "cu_i": {
Type: schema.TypeFloat, Type: schema.TypeFloat,
Computed: true, Computed: true,

View File

@@ -44,6 +44,7 @@ import (
func dataSourceAccountResourceConsumptionListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountResourceConsumptionListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountResourceConsumptionList, err := utilityAccountResourceConsumptionListCheckPresence(ctx, d, m) accountResourceConsumptionList, err := utilityAccountResourceConsumptionListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -119,6 +119,7 @@ func flattenAccRGResources(argr account.RGResources) []map[string]interface{} {
func dataSourceAccountRGListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountRGListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountRGList, err := utilityAccountRGListCheckPresence(ctx, d, m) accountRGList, err := utilityAccountRGListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -66,6 +66,7 @@ func flattenAccountTemplatesList(atl *account.ListTemplates) []map[string]interf
func dataSourceAccountTemplatesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountTemplatesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountTemplatesList, err := utilityAccountTemplatesListCheckPresence(ctx, d, m) accountTemplatesList, err := utilityAccountTemplatesListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -73,6 +73,7 @@ func flattenAccountVinsList(avl *account.ListVINS) []map[string]interface{} {
func dataSourceAccountVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceAccountVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
accountVinsList, err := utilityAccountVinsListCheckPresence(ctx, d, m) accountVinsList, err := utilityAccountVinsListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -148,17 +148,18 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf
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:
if d.Get("restore").(bool) {
req := account.RestoreRequest{
AccountID: accountId,
}
req := account.RestoreRequest{ _, err := c.CloudAPI().Account().Restore(ctx, req)
AccountID: accountId, if err != nil {
return diag.FromErr(err)
}
hasChanged = true
} }
_, err := c.CloudAPI().Account().Restore(ctx, req)
if err != nil {
return diag.FromErr(err)
}
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:
@@ -184,14 +185,14 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} else {
_, err := c.CloudAPI().Account().Disable(ctx, reqSwitch)
if err != nil {
return diag.FromErr(err)
}
} }
} else {
_, err := c.CloudAPI().Account().Disable(ctx, reqSwitch)
if err != nil {
return diag.FromErr(err)
}
} }
} }
@@ -280,15 +281,13 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf
if d.HasChange("restore") { if d.HasChange("restore") {
restore := d.Get("restore").(bool) restore := d.Get("restore").(bool)
if restore { if restore && acc.Status == "DELETED" {
if acc.Status == "DELETED" { req := account.RestoreRequest{
req := account.RestoreRequest{ AccountID: accountId,
AccountID: accountId, }
} _, 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)
}
} }
} }
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
bs, err := utilityBasicServiceCheckPresence(ctx, d, m) bs, err := utilityBasicServiceCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceBasicServiceDeletedListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceBasicServiceDeletedListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
basicServiceDeletedList, err := utilityBasicServiceDeletedListCheckPresence(ctx, d, m) basicServiceDeletedList, err := utilityBasicServiceDeletedListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -45,6 +45,7 @@ import (
func dataSourceBasicServiceGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceBasicServiceGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
bsg, err := utilityBasicServiceGroupCheckPresence(ctx, d, m) bsg, err := utilityBasicServiceGroupCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -77,6 +77,7 @@ func flattenBasicServiceList(bsl *bservice.ListBasicServices) []map[string]inter
func dataSourceBasicServiceListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceBasicServiceListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
basicServiceList, err := utilityBasicServiceListCheckPresence(ctx, d, m) basicServiceList, err := utilityBasicServiceListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceBasicServiceSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceBasicServiceSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
basicServiceSnapshotList, err := utilityBasicServiceSnapshotListCheckPresence(ctx, d, m) basicServiceSnapshotList, err := utilityBasicServiceSnapshotListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -85,6 +86,10 @@ func dataSourceBasicServiceSnapshotListSchemaMake() map[string]*schema.Schema {
}, },
}, },
}, },
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
} }
return res return res
} }

View File

@@ -34,6 +34,7 @@ package bservice
import ( import (
"context" "context"
"fmt"
"strconv" "strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -42,6 +43,7 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"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/dc"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
) )
@@ -83,6 +85,13 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i
return diag.FromErr(err) return diag.FromErr(err)
} }
warn := dc.Warnings{}
if !d.Get("enable").(bool) && d.Get("start").(bool) {
warn.Add(fmt.Errorf("the basic service is in tech_status %s, troubles can occur with the usage. Please, enable bservice first", service.TechStatus))
}
if d.Get("enable").(bool) && (service.Status == status.Disabled || service.Status == status.Created) { if d.Get("enable").(bool) && (service.Status == status.Disabled || service.Status == status.Created) {
log.Debugf("trying to enable bservice %v", serviceId) log.Debugf("trying to enable bservice %v", serviceId)
_, err := c.CloudAPI().BService().Enable(ctx, bservice.EnableRequest{ _, err := c.CloudAPI().BService().Enable(ctx, bservice.EnableRequest{
@@ -92,10 +101,12 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
} }
if d.Get("start").(bool) && d.Get("enable").(bool) { if d.Get("start").(bool) && d.Get("enable").(bool) {
log.Debugf("trying to start bservice %v", serviceId) log.Debugf("trying to start bservice %v", serviceId)
_, err := c.CloudAPI().BService().Enable(ctx, bservice.EnableRequest{ _, err = c.CloudAPI().BService().Start(ctx, bservice.StartRequest{
ServiceID: serviceId, ServiceID: serviceId,
}) })
@@ -104,7 +115,7 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i
} }
} }
return resourceBasicServiceRead(ctx, d, m) return append(warn.Get(), 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 {
@@ -231,24 +242,45 @@ func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m i
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{
ServiceID: id, if restore, ok := d.GetOk("restore"); ok {
} if restore.(bool) {
enableReq := bservice.EnableRequest{ restoreReq := bservice.RestoreRequest{
ServiceID: id, ServiceID: id,
}
_, err := c.CloudAPI().BService().Restore(ctx, restoreReq)
if err != nil {
return diag.FromErr(err)
}
}
hasChanged = true
} }
_, err := c.CloudAPI().BService().Restore(ctx, restoreReq) if enable, ok := d.GetOk("enable"); ok {
if err != nil { if enable.(bool) {
return diag.FromErr(err) enableReq := bservice.EnableRequest{
ServiceID: id,
}
_, err = c.CloudAPI().BService().Enable(ctx, enableReq)
if err != nil {
return diag.FromErr(err)
}
hasChanged = true
}
} }
_, err = c.CloudAPI().BService().Enable(ctx, enableReq) if start, ok := d.GetOk("start"); ok {
if err != nil { if start.(bool) {
return diag.FromErr(err) startReq := bservice.StartRequest{
ServiceID: id,
}
_, err = c.CloudAPI().BService().Start(ctx, startReq)
if err != nil {
return diag.FromErr(err)
}
hasChanged = true
}
} }
hasChanged = true
case status.Deleting: case status.Deleting:
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
@@ -291,19 +323,6 @@ func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m i
} }
} }
if d.HasChange("restore") {
restore := d.Get("restore").(bool)
if restore {
req := bservice.RestoreRequest{
ServiceID: uint64(d.Get("service_id").(int)),
}
_, err := c.CloudAPI().BService().Restore(ctx, req)
if err != nil {
return diag.FromErr(err)
}
}
}
if d.HasChange("start") { if d.HasChange("start") {
start := d.Get("start").(bool) start := d.Get("start").(bool)
if start { if start {
@@ -394,10 +413,9 @@ func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m i
} }
} }
} }
} }
return nil return resourceBasicServiceRead(ctx, d, m)
} }
func isContainsSnapshot(els []interface{}, el interface{}) bool { func isContainsSnapshot(els []interface{}, el interface{}) bool {

View File

@@ -107,12 +107,12 @@ 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)) serviceId := uint64(d.Get("service_id").(int))
if d.Get("start").(bool) { if d.Get("start").(bool) {
log.Debugf("trying to start bservice group %v", compgroupId) log.Debugf("trying to start bservice group %v", compgroupId)
_, err := c.CloudAPI().BService().GroupStart(ctx, bservice.GroupStartRequest{ _, err := c.CloudAPI().BService().GroupStart(ctx, bservice.GroupStartRequest{
ServiceID: serviceId, ServiceID: serviceId,
CompGroupID: compgroupId, CompGroupID: compgroupId,
}) })
@@ -143,6 +143,7 @@ func resourceBasicServiceGroupDelete(ctx context.Context, d *schema.ResourceData
bsg, err := utilityBasicServiceGroupCheckPresence(ctx, d, m) bsg, err := utilityBasicServiceGroupCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -334,7 +335,7 @@ func resourceBasicServiceGroupUpdate(ctx context.Context, d *schema.ResourceData
} }
} }
return nil return resourceBasicServiceGroupRead(ctx, d, m)
} }
func isContainsParent(els []interface{}, el interface{}) bool { func isContainsParent(els []interface{}, el interface{}) bool {

View File

@@ -47,6 +47,7 @@ import (
func dataSourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
disk, err := utilityDiskCheckPresence(ctx, d, m) disk, err := utilityDiskCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceDiskListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceDiskListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
diskList, err := utilityDiskListCheckPresence(ctx, d, m) diskList, err := utilityDiskListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceDiskListTypesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceDiskListTypesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
listTypes, err := utilityDiskListTypesCheckPresence(ctx, d, m) listTypes, err := utilityDiskListTypesCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -47,8 +47,8 @@ func flattenDiskListTypesDetailed(tld *disks.ListTypes) []map[string]interface{}
for _, typeListDetailed := range tld.Data { for _, typeListDetailed := range tld.Data {
toMap := typeListDetailed.(map[string]interface{}) toMap := typeListDetailed.(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), "sep_name": toMap["sepName"].(string),
} }
res = append(res, temp) res = append(res, temp)
@@ -61,9 +61,9 @@ func flattenListTypesDetailedPools(pools []interface{}) []interface{} {
for _, pool := range pools { for _, pool := range pools {
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), "system": toMap["system"].(string),
"types": toMap["types"].([]interface{}), "types": toMap["types"].([]interface{}),
} }
res = append(res, temp) res = append(res, temp)
} }
@@ -74,6 +74,7 @@ func flattenListTypesDetailedPools(pools []interface{}) []interface{} {
func dataSourceDiskListTypesDetailedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceDiskListTypesDetailedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
listTypesDetailed, err := utilityDiskListTypesDetailedCheckPresence(ctx, d, m) listTypesDetailed, err := utilityDiskListTypesDetailedCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -112,8 +113,8 @@ func dataSourceDiskListTypesDetailedSchemaMake() map[string]*schema.Schema {
Description: "Pool name", Description: "Pool name",
}, },
"system": { "system": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"types": { "types": {
Type: schema.TypeList, Type: schema.TypeList,
@@ -132,8 +133,8 @@ func dataSourceDiskListTypesDetailedSchemaMake() map[string]*schema.Schema {
Description: "Storage endpoint provider ID to create disk", Description: "Storage endpoint provider ID to create disk",
}, },
"sep_name": { "sep_name": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
}, },
}, },

View File

@@ -44,6 +44,7 @@ import (
func dataSourceDiskListUnattachedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceDiskListUnattachedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
diskListUnattached, err := utilityDiskListUnattachedCheckPresence(ctx, d, m) diskListUnattached, err := utilityDiskListUnattachedCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -375,6 +376,11 @@ func dataSourceDiskListUnattachedSchemaMake() map[string]*schema.Schema {
Computed: true, Computed: true,
Description: "Storage endpoint provider ID to create disk", Description: "Storage endpoint provider ID to create disk",
}, },
"shareable": {
Type: schema.TypeBool,
Computed: true,
Description: "shareable",
},
"size_max": { "size_max": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,

View File

@@ -45,6 +45,7 @@ import (
func dataSourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
disk, err := utilityDiskCheckPresence(ctx, d, m) disk, err := utilityDiskCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceDiskSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceDiskSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
disk, err := utilityDiskCheckPresence(ctx, d, m) disk, err := utilityDiskCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -45,6 +45,7 @@ import (
func dataSourceDiskListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceDiskListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
diskList, err := utilityDiskListDeletedCheckPresence(ctx, d, m) diskList, err := utilityDiskListDeletedCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -56,6 +56,7 @@ func flattenDiskListUnattached(ul *disks.ListDisksUnattached) []map[string]inter
"res_name": unattachedDisk.ResName, "res_name": unattachedDisk.ResName,
"role": unattachedDisk.Role, "role": unattachedDisk.Role,
"sep_id": unattachedDisk.SEPID, "sep_id": unattachedDisk.SEPID,
"shareable": unattachedDisk.Shareable,
"size_max": unattachedDisk.SizeMax, "size_max": unattachedDisk.SizeMax,
"size_used": unattachedDisk.SizeUsed, "size_used": unattachedDisk.SizeUsed,
"snapshots": flattenDiskSnapshotList(unattachedDisk.Snapshots), "snapshots": flattenDiskSnapshotList(unattachedDisk.Snapshots),

View File

@@ -95,6 +95,7 @@ func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface
diskId, err := c.CloudAPI().Disks().Create(ctx, req) diskId, err := c.CloudAPI().Disks().Create(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -219,6 +220,7 @@ func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface
disk, err := utilityDiskCheckPresence(ctx, d, m) disk, err := utilityDiskCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -377,9 +379,9 @@ func resourceDiskDelete(ctx context.Context, d *schema.ResourceData, m interface
func resourceDiskSchemaMake() map[string]*schema.Schema { func resourceDiskSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{ rets := map[string]*schema.Schema{
"account_id": { "account_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "The unique ID of the subscriber-owner of the disk", Description: "The unique ID of the subscriber-owner of the disk",
}, },
"disk_name": { "disk_name": {
@@ -393,9 +395,9 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
Description: "Size in GB", Description: "Size in GB",
}, },
"gid": { "gid": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "ID of the grid (platform)", Description: "ID of the grid (platform)",
}, },
"pool": { "pool": {

View File

@@ -83,6 +83,7 @@ func resourceDiskSnapshotCreate(ctx context.Context, d *schema.ResourceData, m i
func resourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
disk, err := utilityDiskCheckPresence(ctx, d, m) disk, err := utilityDiskCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -169,15 +170,15 @@ func resourceDiskSnapshotDelete(ctx context.Context, d *schema.ResourceData, m i
func resourceDiskSnapshotSchemaMake() map[string]*schema.Schema { func resourceDiskSnapshotSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{ rets := map[string]*schema.Schema{
"disk_id": { "disk_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "The unique ID of the subscriber-owner of the disk", Description: "The unique ID of the subscriber-owner of the disk",
}, },
"label": { "label": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "Name of the snapshot", Description: "Name of the snapshot",
}, },
"rollback": { "rollback": {

View File

@@ -45,6 +45,7 @@ import (
func dataSourceExtnetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceExtnetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
e, err := utilityExtnetCheckPresence(ctx, d, m) e, err := utilityExtnetCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceExtnetComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceExtnetComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
extnetComputesList, err := utilityExtnetComputesListCheckPresence(ctx, d, m) extnetComputesList, err := utilityExtnetComputesListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -45,6 +45,7 @@ import (
func dataSourceExtnetDefaultRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceExtnetDefaultRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
extnetId, err := utilityExtnetDefaultCheckPresence(ctx, m) extnetId, err := utilityExtnetDefaultCheckPresence(ctx, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceExtnetListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceExtnetListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
extnetList, err := utilityExtnetListCheckPresence(ctx, d, m) extnetList, err := utilityExtnetListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -118,6 +119,10 @@ func dataSourceExtnetListSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"status": {
Type: schema.TypeString,
Computed: true,
},
}, },
}, },
}, },

View File

@@ -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, len (ecs)) 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,
@@ -129,6 +129,7 @@ func flattenExtnetList(el *extnet.ListExtNets) []map[string]interface{} {
"net_id": e.ID, "net_id": e.ID,
"ipcidr": e.IPCIDR, "ipcidr": e.IPCIDR,
"name": e.Name, "name": e.Name,
"status": e.Status,
} }
res = append(res, temp) res = append(res, temp)
} }

View File

@@ -66,6 +66,10 @@ func dataSourceFlipgroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"account_name": {
Type: schema.TypeString,
Computed: true,
},
"client_ids": { "client_ids": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -85,10 +89,26 @@ func dataSourceFlipgroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"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,
}, },
"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,
@@ -121,16 +141,28 @@ func dataSourceFlipgroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"network": {
Type: schema.TypeString,
Computed: true,
},
"rg_id": {
Type: schema.TypeInt,
Computed: true,
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
},
"status": { "status": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"net_mask": { "updated_by": {
Type: schema.TypeInt, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"ckey": { "updated_time": {
Type: schema.TypeString, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
} }

View File

@@ -185,6 +185,13 @@ func dataSourceFlipgroupListSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"meta": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
}, },
}, },
}, },

View File

@@ -36,15 +36,21 @@ package flipgroup
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/flipgroup" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/flipgroup"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
) )
func flattenFlipgroup(d *schema.ResourceData, fg *flipgroup.RecordFLIPGroup) { func flattenFlipgroup(d *schema.ResourceData, fg *flipgroup.RecordFLIPGroup) {
d.Set("account_id", fg.AccountID) d.Set("account_id", fg.AccountID)
d.Set("account_name", fg.AccountName)
d.Set("client_ids", fg.ClientIDs) d.Set("client_ids", fg.ClientIDs)
d.Set("client_type", fg.ClientType) d.Set("client_type", fg.ClientType)
d.Set("conn_id", fg.ConnID) d.Set("conn_id", fg.ConnID)
d.Set("conn_type", fg.ConnType) d.Set("conn_type", fg.ConnType)
d.Set("created_by", fg.CreatedBy)
d.Set("created_time", fg.CreatedTime)
d.Set("default_gw", fg.DefaultGW) d.Set("default_gw", fg.DefaultGW)
d.Set("deleted_by", fg.DeletedBy)
d.Set("deleted_time", fg.DeletedTime)
d.Set("desc", fg.Description) d.Set("desc", fg.Description)
d.Set("gid", fg.GID) d.Set("gid", fg.GID)
d.Set("guid", fg.GUID) d.Set("guid", fg.GUID)
@@ -54,13 +60,20 @@ func flattenFlipgroup(d *schema.ResourceData, fg *flipgroup.RecordFLIPGroup) {
d.Set("name", fg.Name) d.Set("name", fg.Name)
d.Set("net_id", fg.NetID) d.Set("net_id", fg.NetID)
d.Set("net_type", fg.NetType) d.Set("net_type", fg.NetType)
d.Set("network", fg.Network)
d.Set("rg_id", fg.RGID)
d.Set("rg_name", fg.RGName)
d.Set("status", fg.Status) d.Set("status", fg.Status)
d.Set("updated_by", fg.UpdatedBy)
d.Set("updated_time", fg.UpdatedTime)
} }
func flattenFlipgroupList(fg_list *flipgroup.ListFLIPGroups) []map[string]interface{} { func flattenFlipgroupList(fg_list *flipgroup.ListFLIPGroups) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0)
for _, fg := range fg_list.Data { for _, fg := range fg_list.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"ckey": fg.CKey,
"meta": flattens.FlattenMeta(fg.Meta),
"account_id": fg.AccountID, "account_id": fg.AccountID,
"client_ids": fg.ClientIDs, "client_ids": fg.ClientIDs,
"client_type": fg.ClientType, "client_type": fg.ClientType,
@@ -76,6 +89,7 @@ func flattenFlipgroupList(fg_list *flipgroup.ListFLIPGroups) []map[string]interf
"name": fg.Name, "name": fg.Name,
"net_id": fg.NetID, "net_id": fg.NetID,
"net_type": fg.NetType, "net_type": fg.NetType,
"net_mask": fg.NetMask,
"status": fg.Status, "status": fg.Status,
} }
res = append(res, temp) res = append(res, temp)

View File

@@ -64,6 +64,7 @@ func resourceFlipgroupCreate(ctx context.Context, d *schema.ResourceData, m inte
resp, err := c.CloudAPI().FLIPGroup().Create(ctx, req) resp, err := c.CloudAPI().FLIPGroup().Create(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -136,6 +137,7 @@ func resourceFlipgroupDelete(ctx context.Context, d *schema.ResourceData, m inte
fg, err := utilityFlipgroupCheckPresence(ctx, d, m) fg, err := utilityFlipgroupCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -148,6 +150,8 @@ func resourceFlipgroupDelete(ctx context.Context, d *schema.ResourceData, m inte
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId("")
return nil return nil
} }
@@ -205,6 +209,10 @@ func resourceFlipgroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"account_name": {
Type: schema.TypeString,
Computed: true,
},
"conn_id": { "conn_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
@@ -213,10 +221,26 @@ func resourceFlipgroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"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,
}, },
"deleted_by": {
Type: schema.TypeString,
Computed: true,
},
"deleted_time": {
Type: schema.TypeInt,
Computed: true,
},
"gid": { "gid": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
@@ -233,14 +257,26 @@ func resourceFlipgroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"net_mask": { "network": {
Type: schema.TypeString,
Computed: true,
},
"rg_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"ckey": { "rg_name": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
} }
} }

View File

@@ -34,8 +34,8 @@ package image
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"
@@ -44,12 +44,11 @@ import (
func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
image, err := utilityImageCheckPresence(ctx, d, m) image, err := utilityImageCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() d.SetId(strconv.Itoa(int(image.ID)))
d.SetId(id.String())
flattenImage(d, image) flattenImage(d, image)

View File

@@ -44,6 +44,7 @@ import (
func dataSourceImageListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceImageListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
imageList, err := utilityImageListCheckPresence(ctx, d, m) imageList, err := utilityImageListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()

View File

@@ -3,6 +3,7 @@ package image
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image"
"strconv"
) )
func flattenHistory(history []image.History) []map[string]interface{} { func flattenHistory(history []image.History) []map[string]interface{} {
@@ -23,7 +24,7 @@ func flattenImage(d *schema.ResourceData, img *image.RecordImage) {
d.Set("unc_path", img.UNCPath) d.Set("unc_path", img.UNCPath)
d.Set("ckey", img.CKey) d.Set("ckey", img.CKey)
d.Set("account_id", img.AccountID) d.Set("account_id", img.AccountID)
d.Set("acl", img.ACL) d.Set("acl", FlattenACL(img.ACL))
d.Set("architecture", img.Architecture) d.Set("architecture", img.Architecture)
d.Set("boot_type", img.BootType) d.Set("boot_type", img.BootType)
d.Set("bootable", img.Bootable) d.Set("bootable", img.Bootable)
@@ -85,3 +86,18 @@ func flattenImageList(il *image.ListImages) []map[string]interface{} {
} }
return res return res
} }
func FlattenACL(acl interface{}) string {
switch d := acl.(type) {
case string:
return d
case int:
return strconv.Itoa(d)
case int64:
return strconv.FormatInt(d, 10)
case float64:
return strconv.FormatInt(int64(d), 10)
default:
return ""
}
}

View File

@@ -114,6 +114,7 @@ func resourceImageCreate(ctx context.Context, d *schema.ResourceData, m interfac
imageId, err := c.CloudAPI().Image().Create(ctx, req) imageId, err := c.CloudAPI().Image().Create(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -158,6 +159,7 @@ func resourceImageDelete(ctx context.Context, d *schema.ResourceData, m interfac
_, err := utilityImageCheckPresence(ctx, d, m) _, err := utilityImageCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -50,6 +50,7 @@ import (
func dataSourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
cluster, err := utilityDataK8sCheckPresence(ctx, d, m) cluster, err := utilityDataK8sCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.FormatUint(cluster.ID, 10)) d.SetId(strconv.FormatUint(cluster.ID, 10))
@@ -399,6 +400,10 @@ func dataSourceK8sSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"network_plugin": {
Type: schema.TypeString,
Computed: true,
},
"rg_id": { "rg_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,

View File

@@ -271,6 +271,10 @@ func createK8sListSchema() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"network_plugin": {
Type: schema.TypeString,
Computed: true,
},
"rg_id": { "rg_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,

View File

@@ -47,6 +47,7 @@ func dataSourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interfac
wg, workersComputeList, err := utilityDataK8sWgCheckPresence(ctx, d, m) wg, workersComputeList, err := utilityDataK8sWgCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -47,6 +47,7 @@ func dataSourceK8sWgCloudInitRead(ctx context.Context, d *schema.ResourceData, m
metaData, err := utilityK8sWgCloudInitCheckPresence(ctx, d, m) metaData, err := utilityK8sWgCloudInitCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -45,6 +45,7 @@ import (
func dataSourceK8sWgListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceK8sWgListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
wgList, err := utilityK8sWgListCheckPresence(ctx, d, m) wgList, err := utilityK8sWgListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -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, len (aclList)) 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, len (interfaces)) 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, len (detailedInfoList)) 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{}{
@@ -247,6 +247,7 @@ func flattenK8sData(d *schema.ResourceData, cluster k8s.RecordK8S, masters []com
d.Set("workers", flattenK8sGroup(cluster.K8SGroups.Workers, workers)) d.Set("workers", flattenK8sGroup(cluster.K8SGroups.Workers, workers))
d.Set("lb_id", cluster.LBID) d.Set("lb_id", cluster.LBID)
d.Set("name", cluster.Name) d.Set("name", cluster.Name)
d.Set("network_plugin", cluster.NetworkPlugin)
d.Set("rg_id", cluster.RGID) d.Set("rg_id", cluster.RGID)
d.Set("rg_name", cluster.RGName) d.Set("rg_name", cluster.RGName)
d.Set("status", cluster.Status) d.Set("status", cluster.Status)
@@ -267,7 +268,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, len (workersGroups)) 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,11 +289,11 @@ 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, len (k8sItems.Data)) 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,
"account_name": item.Name, "account_name": item.AccountName,
"acl": item.ACL, "acl": item.ACL,
"bservice_id": item.BServiceID, "bservice_id": item.BServiceID,
"ci_id": item.CIID, "ci_id": item.CIID,
@@ -308,6 +309,7 @@ func flattenK8sItems(k8sItems *k8s.ListK8SClusters) []map[string]interface{} {
"lb_id": item.LBID, "lb_id": item.LBID,
"milestones": item.Milestones, "milestones": item.Milestones,
"k8s_name": item.Name, "k8s_name": item.Name,
"network_plugin": item.NetworkPlugin,
"rg_id": item.RGID, "rg_id": item.RGID,
"rg_name": item.RGName, "rg_name": item.RGName,
"service_account": flattenServiceAccount(item.ServiceAccount), "service_account": flattenServiceAccount(item.ServiceAccount),

View File

@@ -35,6 +35,8 @@ package k8s
import ( import (
"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"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators"
) )
func nodeMasterDefault() K8sNodeRecord { func nodeMasterDefault() K8sNodeRecord {
@@ -85,21 +87,25 @@ func mastersSchemaMake() map[string]*schema.Schema {
Optional: true, Optional: true,
} }
masters["cpu"] = &schema.Schema{ masters["cpu"] = &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "Node CPU count.", Description: "Node CPU count.",
} }
masters["ram"] = &schema.Schema{ masters["ram"] = &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
ValidateFunc: validation.All(
validation.IntAtLeast(constants.MinRamPerCompute),
validators.DivisibleBy(constants.RAMDivisibility),
),
Description: "Node RAM in MB.", Description: "Node RAM in MB.",
} }
masters["disk"] = &schema.Schema{ masters["disk"] = &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "Node boot disk size in GB.", Description: "Node boot disk size in GB.",
} }
@@ -117,7 +123,11 @@ func workersSchemaMake() map[string]*schema.Schema {
Required: true, Required: true,
}, },
"ram": { "ram": {
Type: schema.TypeInt, Type: schema.TypeInt,
ValidateFunc: validation.All(
validation.IntAtLeast(constants.MinRamPerCompute),
validators.DivisibleBy(constants.RAMDivisibility),
),
Required: true, Required: true,
}, },
"cpu": { "cpu": {

View File

@@ -14,15 +14,15 @@ func resourceK8sCPSchemaV1() *schema.Resource {
Description: "Name of the cluster.", Description: "Name of the cluster.",
}, },
"rg_id": { "rg_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "Resource group ID that this instance belongs to.", Description: "Resource group ID that this instance belongs to.",
}, },
"k8sci_id": { "k8sci_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "ID of the k8s catalog item to base this instance on.", Description: "ID of the k8s catalog item to base this instance on.",
}, },
"network_plugin": { "network_plugin": {
@@ -136,10 +136,10 @@ func resourceK8sCPSchemaV1() *schema.Resource {
}, },
//// ////
"extnet_id": { "extnet_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
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.",
}, },
"desc": { "desc": {

View File

@@ -189,7 +189,6 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{
if oidcCertificate, ok := d.GetOk("oidc_cert"); ok { if oidcCertificate, ok := d.GetOk("oidc_cert"); ok {
createReq.OidcCertificate = oidcCertificate.(string) createReq.OidcCertificate = oidcCertificate.(string)
} }
///
createReq.ExtNetOnly = d.Get("extnet_only").(bool) createReq.ExtNetOnly = d.Get("extnet_only").(bool)
@@ -211,6 +210,7 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{
resp, err := c.CloudAPI().K8S().Create(ctx, createReq) resp, err := c.CloudAPI().K8S().Create(ctx, createReq)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -316,7 +316,7 @@ func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{})
} }
} }
k8sList, err := utilityK8sListCheckPresence(ctx, d, m) k8sList, err := utilityK8sListForResourceCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
@@ -515,10 +515,11 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{
} }
} }
return nil return resourceK8sRead(ctx, d, m)
} }
func resourceK8sDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceK8sDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceK8sDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) log.Debugf("resourceK8sDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
cluster, err := utilityK8sCheckPresence(ctx, d, m) cluster, err := utilityK8sCheckPresence(ctx, d, m)
@@ -526,12 +527,14 @@ func resourceK8sDelete(ctx context.Context, d *schema.ResourceData, m interface{
return diag.FromErr(err) return diag.FromErr(err)
} }
c := m.(*controller.ControllerCfg) req := k8s.DeleteRequest{K8SID: cluster.ID}
req := k8s.DeleteRequest{
K8SID: cluster.ID, if val, ok := d.GetOk("permanently"); ok {
Permanently: true, req.Permanently = val.(bool)
} }
c := m.(*controller.ControllerCfg)
_, err = c.CloudAPI().K8S().Delete(ctx, req) _, err = c.CloudAPI().K8S().Delete(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
@@ -548,15 +551,15 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
Description: "Name of the cluster.", Description: "Name of the cluster.",
}, },
"rg_id": { "rg_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "Resource group ID that this instance belongs to.", Description: "Resource group ID that this instance belongs to.",
}, },
"k8sci_id": { "k8sci_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "ID of the k8s catalog item to base this instance on.", Description: "ID of the k8s catalog item to base this instance on.",
}, },
"wg_name": { "wg_name": {
@@ -595,7 +598,7 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
Type: schema.TypeList, Type: schema.TypeList,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, //ForceNew: true,
MaxItems: 1, MaxItems: 1,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: mastersSchemaMake(), Schema: mastersSchemaMake(),
@@ -624,12 +627,18 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
Description: "Use only selected ExtNet for infrastructure connections", Description: "Use only selected ExtNet for infrastructure connections",
}, },
"extnet_id": { "extnet_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
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.",
}, },
"permanently": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Determines if cluster should be destroyed",
},
///4.4.0 ///4.4.0
"cloud_init": { "cloud_init": {
@@ -685,8 +694,6 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
Optional: true, Optional: true,
Description: "insert ssl certificate in x509 pem format", Description: "insert ssl certificate in x509 pem format",
}, },
////
"desc": { "desc": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@@ -698,7 +705,6 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
Default: true, Default: true,
Description: "Start k8s cluster", Description: "Start k8s cluster",
}, },
"acl": { "acl": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,

View File

@@ -52,6 +52,7 @@ import (
"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/dc" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators"
) )
func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
@@ -175,8 +176,6 @@ func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interfac
log.Debug(createReq.OidcCertificate) log.Debug(createReq.OidcCertificate)
} }
///
createReq.ExtNetOnly = d.Get("extnet_only").(bool) createReq.ExtNetOnly = d.Get("extnet_only").(bool)
if extNet, ok := d.GetOk("extnet_id"); ok { if extNet, ok := d.GetOk("extnet_id"); ok {
@@ -197,6 +196,7 @@ func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interfac
resp, err := c.CloudAPI().K8S().Create(ctx, createReq) resp, err := c.CloudAPI().K8S().Create(ctx, createReq)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -317,7 +317,7 @@ func resourceK8sCPRead(ctx context.Context, d *schema.ResourceData, m interface{
} }
} }
k8sList, err := utilityK8sListCheckPresence(ctx, d, m) k8sList, err := utilityK8sListForResourceCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
@@ -532,28 +532,34 @@ func resourceK8sCPUpdate(ctx context.Context, d *schema.ResourceData, m interfac
} }
} }
return nil return resourceK8sCPRead(ctx, d, m)
} }
func resourceK8sCPDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceK8sCPDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceK8sControlPlaneDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) log.Debugf("resourceK8sControlPlaneDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
cluster, err := utilityK8sCheckPresence(ctx, d, m) cluster, err := utilityK8sCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
c := m.(*controller.ControllerCfg) req := k8s.DeleteRequest{K8SID: cluster.ID}
req := k8s.DeleteRequest{
K8SID: cluster.ID, if val, ok := d.GetOk("permanently"); ok {
Permanently: true, req.Permanently = val.(bool)
} }
c := m.(*controller.ControllerCfg)
_, err = c.CloudAPI().K8S().Delete(ctx, req) _, err = c.CloudAPI().K8S().Delete(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId("")
return nil return nil
} }
@@ -565,15 +571,15 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
Description: "Name of the cluster.", Description: "Name of the cluster.",
}, },
"rg_id": { "rg_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "Resource group ID that this instance belongs to.", Description: "Resource group ID that this instance belongs to.",
}, },
"k8sci_id": { "k8sci_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "ID of the k8s catalog item to base this instance on.", Description: "ID of the k8s catalog item to base this instance on.",
}, },
"network_plugin": { "network_plugin": {
@@ -596,9 +602,13 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
Description: "Node CPU count.", Description: "Node CPU count.",
}, },
"ram": { "ram": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
ValidateFunc: validation.All(
validation.IntAtLeast(constants.MinRamPerCompute),
validators.DivisibleBy(constants.RAMDivisibility),
),
Description: "Node RAM in MB.", Description: "Node RAM in MB.",
}, },
"disk": { "disk": {
@@ -679,12 +689,11 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
Optional: true, Optional: true,
Description: "insert ssl certificate in x509 pem format", Description: "insert ssl certificate in x509 pem format",
}, },
////
"extnet_id": { "extnet_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
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.",
}, },
"desc": { "desc": {
@@ -767,6 +776,12 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
Computed: true, Computed: true,
Description: "IP address of default load balancer.", Description: "IP address of default load balancer.",
}, },
"permanently": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Determines if cluster should be destroyed",
},
"rg_name": { "rg_name": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,

View File

@@ -34,16 +34,19 @@ package k8s
import ( import (
"context" "context"
"fmt"
"strconv" "strconv"
"strings" "strings"
"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"
log "github.com/sirupsen/logrus" 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/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators"
) )
func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
@@ -101,7 +104,7 @@ func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interfac
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.FormatUint(resp, 10)) d.SetId(fmt.Sprintf("%d#%d", d.Get("k8s_id").(int), resp))
return resourceK8sWgRead(ctx, d, m) return resourceK8sWgRead(ctx, d, m)
} }
@@ -125,7 +128,7 @@ func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{
d.Set("wg_id", wg.ID) d.Set("wg_id", wg.ID)
if strings.Contains(d.Id(), "#") { if strings.Contains(d.Id(), "#") {
k8sId, err := strconv.Atoi(strings.Split(d.Id(), "#")[1]) k8sId, err := strconv.Atoi(strings.Split(d.Id(), "#")[0])
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -134,8 +137,7 @@ func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{
} else { } else {
d.Set("k8s_id", d.Get("k8s_id")) d.Set("k8s_id", d.Get("k8s_id"))
} }
d.SetId(fmt.Sprintf("%d#%d", d.Get("k8s_id").(int), wg.ID))
d.SetId(strings.Split(d.Id(), "#")[0])
flattenWg(d, *wg, workersComputeList) flattenWg(d, *wg, workersComputeList)
@@ -161,11 +163,10 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac
return diag.FromErr(err) return diag.FromErr(err)
} }
wgId, _ := strconv.ParseUint(d.Id(), 10, 64)
if newNum := d.Get("num").(int); uint64(newNum) > wg.Num { if newNum := d.Get("num").(int); uint64(newNum) > wg.Num {
req := k8s.WorkerAddRequest{ req := k8s.WorkerAddRequest{
K8SID: uint64(d.Get("k8s_id").(int)), K8SID: uint64(d.Get("k8s_id").(int)),
WorkersGroupID: wgId, WorkersGroupID: wg.ID,
Num: uint64(newNum) - wg.Num, Num: uint64(newNum) - wg.Num,
} }
@@ -177,7 +178,7 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac
for i := int(wg.Num) - 1; i >= newNum; i-- { for i := int(wg.Num) - 1; i >= newNum; i-- {
req := k8s.DeleteWorkerFromGroupRequest{ req := k8s.DeleteWorkerFromGroupRequest{
K8SID: uint64(d.Get("k8s_id").(int)), K8SID: uint64(d.Get("k8s_id").(int)),
WorkersGroupID: wgId, WorkersGroupID: wg.ID,
WorkerID: wg.DetailedInfo[i].ID, WorkerID: wg.DetailedInfo[i].ID,
} }
@@ -191,7 +192,7 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac
if d.HasChange("cloud_init") { if d.HasChange("cloud_init") {
req := k8s.UpdateWorkerNodesMetaDataRequest{ req := k8s.UpdateWorkerNodesMetaDataRequest{
K8SID: uint64(d.Get("k8s_id").(int)), K8SID: uint64(d.Get("k8s_id").(int)),
WorkersGroupID: wgId, WorkersGroupID: wg.ID,
UserData: d.Get("cloud_init").(string), UserData: d.Get("cloud_init").(string),
} }
@@ -201,7 +202,7 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac
} }
} }
return nil return resourceK8sWgRead(ctx, d, m)
} }
func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
@@ -209,6 +210,7 @@ func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interfac
wg, err := utilityK8sWgCheckPresence(ctx, d, m) wg, err := utilityK8sWgCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -223,22 +225,24 @@ func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interfac
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId("")
return nil return nil
} }
func resourceK8sWgSchemaMake() map[string]*schema.Schema { func resourceK8sWgSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{ return map[string]*schema.Schema{
"k8s_id": { "k8s_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "ID of k8s instance.", Description: "ID of k8s instance.",
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true, //ForceNew: true,
Description: "Name of the worker group.", Description: "Name of the worker group.",
}, },
@@ -250,18 +254,22 @@ func resourceK8sWgSchemaMake() map[string]*schema.Schema {
}, },
"cpu": { "cpu": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
ForceNew: true, //ForceNew: true,
Default: 1, Default: 1,
Description: "Worker node CPU count.", Description: "Worker node CPU count.",
}, },
"ram": { "ram": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
ForceNew: true, //ForceNew: true,
Default: 1024, Default: 1024,
ValidateFunc: validation.All(
validation.IntAtLeast(constants.MinRamPerCompute),
validators.DivisibleBy(constants.RAMDivisibility),
),
Description: "Worker node RAM in MB.", Description: "Worker node RAM in MB.",
}, },

View File

@@ -273,7 +273,22 @@ func utilityK8sListCheckPresence(ctx context.Context, d *schema.ResourceData, m
req.Size = uint64(size.(int)) req.Size = uint64(size.(int))
} }
k8sList, err := c.CloudAPI().K8S().List(ctx, req)
if err != nil {
return nil, err
}
return k8sList, nil
}
func utilityK8sListForResourceCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ListK8SClusters, error) {
c := m.(*controller.ControllerCfg)
req := k8s.ListRequest{
IncludeDeleted: false,
}
if name, ok := d.GetOk("name"); ok {
req.Name = name.(string)
}
k8sList, err := c.CloudAPI().K8S().List(ctx, req) k8sList, err := c.CloudAPI().K8S().List(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -91,11 +91,11 @@ func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m in
var err error var err error
if strings.Contains(d.Id(), "#") { if strings.Contains(d.Id(), "#") {
wgId, err = strconv.Atoi(strings.Split(d.Id(), "#")[0]) wgId, err = strconv.Atoi(strings.Split(d.Id(), "#")[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
k8sId, err = strconv.Atoi(strings.Split(d.Id(), "#")[1]) k8sId, err = strconv.Atoi(strings.Split(d.Id(), "#")[0])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -125,7 +125,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) {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := k8s.GetRequest{ req := k8s.GetRequest{
K8SID: uint64(d.Get("k8s_id").(int)), K8SID: uint64(d.Get("k8s_id").(int)),

View File

@@ -54,6 +54,7 @@ func findInExtraDisks(DiskId uint, ExtraDisks []interface{}) bool {
func dataSourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
compute, err := utilityDataComputeCheckPresence(ctx, d, m) compute, err := utilityDataComputeCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.Itoa(int(compute.ID))) d.SetId(strconv.Itoa(int(compute.ID)))
@@ -290,6 +291,10 @@ func computeListDisksSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"image_name": {
Type: schema.TypeString,
Computed: true,
},
"images": { "images": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
@@ -444,6 +449,10 @@ func computeInterfacesSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"flip_group_id": { "flip_group_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
@@ -606,7 +615,7 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
}, },
}, },
"bootdisk_size": { "boot_disk_size": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
@@ -711,6 +720,10 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"need_reboot" : {
Type: schema.TypeBool,
Computed: true,
},
"natable_vins_id": { "natable_vins_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,

View File

@@ -44,6 +44,7 @@ import (
func dataSourceComputeAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputeAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computeAudits, err := utilityComputeAuditsCheckPresence(ctx, d, m) computeAudits, err := utilityComputeAuditsCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()

View File

@@ -44,6 +44,7 @@ import (
func dataSourceComputeGetAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputeGetAuditsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computeAudits, err := utilityComputeGetAuditsCheckPresence(ctx, d, m) computeAudits, err := utilityComputeGetAuditsCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()

View File

@@ -45,12 +45,13 @@ import (
func dataSourceComputeGetConsoleUrlRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputeGetConsoleUrlRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computeConsoleUrl, err := utilityComputeGetConsoleUrlCheckPresence(ctx, d, m) computeConsoleUrl, err := utilityComputeGetConsoleUrlCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
result := strings.ReplaceAll(string(computeConsoleUrl), "\"", "") result := strings.ReplaceAll(computeConsoleUrl, "\"", "")
result = strings.ReplaceAll(string(result), "\\", "") result = strings.ReplaceAll(result, "\\", "")
d.Set("console_url", result) d.Set("console_url", result)
return nil return nil
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceComputeGetLogRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputeGetLogRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computeGetLog, err := utilityComputeGetLogCheckPresence(ctx, d, m) computeGetLog, err := utilityComputeGetLogCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()

View File

@@ -44,6 +44,7 @@ import (
func dataSourceComputeListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputeListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computeList, err := utilityDataComputeListCheckPresence(ctx, d, m) computeList, err := utilityDataComputeListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -123,7 +124,7 @@ func itemComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
}, },
}, },
"bootdisk_size": { "boot_disk_size": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
@@ -232,6 +233,10 @@ func itemComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"need_reboot": {
Type: schema.TypeBool,
Computed: true,
},
"pinned": { "pinned": {
Type: schema.TypeBool, Type: schema.TypeBool,
Computed: true, Computed: true,

View File

@@ -44,6 +44,7 @@ import (
func dataSourceComputeListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputeListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computeList, err := utilityDataComputeListDeletedCheckPresence(ctx, d, m) computeList, err := utilityDataComputeListDeletedCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceComputePCIDeviceListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputePCIDeviceListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computePCIDeviceList, err := utilityComputePCIDeviceListCheckPresence(ctx, d, m) computePCIDeviceList, err := utilityComputePCIDeviceListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
@@ -80,13 +81,13 @@ func dataSourceComputePCIDeviceListSchemaMake() map[string]*schema.Schema {
Description: "Find by status", Description: "Find by status",
}, },
"page": { "page": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Description: "Page number", Description: "Page number",
}, },
"size": { "size": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Description: "Page size", Description: "Page size",
}, },
"items": { "items": {

View File

@@ -44,6 +44,7 @@ import (
func dataSourceComputePfwListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputePfwListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computePfwList, err := utilityComputePfwListCheckPresence(ctx, d, m) computePfwList, err := utilityComputePfwListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()

View File

@@ -12,6 +12,7 @@ import (
func dataSourceComputeSnapshotUsageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputeSnapshotUsageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computeSnapshotUsage, err := utilityComputeSnapshotUsageCheckPresence(ctx, d, m) computeSnapshotUsage, err := utilityComputeSnapshotUsageCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()

View File

@@ -44,6 +44,7 @@ import (
func dataSourceComputeUserListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputeUserListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computeUserList, err := utilityComputeUserListCheckPresence(ctx, d, m) computeUserList, err := utilityComputeUserListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()

View File

@@ -44,6 +44,7 @@ import (
func dataSourceComputeVGPUListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceComputeVGPUListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computeVGPUList, err := utilityComputeVGPUListCheckPresence(ctx, d, m) computeVGPUList, err := utilityComputeVGPUListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
@@ -75,18 +76,18 @@ func dataSourceComputeVGPUListSchemaMake() map[string]*schema.Schema {
Description: "Find by status", Description: "Find by status",
}, },
"includedeleted": { "includedeleted": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
Description: "Include deleted computes. If using field 'status', then includedeleted will be ignored", Description: "Include deleted computes. If using field 'status', then includedeleted will be ignored",
}, },
"page": { "page": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Description: "Page number", Description: "Page number",
}, },
"size": { "size": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Description: "Page size", Description: "Page size",
}, },
"items": { "items": {
@@ -94,7 +95,6 @@ func dataSourceComputeVGPUListSchemaMake() map[string]*schema.Schema {
Computed: true, Computed: true,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
}, },
}, },
"entry_count": { "entry_count": {

View File

@@ -33,6 +33,7 @@ Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/w
package kvmvm package kvmvm
import ( import (
"context"
"encoding/json" "encoding/json"
"sort" "sort"
"strconv" "strconv"
@@ -72,6 +73,7 @@ func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface
"conn_id": interfaceItem.ConnID, "conn_id": interfaceItem.ConnID,
"conn_type": interfaceItem.ConnType, "conn_type": interfaceItem.ConnType,
"def_gw": interfaceItem.DefGW, "def_gw": interfaceItem.DefGW,
"enabled": interfaceItem.Enabled,
"flip_group_id": interfaceItem.FLIPGroupID, "flip_group_id": interfaceItem.FLIPGroupID,
"guid": interfaceItem.GUID, "guid": interfaceItem.GUID,
"ip_address": interfaceItem.IPAddress, "ip_address": interfaceItem.IPAddress,
@@ -162,7 +164,7 @@ func flattenComputeList(computes *compute.ListComputes) []map[string]interface{}
"anti_affinity_rules": flattenListRules(compute.AntiAffinityRules), "anti_affinity_rules": flattenListRules(compute.AntiAffinityRules),
"arch": compute.Architecture, "arch": compute.Architecture,
"boot_order": compute.BootOrder, "boot_order": compute.BootOrder,
"bootdisk_size": compute.BootDiskSize, "boot_disk_size": compute.BootDiskSize,
"clone_reference": compute.CloneReference, "clone_reference": compute.CloneReference,
"clones": compute.Clones, "clones": compute.Clones,
"computeci_id": compute.ComputeCIID, "computeci_id": compute.ComputeCIID,
@@ -187,6 +189,7 @@ func flattenComputeList(computes *compute.ListComputes) []map[string]interface{}
"migrationjob": compute.MigrationJob, "migrationjob": compute.MigrationJob,
"milestones": compute.Milestones, "milestones": compute.Milestones,
"name": compute.Name, "name": compute.Name,
"need_reboot": compute.NeedReboot,
"pinned": compute.Pinned, "pinned": compute.Pinned,
"ram": compute.RAM, "ram": compute.RAM,
"reference_id": compute.ReferenceID, "reference_id": compute.ReferenceID,
@@ -236,24 +239,31 @@ func flattenBootDisk(bootDisk *compute.ItemComputeDisk) []map[string]interface{}
return res return res
} }
func flattenComputeDisksDemo(disksList compute.ListComputeDisks, extraDisks []interface{}, bootDiskId uint64) []map[string]interface{} { func flattenComputeDisksDemo(ctx context.Context, d *schema.ResourceData, 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 disk.ID == bootDiskId || 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
} }
permanently, ok := ctx.Value(DiskKey(strconv.Itoa(int(disk.ID)))).(bool) // get permamently from Create or Update context
if !ok {
permanently = getPermanentlyByDiskID(d, disk.ID) // get permanently from state when Read is not after Create/Update
}
temp := map[string]interface{}{ temp := map[string]interface{}{
"disk_name": disk.Name, "disk_name": disk.Name,
"disk_id": disk.ID, "disk_id": disk.ID,
"disk_type": disk.Type, "disk_type": disk.Type,
"sep_id": disk.SepID, "sep_id": disk.SepID,
"shareable": disk.Shareable, "shareable": disk.Shareable,
"size_max": disk.SizeMax, "size_max": disk.SizeMax,
"size_used": disk.SizeUsed, "size_used": disk.SizeUsed,
"pool": disk.Pool, "pool": disk.Pool,
"desc": disk.Description, "desc": disk.Description,
"image_id": disk.ImageID, "image_id": disk.ImageID,
"size": disk.SizeMax, "size": disk.SizeMax,
"permanently": permanently,
} }
res = append(res, temp) res = append(res, temp)
} }
@@ -264,6 +274,21 @@ func flattenComputeDisksDemo(disksList compute.ListComputeDisks, extraDisks []in
return res return res
} }
// getPermanentlyByDiskID gets permanently value of specific disk (by diskId) from disks current state
func getPermanentlyByDiskID(d *schema.ResourceData, diskId uint64) bool {
disks := d.Get("disks").([]interface{})
for _, diskItem := range disks {
disk := diskItem.(map[string]interface{})
if uint64(disk["disk_id"].(int)) == diskId {
return disk["permanently"].(bool)
}
}
log.Infof("getPermanentlyByDiskID: disk with id %d not found in state", diskId)
return false
}
func flattenNetwork(interfaces compute.ListInterfaces) []map[string]interface{} { func flattenNetwork(interfaces compute.ListInterfaces) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(interfaces)) res := make([]map[string]interface{}, 0, len(interfaces))
@@ -288,7 +313,7 @@ func findBootDisk(disks compute.ListComputeDisks) *compute.ItemComputeDisk {
return nil return nil
} }
func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute) error { func flattenCompute(ctx context.Context, d *schema.ResourceData, computeRec compute.RecordCompute) error {
// This function expects that compFacts string contains response from API compute/get, // This function expects that compFacts string contains response from API compute/get,
// i.e. detailed information about compute instance. // i.e. detailed information about compute instance.
// //
@@ -307,6 +332,7 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute) er
d.Set("affinity_weight", computeRec.AffinityWeight) d.Set("affinity_weight", computeRec.AffinityWeight)
d.Set("arch", computeRec.Architecture) d.Set("arch", computeRec.Architecture)
d.Set("boot_order", computeRec.BootOrder) d.Set("boot_order", computeRec.BootOrder)
// we intentionally use the SizeMax field, do not change it until the BootDiskSize field is fixed on the platform
d.Set("boot_disk_size", bootDisk.SizeMax) d.Set("boot_disk_size", bootDisk.SizeMax)
d.Set("boot_disk", flattenBootDisk(bootDisk)) d.Set("boot_disk", flattenBootDisk(bootDisk))
d.Set("boot_disk_id", bootDisk.ID) d.Set("boot_disk_id", bootDisk.ID)
@@ -322,7 +348,7 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute) er
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(), bootDisk.ID)) err := d.Set("disks", flattenComputeDisksDemo(ctx, d, computeRec.Disks, d.Get("extra_disks").(*schema.Set).List(), bootDisk.ID))
if err != nil { if err != nil {
return err return err
} }
@@ -343,6 +369,7 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute) er
d.Set("migrationjob", computeRec.MigrationJob) d.Set("migrationjob", computeRec.MigrationJob)
d.Set("milestones", computeRec.Milestones) d.Set("milestones", computeRec.Milestones)
d.Set("name", computeRec.Name) d.Set("name", computeRec.Name)
d.Set("need_reboot", computeRec.NeedReboot)
d.Set("natable_vins_id", computeRec.NatableVINSID) d.Set("natable_vins_id", computeRec.NatableVINSID)
d.Set("natable_vins_ip", computeRec.NatableVINSIP) d.Set("natable_vins_ip", computeRec.NatableVINSIP)
d.Set("natable_vins_name", computeRec.NatableVINSName) d.Set("natable_vins_name", computeRec.NatableVINSName)
@@ -362,7 +389,7 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute) er
d.Set("stateless_sep_id", computeRec.StatelessSepID) d.Set("stateless_sep_id", computeRec.StatelessSepID)
d.Set("stateless_sep_type", computeRec.StatelessSepType) d.Set("stateless_sep_type", computeRec.StatelessSepType)
d.Set("status", computeRec.Status) d.Set("status", computeRec.Status)
d.Set("tags", flattenTags(computeRec.Tags)) // d.Set("tags", flattenTags(computeRec.Tags))
d.Set("tech_status", computeRec.TechStatus) d.Set("tech_status", computeRec.TechStatus)
d.Set("updated_by", computeRec.UpdatedBy) d.Set("updated_by", computeRec.UpdatedBy)
d.Set("updated_time", computeRec.UpdatedTime) d.Set("updated_time", computeRec.UpdatedTime)
@@ -536,7 +563,7 @@ func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute
d.Set("anti_affinity_rules", flattenListRules(computeRec.AntiAffinityRules)) d.Set("anti_affinity_rules", flattenListRules(computeRec.AntiAffinityRules))
d.Set("arch", computeRec.Architecture) d.Set("arch", computeRec.Architecture)
d.Set("boot_order", computeRec.BootOrder) d.Set("boot_order", computeRec.BootOrder)
d.Set("bootdisk_size", computeRec.BootDiskSize) d.Set("boot_disk_size", computeRec.BootDiskSize)
d.Set("clone_reference", computeRec.CloneReference) d.Set("clone_reference", computeRec.CloneReference)
d.Set("clones", computeRec.Clones) d.Set("clones", computeRec.Clones)
d.Set("computeci_id", computeRec.ComputeCIID) d.Set("computeci_id", computeRec.ComputeCIID)
@@ -554,6 +581,7 @@ func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute
d.Set("guid", computeRec.GUID) d.Set("guid", computeRec.GUID)
d.Set("compute_id", computeRec.ID) d.Set("compute_id", computeRec.ID)
d.Set("image_id", computeRec.ImageID) d.Set("image_id", computeRec.ImageID)
d.Set("image_name", computeRec.ImageName)
d.Set("interfaces", flattenInterfaces(computeRec.Interfaces)) d.Set("interfaces", flattenInterfaces(computeRec.Interfaces))
d.Set("lock_status", computeRec.LockStatus) d.Set("lock_status", computeRec.LockStatus)
d.Set("manager_id", computeRec.ManagerID) d.Set("manager_id", computeRec.ManagerID)
@@ -561,6 +589,7 @@ func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute
d.Set("migrationjob", computeRec.MigrationJob) d.Set("migrationjob", computeRec.MigrationJob)
d.Set("milestones", computeRec.Milestones) d.Set("milestones", computeRec.Milestones)
d.Set("name", computeRec.Name) d.Set("name", computeRec.Name)
d.Set("need_reboot", computeRec.NeedReboot)
d.Set("natable_vins_id", computeRec.NatableVINSID) d.Set("natable_vins_id", computeRec.NatableVINSID)
d.Set("natable_vins_ip", computeRec.NatableVINSIP) d.Set("natable_vins_ip", computeRec.NatableVINSIP)
d.Set("natable_vins_name", computeRec.NatableVINSName) d.Set("natable_vins_name", computeRec.NatableVINSName)
@@ -653,19 +682,19 @@ func flattenSnapshotUsage(computeSnapshotUsages compute.ListUsageSnapshots) []ma
return res return res
} }
func flattenSnapshotList(computeSnapshotUsages *compute.ListSnapShots) []map[string]interface{} { // func flattenSnapshotList(computeSnapshotUsages *compute.ListSnapShots) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(computeSnapshotUsages.Data)) // res := make([]map[string]interface{}, 0, len(computeSnapshotUsages.Data))
for _, computeUsage := range computeSnapshotUsages.Data { // for _, computeUsage := range computeSnapshotUsages.Data {
temp := map[string]interface{}{ // temp := map[string]interface{}{
"disks": computeUsage.Disks, // "disks": computeUsage.Disks,
"guid": computeUsage.GUID, // "guid": computeUsage.GUID,
"label": computeUsage.Label, // "label": computeUsage.Label,
"timestamp": computeUsage.Timestamp, // "timestamp": computeUsage.Timestamp,
} // }
res = append(res, temp) // res = append(res, temp)
} // }
return res // return res
} // }
func flattenVGPU(m []interface{}) []string { func flattenVGPU(m []interface{}) []string {
output := []string{} output := []string{}

View File

@@ -40,6 +40,7 @@ import (
log "github.com/sirupsen/logrus" 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/disks"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmppc" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmppc"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmx86" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmx86"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
@@ -47,12 +48,16 @@ import (
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/validators"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/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"
) )
// DiskKey is custom string type to set up context Key for Disk ID
type DiskKey string
func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int)) log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int))
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
@@ -155,6 +160,32 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
} }
} }
createReqPPC.Interfaces = make([]kvmppc.Interface, 0)
if networks, ok := d.GetOk("network"); ok {
if networks.(*schema.Set).Len() > 0 {
ns := networks.(*schema.Set).List()
interfaces := make([]kvmppc.Interface, 0)
for _, elem := range ns {
netInterfaceVal := elem.(map[string]interface{})
reqInterface := kvmppc.Interface{
NetType: netInterfaceVal["net_type"].(string),
NetID: uint64(netInterfaceVal["net_id"].(int)),
}
ipaddr, ipSet := netInterfaceVal["ip_address"]
if ipSet {
reqInterface.IPAddr = ipaddr.(string)
}
interfaces = append(interfaces, reqInterface)
}
createReqPPC.Interfaces = interfaces
}
}
argVal, ok = d.GetOk("cloud_init") argVal, ok = d.GetOk("cloud_init")
if ok { if ok {
userdata := argVal.(string) userdata := argVal.(string)
@@ -242,33 +273,81 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
} }
} }
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface), if disks, ok := d.GetOk("disks"); ok {
// now we need to start it before we report the sequence complete log.Debugf("resourceComputeCreate: Create disks on ComputeID: %d", computeId)
if d.Get("started").(bool) { addedDisks := disks.([]interface{})
req := compute.StartRequest{ComputeID: computeId} if len(addedDisks) > 0 {
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", computeId) for _, disk := range addedDisks {
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil { diskConv := disk.(map[string]interface{})
warnings.Add(err) req := compute.DiskAddRequest{
} ComputeID: computeId,
} DiskName: diskConv["disk_name"].(string),
Size: uint64(diskConv["size"].(int)),
}
if enabled, ok := d.GetOk("enabled"); ok { if diskConv["sep_id"].(int) != 0 {
if enabled.(bool) { req.SepID = uint64(diskConv["sep_id"].(int))
req := compute.EnableRequest{ComputeID: computeId} }
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId) if diskConv["disk_type"].(string) != "" {
if _, err := c.CloudAPI().Compute().Enable(ctx, req); err != nil { req.DiskType = diskConv["disk_type"].(string)
warnings.Add(err) }
} if diskConv["pool"].(string) != "" {
} else { req.Pool = diskConv["pool"].(string)
req := compute.DisableRequest{ComputeID: computeId} }
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId) if diskConv["desc"].(string) != "" {
if _, err := c.CloudAPI().Compute().Disable(ctx, req); err != nil { req.Description = diskConv["desc"].(string)
warnings.Add(err) }
if diskConv["image_id"].(int) != 0 {
req.ImageID = uint64(diskConv["image_id"].(int))
}
diskId, err := c.CloudAPI().Compute().DiskAdd(ctx, req)
if err != nil {
cleanup = true
return diag.FromErr(err)
}
ctx = context.WithValue(ctx, DiskKey(strconv.Itoa(int(diskId))), diskConv["permanently"].(bool))
} }
} }
} }
if !cleanup { if !cleanup {
if enabled, ok := d.GetOk("enabled"); ok {
if enabled.(bool) {
req := compute.EnableRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId)
if _, err := c.CloudAPI().Compute().Enable(ctx, req); err != nil {
warnings.Add(err)
}
} else {
req := compute.DisableRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId)
if _, err := c.CloudAPI().Compute().Disable(ctx, req); err != nil {
warnings.Add(err)
}
}
}
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface),
// now we need to start it before we report the sequence complete
if start, ok := d.GetOk("started"); ok {
if start.(bool) {
req := compute.StartRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", computeId)
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
warnings.Add(err)
}
}
if !start.(bool) {
req := compute.StopRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: stoping Compute ID %d after completing its resource configuration", computeId)
if _, err := c.CloudAPI().Compute().Stop(ctx, req); err != nil {
warnings.Add(err)
}
}
}
if affinityLabel, ok := d.GetOk("affinity_label"); ok { if affinityLabel, ok := d.GetOk("affinity_label"); ok {
req := compute.AffinityLabelSetRequest{ req := compute.AffinityLabelSetRequest{
ComputeID: computeId, ComputeID: computeId,
@@ -281,41 +360,6 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
} }
} }
if disks, ok := d.GetOk("disks"); ok {
log.Debugf("resourceComputeCreate: Create disks on ComputeID: %d", computeId)
addedDisks := disks.([]interface{})
if len(addedDisks) > 0 {
for _, disk := range addedDisks {
diskConv := disk.(map[string]interface{})
req := compute.DiskAddRequest{
ComputeID: computeId,
DiskName: diskConv["disk_name"].(string),
Size: uint64(diskConv["size"].(int)),
SepID: uint64(diskConv["sep_id"].(int)),
}
if diskConv["disk_type"].(string) != "" {
req.DiskType = diskConv["disk_type"].(string)
}
if diskConv["pool"].(string) != "" {
req.Pool = diskConv["pool"].(string)
}
if diskConv["desc"].(string) != "" {
req.Description = diskConv["desc"].(string)
}
if diskConv["image_id"].(int) != 0 {
req.ImageID = uint64(diskConv["image_id"].(int))
}
_, err := c.CloudAPI().Compute().DiskAdd(ctx, req)
if err != nil {
cleanup = true
return diag.FromErr(err)
}
}
}
}
if ars, ok := d.GetOk("affinity_rules"); ok { if ars, ok := d.GetOk("affinity_rules"); ok {
log.Debugf("resourceComputeCreate: Create affinity rules on ComputeID: %d", computeId) log.Debugf("resourceComputeCreate: Create affinity rules on ComputeID: %d", computeId)
addedAR := ars.([]interface{}) addedAR := ars.([]interface{})
@@ -361,133 +405,134 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
} }
} }
} }
}
if tags, ok := d.GetOk("tags"); ok { if tags, ok := d.GetOk("tags"); ok {
log.Debugf("resourceComputeCreate: Create tags on ComputeID: %d", computeId) log.Debugf("resourceComputeCreate: Create tags on ComputeID: %d", computeId)
addedTags := tags.(*schema.Set).List() addedTags := tags.(*schema.Set).List()
if len(addedTags) > 0 { if len(addedTags) > 0 {
for _, tagInterface := range addedTags { for _, tagInterface := range addedTags {
tagItem := tagInterface.(map[string]interface{}) tagItem := tagInterface.(map[string]interface{})
req := compute.TagAddRequest{ req := compute.TagAddRequest{
ComputeID: computeId,
Key: tagItem["key"].(string),
Value: tagItem["value"].(string),
}
_, err := c.CloudAPI().Compute().TagAdd(ctx, req)
if err != nil {
warnings.Add(err)
}
}
}
}
if pfws, ok := d.GetOk("port_forwarding"); ok {
log.Debugf("resourceComputeCreate: Create port farwarding on ComputeID: %d", computeId)
addedPfws := pfws.(*schema.Set).List()
if len(addedPfws) > 0 {
for _, pfwInterface := range addedPfws {
pfwItem := pfwInterface.(map[string]interface{})
req := compute.PFWAddRequest{
ComputeID: computeId,
PublicPortStart: uint64(pfwItem["public_port_start"].(int)),
LocalBasePort: uint64(pfwItem["local_port"].(int)),
Proto: pfwItem["proto"].(string),
}
if pfwItem["public_port_end"].(int) != 0 {
req.PublicPortEnd = int64(pfwItem["public_port_end"].(int))
}
_, err := c.CloudAPI().Compute().PFWAdd(ctx, req)
if err != nil {
warnings.Add(err)
}
}
}
}
if userAcess, ok := d.GetOk("user_access"); ok {
log.Debugf("resourceComputeCreate: Create user access on ComputeID: %d", computeId)
usersAcess := userAcess.(*schema.Set).List()
if len(usersAcess) > 0 {
for _, userAcessInterface := range usersAcess {
userAccessItem := userAcessInterface.(map[string]interface{})
req := compute.UserGrantRequest{
ComputeID: computeId,
Username: userAccessItem["username"].(string),
AccessType: userAccessItem["access_type"].(string),
}
_, err := c.CloudAPI().Compute().UserGrant(ctx, req)
if err != nil {
warnings.Add(err)
}
}
}
}
if snapshotList, ok := d.GetOk("snapshot"); ok {
log.Debugf("resourceComputeCreate: Create snapshot on ComputeID: %d", computeId)
snapshots := snapshotList.(*schema.Set).List()
if len(snapshots) > 0 {
for _, snapshotInterface := range snapshots {
snapshotItem := snapshotInterface.(map[string]interface{})
req := compute.SnapshotCreateRequest{
ComputeID: computeId,
Label: snapshotItem["label"].(string),
}
_, err := c.CloudAPI().Compute().SnapshotCreate(ctx, req)
if err != nil {
warnings.Add(err)
}
}
}
}
if cdtList, ok := d.GetOk("cd"); ok {
log.Debugf("resourceComputeCreate: Create cd on ComputeID: %d", computeId)
cds := cdtList.(*schema.Set).List()
if len(cds) > 0 {
snapshotItem := cds[0].(map[string]interface{})
req := compute.CDInsertRequest{
ComputeID: computeId, ComputeID: computeId,
Key: tagItem["key"].(string), CDROMID: uint64(snapshotItem["cdrom_id"].(int)),
Value: tagItem["value"].(string),
} }
_, err := c.CloudAPI().Compute().TagAdd(ctx, req) _, err := c.CloudAPI().Compute().CDInsert(ctx, req)
if err != nil { if err != nil {
warnings.Add(err) warnings.Add(err)
} }
} }
} }
}
if pfws, ok := d.GetOk("port_forwarding"); ok { if d.Get("pin_to_stack").(bool) {
log.Debugf("resourceComputeCreate: Create port farwarding on ComputeID: %d", computeId) req := compute.PinToStackRequest{
addedPfws := pfws.(*schema.Set).List()
if len(addedPfws) > 0 {
for _, pfwInterface := range addedPfws {
pfwItem := pfwInterface.(map[string]interface{})
req := compute.PFWAddRequest{
ComputeID: computeId,
PublicPortStart: uint64(pfwItem["public_port_start"].(int)),
PublicPortEnd: int64(pfwItem["public_port_end"].(int)),
LocalBasePort: uint64(pfwItem["local_port"].(int)),
Proto: pfwItem["proto"].(string),
}
_, err := c.CloudAPI().Compute().PFWAdd(ctx, req)
if err != nil {
warnings.Add(err)
}
}
}
}
if userAcess, ok := d.GetOk("user_access"); ok {
log.Debugf("resourceComputeCreate: Create user access on ComputeID: %d", computeId)
usersAcess := userAcess.(*schema.Set).List()
if len(usersAcess) > 0 {
for _, userAcessInterface := range usersAcess {
userAccessItem := userAcessInterface.(map[string]interface{})
req := compute.UserGrantRequest{
ComputeID: computeId,
Username: userAccessItem["username"].(string),
AccessType: userAccessItem["access_type"].(string),
}
_, err := c.CloudAPI().Compute().UserGrant(ctx, req)
if err != nil {
warnings.Add(err)
}
}
}
}
if snapshotList, ok := d.GetOk("snapshot"); ok {
log.Debugf("resourceComputeCreate: Create snapshot on ComputeID: %d", computeId)
snapshots := snapshotList.(*schema.Set).List()
if len(snapshots) > 0 {
for _, snapshotInterface := range snapshots {
snapshotItem := snapshotInterface.(map[string]interface{})
req := compute.SnapshotCreateRequest{
ComputeID: computeId,
Label: snapshotItem["label"].(string),
}
_, err := c.CloudAPI().Compute().SnapshotCreate(ctx, req)
if err != nil {
warnings.Add(err)
}
}
}
}
if cdtList, ok := d.GetOk("cd"); ok {
log.Debugf("resourceComputeCreate: Create cd on ComputeID: %d", computeId)
cds := cdtList.(*schema.Set).List()
if len(cds) > 0 {
snapshotItem := cds[0].(map[string]interface{})
req := compute.CDInsertRequest{
ComputeID: computeId, ComputeID: computeId,
CDROMID: uint64(snapshotItem["cdrom_id"].(int)),
} }
_, err := c.CloudAPI().Compute().PinToStack(ctx, req)
if err != nil {
warnings.Add(err)
}
}
_, err := c.CloudAPI().Compute().CDInsert(ctx, req) if d.Get("pause").(bool) {
req := compute.PauseRequest{
ComputeID: computeId,
}
_, err := c.CloudAPI().Compute().Pause(ctx, req)
if err != nil { if err != nil {
warnings.Add(err) warnings.Add(err)
} }
} }
} }
if d.Get("pin_to_stack").(bool) == true {
req := compute.PinToStackRequest{
ComputeID: computeId,
}
_, err := c.CloudAPI().Compute().PinToStack(ctx, req)
if err != nil {
warnings.Add(err)
}
}
if d.Get("pause").(bool) == true {
req := compute.PauseRequest{
ComputeID: computeId,
}
_, err := c.CloudAPI().Compute().Pause(ctx, req)
if err != nil {
warnings.Add(err)
}
}
log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", computeId, d.Get("name").(string)) log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", computeId, d.Get("name").(string))
// We may reuse dataSourceComputeRead here as we maintain similarity // 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
// Compute read function will also update resource ID on success, so that Terraform // Compute read function will also update resource ID on success, so that Terraform
// will know the resource exists // will know the resource exists
defer resourceComputeRead(ctx, d, m) return append(warnings.Get(), resourceComputeRead(ctx, d, m)...)
return warnings.Get()
} }
func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
@@ -498,6 +543,7 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
computeRec, err := utilityComputeCheckPresence(ctx, d, m) computeRec, err := utilityComputeCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -541,7 +587,7 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
} }
} }
if err = flattenCompute(d, computeRec); err != nil { if err = flattenCompute(ctx, d, computeRec); err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -601,6 +647,76 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
return diag.FromErr(err) return diag.FromErr(err)
} }
hasChanged := false
// check compute statuses
switch computeRec.Status {
case status.Deleted:
if restore, ok := d.GetOk("restore"); ok && restore.(bool) {
restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID}
_, err := c.CloudAPI().Compute().Restore(ctx, restoreReq)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
}
if enabled, ok := d.GetOk("enabled"); ok {
if enabled.(bool) {
enableReq := compute.EnableRequest{ComputeID: computeRec.ID}
_, err = c.CloudAPI().Compute().Enable(ctx, enableReq)
if err != nil {
return diag.FromErr(err)
}
}
if !enabled.(bool) {
enableReq := compute.DisableRequest{ComputeID: computeRec.ID}
_, err = c.CloudAPI().Compute().Disable(ctx, enableReq)
if err != nil {
return diag.FromErr(err)
}
}
}
if start, ok := d.GetOk("started"); ok {
if start.(bool) {
req := compute.StartRequest{ComputeID: computeRec.ID}
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
return diag.FromErr(err)
}
}
if !start.(bool) {
req := compute.StopRequest{ComputeID: computeRec.ID}
if _, err := c.CloudAPI().Compute().Stop(ctx, req); err != nil {
return diag.FromErr(err)
}
}
}
hasChanged = true
case status.Destroyed:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceComputeCreate(ctx, d, m)
case status.Disabled:
log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", computeRec.Status)
case status.Redeploying:
case status.Deleting:
case status.Destroying:
return diag.Errorf("The compute is in progress with status: %s", computeRec.Status)
case status.Modeled:
return diag.Errorf("The compute is in status: %s, please, contant the support for more information", computeRec.Status)
}
if hasChanged {
computeRec, err = utilityComputeCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("enabled") { if d.HasChange("enabled") {
enabled := d.Get("enabled").(bool) enabled := d.Get("enabled").(bool)
if enabled { if enabled {
@@ -623,45 +739,39 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
log.Debugf("resourceComputeUpdate: enable=%s Compute ID %v after completing its resource configuration", d.Id(), enabled) log.Debugf("resourceComputeUpdate: enable=%s Compute ID %v after completing its resource configuration", d.Id(), enabled)
} }
// check compute statuses if d.HasChange("started") {
switch computeRec.Status { start := d.Get("started").(bool)
case status.Deleted: if start {
restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID} req := compute.StartRequest{ComputeID: computeRec.ID}
enableReq := compute.EnableRequest{ComputeID: computeRec.ID}
_, err := c.CloudAPI().Compute().Restore(ctx, restoreReq) if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
if err != nil { return diag.FromErr(err)
return diag.FromErr(err) }
} }
if !start {
req := compute.StopRequest{ComputeID: computeRec.ID}
_, err = c.CloudAPI().Compute().Enable(ctx, enableReq) if _, err := c.CloudAPI().Compute().Stop(ctx, req); err != nil {
if err != nil { return diag.FromErr(err)
return diag.FromErr(err) }
} }
case status.Destroyed:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceComputeCreate(ctx, d, m)
case status.Disabled:
log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", computeRec.Status)
case status.Redeploying:
case status.Deleting:
case status.Destroying:
return diag.Errorf("The compute is in progress with status: %s", computeRec.Status)
case status.Modeled:
return diag.Errorf("The compute is in status: %s, please, contant the support for more information", computeRec.Status)
} }
doUpdate := false doUpdate := false
resizeReq := compute.ResizeRequest{ resizeReq := compute.ResizeRequest{
ComputeID: computeRec.ID, ComputeID: computeRec.ID,
Force: true, }
forceResize, ok := d.GetOk("force_resize")
if ok {
resizeReq.Force = forceResize.(bool)
} }
warnings := dc.Warnings{} warnings := dc.Warnings{}
oldCpu, newCpu := d.GetChange("cpu") oldCpu, newCpu := d.GetChange("cpu")
if oldCpu.(int) > newCpu.(int) && !forceResize.(bool) {
return diag.Errorf("Cannot resize compute ID %d: enable 'force_resize' to reduce compute vCPUs", computeRec.ID)
}
if oldCpu.(int) != newCpu.(int) { if oldCpu.(int) != newCpu.(int) {
resizeReq.CPU = uint64(newCpu.(int)) resizeReq.CPU = uint64(newCpu.(int))
doUpdate = true doUpdate = true
@@ -729,14 +839,16 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
} }
} }
if d.HasChange("description") || d.HasChange("name") { if d.HasChanges("description", "name") {
req := compute.UpdateRequest{ req := compute.UpdateRequest{
ComputeID: computeRec.ID, ComputeID: computeRec.ID,
Name: d.Get("name").(string),
} }
if desc, ok := d.GetOk("desc"); ok { if d.HasChange("name") {
req.Description = desc.(string) req.Name = d.Get("name").(string)
}
if d.HasChange("description") {
req.Description = d.Get("description").(string)
} }
if _, err := c.CloudAPI().Compute().Update(ctx, req); err != nil { if _, err := c.CloudAPI().Compute().Update(ctx, req); err != nil {
@@ -747,14 +859,23 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if d.HasChange("disks") { if d.HasChange("disks") {
deletedDisks := make([]interface{}, 0) deletedDisks := make([]interface{}, 0)
addedDisks := make([]interface{}, 0) addedDisks := make([]interface{}, 0)
updatedDisks := make([]interface{}, 0) resizedDisks := make([]interface{}, 0)
renamedDisks := make([]interface{}, 0)
// save permanently in disks based on disk_id to context
for _, diskItemInterface := range d.Get("disks").([]interface{}) {
diskItem := diskItemInterface.(map[string]interface{})
diskId := diskItem["disk_id"].(int)
permanently := diskItem["permanently"].(bool)
ctx = context.WithValue(ctx, DiskKey(strconv.Itoa(diskId)), permanently)
}
oldDisks, newDisks := d.GetChange("disks") oldDisks, newDisks := d.GetChange("disks")
oldConv := oldDisks.([]interface{}) oldConv := oldDisks.([]interface{})
newConv := newDisks.([]interface{}) newConv := newDisks.([]interface{})
for _, el := range oldConv { for _, el := range oldConv {
if !isContainsDisk(newConv, el) { if !isContainsDisk(newConv, el) && !isRenameDisk(newConv, el) && !isResizeDisk(newConv, el) {
flag := false flag := false
extraDisks := d.Get("extra_disks").(*schema.Set).List() extraDisks := d.Get("extra_disks").(*schema.Set).List()
delDisk := el.(map[string]interface{}) delDisk := el.(map[string]interface{})
@@ -778,10 +899,12 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
for _, el := range newConv { for _, el := range newConv {
if !isContainsDisk(oldConv, el) { if !isContainsDisk(oldConv, el) {
addedDisks = append(addedDisks, el) addedDisks = append(addedDisks, el)
} else { }
if isChangeDisk(oldConv, el) { if isResizeDisk(oldConv, el) {
updatedDisks = append(updatedDisks, el) resizedDisks = append(resizedDisks, el)
} }
if isRenameDisk(oldConv, el) {
renamedDisks = append(renamedDisks, el)
} }
} }
@@ -835,9 +958,11 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
ComputeID: computeRec.ID, ComputeID: computeRec.ID,
DiskName: diskConv["disk_name"].(string), DiskName: diskConv["disk_name"].(string),
Size: uint64(diskConv["size"].(int)), Size: uint64(diskConv["size"].(int)),
SepID: uint64(diskConv["sep_id"].(int)),
} }
if diskConv["sep_id"].(int) != 0 {
req.SepID = uint64(diskConv["sep_id"].(int))
}
if diskConv["disk_type"].(string) != "" { if diskConv["disk_type"].(string) != "" {
req.DiskType = diskConv["disk_type"].(string) req.DiskType = diskConv["disk_type"].(string)
} }
@@ -850,15 +975,17 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if diskConv["image_id"].(int) != 0 { if diskConv["image_id"].(int) != 0 {
req.ImageID = uint64(diskConv["image_id"].(int)) req.ImageID = uint64(diskConv["image_id"].(int))
} }
_, err := c.CloudAPI().Compute().DiskAdd(ctx, req) diskId, err := c.CloudAPI().Compute().DiskAdd(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
ctx = context.WithValue(ctx, DiskKey(strconv.Itoa(int(diskId))), diskConv["permanently"].(bool))
} }
} }
if len(updatedDisks) > 0 { if len(resizedDisks) > 0 {
for _, disk := range updatedDisks { for _, disk := range resizedDisks {
diskConv := disk.(map[string]interface{}) diskConv := disk.(map[string]interface{})
if diskConv["disk_type"].(string) == "B" { if diskConv["disk_type"].(string) == "B" {
continue continue
@@ -875,6 +1002,22 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
} }
} }
} }
if len(renamedDisks) > 0 {
for _, disk := range renamedDisks {
diskConv := disk.(map[string]interface{})
req := disks.RenameRequest{
DiskID: uint64(diskConv["disk_id"].(int)),
Name: diskConv["disk_name"].(string),
}
_, err := c.CloudAPI().Disks().Rename(ctx, req)
if err != nil {
return diag.FromErr(err)
}
}
}
} }
if d.HasChange("started") { if d.HasChange("started") {
@@ -1267,7 +1410,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if d.HasChange("pin_to_stack") { if d.HasChange("pin_to_stack") {
oldPin, newPin := d.GetChange("pin_to_stack") oldPin, newPin := d.GetChange("pin_to_stack")
if oldPin.(bool) == true && newPin.(bool) == false { if !newPin.(bool) {
req := compute.UnpinFromStackRequest{ req := compute.UnpinFromStackRequest{
ComputeID: computeRec.ID, ComputeID: computeRec.ID,
} }
@@ -1277,7 +1420,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
return diag.FromErr(err) return diag.FromErr(err)
} }
} }
if oldPin.(bool) == false && newPin.(bool) == true { if !oldPin.(bool) {
req := compute.PinToStackRequest{ req := compute.PinToStackRequest{
ComputeID: computeRec.ID, ComputeID: computeRec.ID,
} }
@@ -1291,7 +1434,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if d.HasChange("pause") { if d.HasChange("pause") {
oldPause, newPause := d.GetChange("pause") oldPause, newPause := d.GetChange("pause")
if oldPause.(bool) == true && newPause.(bool) == false { if !newPause.(bool) {
req := compute.ResumeRequest{ req := compute.ResumeRequest{
ComputeID: computeRec.ID, ComputeID: computeRec.ID,
} }
@@ -1300,7 +1443,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
return diag.FromErr(err) return diag.FromErr(err)
} }
} }
if oldPause.(bool) == false && newPause.(bool) == true { if !oldPause.(bool) {
req := compute.PauseRequest{ req := compute.PauseRequest{
ComputeID: computeRec.ID, ComputeID: computeRec.ID,
} }
@@ -1313,8 +1456,8 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
} }
if d.HasChange("reset") { if d.HasChange("reset") {
oldReset, newReset := d.GetChange("reset") _, newReset := d.GetChange("reset")
if oldReset.(bool) == false && newReset.(bool) == true { if newReset.(bool) {
req := compute.ResetRequest{ req := compute.ResetRequest{
ComputeID: computeRec.ID, ComputeID: computeRec.ID,
} }
@@ -1394,11 +1537,11 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
// 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)
return warnings.Get() return append(warnings.Get(), resourceComputeRead(ctx, d, m)...)
} }
func isChangeDisk(els []interface{}, el interface{}) bool { func isResizeDisk(els []interface{}, el interface{}) bool {
for _, elOld := range els { for _, elOld := range els {
elOldConv := elOld.(map[string]interface{}) elOldConv := elOld.(map[string]interface{})
elConv := el.(map[string]interface{}) elConv := el.(map[string]interface{})
@@ -1410,11 +1553,23 @@ func isChangeDisk(els []interface{}, el interface{}) bool {
return false return false
} }
func isRenameDisk(els []interface{}, el interface{}) bool {
for _, elOld := range els {
elOldConv := elOld.(map[string]interface{})
elConv := el.(map[string]interface{})
if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) &&
elOldConv["disk_name"].(string) != elConv["disk_name"].(string) {
return true
}
}
return false
}
func isContainsDisk(els []interface{}, el interface{}) bool { func isContainsDisk(els []interface{}, el interface{}) bool {
for _, elOld := range els { for _, elOld := range els {
elOldConv := elOld.(map[string]interface{}) elOldConv := elOld.(map[string]interface{})
elConv := el.(map[string]interface{}) elConv := el.(map[string]interface{})
if elOldConv["disk_name"].(string) == elConv["disk_name"].(string) { if elOldConv["disk_id"].(int) == elConv["disk_id"].(int) {
return true return true
} }
} }
@@ -1456,6 +1611,8 @@ func resourceComputeDelete(ctx context.Context, d *schema.ResourceData, m interf
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId("")
return nil return nil
} }
@@ -1504,7 +1661,6 @@ func disksSubresourceSchemaMake() map[string]*schema.Schema {
}, },
"permanently": { "permanently": {
Type: schema.TypeBool, Type: schema.TypeBool,
Computed: true,
Optional: true, Optional: true,
Description: "Disk deletion status", Description: "Disk deletion status",
}, },
@@ -1613,15 +1769,15 @@ 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
@@ -1634,10 +1790,13 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Description: "Number of CPUs to allocate to this compute instance.", Description: "Number of CPUs to allocate to this compute instance.",
}, },
"ram": { "ram": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ValidateFunc: validation.IntAtLeast(constants.MinRamPerCompute), ValidateFunc: validation.All(
Description: "Amount of RAM in MB to allocate to this compute instance.", validation.IntAtLeast(constants.MinRamPerCompute),
validators.DivisibleBy(constants.RAMDivisibility),
),
Description: "Amount of RAM in MB to allocate to this compute instance.",
}, },
"image_id": { "image_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
@@ -1686,7 +1845,7 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
}, },
"value": { "value": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Optional: true,
Description: "value that must match the key to be taken into account when analyzing this rule", Description: "value that must match the key to be taken into account when analyzing this rule",
}, },
}, },
@@ -1722,7 +1881,7 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
}, },
"value": { "value": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Optional: true,
Description: "value that must match the key to be taken into account when analyzing this rule", Description: "value that must match the key to be taken into account when analyzing this rule",
}, },
}, },
@@ -1877,6 +2036,12 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Default: false, Default: false,
}, },
"restore": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"auto_start": { "auto_start": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
@@ -1889,6 +2054,12 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Default: false, Default: false,
Description: "Flag for redeploy compute", Description: "Flag for redeploy compute",
}, },
"force_resize": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Flag for resize compute",
},
"data_disks": { "data_disks": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@@ -2027,6 +2198,10 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"need_reboot": {
Type: schema.TypeBool,
Computed: true,
},
"natable_vins_id": { "natable_vins_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,

View File

@@ -34,18 +34,17 @@ package kvmvm
import ( import (
"context" "context"
"regexp"
"strconv"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"regexp"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
func matchComputes(computeList *compute.ListComputes) *compute.ListComputes { func matchComputes(computeList *compute.ListComputes) *compute.ListComputes {
matched, _ := regexp.Compile("[a-zA-Z]+\\d+-[a-zA-Z]+\\d+-[a-zA-Z]+\\d+") matched, _ := regexp.Compile(`[a-zA-Z]+\\d+-[a-zA-Z]+\\d+-[a-zA-Z]+\\d+`)
result := computeList.FilterFunc(func(ic compute.ItemCompute) bool { result := computeList.FilterFunc(func(ic compute.ItemCompute) bool {
res := matched.Match([]byte(ic.Name)) res := matched.Match([]byte(ic.Name))
return !res return !res
@@ -176,17 +175,6 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
old_set, new_set := d.GetChange("network") old_set, new_set := d.GetChange("network")
req := compute.StopRequest{
ComputeID: computeID,
Force: true,
}
log.Debugf("utilityComputeNetworksConfigure: stopping compute %d", computeID)
_, err := c.CloudAPI().Compute().Stop(ctx, req)
if err != nil {
return err
}
apiErrCount := 0 apiErrCount := 0
var lastSavedError error var lastSavedError error
@@ -246,6 +234,17 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
} }
} }
needStart:= false
if d.Get("network").(*schema.Set).Len() == 1 || old_set.(*schema.Set).Len() < 1 {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
if err := utilityComputeStop(ctx, computeId, m); err != nil {
apiErrCount++
lastSavedError = err
}
needStart = true
}
attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set)) attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set))
log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id()) log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id())
for _, runner := range attach_set.List() { for _, runner := range attach_set.List() {
@@ -270,13 +269,12 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
} }
} }
startReq := compute.StartRequest{ComputeID: computeID} if needStart {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
log.Debugf("utilityComputeNetworksConfigure: starting compute %d", computeID) if numErr, err := utilityComputeStart(ctx, computeId, m); err != nil {
_, err = c.CloudAPI().Compute().Start(ctx, startReq) apiErrCount+= numErr
if err != nil { lastSavedError = err
apiErrCount++ }
lastSavedError = err
} }
if apiErrCount > 0 { if apiErrCount > 0 {
@@ -302,3 +300,30 @@ func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m
return *computeRecord, nil return *computeRecord, nil
} }
func utilityComputeStop(ctx context.Context, computeID uint64, m interface{}) error {
c := m.(*controller.ControllerCfg)
req := compute.StopRequest{
ComputeID: computeID,
Force: true,
}
log.Debugf("utilityComputeNetworksConfigure: stopping compute %d", computeID)
_, err := c.CloudAPI().Compute().Stop(ctx, req)
if err != nil {
return err
}
return nil
}
func utilityComputeStart(ctx context.Context, computeID uint64, m interface{}) (int, error) {
c := m.(*controller.ControllerCfg)
startReq := compute.StartRequest{ComputeID: computeID}
log.Debugf("utilityComputeNetworksConfigure: starting compute %d", computeID)
_, err := c.CloudAPI().Compute().Start(ctx, startReq)
if err != nil {
return 1, err
}
return 0, nil
}

View File

@@ -44,6 +44,7 @@ import (
func dataSourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
lb, err := utilityLBCheckPresence(ctx, d, m) lb, err := utilityLBCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,6 +44,7 @@ import (
func dataSourceLBListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceLBListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
lbList, err := utilityLBListCheckPresence(ctx, d, m) lbList, err := utilityLBListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()

View File

@@ -44,6 +44,7 @@ import (
func dataSourceLBListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceLBListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
lbList, err := utilityLBListDeletedCheckPresence(ctx, d, m) lbList, err := utilityLBListDeletedCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()

View File

@@ -79,6 +79,12 @@ func lbResourceSchemaMake() map[string]*schema.Schema {
Optional: true, Optional: true,
} }
sch["safe"] = &schema.Schema{
Type: schema.TypeBool,
Default: true,
Optional: true,
}
sch["config_reset"] = &schema.Schema{ sch["config_reset"] = &schema.Schema{
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
@@ -93,7 +99,6 @@ func lbResourceSchemaMake() map[string]*schema.Schema {
Optional: true, Optional: true,
} }
/// ///
sch["permanently"] = &schema.Schema{ sch["permanently"] = &schema.Schema{
Type: schema.TypeBool, Type: schema.TypeBool,

View File

@@ -42,6 +42,7 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"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/dc"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
) )
@@ -94,21 +95,16 @@ func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}
lbId, err := c.CloudAPI().LB().Create(ctx, req) lbId, err := c.CloudAPI().LB().Create(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
lbIdParsed := strconv.Itoa(int(lbId)) d.SetId(strconv.FormatUint(lbId, 10))
d.SetId(lbIdParsed)
d.Set("lb_id", lbId) d.Set("lb_id", lbId)
_, err = utilityLBCheckPresence(ctx, d, m) w := dc.Warnings{}
if err != nil {
return diag.FromErr(err)
}
if enable, ok := d.GetOk("enable"); ok { if enable, ok := d.GetOk("enable"); ok {
lbId := uint64(d.Get("lb_id").(int))
req := lb.DisableEnableRequest{ req := lb.DisableEnableRequest{
LBID: lbId, LBID: lbId,
} }
@@ -116,17 +112,33 @@ func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}
if enable.(bool) { if enable.(bool) {
_, err := c.CloudAPI().LB().Enable(ctx, req) _, err := c.CloudAPI().LB().Enable(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) w.Add(err)
} }
} else { } else {
_, err := c.CloudAPI().LB().Disable(ctx, req) _, err := c.CloudAPI().LB().Disable(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) w.Add(err)
}
}
if start, ok := d.GetOk("start"); ok && enable.(bool) {
if start.(bool) {
req := lb.StartRequest{LBID: lbId}
_, err := c.CloudAPI().LB().Start(ctx, req)
if err != nil {
w.Add(err)
}
} else {
req := lb.StopRequest{LBID: lbId}
_, err := c.CloudAPI().LB().Stop(ctx, req)
if err != nil {
w.Add(err)
}
} }
} }
} }
return resourceLBRead(ctx, d, m) return append(w.Get(), resourceLBRead(ctx, d, m)...)
} }
func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
@@ -193,21 +205,17 @@ func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{})
func resourceLBDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBDelete") log.Debugf("resourceLBDelete")
_, err := utilityLBCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
lbId, _ := strconv.ParseUint(d.Id(), 10, 64)
req := lb.DeleteRequest{ req := lb.DeleteRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: lbId,
} }
if permanently, ok := d.GetOk("permanently"); ok { if permanently, ok := d.GetOk("permanently"); ok {
req.Permanently = permanently.(bool) req.Permanently = permanently.(bool)
} }
_, err = c.CloudAPI().LB().Delete(ctx, req) _, err := c.CloudAPI().LB().Delete(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -263,19 +271,47 @@ func resourceLBUpdate(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) if restore, ok := d.GetOk("restore"); ok && restore.(bool) {
restoreReq := lb.RestoreRequest{LBID: lbId} restoreReq := lb.RestoreRequest{LBID: lbRec.ID}
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)
if err != nil {
return diag.FromErr(err)
} }
if enable, ok := d.GetOk("enable"); ok {
req := lb.DisableEnableRequest{
LBID: lbRec.ID,
}
if enable.(bool) {
_, err := c.CloudAPI().LB().Enable(ctx, req)
if err != nil {
return diag.FromErr(err)
}
} else {
_, err := c.CloudAPI().LB().Disable(ctx, req)
if err != nil {
return diag.FromErr(err)
}
}
if start, ok := d.GetOk("start"); ok && enable.(bool) {
if start.(bool) {
req := lb.StartRequest{LBID: lbRec.ID}
_, err := c.CloudAPI().LB().Start(ctx, req)
if err != nil {
return diag.FromErr(err)
}
} else {
req := lb.StopRequest{LBID: lbRec.ID}
_, err := c.CloudAPI().LB().Stop(ctx, req)
if err != nil {
return diag.FromErr(err)
}
}
}
}
hasChanged = true 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)
@@ -302,7 +338,7 @@ func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}
if d.HasChange("ha_mode") { if d.HasChange("ha_mode") {
hamode := d.Get("ha_mode").(bool) hamode := d.Get("ha_mode").(bool)
if hamode { if hamode {
req:= lb.HighlyAvailableRequest { req := lb.HighlyAvailableRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
} }
_, err := c.CloudAPI().LB().HighlyAvailable(ctx, req) _, err := c.CloudAPI().LB().HighlyAvailable(ctx, req)
@@ -327,7 +363,6 @@ func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
} }
} }
@@ -367,6 +402,9 @@ func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}
req := lb.RestartRequest{ req := lb.RestartRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
} }
if safe, ok:= d.GetOk("safe"); ok {
req.Safe = safe.(bool)
}
_, err := c.CloudAPI().LB().Restart(ctx, req) _, err := c.CloudAPI().LB().Restart(ctx, req)
if err != nil { if err != nil {

View File

@@ -94,6 +94,7 @@ func resourceLBBackendCreate(ctx context.Context, d *schema.ResourceData, m inte
_, err = c.CloudAPI().LB().BackendCreate(ctx, req) _, err = c.CloudAPI().LB().BackendCreate(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -101,6 +102,7 @@ func resourceLBBackendCreate(ctx context.Context, d *schema.ResourceData, m inte
_, err = utilityLBBackendCheckPresence(ctx, d, m) _, err = utilityLBBackendCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -128,6 +130,7 @@ func resourceLBBackendDelete(ctx context.Context, d *schema.ResourceData, m inte
_, err := utilityLBBackendCheckPresence(ctx, d, m) _, err := utilityLBBackendCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -139,6 +142,7 @@ func resourceLBBackendDelete(ctx context.Context, d *schema.ResourceData, m inte
_, err = c.CloudAPI().LB().BackendDelete(ctx, req) _, err = c.CloudAPI().LB().BackendDelete(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -195,6 +199,7 @@ func resourceLBBackendUpdate(ctx context.Context, d *schema.ResourceData, m inte
_, err = c.CloudAPI().LB().BackendUpdate(ctx, req) _, err = c.CloudAPI().LB().BackendUpdate(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -98,6 +98,7 @@ func resourceLBBackendServerCreate(ctx context.Context, d *schema.ResourceData,
_, err = c.CloudAPI().LB().BackendServerAdd(ctx, req) _, err = c.CloudAPI().LB().BackendServerAdd(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -105,6 +106,7 @@ func resourceLBBackendServerCreate(ctx context.Context, d *schema.ResourceData,
_, err = utilityLBBackendServerCheckPresence(ctx, d, m) _, err = utilityLBBackendServerCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -133,6 +135,7 @@ func resourceLBBackendServerDelete(ctx context.Context, d *schema.ResourceData,
_, err := utilityLBBackendServerCheckPresence(ctx, d, m) _, err := utilityLBBackendServerCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -145,6 +148,7 @@ func resourceLBBackendServerDelete(ctx context.Context, d *schema.ResourceData,
_, err = c.CloudAPI().LB().BackendServerDelete(ctx, req) _, err = c.CloudAPI().LB().BackendServerDelete(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId("") d.SetId("")
@@ -158,6 +162,7 @@ func resourceLBBackendServerUpdate(ctx context.Context, d *schema.ResourceData,
haveLBID, err := existLBID(ctx, d, m) haveLBID, err := existLBID(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -203,6 +208,7 @@ func resourceLBBackendServerUpdate(ctx context.Context, d *schema.ResourceData,
_, err = c.CloudAPI().LB().BackendServerUpdate(ctx, req) _, err = c.CloudAPI().LB().BackendServerUpdate(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -66,6 +66,7 @@ func resourceLBFrontendCreate(ctx context.Context, d *schema.ResourceData, m int
_, err = c.CloudAPI().LB().FrontendCreate(ctx, req) _, err = c.CloudAPI().LB().FrontendCreate(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -73,6 +74,7 @@ func resourceLBFrontendCreate(ctx context.Context, d *schema.ResourceData, m int
_, err = utilityLBFrontendCheckPresence(ctx, d, m) _, err = utilityLBFrontendCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -100,6 +102,7 @@ func resourceLBFrontendDelete(ctx context.Context, d *schema.ResourceData, m int
_, err := utilityLBFrontendCheckPresence(ctx, d, m) _, err := utilityLBFrontendCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -111,6 +114,7 @@ func resourceLBFrontendDelete(ctx context.Context, d *schema.ResourceData, m int
_, err = c.CloudAPI().LB().FrontendDelete(ctx, req) _, err = c.CloudAPI().LB().FrontendDelete(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -68,6 +68,7 @@ func resourceLBFrontendBindCreate(ctx context.Context, d *schema.ResourceData, m
_, err = c.CloudAPI().LB().FrontendBind(ctx, req) _, err = c.CloudAPI().LB().FrontendBind(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -75,6 +76,7 @@ func resourceLBFrontendBindCreate(ctx context.Context, d *schema.ResourceData, m
_, err = utilityLBFrontendBindCheckPresence(ctx, d, m) _, err = utilityLBFrontendBindCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -103,6 +105,7 @@ func resourceLBFrontendBindDelete(ctx context.Context, d *schema.ResourceData, m
_, err := utilityLBFrontendBindCheckPresence(ctx, d, m) _, err := utilityLBFrontendBindCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -115,6 +118,7 @@ func resourceLBFrontendBindDelete(ctx context.Context, d *schema.ResourceData, m
_, err = c.CloudAPI().LB().FrontendBindDelete(ctx, req) _, err = c.CloudAPI().LB().FrontendBindDelete(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -152,6 +156,7 @@ func resourceLBFrontendBindUpdate(ctx context.Context, d *schema.ResourceData, m
_, err = c.CloudAPI().LB().FrontendBindUpdate(ctx, req) _, err = c.CloudAPI().LB().FrontendBindUpdate(ctx, req)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -44,11 +44,12 @@ import (
) )
func flattenLocationsList(ll *locations.ListLocations) []map[string]interface{} { func flattenLocationsList(ll *locations.ListLocations) []map[string]interface{} {
res := make([]map[string]interface{}, 0) res := make([]map[string]interface{}, 0, len(ll.Data))
for _, l := range ll.Data { for _, l := range ll.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"ckey": l.CKey, "ckey": l.CKey,
"meta": flattens.FlattenMeta(l.Meta), "meta": flattens.FlattenMeta(l.Meta),
"auth_broker": l.AuthBroker,
"flag": l.Flag, "flag": l.Flag,
"gid": l.GID, "gid": l.GID,
"guid": l.GUID, "guid": l.GUID,
@@ -65,6 +66,7 @@ func flattenLocationsList(ll *locations.ListLocations) []map[string]interface{}
func dataSourceLocationsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceLocationsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
locations, err := utilityLocationsListCheckPresence(ctx, d, m) locations, err := utilityLocationsListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -126,6 +128,13 @@ func dataSourceLocationsListSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
}, },
}, },
"auth_broker": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"flag": { "flag": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,

View File

@@ -45,6 +45,7 @@ import (
func dataSourceLocationUrlRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceLocationUrlRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
url, err := utilityLocationUrlCheckPresence(ctx, m) url, err := utilityLocationUrlCheckPresence(ctx, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@@ -42,146 +42,173 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
func sepsSchemaMake() map[string]*schema.Schema { func dataSourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
res := map[string]*schema.Schema{ rg, err := utilityResgroupCheckPresence(ctx, d, m)
"sep_id": { if err != nil {
Type: schema.TypeString, d.SetId("") // ensure ID is empty in this case
Computed: true, return diag.FromErr(err)
},
"data_name": {
Type: schema.TypeString,
Computed: true,
},
"disk_size": {
Type: schema.TypeFloat,
Computed: true,
},
"disk_size_max": {
Type: schema.TypeInt,
Computed: true,
},
} }
d.SetId(strconv.Itoa(d.Get("rg_id").(int)))
return res flattenRg(d, *rg)
return nil
} }
func resourcesSchemaMake() map[string]*schema.Schema { func DataSourceResgroup() *schema.Resource {
res := map[string]*schema.Schema{ return &schema.Resource{
"current": { SchemaVersion: 1,
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cpu": {
Type: schema.TypeInt,
Computed: true,
},
"disk_size": {
Type: schema.TypeFloat,
Computed: true,
},
"disk_size_max": {
Type: schema.TypeFloat,
Computed: true,
},
"extips": {
Type: schema.TypeInt,
Computed: true,
},
"exttraffic": {
Type: schema.TypeInt,
Computed: true,
},
"gpu": {
Type: schema.TypeInt,
Computed: true,
},
"ram": {
Type: schema.TypeInt,
Computed: true,
},
"seps": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"sep_id": {
Type: schema.TypeString,
Computed: true,
},
"map": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
},
},
},
"reserved": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cpu": {
Type: schema.TypeInt,
Computed: true,
},
"disk_size": {
Type: schema.TypeFloat,
Computed: true,
},
"disk_size_max": {
Type: schema.TypeInt,
Computed: true,
},
"extips": {
Type: schema.TypeInt,
Computed: true,
},
"exttraffic": {
Type: schema.TypeInt,
Computed: true,
},
"gpu": {
Type: schema.TypeInt,
Computed: true,
},
"ram": {
Type: schema.TypeInt,
Computed: true,
},
"seps": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"sep_id": {
Type: schema.TypeString,
Computed: true,
},
"map": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
},
},
},
}
return res ReadContext: dataSourceResgroupRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceRgSchemaMake(),
}
} }
// func sepsSchemaMake() map[string]*schema.Schema {
// res := map[string]*schema.Schema{
// "sep_id": {
// Type: schema.TypeString,
// Computed: true,
// },
// "data_name": {
// Type: schema.TypeString,
// Computed: true,
// },
// "disk_size": {
// Type: schema.TypeFloat,
// Computed: true,
// },
// "disk_size_max": {
// Type: schema.TypeInt,
// Computed: true,
// },
// }
// return res
// }
// func resourcesSchemaMake() map[string]*schema.Schema {
// res := map[string]*schema.Schema{
// "current": {
// Type: schema.TypeList,
// Computed: true,
// Elem: &schema.Resource{
// Schema: map[string]*schema.Schema{
// "cpu": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "disk_size": {
// Type: schema.TypeFloat,
// Computed: true,
// },
// "disk_size_max": {
// Type: schema.TypeFloat,
// Computed: true,
// },
// "extips": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "exttraffic": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "gpu": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "ram": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "seps": {
// Type: schema.TypeSet,
// Computed: true,
// Elem: &schema.Resource{
// Schema: map[string]*schema.Schema{
// "sep_id": {
// Type: schema.TypeString,
// Computed: true,
// },
// "map": {
// Type: schema.TypeMap,
// Computed: true,
// Elem: &schema.Schema{
// Type: schema.TypeString,
// },
// },
// },
// },
// },
// },
// },
// },
// "reserved": {
// Type: schema.TypeList,
// Computed: true,
// Elem: &schema.Resource{
// Schema: map[string]*schema.Schema{
// "cpu": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "disk_size": {
// Type: schema.TypeFloat,
// Computed: true,
// },
// "disk_size_max": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "extips": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "exttraffic": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "gpu": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "ram": {
// Type: schema.TypeInt,
// Computed: true,
// },
// "seps": {
// Type: schema.TypeSet,
// Computed: true,
// Elem: &schema.Resource{
// Schema: map[string]*schema.Schema{
// "sep_id": {
// Type: schema.TypeString,
// Computed: true,
// },
// "map": {
// Type: schema.TypeMap,
// Computed: true,
// Elem: &schema.Schema{
// Type: schema.TypeString,
// },
// },
// },
// },
// },
// },
// },
// },
// }
// return res
// }
func aclSchemaMake() map[string]*schema.Schema { func aclSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{ res := map[string]*schema.Schema{
"explicit": { "explicit": {
@@ -392,28 +419,4 @@ func dataSourceRgSchemaMake() map[string]*schema.Schema {
return res return res
} }
func dataSourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
rg, err := utilityResgroupCheckPresence(ctx, d, m)
if err != nil {
d.SetId("") // ensure ID is empty in this case
return diag.FromErr(err)
}
d.SetId(strconv.Itoa(d.Get("rg_id").(int)))
flattenRg(d, *rg)
return nil
}
func DataSourceResgroup() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceResgroupRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceRgSchemaMake(),
}
}

View File

@@ -44,6 +44,7 @@ import (
func dataSourceRgAffinityGroupComputesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceRgAffinityGroupComputesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
rgComputes, err := utilityRgAffinityGroupComputesCheckPresence(ctx, d, m) rgComputes, err := utilityRgAffinityGroupComputesCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
@@ -64,7 +65,6 @@ func dataSourceRgAffinityGroupComputesSchemaMake() map[string]*schema.Schema {
Required: true, Required: true,
Description: "Affinity group label", Description: "Affinity group label",
}, },
"items": { "items": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,

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