main 4.5.3
nlloskutova 11 months ago
parent f49d9f8860
commit b6547e226d

@ -1,36 +1,31 @@
## Version 4.5.2 ## Version 4.5.3
### Bugfix ### Bugfix
- Added resource_limits.cu_dm string field for account, account_consumed_units and account_reserved_units data sources in cloudapi/account - Change field Value in schema resource kvmvm in blocks affinity_rules and anti_affinity_rules from required to optional in cloudapi and cloudbroker
- Fixed restore of account resource in cloudapi/account, it happens if restore parameter is set to true - Change the format ID in resource k8s_wg from wg_id to k8s_id#wg_id
- Fixed restore of bservice resource in cloudapi/bservice, it happens if restore parameter is set to true and only once - Fix scripts intall.bat and intall.sh
- Fixed enable of bservice resource in cloudapi/bservice, it happens if enable parameter is set to true - 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
- Fixed terraform state update for bservice resource update in cloudapi/bservice - Increased timeouts for resources pcidevice, sep, sep_config in cloudbroker
- Fixed terraform state update for bservice_group resource update in cloudapi/bservice - Fix bug in affinity_rules in cloudbroker/kvmvm
- Added entry_count field for bservice_snapshot_list data source in cloudapi/bservice - Add field NeedReboot in cloudapi/kvmvm in data_source, data_source_list and resource schemas
- Added items.shareable boolean field for disk_list_unattached data source in cloudapi/disks - Fix bug with field ExtNetID in CreateInRGRequest in cloudapi/vins and cloudbroker/vins
- Added items.status string field for extnet_list data source in cloudapi/extnet - Add boolean field Safe in Restart func in resource cloudapi/lb
- Fixed multiple minor typos in samples/cloudapi - Add field force_resize in Resize func in resource cloudapi/kvmvm and cloudbroker/kvmvm
- Added account_name string, created_by string, created_time int, deleted_by string, deleted_time int, network string, rg_id int, rg_name string, updated_by string, updated_by int fields for flipgroup data source and resource in cloudapi/flipgroup - Fix bug in cloudBroker/kvmvm with disk and extra_disks
- Removed net_mask string, ckey string fields for flipgroup data source and resource in cloudapi/flipgroup - 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
- Add meta list field for flipgroup_list data source in cloudapi/flipgroup - Fix allowed network plugin value from "weawenet" to "weavenet" for k8ci, k8s resources in cloudbroker and for k8s resource in cloudapi
- Fixed net_mask string field for fligroup_list data source in cloudapi/flipgroup - Fix bug with deleting decort_bservice resource when setting enable=false in cloudapi/bservice
- Fixed id string field for image data source in cloudapi/image - Fix panic in data source decort_bservice_snapshot_list in cloudapi/bservice
- Fix account_name string field for k8s_list data source in cloudapi/k8s - Fix panic in data source decort_rg_affinity_groups_list in cloudapi/rg
- Add network_plugin string field for k8s and k8s_list data sources in cloudapi/k8s - Fix change description in resource decort_cb_kvmvm in cloudbroker
- Fixed terraform state update for k8s, k8_cp and k8s_wg resources update in cloudapi/k8s - 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
- Add image_name string, interfaces.enabled boolean fields for compute data source in cloudapi/kvmvm - Change request logic for delete resource decort_cb_k8s_cp in cloudbroker
- Add the interfaces field to the creation request in cloudapi/kvmvm - 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
- Fixed restore of kvmvm resource in cloudapi/kvmvm, it happens if restore parameter is set to true - Fix panic with RG in cloudapi
- The logic of network connection has been changed, only the first network connects to the kvmvm in the stopped status, the subsequent ones connect without stopping - Fix permanently field for disks delete in decort_kvmvm in cloudapi/kvmvm and decort_cb_kvmvm in cloudbroker/kvmvm
- Token receipt has been removed from the controller - Fix bug with enable request duplication
- Add start/stop function after create for lb in cloudapi/lb
- Fixed restore of lb resource in cloudapi/lb, it happens if restore parameter is set to true ### Feature
- Add field auth_broker in data source location list in cloudapi/location
- Add fields cpu_allocation_parameter and cpu_allocation_ratio in data source rg list lb deleted in cloudapi/rg - Add RAM divisibility validation in compute, k8s, k8s_cp and k8s_wg resources in cloudapi and cloudbroker
- Add fields backend_haip and frontend_haip in data source rg list in cloudapi/rg - Add "permanently" flag in k8s, k8s_cp in cloudapi
- Change type field Ram QuotaRecord struct in cloudapi/rg/models
- Add state upgrader for rg in cloudapi/rg
- Add field owner to the creation request in cloudapi/rg
- Fixed restore of rg resource in cloudapi/rg, it happens if restore parameter is set to true
- Add fields enabled and routesroutes in data source vins in cloudapi/vins

@ -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.2 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\

@ -5,49 +5,51 @@ go 1.18
require ( require (
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.7.3 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
@ -63,15 +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.15.0 // indirect golang.org/x/crypto v0.15.0 // indirect
golang.org/x/mod v0.13.0 // indirect
golang.org/x/sys v0.14.0 // indirect golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.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
) )

212
go.sum

@ -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,20 +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/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
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=
@ -84,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=
@ -133,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=
@ -170,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=
@ -181,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=
@ -194,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=
@ -224,64 +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.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
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 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= 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/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
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=
@ -291,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.3.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 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
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 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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.7.3 h1:NtvW72WsAezk0XYKE5+ag+xauIgKWKcbKLy7YTp5Fuc= repository.basistech.ru/BASIS/decort-golang-sdk v1.7.7 h1:VIF+NXXfYec8DtlTcPae+CjB0fhH8ovBQxKMwEnLgE8=
repository.basistech.ru/BASIS/decort-golang-sdk v1.7.3/go.mod h1:7fj8sgGZFiiExewQeqckCS4WxwOmU0oP6BO6mi1Lpkw= repository.basistech.ru/BASIS/decort-golang-sdk v1.7.7/go.mod h1:7fj8sgGZFiiExewQeqckCS4WxwOmU0oP6BO6mi1Lpkw=

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

@ -1,32 +1,33 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package constants package constants
import "time" import "time"
// timeouts for API calls from CRUD functions of Terraform plugin // timeouts for API calls from CRUD functions of Terraform plugin
var Timeout30s = time.Second * 30 var Timeout30s = time.Second * 30
var Timeout60s = time.Second * 60 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 Timeout20m = time.Minute * 20 var Timeout900s = time.Second * 900
var Timeout30m = time.Minute * 30 var Timeout20m = time.Minute * 20
var Timeout30m = time.Minute * 30

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

@ -40,13 +40,13 @@ import (
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_k8ci "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8ci"
cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s" cb_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_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_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"
) )

@ -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,16 +101,9 @@ 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 enable bservice %v", serviceId)
_, err := c.CloudAPI().BService().Enable(ctx, bservice.EnableRequest{
ServiceID: serviceId,
})
if err != nil {
return diag.FromErr(err)
}
log.Debugf("trying to start bservice %v", serviceId) log.Debugf("trying to start bservice %v", serviceId)
_, err = c.CloudAPI().BService().Start(ctx, bservice.StartRequest{ _, err = c.CloudAPI().BService().Start(ctx, bservice.StartRequest{
@ -113,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 {

@ -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 {
@ -94,6 +96,10 @@ func mastersSchemaMake() map[string]*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{
@ -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": {

@ -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)
@ -520,6 +519,7 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{
} }
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)
@ -527,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)
@ -631,6 +633,12 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
//ForceNew: true, //ForceNew: true,
Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.", Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.",
}, },
"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": {
@ -686,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,
@ -699,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,

@ -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 {
@ -537,6 +536,7 @@ func resourceK8sCPUpdate(ctx context.Context, d *schema.ResourceData, m interfac
} }
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)
@ -545,12 +545,14 @@ func resourceK8sCPDelete(ctx context.Context, d *schema.ResourceData, m interfac
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)
@ -600,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": {
@ -683,7 +689,6 @@ 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,
@ -771,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,

@ -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),
} }
@ -264,7 +265,11 @@ func resourceK8sWgSchemaMake() map[string]*schema.Schema {
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.",
}, },

@ -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)),
@ -142,7 +142,7 @@ func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData,
func utilityK8sWgCloudInitCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { func utilityK8sWgCloudInitCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := k8s.GetWorkerNodesMetaDataRequest{ req := k8s.GetWorkerNodesMetaDataRequest{
K8SID: uint64(d.Get("k8s_id").(int)), K8SID: uint64(d.Get("k8s_id").(int)),
WorkersGroupID: uint64(d.Get("wg_id").(int)), WorkersGroupID: uint64(d.Get("wg_id").(int)),
} }

@ -615,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,
}, },
@ -720,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,

@ -124,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,
}, },
@ -233,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,

@ -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"
@ -163,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,
@ -188,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,
@ -237,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)
} }
@ -265,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))
@ -289,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.
// //
@ -308,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)
@ -323,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
} }
@ -344,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)
@ -537,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)
@ -563,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)

@ -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)
@ -296,11 +301,13 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
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 {
cleanup = true cleanup = true
return diag.FromErr(err) return diag.FromErr(err)
} }
ctx = context.WithValue(ctx, DiskKey(strconv.Itoa(int(diskId))), diskConv["permanently"].(bool))
} }
} }
} }
@ -580,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)
} }
@ -753,12 +760,18 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
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
@ -846,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{})
@ -877,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)
} }
} }
@ -951,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
@ -976,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") {
@ -1499,7 +1541,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
return append(warnings.Get(), resourceComputeRead(ctx, d, m)...) 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{})
@ -1511,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
} }
} }
@ -1736,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,
@ -1788,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",
}, },
}, },
@ -1824,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",
}, },
}, },
@ -1997,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,
@ -2135,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,

@ -234,7 +234,7 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
} }
} }
needStart := false needStart:= false
if d.Get("network").(*schema.Set).Len() == 1 || old_set.(*schema.Set).Len() < 1 { if d.Get("network").(*schema.Set).Len() == 1 || old_set.(*schema.Set).Len() < 1 {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64) computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
@ -272,7 +272,7 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
if needStart { if needStart {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64) computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
if numErr, err := utilityComputeStart(ctx, computeId, m); err != nil { if numErr, err := utilityComputeStart(ctx, computeId, m); err != nil {
apiErrCount += numErr apiErrCount+= numErr
lastSavedError = err lastSavedError = err
} }
} }

@ -1,71 +1,71 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package lb package lb
import ( import (
"context" "context"
"strconv" "strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
) )
func 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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.FormatUint(lb.ID, 10)) d.SetId(strconv.FormatUint(lb.ID, 10))
flattenLB(d, lb) flattenLB(d, lb)
return nil return nil
} }
func DataSourceLB() *schema.Resource { func DataSourceLB() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceLBRead, ReadContext: dataSourceLBRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dsLBSchemaMake(), Schema: dsLBSchemaMake(),
} }
} }

@ -1,71 +1,71 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package lb package lb
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenLBList(lbList)) d.Set("items", flattenLBList(lbList))
d.Set("entry_count", lbList.EntryCount) d.Set("entry_count", lbList.EntryCount)
return nil return nil
} }
func DataSourceLBList() *schema.Resource { func DataSourceLBList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceLBListRead, ReadContext: dataSourceLBListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dsLBListSchemaMake(), Schema: dsLBListSchemaMake(),
} }
} }

@ -1,71 +1,71 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package lb package lb
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenLBList(lbList)) d.Set("items", flattenLBList(lbList))
d.Set("entry_count", lbList.EntryCount) d.Set("entry_count", lbList.EntryCount)
return nil return nil
} }
func DataSourceLBListDeleted() *schema.Resource { func DataSourceLBListDeleted() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceLBListDeletedRead, ReadContext: dataSourceLBListDeletedRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dsLBListDeletedSchemaMake(), Schema: dsLBListDeletedSchemaMake(),
} }
} }

@ -78,6 +78,12 @@ func lbResourceSchemaMake() map[string]*schema.Schema {
Type: schema.TypeBool, Type: schema.TypeBool,
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,
@ -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,

@ -1,467 +1,470 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package lb package lb
import ( import (
"context" "context"
"strconv" "strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"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/dc"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
) )
func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBCreate") log.Debugf("resourceLBCreate")
haveRGID, err := existRGID(ctx, d, m) haveRGID, err := existRGID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveRGID { if !haveRGID {
return diag.Errorf("resourceLBCreate: can't create LB because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) return diag.Errorf("resourceLBCreate: can't create LB because RGID %d is not allowed or does not exist", d.Get("rg_id").(int))
} }
haveExtNetID, err := existExtNetID(ctx, d, m) haveExtNetID, err := existExtNetID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveExtNetID { if !haveExtNetID {
return diag.Errorf("resourceLBCreate: can't create LB because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int)) return diag.Errorf("resourceLBCreate: can't create LB because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int))
} }
haveVins, err := existViNSID(ctx, d, m) haveVins, err := existViNSID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveVins { if !haveVins {
return diag.Errorf("resourceLBCreate: can't create LB because ViNSID %d is not allowed or does not exist", d.Get("vins_id").(int)) return diag.Errorf("resourceLBCreate: can't create LB because ViNSID %d is not allowed or does not exist", d.Get("vins_id").(int))
} }
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := lb.CreateRequest{ req := lb.CreateRequest{
Name: d.Get("name").(string), Name: d.Get("name").(string),
RGID: uint64(d.Get("rg_id").(int)), RGID: uint64(d.Get("rg_id").(int)),
ExtNetID: uint64(d.Get("extnet_id").(int)), ExtNetID: uint64(d.Get("extnet_id").(int)),
VINSID: uint64(d.Get("vins_id").(int)), VINSID: uint64(d.Get("vins_id").(int)),
Start: d.Get("start").(bool), Start: d.Get("start").(bool),
} }
if desc, ok := d.GetOk("desc"); ok { if desc, ok := d.GetOk("desc"); ok {
req.Description = desc.(string) req.Description = desc.(string)
} }
if haMode, ok := d.GetOk("ha_mode"); ok { if haMode, ok := d.GetOk("ha_mode"); ok {
req.HighlyAvailable = haMode.(bool) req.HighlyAvailable = haMode.(bool)
} }
lbId, err := c.CloudAPI().LB().Create(ctx, req) lbId, err := c.CloudAPI().LB().Create(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.FormatUint(lbId, 10)) d.SetId(strconv.FormatUint(lbId, 10))
d.Set("lb_id", lbId) d.Set("lb_id", lbId)
w := dc.Warnings{} w := dc.Warnings{}
if enable, ok := d.GetOk("enable"); ok { if enable, ok := d.GetOk("enable"); ok {
req := lb.DisableEnableRequest{ req := lb.DisableEnableRequest{
LBID: lbId, LBID: lbId,
} }
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 {
w.Add(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 {
w.Add(err) w.Add(err)
} }
} }
if start, ok := d.GetOk("start"); ok && enable.(bool) { if start, ok := d.GetOk("start"); ok && enable.(bool) {
if start.(bool) { if start.(bool) {
req := lb.StartRequest{LBID: lbId} req := lb.StartRequest{LBID: lbId}
_, err := c.CloudAPI().LB().Start(ctx, req) _, err := c.CloudAPI().LB().Start(ctx, req)
if err != nil { if err != nil {
w.Add(err) w.Add(err)
} }
} else { } else {
req := lb.StopRequest{LBID: lbId} req := lb.StopRequest{LBID: lbId}
_, err := c.CloudAPI().LB().Stop(ctx, req) _, err := c.CloudAPI().LB().Stop(ctx, req)
if err != nil { if err != nil {
w.Add(err) w.Add(err)
} }
} }
} }
} }
return append(w.Get(), 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 {
log.Debugf("resourceLBRead") log.Debugf("resourceLBRead")
// c := m.(*controller.ControllerCfg) // c := m.(*controller.ControllerCfg)
lbRec, err := utilityLBCheckPresence(ctx, d, m) lbRec, err := utilityLBCheckPresence(ctx, d, m)
if lbRec == nil { if lbRec == nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
hasChanged := false hasChanged := false
switch lbRec.Status { switch lbRec.Status {
case status.Modeled: case status.Modeled:
return diag.Errorf("The LB is in status: %s, please, contact support for more information", lbRec.Status) return diag.Errorf("The LB is in status: %s, please, contact support for more information", lbRec.Status)
case status.Creating: case status.Creating:
case status.Created: case status.Created:
case status.Deleting: case status.Deleting:
case status.Deleted: case status.Deleted:
// lbId, _ := strconv.ParseUint(d.Id(), 10, 64) // lbId, _ := strconv.ParseUint(d.Id(), 10, 64)
// restoreReq := lb.RestoreRequest{LBID: lbId} // restoreReq := lb.RestoreRequest{LBID: lbId}
// enableReq := lb.DisableEnableRequest{LBID: lbId} // enableReq := lb.DisableEnableRequest{LBID: lbId}
// _, err := c.CloudAPI().LB().Restore(ctx, restoreReq) // _, err := c.CloudAPI().LB().Restore(ctx, restoreReq)
// if err != nil { // if err != nil {
// return diag.FromErr(err) // return diag.FromErr(err)
// } // }
// _, err = c.CloudAPI().LB().Enable(ctx, enableReq) // _, err = c.CloudAPI().LB().Enable(ctx, enableReq)
// if err != nil { // if err != nil {
// return diag.FromErr(err) // return diag.FromErr(err)
// } // }
// hasChanged = true // hasChanged = true
case status.Destroying: case status.Destroying:
return diag.Errorf("The LB is in progress with status: %s", lbRec.Status) return diag.Errorf("The LB is in progress with status: %s", lbRec.Status)
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed") return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceLBCreate(ctx, d, m) // return resourceLBCreate(ctx, d, m)
case status.Enabled: case status.Enabled:
case status.Enabling: case status.Enabling:
case status.Disabling: case status.Disabling:
case status.Disabled: case status.Disabled:
log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lbRec.Status) log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lbRec.Status)
case status.Restoring: case status.Restoring:
} }
if hasChanged { if hasChanged {
lbRec, err = utilityLBCheckPresence(ctx, d, m) lbRec, err = utilityLBCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
} }
flattenResourceLB(d, lbRec) flattenResourceLB(d, lbRec)
return nil return nil
} }
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")
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
lbId, _ := strconv.ParseUint(d.Id(), 10, 64) lbId, _ := strconv.ParseUint(d.Id(), 10, 64)
req := lb.DeleteRequest{ req := lb.DeleteRequest{
LBID: lbId, 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)
} }
d.SetId("") d.SetId("")
return nil return nil
} }
func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBUpdate") log.Debugf("resourceLBUpdate")
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
haveRGID, err := existRGID(ctx, d, m) haveRGID, err := existRGID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveRGID { if !haveRGID {
return diag.Errorf("resourceLBUpdate: can't update LB because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) return diag.Errorf("resourceLBUpdate: can't update LB because RGID %d is not allowed or does not exist", d.Get("rg_id").(int))
} }
haveExtNetID, err := existExtNetID(ctx, d, m) haveExtNetID, err := existExtNetID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveExtNetID { if !haveExtNetID {
return diag.Errorf("resourceLBUpdate: can't update LB because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int)) return diag.Errorf("resourceLBUpdate: can't update LB because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int))
} }
haveVins, err := existViNSID(ctx, d, m) haveVins, err := existViNSID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveVins { if !haveVins {
return diag.Errorf("resourceLBUpdate: can't update LB because ViNSID %d is not allowed or does not exist", d.Get("vins_id").(int)) return diag.Errorf("resourceLBUpdate: can't update LB because ViNSID %d is not allowed or does not exist", d.Get("vins_id").(int))
} }
lbRec, err := utilityLBCheckPresence(ctx, d, m) lbRec, err := utilityLBCheckPresence(ctx, d, m)
if lbRec == nil { if lbRec == nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
hasChanged := false hasChanged := false
switch lbRec.Status { switch lbRec.Status {
case status.Modeled: case status.Modeled:
return diag.Errorf("The LB is in status: %s, please, contact support for more information", lbRec.Status) return diag.Errorf("The LB is in status: %s, please, contact support for more information", lbRec.Status)
case status.Creating: case status.Creating:
case status.Created: case status.Created:
case status.Deleting: case status.Deleting:
case status.Deleted: case status.Deleted:
if restore, ok := d.GetOk("restore"); ok && restore.(bool) { if restore, ok := d.GetOk("restore"); ok && restore.(bool) {
restoreReq := lb.RestoreRequest{LBID: lbRec.ID} restoreReq := lb.RestoreRequest{LBID: lbRec.ID}
_, 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)
} }
} }
if enable, ok := d.GetOk("enable"); ok { if enable, ok := d.GetOk("enable"); ok {
req := lb.DisableEnableRequest{ req := lb.DisableEnableRequest{
LBID: lbRec.ID, LBID: lbRec.ID,
} }
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) return diag.FromErr(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) return diag.FromErr(err)
} }
} }
if start, ok := d.GetOk("start"); ok && enable.(bool) { if start, ok := d.GetOk("start"); ok && enable.(bool) {
if start.(bool) { if start.(bool) {
req := lb.StartRequest{LBID: lbRec.ID} req := lb.StartRequest{LBID: lbRec.ID}
_, err := c.CloudAPI().LB().Start(ctx, req) _, err := c.CloudAPI().LB().Start(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
} else { } else {
req := lb.StopRequest{LBID: lbRec.ID} req := lb.StopRequest{LBID: lbRec.ID}
_, err := c.CloudAPI().LB().Stop(ctx, req) _, err := c.CloudAPI().LB().Stop(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
} }
} }
} }
hasChanged = true hasChanged = true
case status.Destroying: case status.Destroying:
return diag.Errorf("The LB is in progress with status: %s", lbRec.Status) return diag.Errorf("The LB is in progress with status: %s", lbRec.Status)
case status.Destroyed: case status.Destroyed:
d.SetId("") d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed") return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceLBCreate(ctx, d, m) // return resourceLBCreate(ctx, d, m)
case status.Enabled: case status.Enabled:
case status.Enabling: case status.Enabling:
case status.Disabling: case status.Disabling:
case status.Disabled: case status.Disabled:
log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lbRec.Status) log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lbRec.Status)
case status.Restoring: case status.Restoring:
} }
if hasChanged { if hasChanged {
_, err = utilityLBCheckPresence(ctx, d, m) _, err = utilityLBCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
} }
if d.HasChange("ha_mode") { 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)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
} }
} }
if d.HasChange("enable") { if d.HasChange("enable") {
enable := d.Get("enable").(bool) enable := d.Get("enable").(bool)
req := lb.DisableEnableRequest{ req := lb.DisableEnableRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
} }
if enable { if enable {
_, err := c.CloudAPI().LB().Enable(ctx, req) _, err := c.CloudAPI().LB().Enable(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(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) return diag.FromErr(err)
} }
} }
} }
if d.HasChange("start") { if d.HasChange("start") {
start := d.Get("start").(bool) start := d.Get("start").(bool)
lbId := uint64(d.Get("lb_id").(int)) lbId := uint64(d.Get("lb_id").(int))
if start { if start {
req := lb.StartRequest{LBID: lbId} req := lb.StartRequest{LBID: lbId}
_, err := c.CloudAPI().LB().Start(ctx, req) _, err := c.CloudAPI().LB().Start(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
} else { } else {
req := lb.StopRequest{LBID: lbId} req := lb.StopRequest{LBID: lbId}
_, err := c.CloudAPI().LB().Stop(ctx, req) _, err := c.CloudAPI().LB().Stop(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
} }
} }
if d.HasChange("desc") { if d.HasChange("desc") {
req := lb.UpdateRequest{ req := lb.UpdateRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
Description: d.Get("desc").(string), Description: d.Get("desc").(string),
} }
_, err := c.CloudAPI().LB().Update(ctx, req) _, err := c.CloudAPI().LB().Update(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
} }
if d.HasChange("restart") { if d.HasChange("restart") {
restart := d.Get("restart").(bool) restart := d.Get("restart").(bool)
if restart { if restart {
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 {
_, err := c.CloudAPI().LB().Restart(ctx, req) req.Safe = safe.(bool)
if err != nil { }
return diag.FromErr(err)
} _, err := c.CloudAPI().LB().Restart(ctx, req)
} if err != nil {
} return diag.FromErr(err)
}
if d.HasChange("restore") { }
restore := d.Get("restore").(bool) }
if restore {
req := lb.RestoreRequest{ if d.HasChange("restore") {
LBID: uint64(d.Get("lb_id").(int)), restore := d.Get("restore").(bool)
} if restore {
req := lb.RestoreRequest{
_, err := c.CloudAPI().LB().Restore(ctx, req) LBID: uint64(d.Get("lb_id").(int)),
if err != nil { }
return diag.FromErr(err)
} _, err := c.CloudAPI().LB().Restore(ctx, req)
} if err != nil {
} return diag.FromErr(err)
}
if d.HasChange("config_reset") { }
cfgReset := d.Get("config_reset").(bool) }
if cfgReset {
req := lb.ConfigResetRequest{ if d.HasChange("config_reset") {
LBID: uint64(d.Get("lb_id").(int)), cfgReset := d.Get("config_reset").(bool)
} if cfgReset {
req := lb.ConfigResetRequest{
_, err := c.CloudAPI().LB().ConfigReset(ctx, req) LBID: uint64(d.Get("lb_id").(int)),
if err != nil { }
return diag.FromErr(err)
} _, err := c.CloudAPI().LB().ConfigReset(ctx, req)
} if err != nil {
} return diag.FromErr(err)
}
return resourceLBRead(ctx, d, m) }
} }
func ResourceLB() *schema.Resource { return resourceLBRead(ctx, d, m)
return &schema.Resource{ }
SchemaVersion: 1,
func ResourceLB() *schema.Resource {
CreateContext: resourceLBCreate, return &schema.Resource{
ReadContext: resourceLBRead, SchemaVersion: 1,
UpdateContext: resourceLBUpdate,
DeleteContext: resourceLBDelete, CreateContext: resourceLBCreate,
ReadContext: resourceLBRead,
Importer: &schema.ResourceImporter{ UpdateContext: resourceLBUpdate,
StateContext: schema.ImportStatePassthroughContext, DeleteContext: resourceLBDelete,
},
Importer: &schema.ResourceImporter{
Timeouts: &schema.ResourceTimeout{ StateContext: schema.ImportStatePassthroughContext,
Create: &constants.Timeout600s, },
Read: &constants.Timeout300s,
Update: &constants.Timeout300s, Timeouts: &schema.ResourceTimeout{
Delete: &constants.Timeout300s, Create: &constants.Timeout600s,
Default: &constants.Timeout300s, Read: &constants.Timeout300s,
}, Update: &constants.Timeout300s,
Delete: &constants.Timeout300s,
Schema: lbResourceSchemaMake(), Default: &constants.Timeout300s,
} },
}
Schema: lbResourceSchemaMake(),
}
}

@ -1,379 +1,379 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package lb package lb
import ( import (
"context" "context"
"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" "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/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"
) )
func resourceLBBackendCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBBackendCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBBackendCreate") log.Debugf("resourceLBBackendCreate")
haveLBID, err := existLBID(ctx, d, m) haveLBID, err := existLBID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveLBID { if !haveLBID {
return diag.Errorf("resourceLBBackendCreate: can't create LB backend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) return diag.Errorf("resourceLBBackendCreate: can't create LB backend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
} }
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := lb.BackendCreateRequest{} req := lb.BackendCreateRequest{}
req.BackendName = d.Get("name").(string) req.BackendName = d.Get("name").(string)
req.LBID = uint64(d.Get("lb_id").(int)) req.LBID = uint64(d.Get("lb_id").(int))
if algorithm, ok := d.GetOk("algorithm"); ok { if algorithm, ok := d.GetOk("algorithm"); ok {
req.Algorithm = algorithm.(string) req.Algorithm = algorithm.(string)
} }
if inter, ok := d.GetOk("inter"); ok { if inter, ok := d.GetOk("inter"); ok {
req.Inter = uint64(inter.(int)) req.Inter = uint64(inter.(int))
} }
if downinter, ok := d.GetOk("downinter"); ok { if downinter, ok := d.GetOk("downinter"); ok {
req.DownInter = uint64(downinter.(int)) req.DownInter = uint64(downinter.(int))
} }
if rise, ok := d.GetOk("rise"); ok { if rise, ok := d.GetOk("rise"); ok {
req.Rise = uint64(rise.(int)) req.Rise = uint64(rise.(int))
} }
if fall, ok := d.GetOk("fall"); ok { if fall, ok := d.GetOk("fall"); ok {
req.Fall = uint64(fall.(int)) req.Fall = uint64(fall.(int))
} }
if slowstart, ok := d.GetOk("slowstart"); ok { if slowstart, ok := d.GetOk("slowstart"); ok {
req.SlowStart = uint64(slowstart.(int)) req.SlowStart = uint64(slowstart.(int))
} }
if maxconn, ok := d.GetOk("maxconn"); ok { if maxconn, ok := d.GetOk("maxconn"); ok {
req.MaxConn = uint64(maxconn.(int)) req.MaxConn = uint64(maxconn.(int))
} }
if maxqueue, ok := d.GetOk("maxqueue"); ok { if maxqueue, ok := d.GetOk("maxqueue"); ok {
req.MaxQueue = uint64(maxqueue.(int)) req.MaxQueue = uint64(maxqueue.(int))
} }
if weight, ok := d.GetOk("weight"); ok { if weight, ok := d.GetOk("weight"); ok {
req.Weight = uint64(weight.(int)) req.Weight = uint64(weight.(int))
} }
_, err = c.CloudAPI().LB().BackendCreate(ctx, req) _, err = c.CloudAPI().LB().BackendCreate(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("name").(string)) d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("name").(string))
_, err = utilityLBBackendCheckPresence(ctx, d, m) _, err = utilityLBBackendCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
return resourceLBBackendRead(ctx, d, m) return resourceLBBackendRead(ctx, d, m)
} }
func resourceLBBackendRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBBackendRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBBackendRead") log.Debugf("resourceLBBackendRead")
b, err := utilityLBBackendCheckPresence(ctx, d, m) b, err := utilityLBBackendCheckPresence(ctx, d, m)
if b == nil { if b == nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32)
flattenResourceLBBackend(d, b, lbId) flattenResourceLBBackend(d, b, lbId)
return nil return nil
} }
func resourceLBBackendDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBBackendDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBBackendDelete") log.Debugf("resourceLBBackendDelete")
_, err := utilityLBBackendCheckPresence(ctx, d, m) _, err := utilityLBBackendCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := lb.BackendDeleteRequest{ req := lb.BackendDeleteRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
BackendName: d.Get("name").(string), BackendName: d.Get("name").(string),
} }
_, err = c.CloudAPI().LB().BackendDelete(ctx, req) _, err = c.CloudAPI().LB().BackendDelete(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId("") d.SetId("")
return nil return nil
} }
func resourceLBBackendUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBBackendUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBBackendEdit") log.Debugf("resourceLBBackendEdit")
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
haveLBID, err := existLBID(ctx, d, m) haveLBID, err := existLBID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveLBID { if !haveLBID {
return diag.Errorf("resourceLBBackendUpdate: can't update LB backend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) return diag.Errorf("resourceLBBackendUpdate: can't update LB backend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
} }
req := lb.BackendUpdateRequest{ req := lb.BackendUpdateRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
BackendName: d.Get("name").(string), BackendName: d.Get("name").(string),
} }
if d.HasChange("algorithm") { if d.HasChange("algorithm") {
req.Algorithm = d.Get("algorithm").(string) req.Algorithm = d.Get("algorithm").(string)
} }
if d.HasChange("inter") { if d.HasChange("inter") {
req.Inter = uint64(d.Get("inter").(int)) req.Inter = uint64(d.Get("inter").(int))
} }
if d.HasChange("downinter") { if d.HasChange("downinter") {
req.DownInter = uint64(d.Get("downinter").(int)) req.DownInter = uint64(d.Get("downinter").(int))
} }
if d.HasChange("rise") { if d.HasChange("rise") {
req.Rise = uint64(d.Get("rise").(int)) req.Rise = uint64(d.Get("rise").(int))
} }
if d.HasChange("fall") { if d.HasChange("fall") {
req.Fall = uint64(d.Get("fall").(int)) req.Fall = uint64(d.Get("fall").(int))
} }
if d.HasChange("slowstart") { if d.HasChange("slowstart") {
req.SlowStart = uint64(d.Get("slowstart").(int)) req.SlowStart = uint64(d.Get("slowstart").(int))
} }
if d.HasChange("maxconn") { if d.HasChange("maxconn") {
req.MaxConn = uint64(d.Get("maxconn").(int)) req.MaxConn = uint64(d.Get("maxconn").(int))
} }
if d.HasChange("maxqueue") { if d.HasChange("maxqueue") {
req.MaxQueue = uint64(d.Get("maxqueue").(int)) req.MaxQueue = uint64(d.Get("maxqueue").(int))
} }
if d.HasChange("weight") { if d.HasChange("weight") {
req.Weight = uint64(d.Get("weight").(int)) req.Weight = uint64(d.Get("weight").(int))
} }
_, err = c.CloudAPI().LB().BackendUpdate(ctx, req) _, err = c.CloudAPI().LB().BackendUpdate(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
return resourceLBBackendRead(ctx, d, m) return resourceLBBackendRead(ctx, d, m)
} }
func ResourceLBBackend() *schema.Resource { func ResourceLBBackend() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
CreateContext: resourceLBBackendCreate, CreateContext: resourceLBBackendCreate,
ReadContext: resourceLBBackendRead, ReadContext: resourceLBBackendRead,
UpdateContext: resourceLBBackendUpdate, UpdateContext: resourceLBBackendUpdate,
DeleteContext: resourceLBBackendDelete, DeleteContext: resourceLBBackendDelete,
Importer: &schema.ResourceImporter{ Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext, StateContext: schema.ImportStatePassthroughContext,
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout600s, Create: &constants.Timeout600s,
Read: &constants.Timeout300s, Read: &constants.Timeout300s,
Update: &constants.Timeout300s, Update: &constants.Timeout300s,
Delete: &constants.Timeout300s, Delete: &constants.Timeout300s,
Default: &constants.Timeout300s, Default: &constants.Timeout300s,
}, },
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"lb_id": { "lb_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
Description: "ID of the LB instance to backendCreate", Description: "ID of the LB instance to backendCreate",
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
Description: "Must be unique among all backends of this LB - name of the new backend to create", Description: "Must be unique among all backends of this LB - name of the new backend to create",
}, },
"algorithm": { "algorithm": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
ValidateFunc: validation.StringInSlice([]string{"roundrobin", "static-rr", "leastconn"}, false), ValidateFunc: validation.StringInSlice([]string{"roundrobin", "static-rr", "leastconn"}, false),
}, },
"guid": { "guid": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"downinter": { "downinter": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"fall": { "fall": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"inter": { "inter": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"maxconn": { "maxconn": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"maxqueue": { "maxqueue": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"rise": { "rise": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"slowstart": { "slowstart": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"weight": { "weight": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"servers": { "servers": {
Type: schema.TypeList, Type: schema.TypeList,
Optional: true, Optional: true,
Computed: true, Computed: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"address": { "address": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"check": { "check": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"guid": { "guid": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"port": { "port": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"server_settings": { "server_settings": {
Type: schema.TypeList, Type: schema.TypeList,
Optional: true, Optional: true,
Computed: true, Computed: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"downinter": { "downinter": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"fall": { "fall": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"guid": { "guid": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"inter": { "inter": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"maxconn": { "maxconn": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"maxqueue": { "maxqueue": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"rise": { "rise": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"slowstart": { "slowstart": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"weight": { "weight": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
}, },
}, },
}, },
}, },
}, },
}, },
}, },
} }
} }

@ -1,320 +1,320 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package lb package lb
import ( import (
"context" "context"
"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" "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/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"
) )
func resourceLBBackendServerCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBBackendServerCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBBackendServerCreate") log.Debugf("resourceLBBackendServerCreate")
haveLBID, err := existLBID(ctx, d, m) haveLBID, err := existLBID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveLBID { if !haveLBID {
return diag.Errorf("resourceLBBackendServerCreate: can't create LB backend server because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) return diag.Errorf("resourceLBBackendServerCreate: can't create LB backend server because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
} }
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := lb.BackendServerAddRequest{ req := lb.BackendServerAddRequest{
BackendName: d.Get("backend_name").(string), BackendName: d.Get("backend_name").(string),
ServerName: d.Get("name").(string), ServerName: d.Get("name").(string),
Address: d.Get("address").(string), Address: d.Get("address").(string),
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
Port: uint64(d.Get("port").(int)), Port: uint64(d.Get("port").(int)),
} }
if check, ok := d.GetOk("check"); ok { if check, ok := d.GetOk("check"); ok {
req.Check = check.(string) req.Check = check.(string)
} }
if inter, ok := d.GetOk("inter"); ok { if inter, ok := d.GetOk("inter"); ok {
req.Inter = uint64(inter.(int)) req.Inter = uint64(inter.(int))
} }
if downinter, ok := d.GetOk("downinter"); ok { if downinter, ok := d.GetOk("downinter"); ok {
req.DownInter = uint64(downinter.(int)) req.DownInter = uint64(downinter.(int))
} }
if rise, ok := d.GetOk("rise"); ok { if rise, ok := d.GetOk("rise"); ok {
req.Rise = uint64(rise.(int)) req.Rise = uint64(rise.(int))
} }
if fall, ok := d.GetOk("fall"); ok { if fall, ok := d.GetOk("fall"); ok {
req.Fall = uint64(fall.(int)) req.Fall = uint64(fall.(int))
} }
if slowstart, ok := d.GetOk("slowstart"); ok { if slowstart, ok := d.GetOk("slowstart"); ok {
req.SlowStart = uint64(slowstart.(int)) req.SlowStart = uint64(slowstart.(int))
} }
if maxconn, ok := d.GetOk("maxconn"); ok { if maxconn, ok := d.GetOk("maxconn"); ok {
req.MaxConn = uint64(maxconn.(int)) req.MaxConn = uint64(maxconn.(int))
} }
if maxqueue, ok := d.GetOk("maxqueue"); ok { if maxqueue, ok := d.GetOk("maxqueue"); ok {
req.MaxQueue = uint64(maxqueue.(int)) req.MaxQueue = uint64(maxqueue.(int))
} }
if weight, ok := d.GetOk("weight"); ok { if weight, ok := d.GetOk("weight"); ok {
req.Weight = uint64(weight.(int)) req.Weight = uint64(weight.(int))
} }
_, err = c.CloudAPI().LB().BackendServerAdd(ctx, req) _, err = c.CloudAPI().LB().BackendServerAdd(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("backend_name").(string) + "#" + d.Get("name").(string)) d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("backend_name").(string) + "#" + d.Get("name").(string))
_, err = utilityLBBackendServerCheckPresence(ctx, d, m) _, err = utilityLBBackendServerCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
return resourceLBBackendServerRead(ctx, d, m) return resourceLBBackendServerRead(ctx, d, m)
} }
func resourceLBBackendServerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBBackendServerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBBackendServerRead") log.Debugf("resourceLBBackendServerRead")
s, err := utilityLBBackendServerCheckPresence(ctx, d, m) s, err := utilityLBBackendServerCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32)
backendName := strings.Split(d.Id(), "#")[1] backendName := strings.Split(d.Id(), "#")[1]
flattenResourceLBBackendServer(d, s, lbId, backendName) flattenResourceLBBackendServer(d, s, lbId, backendName)
return nil return nil
} }
func resourceLBBackendServerDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBBackendServerDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBBackendServerDelete") log.Debugf("resourceLBBackendServerDelete")
_, err := utilityLBBackendServerCheckPresence(ctx, d, m) _, err := utilityLBBackendServerCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := lb.BackendServerDeleteRequest{ req := lb.BackendServerDeleteRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
BackendName: d.Get("backend_name").(string), BackendName: d.Get("backend_name").(string),
ServerName: d.Get("name").(string), ServerName: d.Get("name").(string),
} }
_, err = c.CloudAPI().LB().BackendServerDelete(ctx, req) _, err = c.CloudAPI().LB().BackendServerDelete(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId("") d.SetId("")
return nil return nil
} }
func resourceLBBackendServerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBBackendServerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBBackendServerEdit") log.Debugf("resourceLBBackendServerEdit")
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
haveLBID, err := existLBID(ctx, d, m) haveLBID, err := existLBID(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveLBID { if !haveLBID {
return diag.Errorf("resourceLBBackendServerUpdate: can't update LB backend server because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) return diag.Errorf("resourceLBBackendServerUpdate: can't update LB backend server because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
} }
req := lb.BackendServerUpdateRequest{ req := lb.BackendServerUpdateRequest{
BackendName: d.Get("backend_name").(string), BackendName: d.Get("backend_name").(string),
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
ServerName: d.Get("name").(string), ServerName: d.Get("name").(string),
Address: d.Get("address").(string), Address: d.Get("address").(string),
Port: uint64(d.Get("port").(int)), Port: uint64(d.Get("port").(int)),
} }
if d.HasChange("check") { if d.HasChange("check") {
req.Check = d.Get("check").(string) req.Check = d.Get("check").(string)
} }
if d.HasChange("inter") { if d.HasChange("inter") {
req.Inter = uint64(d.Get("inter").(int)) req.Inter = uint64(d.Get("inter").(int))
} }
if d.HasChange("downinter") { if d.HasChange("downinter") {
req.DownInter = uint64(d.Get("downinter").(int)) req.DownInter = uint64(d.Get("downinter").(int))
} }
if d.HasChange("rise") { if d.HasChange("rise") {
req.Rise = uint64(d.Get("rise").(int)) req.Rise = uint64(d.Get("rise").(int))
} }
if d.HasChange("fall") { if d.HasChange("fall") {
req.Fall = uint64(d.Get("fall").(int)) req.Fall = uint64(d.Get("fall").(int))
} }
if d.HasChange("slowstart") { if d.HasChange("slowstart") {
req.SlowStart = uint64(d.Get("slowstart").(int)) req.SlowStart = uint64(d.Get("slowstart").(int))
} }
if d.HasChange("maxconn") { if d.HasChange("maxconn") {
req.MaxConn = uint64(d.Get("maxconn").(int)) req.MaxConn = uint64(d.Get("maxconn").(int))
} }
if d.HasChange("maxqueue") { if d.HasChange("maxqueue") {
req.MaxQueue = uint64(d.Get("maxqueue").(int)) req.MaxQueue = uint64(d.Get("maxqueue").(int))
} }
if d.HasChange("weight") { if d.HasChange("weight") {
req.Weight = uint64(d.Get("weight").(int)) req.Weight = uint64(d.Get("weight").(int))
} }
_, err = c.CloudAPI().LB().BackendServerUpdate(ctx, req) _, err = c.CloudAPI().LB().BackendServerUpdate(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
//TODO: перенести servers сюда //TODO: перенести servers сюда
return resourceLBBackendServerRead(ctx, d, m) return resourceLBBackendServerRead(ctx, d, m)
} }
func ResourceLBBackendServer() *schema.Resource { func ResourceLBBackendServer() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
CreateContext: resourceLBBackendServerCreate, CreateContext: resourceLBBackendServerCreate,
ReadContext: resourceLBBackendServerRead, ReadContext: resourceLBBackendServerRead,
UpdateContext: resourceLBBackendServerUpdate, UpdateContext: resourceLBBackendServerUpdate,
DeleteContext: resourceLBBackendServerDelete, DeleteContext: resourceLBBackendServerDelete,
Importer: &schema.ResourceImporter{ Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext, StateContext: schema.ImportStatePassthroughContext,
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout600s, Create: &constants.Timeout600s,
Read: &constants.Timeout300s, Read: &constants.Timeout300s,
Update: &constants.Timeout300s, Update: &constants.Timeout300s,
Delete: &constants.Timeout300s, Delete: &constants.Timeout300s,
Default: &constants.Timeout300s, Default: &constants.Timeout300s,
}, },
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"lb_id": { "lb_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
Description: "ID of the LB instance to backendCreate", Description: "ID of the LB instance to backendCreate",
}, },
"backend_name": { "backend_name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
Description: "Must be unique among all backends of this LB - name of the new backend to create", Description: "Must be unique among all backends of this LB - name of the new backend to create",
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
Description: "Must be unique among all servers defined for this backend - name of the server definition to add.", Description: "Must be unique among all servers defined for this backend - name of the server definition to add.",
}, },
"address": { "address": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
Description: "IP address of the server.", Description: "IP address of the server.",
}, },
"port": { "port": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
Description: "Port number on the server", Description: "Port number on the server",
}, },
"check": { "check": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
ValidateFunc: validation.StringInSlice([]string{"disabled", "enabled"}, false), ValidateFunc: validation.StringInSlice([]string{"disabled", "enabled"}, false),
Description: "set to disabled if this server should be used regardless of its state.", Description: "set to disabled if this server should be used regardless of its state.",
}, },
"guid": { "guid": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"downinter": { "downinter": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"fall": { "fall": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"inter": { "inter": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"maxconn": { "maxconn": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"maxqueue": { "maxqueue": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"rise": { "rise": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"slowstart": { "slowstart": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"weight": { "weight": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
}, },
} }
} }

@ -1,195 +1,195 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package lb package lb
import ( import (
"context" "context"
"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"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"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"
) )
func resourceLBFrontendCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBFrontendCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBFrontendCreate") log.Debugf("resourceLBFrontendCreate")
haveLBID, err := existLBID(ctx, d, m) haveLBID, err := existLBID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveLBID { if !haveLBID {
return diag.Errorf("resourceLBFrontendCreate: can't create LB frontend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) return diag.Errorf("resourceLBFrontendCreate: can't create LB frontend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
} }
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := lb.FrontendCreateRequest{ req := lb.FrontendCreateRequest{
BackendName: d.Get("backend_name").(string), BackendName: d.Get("backend_name").(string),
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
FrontendName: d.Get("name").(string), FrontendName: d.Get("name").(string),
} }
_, err = c.CloudAPI().LB().FrontendCreate(ctx, req) _, err = c.CloudAPI().LB().FrontendCreate(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("name").(string)) d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("name").(string))
_, err = utilityLBFrontendCheckPresence(ctx, d, m) _, err = utilityLBFrontendCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
return resourceLBFrontendRead(ctx, d, m) return resourceLBFrontendRead(ctx, d, m)
} }
func resourceLBFrontendRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBFrontendRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBFrontendRead") log.Debugf("resourceLBFrontendRead")
f, err := utilityLBFrontendCheckPresence(ctx, d, m) f, err := utilityLBFrontendCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32)
flattenLBFrontend(d, f, lbId) flattenLBFrontend(d, f, lbId)
return nil return nil
} }
func resourceLBFrontendDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBFrontendDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBFrontendDelete") log.Debugf("resourceLBFrontendDelete")
_, err := utilityLBFrontendCheckPresence(ctx, d, m) _, err := utilityLBFrontendCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := lb.FrontendDeleteRequest{ req := lb.FrontendDeleteRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
FrontendName: d.Get("name").(string), FrontendName: d.Get("name").(string),
} }
_, err = c.CloudAPI().LB().FrontendDelete(ctx, req) _, err = c.CloudAPI().LB().FrontendDelete(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId("") d.SetId("")
return nil return nil
} }
func resourceLBFrontendEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBFrontendEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
return nil return nil
} }
func ResourceLBFrontend() *schema.Resource { func ResourceLBFrontend() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
CreateContext: resourceLBFrontendCreate, CreateContext: resourceLBFrontendCreate,
ReadContext: resourceLBFrontendRead, ReadContext: resourceLBFrontendRead,
UpdateContext: resourceLBFrontendEdit, UpdateContext: resourceLBFrontendEdit,
DeleteContext: resourceLBFrontendDelete, DeleteContext: resourceLBFrontendDelete,
Importer: &schema.ResourceImporter{ Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext, StateContext: schema.ImportStatePassthroughContext,
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout600s, Create: &constants.Timeout600s,
Read: &constants.Timeout300s, Read: &constants.Timeout300s,
Update: &constants.Timeout300s, Update: &constants.Timeout300s,
Delete: &constants.Timeout300s, Delete: &constants.Timeout300s,
Default: &constants.Timeout300s, Default: &constants.Timeout300s,
}, },
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"lb_id": { "lb_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
Description: "ID of the LB instance to backendCreate", Description: "ID of the LB instance to backendCreate",
}, },
"backend_name": { "backend_name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
}, },
"bindings": { "bindings": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"address": { "address": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"guid": { "guid": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"port": { "port": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
}, },
}, },
}, },
"guid": { "guid": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
}, },
} }
} }

@ -1,216 +1,216 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package lb package lb
import ( import (
"context" "context"
"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"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"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"
) )
func resourceLBFrontendBindCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBFrontendBindCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBFrontendBindCreate") log.Debugf("resourceLBFrontendBindCreate")
haveLBID, err := existLBID(ctx, d, m) haveLBID, err := existLBID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveLBID { if !haveLBID {
return diag.Errorf("resourceLBFrontendBindCreate: can't create LB frontend bind because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) return diag.Errorf("resourceLBFrontendBindCreate: can't create LB frontend bind because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
} }
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := lb.FrontendBindRequest{ req := lb.FrontendBindRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
FrontendName: d.Get("frontend_name").(string), FrontendName: d.Get("frontend_name").(string),
BindingName: d.Get("name").(string), BindingName: d.Get("name").(string),
BindingAddress: d.Get("address").(string), BindingAddress: d.Get("address").(string),
BindingPort: uint64(d.Get("port").(int)), BindingPort: uint64(d.Get("port").(int)),
} }
_, err = c.CloudAPI().LB().FrontendBind(ctx, req) _, err = c.CloudAPI().LB().FrontendBind(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("frontend_name").(string) + "#" + d.Get("name").(string)) d.SetId(strconv.Itoa(d.Get("lb_id").(int)) + "#" + d.Get("frontend_name").(string) + "#" + d.Get("name").(string))
_, err = utilityLBFrontendBindCheckPresence(ctx, d, m) _, err = utilityLBFrontendBindCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
return resourceLBFrontendBindRead(ctx, d, m) return resourceLBFrontendBindRead(ctx, d, m)
} }
func resourceLBFrontendBindRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBFrontendBindRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBFrontendBindRead") log.Debugf("resourceLBFrontendBindRead")
b, err := utilityLBFrontendBindCheckPresence(ctx, d, m) b, err := utilityLBFrontendBindCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32)
frontendName := strings.Split(d.Id(), "#")[1] frontendName := strings.Split(d.Id(), "#")[1]
flattenLBFrontendBind(d, b, lbId, frontendName) flattenLBFrontendBind(d, b, lbId, frontendName)
return nil return nil
} }
func resourceLBFrontendBindDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBFrontendBindDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBFrontendBindDelete") log.Debugf("resourceLBFrontendBindDelete")
_, err := utilityLBFrontendBindCheckPresence(ctx, d, m) _, err := utilityLBFrontendBindCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := lb.FrontendBindDeleteRequest{ req := lb.FrontendBindDeleteRequest{
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
FrontendName: d.Get("frontend_name").(string), FrontendName: d.Get("frontend_name").(string),
BindingName: d.Get("name").(string), BindingName: d.Get("name").(string),
} }
_, err = c.CloudAPI().LB().FrontendBindDelete(ctx, req) _, err = c.CloudAPI().LB().FrontendBindDelete(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId("") d.SetId("")
return nil return nil
} }
func resourceLBFrontendBindUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceLBFrontendBindUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLBFrontendBindEdit") log.Debugf("resourceLBFrontendBindEdit")
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
haveLBID, err := existLBID(ctx, d, m) haveLBID, err := existLBID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveLBID { if !haveLBID {
return diag.Errorf("resourceLBFrontendBindUpdate: can't update LB frontend bind because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) return diag.Errorf("resourceLBFrontendBindUpdate: can't update LB frontend bind because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
} }
req := lb.FrontendBindUpdateRequest{ req := lb.FrontendBindUpdateRequest{
FrontendName: d.Get("frontend_name").(string), FrontendName: d.Get("frontend_name").(string),
BindingName: d.Get("name").(string), BindingName: d.Get("name").(string),
LBID: uint64(d.Get("lb_id").(int)), LBID: uint64(d.Get("lb_id").(int)),
} }
if d.HasChange("address") { if d.HasChange("address") {
req.BindingAddress = d.Get("address").(string) req.BindingAddress = d.Get("address").(string)
} }
if d.HasChange("port") { if d.HasChange("port") {
req.BindingPort = uint64(d.Get("port").(int)) req.BindingPort = uint64(d.Get("port").(int))
} }
_, err = c.CloudAPI().LB().FrontendBindUpdate(ctx, req) _, err = c.CloudAPI().LB().FrontendBindUpdate(ctx, req)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
return resourceLBFrontendBindRead(ctx, d, m) return resourceLBFrontendBindRead(ctx, d, m)
} }
func ResourceLBFrontendBind() *schema.Resource { func ResourceLBFrontendBind() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
CreateContext: resourceLBFrontendBindCreate, CreateContext: resourceLBFrontendBindCreate,
ReadContext: resourceLBFrontendBindRead, ReadContext: resourceLBFrontendBindRead,
UpdateContext: resourceLBFrontendBindUpdate, UpdateContext: resourceLBFrontendBindUpdate,
DeleteContext: resourceLBFrontendBindDelete, DeleteContext: resourceLBFrontendBindDelete,
Importer: &schema.ResourceImporter{ Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext, StateContext: schema.ImportStatePassthroughContext,
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout600s, Create: &constants.Timeout600s,
Read: &constants.Timeout300s, Read: &constants.Timeout300s,
Update: &constants.Timeout300s, Update: &constants.Timeout300s,
Delete: &constants.Timeout300s, Delete: &constants.Timeout300s,
Default: &constants.Timeout300s, Default: &constants.Timeout300s,
}, },
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"lb_id": { "lb_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
Description: "ID of the LB instance to backendCreate", Description: "ID of the LB instance to backendCreate",
}, },
"frontend_name": { "frontend_name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
Description: "Must be unique among all backends of this LB - name of the new backend to create", Description: "Must be unique among all backends of this LB - name of the new backend to create",
}, },
"address": { "address": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
}, },
"guid": { "guid": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
}, },
"port": { "port": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
}, },
}, },
} }
} }

@ -1,190 +1,190 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package locations package locations
import ( import (
"context" "context"
"github.com/google/uuid" "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/decort-golang-sdk/pkg/cloudapi/locations" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
) )
func flattenLocationsList(ll *locations.ListLocations) []map[string]interface{} { func flattenLocationsList(ll *locations.ListLocations) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(ll.Data)) 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, "auth_broker": l.AuthBroker,
"flag": l.Flag, "flag": l.Flag,
"gid": l.GID, "gid": l.GID,
"guid": l.GUID, "guid": l.GUID,
"id": l.ID, "id": l.ID,
"location_code": l.LocationCode, "location_code": l.LocationCode,
"name": l.Name, "name": l.Name,
} }
res = append(res, temp) res = append(res, temp)
} }
return res return res
} }
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenLocationsList(locations)) d.Set("items", flattenLocationsList(locations))
d.Set("entry_count", locations.EntryCount) d.Set("entry_count", locations.EntryCount)
return nil return nil
} }
func dataSourceLocationsListSchemaMake() map[string]*schema.Schema { func dataSourceLocationsListSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{ return map[string]*schema.Schema{
"flag": { "flag": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Description: "Filter by flag", Description: "Filter by flag",
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Description: "Filter by name", Description: "Filter by name",
}, },
"by_id": { "by_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Description: "Filter by ID", Description: "Filter by ID",
}, },
"location_code": { "location_code": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Description: "Filter by location code", Description: "Filter by location code",
}, },
"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": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Description: "Locations list", Description: "Locations list",
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"ckey": { "ckey": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"meta": { "meta": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
}, },
}, },
"auth_broker": { "auth_broker": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
}, },
}, },
"flag": { "flag": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"gid": { "gid": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
Description: "Grid id", Description: "Grid id",
}, },
"guid": { "guid": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
Description: "location id", Description: "location id",
}, },
"id": { "id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
Description: "location id", Description: "location id",
}, },
"location_code": { "location_code": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
Description: "Location code", Description: "Location code",
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
Description: "Location name", Description: "Location name",
}, },
}, },
}, },
}, },
"entry_count": { "entry_count": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
} }
} }
func DataSourceLocationsList() *schema.Resource { func DataSourceLocationsList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceLocationsListRead, ReadContext: dataSourceLocationsListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceLocationsListSchemaMake(), Schema: dataSourceLocationsListSchemaMake(),
} }
} }

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

@ -68,6 +68,7 @@ func DataSourceResgroup() *schema.Resource {
} }
} }
// func sepsSchemaMake() map[string]*schema.Schema { // func sepsSchemaMake() map[string]*schema.Schema {
// res := map[string]*schema.Schema{ // res := map[string]*schema.Schema{
// "sep_id": { // "sep_id": {
@ -417,3 +418,5 @@ func dataSourceRgSchemaMake() map[string]*schema.Schema {
} }
return res return res
} }

@ -83,17 +83,8 @@ func dataSourceRgAffinityGroupsListSchemaMake() map[string]*schema.Schema {
"ids": { "ids": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Resource{ Elem: &schema.Schema{
Schema: map[string]*schema.Schema{ Type: schema.TypeInt,
"id": {
Type: schema.TypeInt,
Computed: true,
},
"node_id": {
Type: schema.TypeInt,
Computed: true,
},
},
}, },
}, },
}, },

@ -1,280 +1,280 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package rg package rg
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
func dataSourceRgListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceRgListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
rgList, err := utilityRgListCheckPresence(ctx, d, m) rgList, err := utilityRgListCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenRgList(rgList)) d.Set("items", flattenRgList(rgList))
d.Set("entry_count", rgList.EntryCount) d.Set("entry_count", rgList.EntryCount)
return nil return nil
} }
func dataSourceRgListSchemaMake() map[string]*schema.Schema { func dataSourceRgListSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{ res := map[string]*schema.Schema{
"by_id": { "by_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Description: "Find by ID", Description: "Find by ID",
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Description: "Find by name", Description: "Find by name",
}, },
"account_id": { "account_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Description: "Find by account ID", Description: "Find by account ID",
}, },
"account_name": { "account_name": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Description: "Find by account name", Description: "Find by account name",
}, },
"created_after": { "created_after": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Description: "Find RGs created after specific time (unix timestamp)", Description: "Find RGs created after specific time (unix timestamp)",
}, },
"created_before": { "created_before": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Description: "Find RGs created before specific time (unix timestamp)", Description: "Find RGs created before specific time (unix timestamp)",
}, },
"status": { "status": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Description: "Find by status", Description: "Find by status",
}, },
"lock_status": { "lock_status": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Description: "Find by lock status", Description: "Find by lock status",
}, },
"includedeleted": { "includedeleted": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
Default: false, Default: false,
Description: "included deleted resource groups", Description: "included deleted resource groups",
}, },
"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": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"account_acl": { "account_acl": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: aclSchemaMake(), Schema: aclSchemaMake(),
}, },
}, },
"account_id": { "account_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"account_name": { "account_name": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"created_by": { "created_by": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"created_time": { "created_time": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"def_net_id": { "def_net_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"def_net_type": { "def_net_type": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"deleted_by": { "deleted_by": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"deleted_time": { "deleted_time": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"desc": { "desc": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"dirty": { "dirty": {
Type: schema.TypeBool, Type: schema.TypeBool,
Computed: true, Computed: true,
}, },
"gid": { "gid": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"guid": { "guid": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"rg_id": { "rg_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"lock_status": { "lock_status": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"milestones": { "milestones": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"register_computes": { "register_computes": {
Type: schema.TypeBool, Type: schema.TypeBool,
Computed: true, Computed: true,
}, },
"resource_limits": { "resource_limits": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: resourceLimitsSchemaMake(), Schema: resourceLimitsSchemaMake(),
}, },
}, },
"secret": { "secret": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"status": { "status": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"updated_by": { "updated_by": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"updated_time": { "updated_time": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
"vins": { "vins": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
}, },
}, },
"vms": { "vms": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
}, },
}, },
"resource_types": { "resource_types": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
}, },
}, },
"cpu_allocation_parameter": { "cpu_allocation_parameter": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"cpu_allocation_ratio": { "cpu_allocation_ratio": {
Type: schema.TypeFloat, Type: schema.TypeFloat,
Computed: true, Computed: true,
}, },
"uniq_pools": { "uniq_pools": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
}, },
}, },
}, },
}, },
}, },
"entry_count": { "entry_count": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
} }
return res return res
} }
func DataSourceRgList() *schema.Resource { func DataSourceRgList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceRgListRead, ReadContext: dataSourceRgListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceRgListSchemaMake(), Schema: dataSourceRgListSchemaMake(),
} }
} }

@ -542,7 +542,7 @@ func flattenRgListGroups(list *rg.ListAffinityGroups) []map[string]interface{} {
for label, ag := range groupVal { for label, ag := range groupVal {
temp := map[string]interface{}{ temp := map[string]interface{}{
"label": label, "label": label,
"ids": flattenRgAffinityListGroup(ag), "ids": ag,
} }
res = append(res, temp) res = append(res, temp)
} }
@ -551,19 +551,6 @@ func flattenRgListGroups(list *rg.ListAffinityGroups) []map[string]interface{} {
return res return res
} }
func flattenRgAffinityListGroup(list rg.ListAffinityGroup) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(list))
for _, ag := range list {
temp := map[string]interface{}{
"id": ag.ID,
"node_id": ag.NodeID,
}
res = append(res, temp)
}
return res
}
func flattenRgUsageResource(d *schema.ResourceData, usage rg.RecordResourceUsage) { func flattenRgUsageResource(d *schema.ResourceData, usage rg.RecordResourceUsage) {
d.Set("cpu", usage.CPU) d.Set("cpu", usage.CPU)
d.Set("disk_size", usage.DiskSize) d.Set("disk_size", usage.DiskSize)

File diff suppressed because it is too large Load Diff

@ -557,8 +557,8 @@ func ResourceRgSchemaMake() map[string]*schema.Schema {
}, },
"gid": { "gid": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
// ForceNew: true, // ForceNew: true,
Description: "Unique ID of the grid, where this resource group is deployed.", Description: "Unique ID of the grid, where this resource group is deployed.",
}, },
@ -603,8 +603,8 @@ func ResourceRgSchemaMake() map[string]*schema.Schema {
}, },
"owner": { "owner": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
"quota": { "quota": {
@ -619,35 +619,35 @@ func ResourceRgSchemaMake() map[string]*schema.Schema {
Default: -1, Default: -1,
Description: "Limit on the total number of CPUs in this resource group.", Description: "Limit on the total number of CPUs in this resource group.",
}, },
"ram": { "ram": {
Type: schema.TypeInt, // NB: API expects and returns this as float in units of MB! This may be changed in the future. Type: schema.TypeInt, // NB: API expects and returns this as float in units of MB! This may be changed in the future.
Optional: true, Optional: true,
Default: -1, Default: -1,
Description: "Limit on the total amount of RAM in this resource group, specified in MB.", Description: "Limit on the total amount of RAM in this resource group, specified in MB.",
}, },
"disk": { "disk": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Default: -1, Default: -1,
Description: "Limit on the total volume of storage resources in this resource group, specified in GB.", Description: "Limit on the total volume of storage resources in this resource group, specified in GB.",
}, },
"ext_traffic": { "ext_traffic": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Default: -1, Default: -1,
Description: "Limit on the total ingress network traffic for this resource group, specified in GB.", Description: "Limit on the total ingress network traffic for this resource group, specified in GB.",
}, },
"ext_ips": { "ext_ips": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Default: -1, Default: -1,
Description: "Limit on the total number of external IP addresses this resource group can use.", Description: "Limit on the total number of external IP addresses this resource group can use.",
}, },
"gpu_units": { "gpu_units": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,

@ -8,21 +8,10 @@ import (
func resourceRGStateUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) { func resourceRGStateUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) {
log.Debug("resourceRGStateUpgradeV1: upgrading state") log.Debug("resourceRGStateUpgradeV1: upgrading state")
quota, ok := rawState["quota"] oldQuotaList := rawState["quota"].([]interface{})
if !ok || quota == nil { if len(oldQuotaList) != 0 {
rawState["quota"] = QuotaRecord{ oldQuota := oldQuotaList[0].(map[string]interface{})
Cpu: -1, oldQuota["ram"] = int64(oldQuota["ram"].(float64))
Ram: -1,
Disk: -1,
ExtTraffic: -1,
ExtIPs: -1,
GpuUnits: -1,
}
return rawState, nil
} }
oldQuotaList := quota.([]interface{})
oldQuota := oldQuotaList[0].(map[string]interface{})
oldQuota["ram"] = int64(oldQuota["ram"].(float64))
return rawState, nil return rawState, nil
} }

@ -79,12 +79,20 @@ func utilityUpdateRG(ctx context.Context, d *schema.ResourceData, m interface{},
if d.HasChange("quota") { if d.HasChange("quota") {
log.Debugf("resourceResgroupUpdate: quota specified - looking for deltas from the old quota.") log.Debugf("resourceResgroupUpdate: quota specified - looking for deltas from the old quota.")
quotaList := d.Get("quota").([]interface{}) quotaList := d.Get("quota").([]interface{})
quota := quotaList[0].(map[string]interface{}) if len(quotaList) != 0 {
req.MaxCPUCapacity = int64(quota["cpu"].(int)) quota := quotaList[0].(map[string]interface{})
req.MaxVDiskCapacity = int64(quota["disk"].(int)) req.MaxCPUCapacity = int64(quota["cpu"].(int))
req.MaxMemoryCapacity = int64(quota["ram"].(int)) req.MaxVDiskCapacity = int64(quota["disk"].(int))
req.MaxNetworkPeerTransfer = int64(quota["ext_traffic"].(int)) req.MaxMemoryCapacity = int64(quota["ram"].(int))
req.MaxNumPublicIP = int64(quota["ext_ips"].(int)) req.MaxNetworkPeerTransfer = int64(quota["ext_traffic"].(int))
req.MaxNumPublicIP = int64(quota["ext_ips"].(int))
} else {
req.MaxCPUCapacity = -1
req.MaxVDiskCapacity = -1
req.MaxMemoryCapacity = -1
req.MaxNetworkPeerTransfer = -1
req.MaxNumPublicIP = -1
}
} }
if d.HasChange("description") { if d.HasChange("description") {

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

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

@ -1,108 +1,108 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package vins package vins
import ( import (
"context" "context"
"strconv" "strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
) )
func dataSourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func dataSourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
staticRoute, err := utilityDataStaticRouteCheckPresence(ctx, d, m) staticRoute, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(strconv.FormatUint(staticRoute.ID, 10)) d.SetId(strconv.FormatUint(staticRoute.ID, 10))
flattenStaticRouteData(d, staticRoute) flattenStaticRouteData(d, staticRoute)
return nil return nil
} }
func dataSourceStaticRouteSchemaMake() map[string]*schema.Schema { func dataSourceStaticRouteSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{ rets := map[string]*schema.Schema{
"vins_id": { "vins_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
Description: "Unique ID of the ViNS", Description: "Unique ID of the ViNS",
}, },
"route_id": { "route_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
Description: "Unique ID of the static route", Description: "Unique ID of the static route",
}, },
"compute_ids": { "compute_ids": {
Type: schema.TypeList, Type: schema.TypeList,
Computed: true, Computed: true,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
}, },
}, },
"destination": { "destination": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"gateway": { "gateway": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"guid": { "guid": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"netmask": { "netmask": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
} }
return rets return rets
} }
func DataSourceStaticRoute() *schema.Resource { func DataSourceStaticRoute() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceStaticRouteRead, ReadContext: dataSourceStaticRouteRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceStaticRouteSchemaMake(), Schema: dataSourceStaticRouteSchemaMake(),
} }
} }

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

@ -545,6 +545,7 @@ func routesSchemaMake() map[string]*schema.Schema {
} }
} }
func gwConfigSchemaMake() map[string]*schema.Schema { func gwConfigSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{ return map[string]*schema.Schema{
"default_gw": { "default_gw": {

@ -1,277 +1,277 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru> Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package vins package vins
import ( import (
"context" "context"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/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/dc"
"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"
) )
func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
if _, ok := d.GetOk("vins_id"); ok { if _, ok := d.GetOk("vins_id"); ok {
haveVinsID, err := existVinsID(ctx, d, m) haveVinsID, err := existVinsID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveVinsID { if !haveVinsID {
return diag.Errorf("resourceStaticRouteCreate: can't create Static Route because Vins ID %d is not allowed or does not exist", d.Get("vins_id").(int)) return diag.Errorf("resourceStaticRouteCreate: can't create Static Route because Vins ID %d is not allowed or does not exist", d.Get("vins_id").(int))
} }
} }
req := vins.StaticRouteAddRequest{ req := vins.StaticRouteAddRequest{
VINSID: uint64(d.Get("vins_id").(int)), VINSID: uint64(d.Get("vins_id").(int)),
Destination: d.Get("destination").(string), Destination: d.Get("destination").(string),
Netmask: d.Get("netmask").(string), Netmask: d.Get("netmask").(string),
Gateway: d.Get("gateway").(string), Gateway: d.Get("gateway").(string),
} }
if computesIDS, ok := d.GetOk("compute_ids"); ok { if computesIDS, ok := d.GetOk("compute_ids"); ok {
ids := computesIDS.([]interface{}) ids := computesIDS.([]interface{})
res := make([]uint64, 10) res := make([]uint64, 10)
for _, id := range ids { for _, id := range ids {
computeId := uint64(id.(int)) computeId := uint64(id.(int))
res = append(res, computeId) res = append(res, computeId)
} }
req.ComputeIds = res req.ComputeIds = res
} }
_, err := c.CloudAPI().VINS().StaticRouteAdd(ctx, req) _, err := c.CloudAPI().VINS().StaticRouteAdd(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
staticRouteData, err := getStaticRouteData(ctx, d, m) staticRouteData, err := getStaticRouteData(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId(fmt.Sprintf("%d#%d", req.VINSID, staticRouteData.ID)) d.SetId(fmt.Sprintf("%d#%d", req.VINSID, staticRouteData.ID))
return resourceStaticRouteRead(ctx, d, m) return resourceStaticRouteRead(ctx, d, m)
} }
func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
warnings := dc.Warnings{} warnings := dc.Warnings{}
staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m) staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
flattenStaticRouteData(d, staticRouteData) flattenStaticRouteData(d, staticRouteData)
return warnings.Get() return warnings.Get()
} }
func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
warnings := dc.Warnings{} warnings := dc.Warnings{}
if _, ok := d.GetOk("vins_id"); ok { if _, ok := d.GetOk("vins_id"); ok {
haveVinsID, err := existVinsID(ctx, d, m) haveVinsID, err := existVinsID(ctx, d, m)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
if !haveVinsID { if !haveVinsID {
return diag.Errorf("resourceVinsUpdate: can't update Static Route because VinsID %d is not allowed or does not exist", d.Get("vins_id").(int)) return diag.Errorf("resourceVinsUpdate: can't update Static Route because VinsID %d is not allowed or does not exist", d.Get("vins_id").(int))
} }
} }
staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m) staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
if d.HasChange("compute_ids") { if d.HasChange("compute_ids") {
deletedIds := make([]uint64, 0) deletedIds := make([]uint64, 0)
addedIds := make([]uint64, 0) addedIds := make([]uint64, 0)
oldComputeIds, newComputeIds := d.GetChange("compute_ids") oldComputeIds, newComputeIds := d.GetChange("compute_ids")
oldComputeIdsSlice := oldComputeIds.([]interface{}) oldComputeIdsSlice := oldComputeIds.([]interface{})
newComputeIdsSlice := newComputeIds.([]interface{}) newComputeIdsSlice := newComputeIds.([]interface{})
for _, el := range oldComputeIdsSlice { for _, el := range oldComputeIdsSlice {
if !isContainsIds(newComputeIdsSlice, el) { if !isContainsIds(newComputeIdsSlice, el) {
convertedEl := uint64(el.(int)) convertedEl := uint64(el.(int))
deletedIds = append(deletedIds, convertedEl) deletedIds = append(deletedIds, convertedEl)
} }
} }
for _, el := range newComputeIdsSlice { for _, el := range newComputeIdsSlice {
if !isContainsIds(oldComputeIdsSlice, el) { if !isContainsIds(oldComputeIdsSlice, el) {
convertedEl := uint64(el.(int)) convertedEl := uint64(el.(int))
addedIds = append(addedIds, convertedEl) addedIds = append(addedIds, convertedEl)
} }
} }
if len(deletedIds) > 0 { if len(deletedIds) > 0 {
req := vins.StaticRouteAccessRevokeRequest{ req := vins.StaticRouteAccessRevokeRequest{
VINSID: uint64(d.Get("vins_id").(int)), VINSID: uint64(d.Get("vins_id").(int)),
RouteId: staticRouteData.ID, RouteId: staticRouteData.ID,
ComputeIds: deletedIds, ComputeIds: deletedIds,
} }
_, err := c.CloudAPI().VINS().StaticRouteAccessRevoke(ctx, req) _, err := c.CloudAPI().VINS().StaticRouteAccessRevoke(ctx, req)
if err != nil { if err != nil {
warnings.Add(err) warnings.Add(err)
} }
} }
if len(addedIds) > 0 { if len(addedIds) > 0 {
req := vins.StaticRouteAccessGrantRequest{ req := vins.StaticRouteAccessGrantRequest{
VINSID: uint64(d.Get("vins_id").(int)), VINSID: uint64(d.Get("vins_id").(int)),
RouteId: staticRouteData.ID, RouteId: staticRouteData.ID,
ComputeIds: addedIds, ComputeIds: addedIds,
} }
_, err := c.CloudAPI().VINS().StaticRouteAccessGrant(ctx, req) _, err := c.CloudAPI().VINS().StaticRouteAccessGrant(ctx, req)
if err != nil { if err != nil {
warnings.Add(err) warnings.Add(err)
} }
} }
} }
return append(warnings.Get(), resourceStaticRouteRead(ctx, d, m)...) return append(warnings.Get(), resourceStaticRouteRead(ctx, d, m)...)
} }
func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
arr := strings.Split(d.Id(), "#") arr := strings.Split(d.Id(), "#")
if len(arr) != 2 { if len(arr) != 2 {
return diag.FromErr(fmt.Errorf("broken state id")) return diag.FromErr(fmt.Errorf("broken state id"))
} }
vinsId, _ := strconv.ParseUint(arr[0], 10, 64) vinsId, _ := strconv.ParseUint(arr[0], 10, 64)
routeId, _ := strconv.ParseUint(arr[1], 10, 64) routeId, _ := strconv.ParseUint(arr[1], 10, 64)
req := vins.StaticRouteDelRequest{ req := vins.StaticRouteDelRequest{
VINSID: vinsId, VINSID: vinsId,
RouteId: routeId, RouteId: routeId,
} }
_, err := c.CloudAPI().VINS().StaticRouteDel(ctx, req) _, err := c.CloudAPI().VINS().StaticRouteDel(ctx, req)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
d.SetId("") d.SetId("")
return nil return nil
} }
func resourceStaticRouteSchemaMake() map[string]*schema.Schema { func resourceStaticRouteSchemaMake() map[string]*schema.Schema {
rets := dataSourceStaticRouteSchemaMake() rets := dataSourceStaticRouteSchemaMake()
rets["route_id"] = &schema.Schema{ rets["route_id"] = &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
Optional: true, Optional: true,
} }
rets["compute_ids"] = &schema.Schema{ rets["compute_ids"] = &schema.Schema{
Type: schema.TypeList, Type: schema.TypeList,
Optional: true, Optional: true,
Computed: true, Computed: true,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
}, },
} }
rets["destination"] = &schema.Schema{ rets["destination"] = &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
} }
rets["gateway"] = &schema.Schema{ rets["gateway"] = &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
} }
rets["netmask"] = &schema.Schema{ rets["netmask"] = &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
} }
return rets return rets
} }
func isContainsIds(els []interface{}, el interface{}) bool { func isContainsIds(els []interface{}, el interface{}) bool {
convEl := el.(int) convEl := el.(int)
for _, elOld := range els { for _, elOld := range els {
if convEl == elOld.(int) { if convEl == elOld.(int) {
return true return true
} }
} }
return false return false
} }
func ResourceStaticRoute() *schema.Resource { func ResourceStaticRoute() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
CreateContext: resourceStaticRouteCreate, CreateContext: resourceStaticRouteCreate,
ReadContext: resourceStaticRouteRead, ReadContext: resourceStaticRouteRead,
UpdateContext: resourceStaticRouteUpdate, UpdateContext: resourceStaticRouteUpdate,
DeleteContext: resourceStaticRouteDelete, DeleteContext: resourceStaticRouteDelete,
Importer: &schema.ResourceImporter{ Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext, StateContext: schema.ImportStatePassthroughContext,
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout20m, Create: &constants.Timeout20m,
Read: &constants.Timeout600s, Read: &constants.Timeout600s,
Update: &constants.Timeout20m, Update: &constants.Timeout20m,
Delete: &constants.Timeout600s, Delete: &constants.Timeout600s,
Default: &constants.Timeout600s, Default: &constants.Timeout600s,
}, },
Schema: resourceStaticRouteSchemaMake(), Schema: resourceStaticRouteSchemaMake(),
} }
} }

@ -112,7 +112,7 @@ func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface
} }
//extnet v1 //extnet v1
req.ExtNetID = uint64(d.Get("ext_net_id").(int)) req.ExtNetID = int64(d.Get("ext_net_id").(int))
if extIp, ok := d.GetOk("ext_ip_addr"); ok { if extIp, ok := d.GetOk("ext_ip_addr"); ok {
req.ExtIP = extIp.(string) req.ExtIP = extIp.(string)
} }
@ -122,7 +122,7 @@ func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface
extNetSl := extNetResp.([]interface{}) extNetSl := extNetResp.([]interface{})
extNet := extNetSl[0].(map[string]interface{}) extNet := extNetSl[0].(map[string]interface{})
req.ExtNetID = uint64(extNet["ext_net_id"].(int)) req.ExtNetID = int64(extNet["ext_net_id"].(int))
req.ExtIP = extNet["ext_net_ip"].(string) req.ExtIP = extNet["ext_net_ip"].(string)
} }
@ -388,7 +388,7 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface
return diag.Errorf("The resource cannot be updated because it has been destroyed") return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceVinsCreate(ctx, d, m) // return resourceVinsCreate(ctx, d, m)
case status.Deleted: case status.Deleted:
if restore, ok := d.GetOk("restore"); ok && restore.(bool) { if restore, ok:= d.GetOk("restore"); ok && restore.(bool) {
req := vins.RestoreRequest{ req := vins.RestoreRequest{
VINSID: vinsData.ID, VINSID: vinsData.ID,
} }
@ -478,7 +478,7 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface
} }
} }
if newExtNedId.(int) > 0 { if newExtNedId.(int) >= 0 {
// new external network connection requested - connect ViNS // new external network connection requested - connect ViNS
req := vins.ExtNetConnectRequest{ req := vins.ExtNetConnectRequest{
VINSID: vinsData.ID, VINSID: vinsData.ID,

@ -60,3 +60,4 @@ func utilityDataVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m
return vins, nil return vins, nil
} }

@ -1,70 +1,70 @@
/* /*
Copyright (c) 2019-2023 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>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package account package account
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenAccountAuditsList(accountAuditsList)) d.Set("items", flattenAccountAuditsList(accountAuditsList))
return nil return nil
} }
func DataSourceAccountAuditsList() *schema.Resource { func DataSourceAccountAuditsList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceAccountAuditsListRead, ReadContext: dataSourceAccountAuditsListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceAccountAuditsListSchemaMake(), Schema: dataSourceAccountAuditsListSchemaMake(),
} }
} }

@ -1,71 +1,71 @@
/* /*
Copyright (c) 2019-2023 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>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package account package account
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenAccountComputesList(accountComputesList)) d.Set("items", flattenAccountComputesList(accountComputesList))
d.Set("entry_count", accountComputesList.EntryCount) d.Set("entry_count", accountComputesList.EntryCount)
return nil return nil
} }
func DataSourceAccountComputesList() *schema.Resource { func DataSourceAccountComputesList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceAccountComputesListRead, ReadContext: dataSourceAccountComputesListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceAccountComputesListSchemaMake(), Schema: dataSourceAccountComputesListSchemaMake(),
} }
} }

@ -1,71 +1,71 @@
/* /*
Copyright (c) 2019-2023 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>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package account package account
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenListDeleted(accountDeletedList)) d.Set("items", flattenListDeleted(accountDeletedList))
d.Set("entry_count", accountDeletedList.EntryCount) d.Set("entry_count", accountDeletedList.EntryCount)
return nil return nil
} }
func DataSourceAccountDeletedList() *schema.Resource { func DataSourceAccountDeletedList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceAccountDeletedListRead, ReadContext: dataSourceAccountDeletedListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceAccountListDeletedSchemaMake(), Schema: dataSourceAccountListDeletedSchemaMake(),
} }
} }

@ -1,70 +1,70 @@
/* /*
Copyright (c) 2019-2023 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>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package account package account
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenAccountDisksList(accountDisksList)) d.Set("items", flattenAccountDisksList(accountDisksList))
d.Set("entry_count", accountDisksList.EntryCount) d.Set("entry_count", accountDisksList.EntryCount)
return nil return nil
} }
func DataSourceAccountDisksList() *schema.Resource { func DataSourceAccountDisksList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceAccountDisksListRead, ReadContext: dataSourceAccountDisksListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceAccountDisksListSchemaMake(), Schema: dataSourceAccountDisksListSchemaMake(),
} }
} }

@ -1,71 +1,71 @@
/* /*
Copyright (c) 2019-2023 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>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package account package account
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenAccountFlipGroupsList(accountFlipGroupsList)) d.Set("items", flattenAccountFlipGroupsList(accountFlipGroupsList))
d.Set("entry_count", accountFlipGroupsList.EntryCount) d.Set("entry_count", accountFlipGroupsList.EntryCount)
return nil return nil
} }
func DataSourceAccountFlipGroupsList() *schema.Resource { func DataSourceAccountFlipGroupsList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceAccountFlipGroupsListRead, ReadContext: dataSourceAccountFlipGroupsListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceAccountFlipGroupsListSchemaMake(), Schema: dataSourceAccountFlipGroupsListSchemaMake(),
} }
} }

@ -1,72 +1,72 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Nikita Sorokin, <nesorokin@basistech.ru> Nikita Sorokin, <nesorokin@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package account package account
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenAccountList(accountList)) d.Set("items", flattenAccountList(accountList))
d.Set("entry_count", accountList.EntryCount) d.Set("entry_count", accountList.EntryCount)
return nil return nil
} }
func DataSourceAccountList() *schema.Resource { func DataSourceAccountList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceAccountListRead, ReadContext: dataSourceAccountListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceAccountListSchemaMake(), Schema: dataSourceAccountListSchemaMake(),
} }
} }

@ -1,71 +1,71 @@
/* /*
Copyright (c) 2019-2023 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>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package account package account
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenAccountRGList(accountRGList)) d.Set("items", flattenAccountRGList(accountRGList))
d.Set("entry_count", accountRGList.EntryCount) d.Set("entry_count", accountRGList.EntryCount)
return nil return nil
} }
func DataSourceAccountRGList() *schema.Resource { func DataSourceAccountRGList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceAccountRGListRead, ReadContext: dataSourceAccountRGListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceAccountRGListSchemaMake(), Schema: dataSourceAccountRGListSchemaMake(),
} }
} }

@ -1,71 +1,71 @@
/* /*
Copyright (c) 2019-2023 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>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package account package account
import ( import (
"context" "context"
"github.com/google/uuid" "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"
) )
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("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
id := uuid.New() id := uuid.New()
d.SetId(id.String()) d.SetId(id.String())
d.Set("items", flattenAccountVinsList(accountVinsList)) d.Set("items", flattenAccountVinsList(accountVinsList))
d.Set("entry_count", accountVinsList.EntryCount) d.Set("entry_count", accountVinsList.EntryCount)
return nil return nil
} }
func DataSourceAccountVinsList() *schema.Resource { func DataSourceAccountVinsList() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
SchemaVersion: 1, SchemaVersion: 1,
ReadContext: dataSourceAccountVinsListRead, ReadContext: dataSourceAccountVinsListRead,
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s, Read: &constants.Timeout30s,
Default: &constants.Timeout60s, Default: &constants.Timeout60s,
}, },
Schema: dataSourceAccountVinsListSchemaMake(), Schema: dataSourceAccountVinsListSchemaMake(),
} }
} }

@ -187,7 +187,7 @@ func flattenRgAcl(rgAcls []account.ACL) []map[string]interface{} {
} }
func flattenListDeleted(al *account.ListAccounts) []map[string]interface{} { func flattenListDeleted(al *account.ListAccounts) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(al.Data)) res := make([]map[string]interface{}, 0, len (al.Data))
for _, acc := range al.Data { for _, acc := range al.Data {
temp := map[string]interface{}{ temp := map[string]interface{}{
"dc_location": acc.DCLocation, "dc_location": acc.DCLocation,

@ -330,11 +330,11 @@ func ResourceAccount() *schema.Resource {
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout60s, Create: &constants.Timeout600s,
Read: &constants.Timeout30s, Read: &constants.Timeout300s,
Update: &constants.Timeout60s, Update: &constants.Timeout300s,
Delete: &constants.Timeout60s, Delete: &constants.Timeout300s,
Default: &constants.Timeout60s, Default: &constants.Timeout300s,
}, },
Schema: resourceAccountSchemaMake(), Schema: resourceAccountSchemaMake(),

@ -313,4 +313,4 @@ func isChangedUser(els []interface{}, el interface{}) bool {
} }
} }
return false return false
} }

@ -361,11 +361,11 @@ func ResourceDisk() *schema.Resource {
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout180s, Create: &constants.Timeout600s,
Read: &constants.Timeout30s, Read: &constants.Timeout300s,
Update: &constants.Timeout180s, Update: &constants.Timeout300s,
Delete: &constants.Timeout60s, Delete: &constants.Timeout300s,
Default: &constants.Timeout60s, Default: &constants.Timeout300s,
}, },
Schema: resourceDiskSchemaMake(), Schema: resourceDiskSchemaMake(),

@ -65,7 +65,7 @@ func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m in
if computesIDS, ok := d.GetOk("compute_ids"); ok { if computesIDS, ok := d.GetOk("compute_ids"); ok {
ids := computesIDS.([]interface{}) ids := computesIDS.([]interface{})
res := make([]uint64, 0, len(ids)) res := make([]uint64, 0, len (ids))
for _, id := range ids { for _, id := range ids {
computeId := uint64(id.(int)) computeId := uint64(id.(int))
@ -92,7 +92,7 @@ func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m in
} }
func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m) staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
@ -113,7 +113,7 @@ func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, m in
} }
if d.HasChange("compute_ids") { if d.HasChange("compute_ids") {
if err := utilityStaticRouteComputeIDsUpdate(ctx, d, m); err != nil { if err:= utilityStaticRouteComputeIDsUpdate(ctx, d, m); err != nil {
warnings.Add(err) warnings.Add(err)
} }
} }

@ -718,7 +718,7 @@ func resourceExtnetSchemaMake() map[string]*schema.Schema {
"shared_with": { "shared_with": {
Type: schema.TypeSet, Type: schema.TypeSet,
Computed: true, Computed: true,
Optional: true, Optional: true,
Elem: &schema.Schema{ Elem: &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
}, },
@ -899,4 +899,4 @@ func resourceExtnetSchemaMake() map[string]*schema.Schema {
}, },
}, },
} }
} }

@ -340,3 +340,4 @@ func handleMigrateUpdate(ctx context.Context, d *schema.ResourceData, c *control
return nil return nil
} }

@ -245,11 +245,11 @@ func ResourceCDROMImage() *schema.Resource {
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout60s, Create: &constants.Timeout600s,
Read: &constants.Timeout30s, Read: &constants.Timeout300s,
Update: &constants.Timeout60s, Update: &constants.Timeout300s,
Delete: &constants.Timeout60s, Delete: &constants.Timeout300s,
Default: &constants.Timeout60s, Default: &constants.Timeout300s,
}, },
Schema: resourceCDROMImageSchemaMake(), Schema: resourceCDROMImageSchemaMake(),

@ -329,11 +329,11 @@ func ResourceImage() *schema.Resource {
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout60s, Create: &constants.Timeout600s,
Read: &constants.Timeout30s, Read: &constants.Timeout300s,
Update: &constants.Timeout60s, Update: &constants.Timeout300s,
Delete: &constants.Timeout60s, Delete: &constants.Timeout300s,
Default: &constants.Timeout60s, Default: &constants.Timeout300s,
}, },
Schema: resourceImageSchemaMake(), Schema: resourceImageSchemaMake(),

@ -208,11 +208,11 @@ func ResourceVirtualImage() *schema.Resource {
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout60s, Create: &constants.Timeout600s,
Read: &constants.Timeout30s, Read: &constants.Timeout300s,
Update: &constants.Timeout60s, Update: &constants.Timeout300s,
Delete: &constants.Timeout60s, Delete: &constants.Timeout300s,
Default: &constants.Timeout60s, Default: &constants.Timeout300s,
}, },
Schema: resourceVirtualImageSchemaMake(), Schema: resourceVirtualImageSchemaMake(),

@ -1,60 +1,60 @@
/* /*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors: Authors:
Petr Krutov, <petr.krutov@digitalenergy.online> Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online> Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package image package image
import ( import (
"context" "context"
"strconv" "strconv"
"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/cloudbroker/image" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
) )
func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.RecordImage, error) { func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.RecordImage, error) {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := image.GetRequest{} req := image.GetRequest{}
if d.Id() != "" { if d.Id() != "" {
id, _ := strconv.ParseUint(d.Id(), 10, 64) id, _ := strconv.ParseUint(d.Id(), 10, 64)
req.ImageID = id req.ImageID = id
} else { } else {
req.ImageID = uint64(d.Get("image_id").(int)) req.ImageID = uint64(d.Get("image_id").(int))
} }
image, err := c.CloudBroker().Image().Get(ctx, req) image, err := c.CloudBroker().Image().Get(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return image, nil return image, nil
} }

@ -1,98 +1,98 @@
/* /*
Copyright (c) 2019-2023 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>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package image package image
import ( import (
"context" "context"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.ListImages, error) { func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.ListImages, error) {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := image.ListRequest{} req := image.ListRequest{}
if sepId, ok := d.GetOk("sep_id"); ok { if sepId, ok := d.GetOk("sep_id"); ok {
req.SepID = uint64(sepId.(int)) req.SepID = uint64(sepId.(int))
} }
if byId, ok := d.GetOk("by_id"); ok { if byId, ok := d.GetOk("by_id"); ok {
req.ByID = uint64(byId.(int)) req.ByID = uint64(byId.(int))
} }
if name, ok := d.GetOk("name"); ok { if name, ok := d.GetOk("name"); ok {
req.Name = name.(string) req.Name = name.(string)
} }
if status, ok := d.GetOk("status"); ok { if status, ok := d.GetOk("status"); ok {
req.Status = status.(string) req.Status = status.(string)
} }
if architecture, ok := d.GetOk("architecture"); ok { if architecture, ok := d.GetOk("architecture"); ok {
req.Architecture = architecture.(string) req.Architecture = architecture.(string)
} }
if typeImage, ok := d.GetOk("type_image"); ok { if typeImage, ok := d.GetOk("type_image"); ok {
req.TypeImage = typeImage.(string) req.TypeImage = typeImage.(string)
} }
if imageSize, ok := d.GetOk("image_size"); ok { if imageSize, ok := d.GetOk("image_size"); ok {
req.ImageSize = uint64(imageSize.(int)) req.ImageSize = uint64(imageSize.(int))
} }
if sepName, ok := d.GetOk("sep_name"); ok { if sepName, ok := d.GetOk("sep_name"); ok {
req.SEPName = sepName.(string) req.SEPName = sepName.(string)
} }
if pool, ok := d.GetOk("pool"); ok { if pool, ok := d.GetOk("pool"); ok {
req.Pool = pool.(string) req.Pool = pool.(string)
} }
if public, ok := d.GetOk("public"); ok { if public, ok := d.GetOk("public"); ok {
req.Public = public.(bool) req.Public = public.(bool)
} }
if hotResize, ok := d.GetOk("hot_resize"); ok { if hotResize, ok := d.GetOk("hot_resize"); ok {
req.HotResize = hotResize.(bool) req.HotResize = hotResize.(bool)
} }
if bootable, ok := d.GetOk("bootable"); ok { if bootable, ok := d.GetOk("bootable"); ok {
req.Bootable = bootable.(bool) req.Bootable = bootable.(bool)
} }
if page, ok := d.GetOk("page"); ok { if page, ok := d.GetOk("page"); ok {
req.Page = uint64(page.(int)) req.Page = uint64(page.(int))
} }
if size, ok := d.GetOk("size"); ok { if size, ok := d.GetOk("size"); ok {
req.Size = uint64(size.(int)) req.Size = uint64(size.(int))
} }
log.Debugf("utilityImageListCheckPresence: load image list") log.Debugf("utilityImageListCheckPresence: load image list")
imageList, err := c.CloudBroker().Image().List(ctx, req) imageList, err := c.CloudBroker().Image().List(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return imageList, nil return imageList, nil
} }

@ -1,73 +1,73 @@
/* /*
Copyright (c) 2019-2023 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>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package image package image
import ( import (
"context" "context"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
func utilityImageListStacksCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.ListStacks, error) { func utilityImageListStacksCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.ListStacks, error) {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := image.ListStacksRequest{ req := image.ListStacksRequest{
ImageID: uint64(d.Get("image_id").(int)), ImageID: uint64(d.Get("image_id").(int)),
} }
if page, ok := d.GetOk("page"); ok { if page, ok := d.GetOk("page"); ok {
req.Page = uint64(page.(int)) req.Page = uint64(page.(int))
} }
if size, ok := d.GetOk("size"); ok { if size, ok := d.GetOk("size"); ok {
req.Size = uint64(size.(int)) req.Size = uint64(size.(int))
} }
if name, ok := d.GetOk("name"); ok { if name, ok := d.GetOk("name"); ok {
req.Name = name.(string) req.Name = name.(string)
} }
if status, ok := d.GetOk("status"); ok { if status, ok := d.GetOk("status"); ok {
req.Status = status.(string) req.Status = status.(string)
} }
if typeImage, ok := d.GetOk("type_image"); ok { if typeImage, ok := d.GetOk("type_image"); ok {
req.Type = typeImage.(string) req.Type = typeImage.(string)
} }
log.Debugf("utilityImageListStacksCheckPresence: load image list") log.Debugf("utilityImageListStacksCheckPresence: load image list")
imageListStacks, err := c.CloudBroker().Image().ListStacks(ctx, req) imageListStacks, err := c.CloudBroker().Image().ListStacks(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return imageListStacks, nil return imageListStacks, nil
} }

@ -54,6 +54,7 @@ func utilityK8CICheckPresence(ctx context.Context, d *schema.ResourceData, m int
req.K8CIID = uint64(d.Get("k8ci_id").(int)) req.K8CIID = uint64(d.Get("k8ci_id").(int))
} }
res, err := c.CloudBroker().K8CI().Get(ctx, req) res, err := c.CloudBroker().K8CI().Get(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err

@ -49,8 +49,8 @@ func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *contro
rgid := uint64(d.Get("rg_id").(int)) rgid := uint64(d.Get("rg_id").(int))
k8ciId := uint64(d.Get("k8sci_id").(int)) k8ciId := uint64(d.Get("k8sci_id").(int))
extNetId := uint64(d.Get("extnet_id").(int)) extNetId := uint64(d.Get("extnet_id").(int))
vinsId := uint64(d.Get("vins_id").(int)) vinsId := uint64(d.Get("vins_id").(int))
if err := ic.ExistRG(ctx, rgid, c); err != nil { if err := ic.ExistRG(ctx, rgid, c); err != nil {
errs = append(errs, err) errs = append(errs, err)

@ -399,9 +399,10 @@ func resourceK8sCPDelete(ctx context.Context, d *schema.ResourceData, m interfac
} }
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := k8s.DeleteRequest{ req := k8s.DeleteRequest{K8SID: k8sData.ID}
K8SID: k8sData.ID,
Permanently: d.Get("permanently").(bool), if val, ok := d.GetOk("permanently"); ok {
req.Permanently = val.(bool)
} }
_, err = c.CloudBroker().K8S().Delete(ctx, req) _, err = c.CloudBroker().K8S().Delete(ctx, req)

@ -115,8 +115,7 @@ func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interfac
if task.Error != "" { if task.Error != "" {
return diag.FromErr(fmt.Errorf("cannot create k8sWg instance: %v", task.Error)) return diag.FromErr(fmt.Errorf("cannot create k8sWg instance: %v", task.Error))
} }
d.SetId(fmt.Sprintf("%d#%d", d.Get("k8s_id").(int), int(task.Result)))
d.SetId(strconv.Itoa(int(task.Result)))
break break
} }
@ -146,7 +145,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)
} }
@ -155,8 +154,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)
@ -177,13 +175,12 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac
d.SetId("") d.SetId("")
return diag.FromErr(err) return diag.FromErr(err)
} }
wgId, _ := strconv.ParseUint(d.Id(), 10, 64)
if d.HasChange("num") { if d.HasChange("num") {
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,
} }
@ -195,7 +192,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,
} }
@ -210,7 +207,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),
} }
@ -262,10 +259,10 @@ func ResourceK8sWg() *schema.Resource {
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout20m, Create: &constants.Timeout20m,
Read: &constants.Timeout30s, Read: &constants.Timeout20m,
Update: &constants.Timeout20m, Update: &constants.Timeout20m,
Delete: &constants.Timeout60s, Delete: &constants.Timeout20m,
Default: &constants.Timeout60s, Default: &constants.Timeout20m,
}, },
Schema: resourceK8sWgSchemaMake(), Schema: resourceK8sWgSchemaMake(),

@ -3,6 +3,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"
) )
/* /*
@ -1345,9 +1347,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": {
@ -1735,9 +1741,13 @@ func resourceK8sWgSchemaMake() map[string]*schema.Schema {
Description: "Worker node CPU count.", Description: "Worker node CPU count.",
}, },
"ram": { "ram": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: 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.",
}, },
"disk": { "disk": {

@ -51,11 +51,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
} }

@ -33,6 +33,7 @@ package kvmvm
import ( import (
"context" "context"
"strconv"
// "net/url" // "net/url"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
@ -49,10 +50,8 @@ func dataSourceComputeRead(ctx context.Context, d *schema.ResourceData, m interf
return diag.FromErr(err) return diag.FromErr(err)
} }
if err = flattenDataCompute(d, compFacts); err != nil { d.SetId(strconv.Itoa(int(compFacts.ID)))
return diag.FromErr(err) flattenDataCompute(d, compFacts)
}
return nil return nil
} }

@ -1,8 +1,8 @@
package kvmvm package kvmvm
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt"
"sort" "sort"
"strconv" "strconv"
@ -12,7 +12,7 @@ import (
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
) )
func flattenCompute(d *schema.ResourceData, computeRec *compute.RecordCompute) error { func flattenCompute(ctx context.Context, d *schema.ResourceData, computeRec *compute.RecordCompute) error {
log.Debugf("flattenCompute: ID %d, RG ID %d", computeRec.ID, computeRec.RGID) log.Debugf("flattenCompute: ID %d, RG ID %d", computeRec.ID, computeRec.RGID)
customFields, _ := json.Marshal(computeRec.CustomFields) customFields, _ := json.Marshal(computeRec.CustomFields)
@ -20,14 +20,6 @@ func flattenCompute(d *schema.ResourceData, computeRec *compute.RecordCompute) e
userData, _ := json.Marshal(computeRec.Userdata) userData, _ := json.Marshal(computeRec.Userdata)
bootDisk := findBootDisk(computeRec.Disks) bootDisk := findBootDisk(computeRec.Disks)
//extra fields setting
if len(computeRec.Disks) > 0 {
log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(computeRec.Disks))
if err := d.Set("extra_disks", parseComputeDisksToExtraDisks(computeRec.Disks)); err != nil {
return err
}
}
if len(computeRec.Interfaces) > 0 { if len(computeRec.Interfaces) > 0 {
log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(computeRec.Interfaces)) log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(computeRec.Interfaces))
if err := d.Set("network", parseComputeInterfacesToNetworks(computeRec.Interfaces)); err != nil { if err := d.Set("network", parseComputeInterfacesToNetworks(computeRec.Interfaces)); err != nil {
@ -44,7 +36,8 @@ func flattenCompute(d *schema.ResourceData, computeRec *compute.RecordCompute) e
d.Set("arch", computeRec.Arch) d.Set("arch", computeRec.Arch)
d.Set("boot_order", computeRec.BootOrder) d.Set("boot_order", computeRec.BootOrder)
d.Set("boot_disk_id", bootDisk.ID) d.Set("boot_disk_id", bootDisk.ID)
d.Set("boot_disk_size", computeRec.BootDiskSize) // 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("cd_image_id", computeRec.CdImageId) d.Set("cd_image_id", computeRec.CdImageId)
d.Set("clone_reference", computeRec.CloneReference) d.Set("clone_reference", computeRec.CloneReference)
d.Set("clones", computeRec.Clones) d.Set("clones", computeRec.Clones)
@ -56,7 +49,7 @@ func flattenCompute(d *schema.ResourceData, computeRec *compute.RecordCompute) e
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", flattenComputeDisks(computeRec.Disks, d.Get("extra_disks").(*schema.Set).List(), bootDisk.ID)) err := d.Set("disks", flattenComputeDisks(ctx, d, computeRec.Disks, d.Get("extra_disks").(*schema.Set).List(), bootDisk.ID))
if err != nil { if err != nil {
return err return err
} }
@ -178,24 +171,31 @@ func flattenQOS(qos compute.QOS) []map[string]interface{} {
} }
} }
func flattenComputeDisks(disksList compute.ListDisks, extraDisks []interface{}, bootDiskId uint64) []map[string]interface{} { func flattenComputeDisks(ctx context.Context, d *schema.ResourceData, disksList compute.ListDisks, 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,
"size": disk.SizeMax, "size": disk.SizeMax,
"sep_id": disk.SEPID, "sep_id": disk.SEPID,
"disk_type": disk.Type, "disk_type": disk.Type,
"pool": disk.Pool, "pool": disk.Pool,
"desc": disk.Description, "desc": disk.Description,
"image_id": disk.ImageID, "image_id": disk.ImageID,
"disk_id": disk.ID, "disk_id": disk.ID,
"shareable": disk.Shareable, "shareable": disk.Shareable,
"size_used": disk.SizeUsed, "size_used": disk.SizeUsed,
"size_max": disk.SizeMax, "size_max": disk.SizeMax,
"permanently": permanently,
} }
res = append(res, temp) res = append(res, temp)
} }
@ -205,6 +205,21 @@ func flattenComputeDisks(disksList compute.ListDisks, extraDisks []interface{},
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 findInExtraDisks(diskId uint, extraDisks []interface{}) bool { func findInExtraDisks(diskId uint, extraDisks []interface{}) bool {
for _, ExtraDisk := range extraDisks { for _, ExtraDisk := range extraDisks {
if diskId == uint(ExtraDisk.(int)) { if diskId == uint(ExtraDisk.(int)) {
@ -247,7 +262,7 @@ func flattenComputeList(computes *compute.ListComputes) []map[string]interface{}
"arch": computeItem.Arch, "arch": computeItem.Arch,
"cd_image_id": computeItem.CdImageId, "cd_image_id": computeItem.CdImageId,
"boot_order": computeItem.BootOrder, "boot_order": computeItem.BootOrder,
"bootdisk_size": computeItem.BootDiskSize, "boot_disk_size": computeItem.BootDiskSize,
"clone_reference": computeItem.CloneReference, "clone_reference": computeItem.CloneReference,
"clones": computeItem.Clones, "clones": computeItem.Clones,
"computeci_id": computeItem.ComputeCIID, "computeci_id": computeItem.ComputeCIID,
@ -538,8 +553,6 @@ func flattenDataCompute(d *schema.ResourceData, compFacts *compute.RecordCompute
customFields, _ := json.Marshal(compFacts.CustomFields) customFields, _ := json.Marshal(compFacts.CustomFields)
devices, _ := json.Marshal(compFacts.Devices) devices, _ := json.Marshal(compFacts.Devices)
userData, _ := json.Marshal(compFacts.Userdata) userData, _ := json.Marshal(compFacts.Userdata)
// general fields setting
d.SetId(fmt.Sprintf("%d", compFacts.ID))
d.Set("account_id", compFacts.AccountID) d.Set("account_id", compFacts.AccountID)
d.Set("account_name", compFacts.AccountName) d.Set("account_name", compFacts.AccountName)
d.Set("acl", flattenListACLInterface(compFacts.ACL)) d.Set("acl", flattenListACLInterface(compFacts.ACL))
@ -549,6 +562,7 @@ func flattenDataCompute(d *schema.ResourceData, compFacts *compute.RecordCompute
d.Set("anti_affinity_rules", flattenAffinityRules(compFacts.AntiAffinityRules)) d.Set("anti_affinity_rules", flattenAffinityRules(compFacts.AntiAffinityRules))
d.Set("arch", compFacts.Arch) d.Set("arch", compFacts.Arch)
d.Set("boot_order", compFacts.BootOrder) d.Set("boot_order", compFacts.BootOrder)
d.Set("boot_disk_size", compFacts.BootDiskSize)
d.Set("cd_image_id", compFacts.CdImageId) d.Set("cd_image_id", compFacts.CdImageId)
d.Set("clone_reference", compFacts.CloneReference) d.Set("clone_reference", compFacts.CloneReference)
d.Set("clones", compFacts.Clones) d.Set("clones", compFacts.Clones)
@ -597,62 +611,9 @@ func flattenDataCompute(d *schema.ResourceData, compFacts *compute.RecordCompute
d.Set("vgpus", compFacts.VGPUs) d.Set("vgpus", compFacts.VGPUs)
d.Set("virtual_image_id", compFacts.VirtualImageID) d.Set("virtual_image_id", compFacts.VirtualImageID)
//extra fields setting
bootDisk := findBootDisk(compFacts.Disks)
if bootDisk != nil {
d.Set("boot_disk_size", bootDisk.SizeMax)
d.Set("boot_disk_id", bootDisk.ID) // we may need boot disk ID in resize operations
d.Set("sep_id", bootDisk.SEPID)
d.Set("pool", bootDisk.Pool)
}
if len(compFacts.Disks) > 0 {
log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(compFacts.Disks))
if err := d.Set("extra_disks", parseComputeDisksToExtraDisks(compFacts.Disks)); err != nil {
return err
}
}
if len(compFacts.Interfaces) > 0 {
log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(compFacts.Interfaces))
if err := d.Set("network", parseComputeInterfacesToNetworks(compFacts.Interfaces)); err != nil {
return err
}
}
return nil return nil
} }
// Parse list of all disks from API compute/get into a list of "extra disks" attached to this compute
// Extra disks are all compute disks but a boot disk.
func parseComputeDisksToExtraDisks(disks compute.ListDisks) []interface{} {
// this return value will be used to d.Set("extra_disks",) item of dataSourceCompute schema,
// which is a simple list of integer disk IDs excluding boot disk ID
length := len(disks)
log.Debugf("parseComputeDisksToExtraDisks: called for %d disks", length)
if length == 0 || (length == 1 && disks[0].Type == "B") {
// the disk list is empty (which is kind of strange - diskless compute?), or
// there is only one disk in the list and it is a boot disk;
// as we skip boot disks, the result will be of 0 length anyway
return make([]interface{}, 0)
}
result := make([]interface{}, length-1)
idx := 0
for _, value := range disks {
if value.Type == "B" {
// skip boot disk when iterating over the list of disks
continue
}
result[idx] = value.ID
idx++
}
return result
}
// Parse the list of interfaces from compute/get response into a list of networks // Parse the list of interfaces from compute/get response into a list of networks
// attached to this compute // attached to this compute
func parseComputeInterfacesToNetworks(ifaces compute.ListInterfaces) []interface{} { func parseComputeInterfacesToNetworks(ifaces compute.ListInterfaces) []interface{} {

@ -49,6 +49,9 @@ import (
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
) )
// 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)
@ -305,11 +308,13 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
req.ImageID = uint64(diskConv["image_id"].(int)) req.ImageID = uint64(diskConv["image_id"].(int))
} }
_, err := c.CloudBroker().Compute().DiskAdd(ctx, req) diskId, err := c.CloudBroker().Compute().DiskAdd(ctx, req)
if err != nil { if err != nil {
cleanup = true cleanup = true
return diag.FromErr(err) return diag.FromErr(err)
} }
ctx = context.WithValue(ctx, DiskKey(strconv.Itoa(int(diskId))), diskConv["permanently"].(bool))
} }
} }
} }
@ -555,7 +560,7 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
d.SetId(strconv.FormatUint(computeRec.ID, 10)) d.SetId(strconv.FormatUint(computeRec.ID, 10))
if err = flattenCompute(d, computeRec); err != nil { if err = flattenCompute(ctx, d, computeRec); err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }

@ -5,6 +5,7 @@ import (
"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/constants"
"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/validators"
) )
func dataSourceComputeSchemaMake() map[string]*schema.Schema { func dataSourceComputeSchemaMake() map[string]*schema.Schema {
@ -145,6 +146,10 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString, Type: schema.TypeString,
}, },
}, },
"boot_disk_size": {
Type: schema.TypeInt,
Computed: true,
},
"cd_image_id": { "cd_image_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
@ -769,57 +774,6 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
}, },
//extra parameters
"boot_disk_size": {
Type: schema.TypeInt,
Computed: true,
},
"boot_disk_id": {
Type: schema.TypeInt,
Computed: true,
},
"sep_id": {
Type: schema.TypeInt,
Computed: true,
},
"pool": {
Type: schema.TypeString,
Computed: true,
},
"extra_disks": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
Description: "IDs of the extra disk(s) attached to this compute.",
},
"network": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"net_id": {
Type: schema.TypeInt,
Computed: true,
},
"net_type": {
Type: schema.TypeString,
Computed: true,
},
"ip_address": {
Type: schema.TypeString,
Computed: true,
},
"mac": {
Type: schema.TypeString,
Computed: true,
},
},
},
Description: "Network connection(s) for this compute.",
},
} }
return res return res
} }
@ -1023,7 +977,7 @@ func dataSourceComputeListSchemaMake() 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,
}, },
@ -2577,10 +2531,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,
@ -2631,7 +2588,7 @@ func resourceComputeSchemaMake() map[string]*schema.Schema {
"stack_id": { "stack_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Default: 0, Computed: true,
Description: "ID of stack to start compute", Description: "ID of stack to start compute",
}, },
"is": { "is": {
@ -2699,9 +2656,8 @@ func resourceComputeSchemaMake() map[string]*schema.Schema {
Description: "Set affinity label for compute", Description: "Set affinity label for compute",
}, },
"affinity_rules": { "affinity_rules": {
Type: schema.TypeSet, Type: schema.TypeList,
Optional: true, Optional: true,
Computed: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"topology": { "topology": {
@ -2729,7 +2685,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",
}, },
}, },
@ -2738,7 +2694,6 @@ func resourceComputeSchemaMake() map[string]*schema.Schema {
"anti_affinity_rules": { "anti_affinity_rules": {
Type: schema.TypeList, Type: schema.TypeList,
Optional: true, Optional: true,
Computed: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"topology": { "topology": {
@ -2766,7 +2721,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",
}, },
}, },
@ -3015,6 +2970,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,

@ -33,11 +33,13 @@ package kvmvm
import ( import (
"context" "context"
"fmt"
"strconv" "strconv"
"strings" "strings"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@ -109,11 +111,18 @@ func utilityComputeResize(ctx context.Context, d *schema.ResourceData, m interfa
resizeReq := compute.ResizeRequest{ resizeReq := compute.ResizeRequest{
ComputeID: computeId, ComputeID: computeId,
Force: true,
} }
forceResize, ok := d.GetOk("force_resize")
if ok {
resizeReq.Force = forceResize.(bool)
}
doUpdate := false doUpdate := false
oldCpu, newCpu := d.GetChange("cpu") oldCpu, newCpu := d.GetChange("cpu")
if oldCpu.(int) > newCpu.(int) && !forceResize.(bool) {
return fmt.Errorf("сannot resize compute ID %d: enable 'force_resize' to reduce compute vCPUs", computeId)
}
if oldCpu.(int) != newCpu.(int) { if oldCpu.(int) != newCpu.(int) {
resizeReq.CPU = uint64(newCpu.(int)) resizeReq.CPU = uint64(newCpu.(int))
doUpdate = true doUpdate = true
@ -182,25 +191,52 @@ func utilityComputeUpdateDisks(ctx context.Context, d *schema.ResourceData, m in
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) {
deletedDisks = append(deletedDisks, el) flag := false
extraDisks := d.Get("extra_disks").(*schema.Set).List()
delDisk := el.(map[string]interface{})
delDiskId := delDisk["disk_id"].(int)
for _, extraDiskId := range extraDisks {
if extraDiskId.(int) == delDiskId {
flag = true
break
}
}
if !flag {
deletedDisks = append(deletedDisks, el)
} else {
log.Debugf("disk %d will not be deleted because it is present in the extra_disks block", delDiskId)
}
} }
} }
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)
} }
} }
@ -268,15 +304,17 @@ func utilityComputeUpdateDisks(ctx context.Context, d *schema.ResourceData, m in
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.CloudBroker().Compute().DiskAdd(ctx, req) diskId, err := c.CloudBroker().Compute().DiskAdd(ctx, req)
if err != nil { if err != nil {
return err return 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
@ -294,6 +332,22 @@ func utilityComputeUpdateDisks(ctx context.Context, d *schema.ResourceData, m in
} }
} }
if len(renamedDisks) > 0 {
for _, disk := range renamedDisks {
diskConv := disk.(map[string]interface{})
req := disks.RenameRequest{
DiskID: uint64(diskConv["disk_id"].(int)),
Name: diskConv["disk_name"].(string),
}
_, err := c.CloudBroker().Disks().Rename(ctx, req)
if err != nil {
return err
}
}
}
return nil return nil
} }
@ -567,8 +621,8 @@ func utilityComputeUpdate(ctx context.Context, d *schema.ResourceData, m interfa
if d.HasChange("name") { if d.HasChange("name") {
req.Name = d.Get("name").(string) req.Name = d.Get("name").(string)
} }
if d.HasChange("desc") { if d.HasChange("description") {
req.Description = d.Get("desc").(string) req.Description = d.Get("description").(string)
} }
if _, err := c.CloudBroker().Compute().Update(ctx, req); err != nil { if _, err := c.CloudBroker().Compute().Update(ctx, req); err != nil {
@ -1234,7 +1288,7 @@ func utilityComputeStart(ctx context.Context, computeID uint64, m interface{}) (
return 0, nil return 0, nil
} }
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{})
@ -1246,11 +1300,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
} }
} }

@ -183,11 +183,11 @@ func ResourcePcidevice() *schema.Resource {
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout60s, Create: &constants.Timeout900s,
Read: &constants.Timeout30s, Read: &constants.Timeout300s,
Update: &constants.Timeout60s, Update: &constants.Timeout300s,
Delete: &constants.Timeout60s, Delete: &constants.Timeout300s,
Default: &constants.Timeout60s, Default: &constants.Timeout300s,
}, },
Schema: resourcePcideviceSchemaMake(), Schema: resourcePcideviceSchemaMake(),

@ -606,7 +606,7 @@ func resourceRGSetCPUAllocationParameter(ctx context.Context, d *schema.Resource
func resourceRGSetCPUAllocationRatio(ctx context.Context, d *schema.ResourceData, m interface{}) error { func resourceRGSetCPUAllocationRatio(ctx context.Context, d *schema.ResourceData, m interface{}) error {
cpuAllocationRatio := d.Get("cpu_allocation_ratio").(float64) cpuAllocationRatio := d.Get("cpu_allocation_ratio").(float64)
log.Debugf("resourceRGSetCPUAllocationRatio: cpuAllocationRatio %s for rg id %d", cpuAllocationRatio, uint64(d.Get("rg_id").(int))) log.Debugf("resourceRGSetCPUAllocationRatio: cpuAllocationRatio %f for rg id %d", cpuAllocationRatio, uint64(d.Get("rg_id").(int)))
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
@ -709,11 +709,11 @@ func ResourceResgroup() *schema.Resource {
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout180s, Create: &constants.Timeout600s,
Read: &constants.Timeout600s, Read: &constants.Timeout300s,
Update: &constants.Timeout180s, Update: &constants.Timeout600s,
Delete: &constants.Timeout60s, Delete: &constants.Timeout900s,
Default: &constants.Timeout60s, Default: &constants.Timeout300s,
}, },
Schema: resourceRgSchemaMake(), Schema: resourceRgSchemaMake(),

@ -522,11 +522,11 @@ func ResourceSep() *schema.Resource {
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout60s, Create: &constants.Timeout600s,
Read: &constants.Timeout30s, Read: &constants.Timeout300s,
Update: &constants.Timeout60s, Update: &constants.Timeout600s,
Delete: &constants.Timeout60s, Delete: &constants.Timeout300s,
Default: &constants.Timeout60s, Default: &constants.Timeout300s,
}, },
Schema: resourceSepSchemaMake(), Schema: resourceSepSchemaMake(),

@ -115,11 +115,11 @@ func ResourceSepConfig() *schema.Resource {
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout60s, Create: &constants.Timeout600s,
Read: &constants.Timeout30s, Read: &constants.Timeout300s,
Update: &constants.Timeout60s, Update: &constants.Timeout600s,
Delete: &constants.Timeout60s, Delete: &constants.Timeout300s,
Default: &constants.Timeout60s, Default: &constants.Timeout300s,
}, },
Schema: resourceSepConfigSchemaMake(), Schema: resourceSepConfigSchemaMake(),

@ -97,7 +97,7 @@ func createVinsInRG(ctx context.Context, d *schema.ResourceData, m interface{},
} }
if extNetID, ok := d.GetOk("ext_net_id"); ok { if extNetID, ok := d.GetOk("ext_net_id"); ok {
req.ExtNetID = uint64(extNetID.(int)) req.ExtNetID = int64(extNetID.(int))
} }
if extIP, ok := d.GetOk("ext_ip"); ok { if extIP, ok := d.GetOk("ext_ip"); ok {

@ -504,7 +504,7 @@ func resourceVinsChangeExtNetId(ctx context.Context, d *schema.ResourceData, m i
return err return err
} }
if newExtNedId.(int) > 0 { if newExtNedId.(int) >= 0 {
req := vins.ExtNetConnectRequest{ req := vins.ExtNetConnectRequest{
VINSID: vinsId, VINSID: vinsId,
NetID: uint64(newExtNedId.(int)), NetID: uint64(newExtNedId.(int)),
@ -796,11 +796,11 @@ func ResourceVins() *schema.Resource {
}, },
Timeouts: &schema.ResourceTimeout{ Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout180s, Create: &constants.Timeout20m,
Read: &constants.Timeout30s, Read: &constants.Timeout600s,
Update: &constants.Timeout180s, Update: &constants.Timeout20m,
Delete: &constants.Timeout60s, Delete: &constants.Timeout30m,
Default: &constants.Timeout60s, Default: &constants.Timeout600s,
}, },
Schema: resourceVinsSchemaMake(), Schema: resourceVinsSchemaMake(),

@ -1,80 +1,80 @@
/* /*
Copyright (c) 2019-2023 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>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp. Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it Please see README.md to learn where to place source code so that it
builds seamlessly. builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/ */
package vins package vins
import ( import (
"context" "context"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListVINS, error) { func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListVINS, error) {
c := m.(*controller.ControllerCfg) c := m.(*controller.ControllerCfg)
req := vins.ListRequest{} req := vins.ListRequest{}
if byId, ok := d.GetOk("by_id"); ok { if byId, ok := d.GetOk("by_id"); ok {
req.ByID = uint64(byId.(int)) req.ByID = uint64(byId.(int))
} }
if name, ok := d.GetOk("name"); ok { if name, ok := d.GetOk("name"); ok {
req.Name = name.(string) req.Name = name.(string)
} }
if accountId, ok := d.GetOk("account_id"); ok { if accountId, ok := d.GetOk("account_id"); ok {
req.AccountID = uint64(accountId.(int)) req.AccountID = uint64(accountId.(int))
} }
if rgId, ok := d.GetOk("rg_id"); ok { if rgId, ok := d.GetOk("rg_id"); ok {
req.RGID = uint64(rgId.(int)) req.RGID = uint64(rgId.(int))
} }
if extIp, ok := d.GetOk("ext_ip"); ok { if extIp, ok := d.GetOk("ext_ip"); ok {
req.ExtIP = extIp.(string) req.ExtIP = extIp.(string)
} }
if page, ok := d.GetOk("page"); ok { if page, ok := d.GetOk("page"); ok {
req.Page = uint64(page.(int)) req.Page = uint64(page.(int))
} }
if size, ok := d.GetOk("size"); ok { if size, ok := d.GetOk("size"); ok {
req.Size = uint64(size.(int)) req.Size = uint64(size.(int))
} }
if includeDeleted, ok := d.GetOk("include_deleted"); ok { if includeDeleted, ok := d.GetOk("include_deleted"); ok {
req.IncludeDeleted = includeDeleted.(bool) req.IncludeDeleted = includeDeleted.(bool)
} }
log.Debugf("utilityVinsListCheckPresence") log.Debugf("utilityVinsListCheckPresence")
vinsList, err := c.CloudBroker().VINS().List(ctx, req) vinsList, err := c.CloudBroker().VINS().List(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return vinsList, nil return vinsList, nil
} }

@ -0,0 +1,22 @@
package validators
import (
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func DivisibleBy(divisibility int) schema.SchemaValidateFunc {
return func(i interface{}, k string) (warnings []string, errors []error) {
total, ok := i.(int)
if !ok {
errors = append(errors, fmt.Errorf("expected type of %s to be integer", k))
return warnings, errors
}
if total % divisibility != 0 {
errors = append(errors, fmt.Errorf("expected value of %s to be divisible by %d", k, divisibility))
}
return warnings, errors
}
}

@ -0,0 +1,9 @@
---
users:
- groups: users, wheel
name: user
plain_text_passwd: examplePassword
primary_group: user
ssh_authorized_keys:
- ssh-rsa EXAMPLE%id_rsa.pub
sudo: ALL=(ALL) NOPASSWD:ALL

@ -18,6 +18,8 @@ provider "decort" {
controller_url = "https://ds1.digitalenergy.online" controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL> #oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online" oauth2_url = "https://sso.digitalenergy.online"
#app_id = <APP-ID>
#app_secret = <APP-SECRET>
allow_unverified_ssl = true allow_unverified_ssl = true
} }
@ -31,7 +33,7 @@ resource "decort_k8s" "cluster" {
#id resource group #id resource group
#обязательный параметр #обязательный параметр
#тип - число #тип - число
rg_id = 776 rg_id = 907
#id catalogue item #id catalogue item
#обязательный параметр #обязательный параметр
@ -282,6 +284,11 @@ resource "decort_k8s" "cluster" {
# опциональный параметр # опциональный параметр
# тип - булев тип # тип - булев тип
start = true start = true
# команда destroy удаляет кластер без возможности восстановления
# опциональный параметр
# тип - булев тип
permanently = true
} }
output "test_cluster" { output "test_cluster" {

@ -1,6 +1,7 @@
#Расскомментируйте этот код, #Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь, #и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером #чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/* /*
terraform { terraform {
required_providers { required_providers {
@ -18,6 +19,8 @@ provider "decort" {
controller_url = "https://ds1.digitalenergy.online" controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL> #oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online" oauth2_url = "https://sso.digitalenergy.online"
#app_id = <APP-ID>
#app_secret = <APP-SECRET>
allow_unverified_ssl = true allow_unverified_ssl = true
} }
@ -139,7 +142,7 @@ resource "decort_k8s_cp" "cp" {
# тип - строка # тип - строка
join_config = "{JSON string}" join_config = "{JSON string}"
# при создании кластре использовать подключение только к сети ExtNet # при создании кластер использовать подключение только к сети ExtNet
# опциональный параметр # опциональный параметр
# тип - булев тип # тип - булев тип
extnet_only = true extnet_only = true
@ -149,6 +152,11 @@ resource "decort_k8s_cp" "cp" {
# тип - файл # тип - файл
oidc_cert = file("ca.crt") oidc_cert = file("ca.crt")
# команда destroy удаляет кластер без возможности восстановления
# опциональный параметр
# тип - булев тип
permanently = true
} }
output "cp_out" { output "cp_out" {

@ -2,6 +2,7 @@
#Расскомментируйте этот код, #Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь, #и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером #чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/* /*
terraform { terraform {
required_providers { required_providers {
@ -19,6 +20,8 @@ provider "decort" {
controller_url = "https://ds1.digitalenergy.online" controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL> #oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online" oauth2_url = "https://sso.digitalenergy.online"
#app_id = <APP-ID>
#app_secret = <APP-SECRET>
allow_unverified_ssl = true allow_unverified_ssl = true
} }

@ -9,24 +9,26 @@
#Расскомментируйте этот код, #Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь, #и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером #чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/* /*
terraform { terraform {
required_providers { required_providers {
decort = { decort = {
source = "basis/decort/decort"
version = "<VERSION>" version = "<VERSION>"
source = "basis/decort/decort"
} }
} }
} }
*/ */
provider "decort" { provider "decort" {
authenticator = "decs3o" 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>
oauth2_url = "https://sso.digitalenergy.online" oauth2_url = "https://sso.digitalenergy.online"
#app_id = <APP-ID>
#app_secret = <APP-SECRET>
allow_unverified_ssl = true allow_unverified_ssl = true
} }
@ -55,7 +57,7 @@ resource "decort_kvmvm" "comp" {
#кол-во оперативной памяти, МБ #кол-во оперативной памяти, МБ
#обязательный параметр #обязательный параметр
#тип - число #тип - число
ram = 2048 ram = 2049
#id образа диска для создания compute #id образа диска для создания compute
#обязательный параметр #обязательный параметр
@ -160,7 +162,7 @@ resource "decort_kvmvm" "comp" {
key = "testkey" key = "testkey"
#ключ правила #ключ правила
#обязательный параметр #необязательный параметр
#тип строка #тип строка
value = "testvalue" value = "testvalue"
} }
@ -194,7 +196,7 @@ resource "decort_kvmvm" "comp" {
key = "testkey" key = "testkey"
#ключ правила #ключ правила
#обязательный параметр #необязательный параметр
#тип строка #тип строка
value = "testvalue" value = "testvalue"
} }
@ -367,6 +369,11 @@ resource "decort_kvmvm" "comp" {
#тип - булев #тип - булев
force_stop = true force_stop = true
#флаг для ресайза компьюта
#опциональный параметр
#тип - булев
force_resize = true
#поле для редеплоя компьюта #поле для редеплоя компьюта
#опциональный параметр #опциональный параметр
#тип - строка #тип - строка

@ -101,13 +101,11 @@ resource "decort_lb" "lb" {
#восстановить можно load balancer, удаленным с флагом permanently = false #восстановить можно load balancer, удаленным с флагом permanently = false
#restore = true #restore = true
#флаг используемый при рестарте load balancer
timeouts { #необязательный параметр
create = "5m" #тип - булев тип
read = "5m" #значение по умолчанию - true, при данном значении рестарт производится на обоих нодах в HA mode
update = "5m" #safe = true
delete = "5m"
}
} }
output "test" { output "test" {

@ -13,11 +13,15 @@ terraform {
*/ */
provider "decort" { provider "decort" {
authenticator = "decs3o" authenticator = "decs3o"
oauth2_url = "https://sso.digitalenergy.online" #controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://mr4.digitalenergy.online" controller_url = "https://ds1.digitalenergy.online"
app_id = "" #oauth2_url = <DECORT_SSO_URL>
app_secret = "" oauth2_url = "https://sso.digitalenergy.online"
#app_id = <APP-ID>
#app_secret = <APP-SECRET>
allow_unverified_ssl = true
} }
resource "decort_cb_k8s_cp" "cp" { resource "decort_cb_k8s_cp" "cp" {

@ -1,96 +1,99 @@
#Расскомментируйте этот код, #Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь, #и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером #чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/* /*
terraform { terraform {
required_providers { required_providers {
decort = { decort = {
source = "basis/decort/decort" source = "basis/decort/decort"
version = "<VERSION>" version = "<VERSION>"
} }
} }
} }
*/ */
provider "decort" { provider "decort" {
authenticator = "decs3o" authenticator = "decs3o"
oauth2_url = "https://sso.digitalenergy.online" #controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://mr4.digitalenergy.online" controller_url = "https://ds1.digitalenergy.online"
app_id = "" #oauth2_url = <DECORT_SSO_URL>
app_secret = "" oauth2_url = "https://sso.digitalenergy.online"
} #app_id = <APP-ID>
#app_secret = <APP-SECRET>
allow_unverified_ssl = true
resource "decort_cb_k8s_wg" "wg" { }
#id экземпляра k8s
#обязательный параметр
#тип - число resource "decort_cb_k8s_wg" "wg" {
k8s_id = 1234 //это значение должно быть и результат вызова decort_cb_k8s.cluster.k8s_id #id экземпляра k8s
#обязательный параметр
#имя worker group #тип - число
#обязательный параметр k8s_id = 1234 //это значение должно быть и результат вызова decort_cb_k8s.cluster.k8s_id
#тип - строка
name = "workers-2" #имя worker group
#обязательный параметр
#количество worker node для создания #тип - строка
#опциональный параметр name = "workers-2"
#тип - число
#по - умолчанию - 1 #количество worker node для создания
num = 2 #опциональный параметр
#тип - число
#количество cpu для 1 worker node #по - умолчанию - 1
#опциональный параметр num = 2
#тип - число
#по - умолчанию - 1 #количество cpu для 1 worker node
cpu = 1 #опциональный параметр
#тип - число
#количество RAM для одной worker node в Мбайтах #по - умолчанию - 1
#опциональный параметр cpu = 1
#тип - число
#по-умолчанию - 1024 #количество RAM для одной worker node в Мбайтах
ram = 1024 #опциональный параметр
#тип - число
#размер загрузочного диска для worker node, в Гбайтах #по-умолчанию - 1024
#опциональный параметр ram = 1024
#тип - число
#по - умолчанию - 0 #размер загрузочного диска для worker node, в Гбайтах
#если установлен параметр 0, то размер диска будет равен размеру образа #опциональный параметр
disk = 10 #тип - число
#по - умолчанию - 0
#список строк с labels для worker группы, в формате: ["label1=value1", "label2=value2"] #если установлен параметр 0, то размер диска будет равен размеру образа
#опциональный параметр disk = 10
#тип - массив строк
labels = ["label1=value1", "label2=value2"] #список строк с labels для worker группы, в формате: ["label1=value1", "label2=value2"]
#опциональный параметр
#Список строк с annotations для worker группы, в формате: ["key1=value1", "key2=value2"] #тип - массив строк
#опциональный параметр labels = ["label1=value1", "label2=value2"]
#тип - массив строк
annotations = ["key1=value1", "key2=value2"] #Список строк с annotations для worker группы, в формате: ["key1=value1", "key2=value2"]
#опциональный параметр
#Список строк с taints для worker группы, в формате: ["key1=value1:NoSchedule", "key2=value2:NoExecute"] #тип - массив строк
#опциональный параметр annotations = ["key1=value1", "key2=value2"]
#тип - массив строк
taints = ["key1=value1", "key2=value2"] #Список строк с taints для worker группы, в формате: ["key1=value1:NoSchedule", "key2=value2:NoExecute"]
#опциональный параметр
#ID СХД для создания загрузочных дисков для Worker-групп по умолчанию. Использует sepId образа, если не указан. #тип - массив строк
#опциональный параметр taints = ["key1=value1", "key2=value2"]
#тип - число
worker_sep_id = 1 #ID СХД для создания загрузочных дисков для Worker-групп по умолчанию. Использует sepId образа, если не указан.
#опциональный параметр
#Пул для хранения Workers. Если не заполнить, будет выбран системой #тип - число
#опциональный параметр worker_sep_id = 1
#тип - число
worker_sep_pool = "worker_pool" #Пул для хранения Workers. Если не заполнить, будет выбран системой
#опциональный параметр
#Перечень аргументов для cloud-init для виртуальных машин worker групп #тип - число
#опциональный параметр worker_sep_pool = "worker_pool"
#тип - файл
#используется при создании и обновлении ресурса #Перечень аргументов для cloud-init для виртуальных машин worker групп
cloud_init = file("initconfig.tftpl") #опциональный параметр
} #тип - файл
#используется при создании и обновлении ресурса
cloud_init = file("initconfig.tftpl")
output "test_wg" { }
value = decort_cb_k8s_wg.wg
}
output "test_wg" {
value = decort_cb_k8s_wg.wg
}

@ -1,423 +1,429 @@
/* /*
Пример использования Пример использования
Работа с ресурсом kvmvm (compute) Работа с ресурсом kvmvm (compute)
Ресурс позволяет: Ресурс позволяет:
1. Создавать compute 1. Создавать compute
2. Редактировать compute 2. Редактировать compute
3. Удалять compute 3. Удалять compute
*/ */
#Расскомментируйте этот код, #Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь, #и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером #чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/* /*
terraform { terraform {
required_providers { required_providers {
decort = { decort = {
version = "<VERSION>" source = "basis/decort/decort"
source = "basis/decort/decort" version = "<VERSION>"
} }
} }
} }
*/ */
provider "decort" {
provider "decort" { authenticator = "decs3o"
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> oauth2_url = "https://sso.digitalenergy.online"
oauth2_url = "https://sso.digitalenergy.online" #app_id = <APP-ID>
allow_unverified_ssl = true #app_secret = <APP-SECRET>
} allow_unverified_ssl = true
}
resource "decort_cb_kvmvm" "comp" {
#имя compute resource "decort_cb_kvmvm" "comp" {
#обязательный параметр #имя compute
#мб изменен #обязательный параметр
#тип - строка #мб изменен
name = "test-tf-compute-update-new" #тип - строка
name = "test-tf-compute-update-new"
#id resource group
#обязательный параметр #id resource group
#тип - число #обязательный параметр
rg_id = 1111 #тип - число
rg_id = 1111
#тип драйвера для compute
#обязательный параметр #тип драйвера для compute
#тип - строка #обязательный параметр
driver = "KVM_X86" #тип - строка
driver = "KVM_X86"
#число cpu
#обязательный параметр #число cpu
#тип - число #обязательный параметр
cpu = 1 #тип - число
cpu = 1
#кол-во оперативной памяти, МБ
#обязательный параметр #кол-во оперативной памяти, МБ
#тип - число #обязательный параметр
ram = 2048 #тип - число
ram = 2048
#id образа диска для создания compute
#обязательный параметр #id образа диска для создания compute
#тип - число #обязательный параметр
image_id = 111 #тип - число
image_id = 111
#размер загрузочного диска
#опциональный параметр #размер загрузочного диска
#тип - число #опциональный параметр
boot_disk_size = 20 #тип - число
boot_disk_size = 20
#ID сепа для boot диска
#опциональный параметр #ID сепа для boot диска
#тип - число #опциональный параметр
sep_id = 1 #тип - число
sep_id = 1
#Название пула
#опциональный параметр #Название пула
#тип - строка #опциональный параметр
pool = "data02" #тип - строка
pool = "data02"
#конфигурация cloud init
#опциональный параметр #конфигурация cloud init
#тип - файл в формате JSON/YAML #опциональный параметр
cloud_init = file("initconfig.tftpl") #тип - файл в формате JSON/YAML
cloud_init = file("initconfig.tftpl")
#описание compute
#опциональный параметр #описание compute
#тип - строка #опциональный параметр
description = "test update description in tf words update" #тип - строка
description = "test update description in tf words update"
#stack id
#опциональный параметр #stack id
#тип - число #опциональный параметр
stack_id = 1 #тип - число
stack_id = 1
#id образа CD-ROM для загрузки
#используется при изменении ресурса, при повторном старте вм #id образа CD-ROM для загрузки
#опциональный параметр #используется при изменении ресурса, при повторном старте вм
#тип - число #опциональный параметр
alt_boot_id = 1 #тип - число
alt_boot_id = 1
#Создание и добавление диска дял compute
#опциональный параметр #Создание и добавление диска дял compute
#тип - список дисков #опциональный параметр
disks { #тип - список дисков
#Имя диска disks {
#Обязательный для диска параметр #Имя диска
#Тип - строка #Обязательный для диска параметр
disk_name = "disk_name" #Тип - строка
disk_name = "disk_name"
#Размер диска
#Обязательный для диска параметр #Размер диска
#Тип - число #Обязательный для диска параметр
size = 5 #Тип - число
size = 5
#Тип диска
#опциональный параметр #Тип диска
#тип - строка #опциональный параметр
disk_type = "D" #тип - строка
disk_type = "D"
#опциональный параметр
#тип - число #опциональный параметр
sep_id = 1 #тип - число
sep_id = 1
#Название пула
#опциональный параметр #Название пула
#тип - строка #опциональный параметр
pool = "data01" #тип - строка
pool = "data01"
#Описание диска
#опциональный параметр #Описание диска
#тип - строка #опциональный параметр
desc = "" #тип - строка
desc = ""
#Айди образа
#опциональный параметр #Айди образа
image_id = 378 #опциональный параметр
image_id = 378
#Флаг для удаления диска
#опциональный параметр #Флаг для удаления диска
#тип - bool #опциональный параметр
permanently = false #тип - bool
} permanently = false
}
#правила affinity
#опциональный параметр #правила affinity
#может быть один, несколько или ни одного блока #опциональный параметр
#тип - блок #может быть один, несколько или ни одного блока
affinity_rules { #тип - блок
#тип правила affinity_rules {
#возможные значения - compute или node #тип правила
#обязательный параметр #возможные значения - compute или node
#тип - строка #обязательный параметр
topology = "compute" #тип - строка
topology = "compute"
#строгость правила
#возможные значения - RECOMMENDED и REQUIRED #строгость правила
#обязательный параметр #возможные значения - RECOMMENDED и REQUIRED
#тип - строка #обязательный параметр
policy = "RECOMMENDED" #тип - строка
policy = "RECOMMENDED"
#режим проверки
#возможные значения - ANY, EQ, NE #режим проверки
#обязательный параметр #возможные значения - ANY, EQ, NE
#тип - строка #обязательный параметр
mode = "ANY" #тип - строка
mode = "ANY"
#ключ правила
#обязательный параметр #ключ правила
#тип строка #обязательный параметр
key = "testkey" #тип строка
key = "testkey"
#ключ правила
#обязательный параметр #ключ правила
#тип строка #необязательный параметр
value = "testvalue" #тип строка
} value = "testvalue"
}
#правила anti-affinity
#опциональный параметр #правила anti-affinity
#может быть один, несколько или ни одного блока #опциональный параметр
#тип - блок #может быть один, несколько или ни одного блока
anti_affinity_rules { #тип - блок
#тип правила anti_affinity_rules {
#возможные значения - compute или node #тип правила
#обязательный параметр #возможные значения - compute или node
#тип - строка #обязательный параметр
topology = "compute" #тип - строка
topology = "compute"
#строгость правила
#возможные значения - RECOMMENDED и REQUIRED #строгость правила
#обязательный параметр #возможные значения - RECOMMENDED и REQUIRED
#тип - строка #обязательный параметр
policy = "RECOMMENDED" #тип - строка
policy = "RECOMMENDED"
#режим проверки
#возможные значения - ANY, EQ, NE #режим проверки
#обязательный параметр #возможные значения - ANY, EQ, NE
#тип - строка #обязательный параметр
mode = "ANY" #тип - строка
mode = "ANY"
#ключ правила
#обязательный параметр #ключ правила
#тип строка #обязательный параметр
key = "testkey" #тип строка
key = "testkey"
#ключ правила
#обязательный параметр #ключ правила
#тип строка #необязательный параметр
value = "testvalue" #тип строка
} value = "testvalue"
}
#установка метки для вм
#опциональный параметр #установка метки для вм
#тип - строка #опциональный параметр
affinity_label = "test4" #тип - строка
affinity_label = "test4"
#наименование системы
#опциональный параметр #наименование системы
#используется при создании вм #опциональный параметр
#по умолчанию - не задан #используется при создании вм
#тип - строка #по умолчанию - не задан
is="" #тип - строка
is=""
#назначение вм
#опциональный параметр #назначение вм
#используется при создании вм #опциональный параметр
#по умолчанию - не задан #используется при создании вм
#тип - строка #по умолчанию - не задан
ipa_type = "" #тип - строка
ipa_type = ""
#Id экстра дисков
#опциональный параметр #Id экстра дисков
#тип - список чисел #опциональный параметр
extra_disks = [1234, 4322, 1344] #тип - список чисел
extra_disks = [1234, 4322, 1344]
#Управление XML виртуальной машины
#опциональный параметр #Управление XML виртуальной машины
#тип - строка (json-encoded) #опциональный параметр
custom_fields = "{`key`:`value`}" #тип - строка (json-encoded)
custom_fields = "{`key`:`value`}"
#Описание необходимости выполнения действия
#опциональный параметр #Описание необходимости выполнения действия
#тип - строка #опциональный параметр
reason = "need" #тип - строка
reason = "need"
#Присоеденения сетей и удаление сетей в компьюте
#опциональный параметр #Присоеденения сетей и удаление сетей в компьюте
#тип - блок #опциональный параметр
network { #тип - блок
#Тип сети VINS/EXTNET network {
#Обязательный параметр #Тип сети VINS/EXTNET
#тип - строка #Обязательный параметр
net_type = "VINS" #тип - строка
net_type = "VINS"
#ID сети
#Обязательный параметр #ID сети
#тип - число #Обязательный параметр
net_id = 1234 #тип - число
net_id = 1234
#IP адрес входящий в сеть
#опциональный параметр #IP адрес входящий в сеть
#тип - строка #опциональный параметр
ip_address = "127.0.0.1" #тип - строка
} ip_address = "127.0.0.1"
}
#добавление и удаление тэгов
#опциональный параметр #добавление и удаление тэгов
#тип - блок #опциональный параметр
tags { #тип - блок
#Ключ для тэга tags {
#Обязательный параметр #Ключ для тэга
#тип - строка #Обязательный параметр
key = "key" #тип - строка
key = "key"
#Значения тэга
#Обязательный параметр #Значения тэга
#тип - строка #Обязательный параметр
value = "value" #тип - строка
} value = "value"
}
#добавление и удаление port forwarding
#опциональный параметр #добавление и удаление port forwarding
#тип - блок #опциональный параметр
port_forwarding { #тип - блок
#номер внешнего начального порта для правила port_forwarding {
#Обязательный параметр #номер внешнего начального порта для правила
#тип - число #Обязательный параметр
public_port_start = 2023 #тип - число
public_port_start = 2023
#номер внешнего последнего порта для правила
#опциональный параметр #номер внешнего последнего порта для правила
#тип - число #опциональный параметр
#по умолчанию - -1 #тип - число
public_port_end = 2023 #по умолчанию - -1
public_port_end = 2023
#номер внутреннего базового порта
#Обязательный параметр #номер внутреннего базового порта
#тип - число #Обязательный параметр
local_port = 80 #тип - число
local_port = 80
#сетевой протокол
#Обязательный параметр #сетевой протокол
#тип - строка #Обязательный параметр
proto = "tcp" #тип - строка
} proto = "tcp"
}
#предоставить/забрать пользователю доступ к компьюту
#опциональный параметр #предоставить/забрать пользователю доступ к компьюту
#тип - блок #опциональный параметр
user_access { #тип - блок
#Имя юзера, которому предоставляем доступ user_access {
#Обязательный параметр #Имя юзера, которому предоставляем доступ
#тип - строка #Обязательный параметр
username = "some@decs3o" #тип - строка
username = "some@decs3o"
#Права: 'R' - только на чтение, 'RCX' - чтение/запись, 'ARCXDU' - админ
#Обязательный параметр #Права: 'R' - только на чтение, 'RCX' - чтение/запись, 'ARCXDU' - админ
#тип - строка #Обязательный параметр
access_type = "ARCXDU" #тип - строка
} access_type = "ARCXDU"
}
#Создать/удалить снапшот компьюта
#опциональный параметр #Создать/удалить снапшот компьюта
#тип - блок #опциональный параметр
snapshot { #тип - блок
#Лейбл снапшота snapshot {
#Обязательный параметр #Лейбл снапшота
#тип - строка #Обязательный параметр
label = "label1" #тип - строка
} label = "label1"
}
#Rollback на нужный снапшот
#опциональный параметр #Rollback на нужный снапшот
#Не имеет смысла при отсутсвии снапшотов #опциональный параметр
#тип - блок #Не имеет смысла при отсутсвии снапшотов
rollback { #тип - блок
#Лейбл снапшота rollback {
#Обязательный параметр #Лейбл снапшота
#тип - строка #Обязательный параметр
label = "label1" #тип - строка
} label = "label1"
}
#Вставить/удалить СD rom
#опциональный параметр #Вставить/удалить СD rom
#Максимальное кол-во - 1 #опциональный параметр
#тип - блок #Максимальное кол-во - 1
cd { #тип - блок
#ID образа диска CD rom cd {
#Обязательный параметр #ID образа диска CD rom
#тип - число #Обязательный параметр
cdrom_id = 344 #тип - число
} cdrom_id = 344
}
#Добавить компьют на стэк
#опциональный параметр #Добавить компьют на стэк
#тип - булев #опциональный параметр
pin_to_stack = true #тип - булев
pin_to_stack = true
#id stack для добавления компьюта на этот стэк
#опциональный параметр #id stack для добавления компьюта на этот стэк
#тип - число #опциональный параметр
target_stack_id = 1 #тип - число
target_stack_id = 1
#Флаг для принужительного добавления компьюта на стэк
#опциональный параметр #Флаг для принужительного добавления компьюта на стэк
#тип - булев #опциональный параметр
force_pin = true #тип - булев
force_pin = true
#Флаг доступности компьюта для проведения с ним операций
#опциональный параметр #Флаг доступности компьюта для проведения с ним операций
#тип - булев #опциональный параметр
enabled = true #тип - булев
enabled = true
#pause/resume компьюта
#опциональный параметр #pause/resume компьюта
#тип - булев #опциональный параметр
pause = true #тип - булев
pause = true
#сделать компьют заново
#опциональный параметр #сделать компьют заново
#тип - булев #опциональный параметр
reset = true #тип - булев
reset = true
#восстановить удаленный компьют из корзины
#опциональный параметр #восстановить удаленный компьют из корзины
#тип - булев #опциональный параметр
restore = true #тип - булев
restore = true
#флаг для редеплоя компьюта
#опциональный параметр #флаг для редеплоя компьюта
#тип - булев #опциональный параметр
auto_start = true #тип - булев
auto_start = true
#флаг для редеплоя компьюта
#опциональный параметр #флаг для редеплоя компьюта
#тип - булев #опциональный параметр
force_stop = true #тип - булев
force_stop = true
#поле для редеплоя компьюта
#опциональный параметр #флаг для ресайза компьюта
#тип - строка #опциональный параметр
data_disks = "KEEP" #тип - булев
force_resize = true
#запуск/стоп компьюта
#опциональный параметр #поле для редеплоя компьюта
#тип - булев #опциональный параметр
started = true #тип - строка
data_disks = "KEEP"
#detach диска при удалении компьюта
#опциональный параметр #запуск/стоп компьюта
#тип - булев #опциональный параметр
detach_disks = true #тип - булев
started = true
#Флаг для удаления компьюта
#опциональный параметр #detach диска при удалении компьюта
#тип - bool #опциональный параметр
permanently = false #тип - булев
} detach_disks = true
output "test" { #Флаг для удаления компьюта
value = decort_cb_kvmvm.comp #опциональный параметр
} #тип - bool
permanently = false
}
output "test" {
value = decort_cb_kvmvm.comp
}

@ -18,12 +18,10 @@
@echo off @echo off
FOR %%f IN (bin\*) DO ( cd /d "%~dp0"
if "%%~xf" == ".exe" ( pushd .\bin\
set filename=bin\%%~nf for %%f in (*.exe) do (
) else ( set filename=%%~nf
set filename=%%f
)
) )
for /F "tokens=1,2,3,4 delims=_" %%a in ("%filename%") do ( for /F "tokens=1,2,3,4 delims=_" %%a in ("%filename%") do (
@ -32,27 +30,16 @@ for /F "tokens=1,2,3,4 delims=_" %%a in ("%filename%") do (
set arch=%%d set arch=%%d
) )
if "%os%" neq "windows" (
echo Unable to find provider executable, is it moved or renamed?
pause
exit /b
)
set provider_path=%appdata%\terraform.d\plugins\basis\decort\decort\%version%\%os%_%arch%\ set provider_path=%appdata%\terraform.d\plugins\basis\decort\decort\%version%\%os%_%arch%\
if exist %provider_path% ( if exist %provider_path% (
echo Provider directory already exists, checking for decort provider executable.. echo Provider directory already exists, checking for decort provider executable..
dir /b /s /a "%provider_path%" | findstr .>nul || ( copy /y %filename%.exe %provider_path%
copy %filename% %provider_path%\terraform-provider-decort.exe
if errorlevel 1 ( if errorlevel 1 (
pause pause
exit /b exit /b
) )
call :print_success call :print_success
pause
exit /b
)
echo DECORT provider version %version% is already installed. Exiting.
pause pause
exit /b exit /b
) else ( ) else (
@ -62,7 +49,7 @@ if exist %provider_path% (
pause pause
exit /b exit /b
) )
copy %filename% %provider_path%\terraform-provider-decort.exe copy %filename%.exe %provider_path%
if errorlevel 1 ( if errorlevel 1 (
pause pause
exit /b exit /b
@ -84,4 +71,4 @@ echo source = "basis/decort/decort"
echo } echo }
echo } echo }
echo } echo }
goto:eof goto:eof

@ -47,7 +47,7 @@ install () {
then then
echo "Provider directory already exists, checking for decort provider executable.." echo "Provider directory already exists, checking for decort provider executable.."
if [[ ! "$(ls -A $plugins_dir$provider_path)" ]]; then if [[ ! "$(ls -A $plugins_dir$provider_path)" ]]; then
cp bin/terraform-provider-decort_$version\_$os\_$arch $plugins_dir$provider_path/terraform-provider-decort cp bin/terraform-provider-decort_$version\_$os\_$arch $plugins_dir$provider_path/terraform-provider-decort_$version/$os\_$arch
print_info print_info
else else
echo "DECORT provider version $version is already installed. Exiting.." echo "DECORT provider version $version is already installed. Exiting.."
@ -56,7 +56,7 @@ install () {
else else
echo "Creating provider directory.." echo "Creating provider directory.."
mkdir -p $plugins_dir/$provider_path mkdir -p $plugins_dir/$provider_path
cp bin/terraform-provider-decort_$version\_$os\_$arch $plugins_dir$provider_path/terraform-provider-decort cp bin/terraform-provider-decort_$version\_$os\_$arch $plugins_dir$provider_path/terraform-provider-decort_$version/$os\_$arch
echo "DECORT provider version $version has been successfully installed" echo "DECORT provider version $version has been successfully installed"
print_info print_info
fi fi

Loading…
Cancel
Save