Compare commits

..

6 Commits
4.4.1 ... 4.5.2

Author SHA1 Message Date
f49d9f8860 4.5.2 2023-12-19 16:37:50 +03:00
20050bc169 4.5.1 2023-12-18 18:55:52 +03:00
e2ee45ee14 4.5.1 2023-12-18 18:36:55 +03:00
Nikita Sorokin
294680282e 4.5.0 2023-11-13 00:59:02 +03:00
Nikita Sorokin
2bc0fbae9a 4.5.0-alpha 2023-11-07 18:26:09 +03:00
Nikita Sorokin
2453a32d01 4.4.2 2023-10-18 08:30:37 +03:00
676 changed files with 70891 additions and 26596 deletions

View File

@@ -1,25 +1,36 @@
## Version 4.4.1
## Version 4.5.2
### Bugfix
- Add in cloudapi in account/data_source_account_templates_list fields for filters - image_id, name, type, page, size.
- Add in cloudapi in disks/data_source_disk_list_types_detailed, disks/data_source_disk_list_types fields for filters - page, size.
- Add in cloudapi in disks/data_source_disk_list, disks/data_source_disk_list_unattached fields for filters - account_id, type, sep_id, pool_name, page, size.
- Add in cloudapi in extnet/data_source_extnet_computes_list fields for filters - rg_id, compute_id, page, size.
- Add in cloudapi in k8s/data_source_k8s_list_deleted fields for filters page, size, delete field for filters status. In k8s/data_source_k8s_list add fields for filters page, size, includedeleted.
- Add in cloudapi in rg/data_source_rg_affinity_groups_list fields for filters - page, size.
- Fixed tag Required in rg/data_source_rg_list_vins fields - vins_id, page, size.
- Fixed panic in pfw
- Fixed panic in image_virtual
- Fixed error reading data_source_vins_static_route
- Fixed static_route deletion
- Fixed start bservice and bservice_group
## Feature
- Add in cloudapi in account "data_source_account_get_resource_consumption" and "data_source_account_resource_consumption_list".
- Add in cloudapi in kvmvm "data_source_compute_list_deleted", "data_source_compute_pci_device_list", "data_source_compute_vgpu_list".
- Add in cloudapi in rg "data_source_rg_get_resource_consumption", "data_source_rg_resource_consumption_list".
- Add in cloudapi in k8s "decort_k8s_wg_cloud_init".
- Upgraded image_id existence check
- Added sample of image_virtual config
- Added cloud_init parameter to decort_k8s_wg resource
- Added resource_limits.cu_dm string field for account, account_consumed_units and account_reserved_units data sources in cloudapi/account
- Fixed restore of account resource in cloudapi/account, it happens if restore parameter is set to true
- Fixed restore of bservice resource in cloudapi/bservice, it happens if restore parameter is set to true and only once
- Fixed enable of bservice resource in cloudapi/bservice, it happens if enable parameter is set to true
- Fixed terraform state update for bservice resource update in cloudapi/bservice
- Fixed terraform state update for bservice_group resource update in cloudapi/bservice
- Added entry_count field for bservice_snapshot_list data source in cloudapi/bservice
- Added items.shareable boolean field for disk_list_unattached data source in cloudapi/disks
- Added items.status string field for extnet_list data source in cloudapi/extnet
- Fixed multiple minor typos in samples/cloudapi
- 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
- Removed net_mask string, ckey string fields for flipgroup data source and resource in cloudapi/flipgroup
- Add meta list field for flipgroup_list data source in cloudapi/flipgroup
- Fixed net_mask string field for fligroup_list data source in cloudapi/flipgroup
- Fixed id string field for image data source in cloudapi/image
- Fix account_name string field for k8s_list data source in cloudapi/k8s
- Add network_plugin string field for k8s and k8s_list data sources in cloudapi/k8s
- Fixed terraform state update for k8s, k8_cp and k8s_wg resources update in cloudapi/k8s
- Add image_name string, interfaces.enabled boolean fields for compute data source in cloudapi/kvmvm
- Add the interfaces field to the creation request in cloudapi/kvmvm
- Fixed restore of kvmvm resource in cloudapi/kvmvm, it happens if restore parameter is set to true
- 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
- Token receipt has been removed from the controller
- 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
- 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 fields backend_haip and frontend_haip in data source rg list in cloudapi/rg
- 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

View File

@@ -7,7 +7,7 @@ ZIPDIR = ./zip
BINARY=${NAME}
WORKPATH= ./examples/terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH}
MAINPATH = ./cmd/decort/
VERSION=4.4.1
VERSION=4.5.2
OS_ARCH=$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH)
FILES = ${BINARY}_${VERSION}_darwin_amd64\

View File

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

View File

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

15
go.mod
View File

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

30
go.sum
View File

@@ -58,15 +58,13 @@ 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/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
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.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.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
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/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.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -249,8 +247,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-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.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -265,8 +263,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/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=
@@ -293,8 +291,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@@ -304,8 +302,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.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.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@@ -322,8 +320,8 @@ google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
google.golang.org/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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
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 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -339,5 +337,5 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
repository.basistech.ru/BASIS/decort-golang-sdk v1.6.5 h1:37OLNiSgF3SXjj0ZMRikVrBiNlNdS9NY8QxD9YFfHBY=
repository.basistech.ru/BASIS/decort-golang-sdk v1.6.5/go.mod h1:szsTGa73O75ckCWVGJPvTtRbhA/ubuYrYhMkPjvHlmE=
repository.basistech.ru/BASIS/decort-golang-sdk v1.7.3 h1:NtvW72WsAezk0XYKE5+ag+xauIgKWKcbKLy7YTp5Fuc=
repository.basistech.ru/BASIS/decort-golang-sdk v1.7.3/go.mod h1:7fj8sgGZFiiExewQeqckCS4WxwOmU0oP6BO6mi1Lpkw=

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
@@ -21,17 +21,15 @@ limitations under the License.
package controller
import (
"bytes"
"crypto/tls"
"fmt"
"io/ioutil"
"io"
"net/http"
"net/url"
"strconv"
"strings"
// "time"
log "github.com/sirupsen/logrus"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
@@ -39,31 +37,37 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker"
jwt "github.com/golang-jwt/jwt/v4"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
// enumerated constants that define authentication modes
const (
MODE_UNDEF = iota // this is the invalid mode - it should never be seen
MODE_LEGACY = iota
MODE_OAUTH2 = iota
MODE_JWT = iota
MODE_LEGACY
MODE_DECS3O
MODE_JWT
MODE_BVS
)
type ControllerCfg struct {
controller_url string // always required
auth_mode_code int // always required
auth_mode_txt string // always required, it is a text representation of auth mode
bvs_user string // required for bvs mode
bvs_password string // required for bvs mode
domain string // required for bvs mode
token config.Token // obtained from BVS provider on successful login in bvs mode
path_cfg string // the path of the configuration file entry
path_token string // the path of the token file entry
time_to_refresh int64 // the number of minutes before the expiration of the token, a refresh will be made
legacy_user string // required for legacy mode
legacy_password string // required for legacy mode
legacy_sid string // obtained from DECORT controller on successful login in legacy mode
jwt string // obtained from Outh2 provider on successful login in oauth2 mode, required in jwt mode
app_id string // required for oauth2 mode
app_secret string // required for oauth2 mode
oauth2_url string // always required
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification
jwt string // obtained from Outh2 provider on successful login in decs3o mode, required in jwt mode
app_id string // required for decs3o and bvs mode
app_secret string // required for decs3o and bvs mode
oauth2_url string // required for decs3o and bvs mode
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (decs3o mode) upon successful verification
cc_client *http.Client // assigned when all initial checks successfully passed
caller interfaces.Caller
}
@@ -86,17 +90,24 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
legacy_user: d.Get("user").(string),
legacy_password: d.Get("password").(string),
legacy_sid: "",
bvs_user: d.Get("bvs_user").(string),
bvs_password: d.Get("bvs_password").(string),
domain: d.Get("domain").(string),
jwt: d.Get("jwt").(string),
app_id: d.Get("app_id").(string),
app_secret: d.Get("app_secret").(string),
oauth2_url: d.Get("oauth2_url").(string),
decort_username: "",
token: config.Token{},
path_cfg: d.Get("path_cfg").(string),
path_token: d.Get("path_token").(string),
time_to_refresh: int64(d.Get("time_to_refresh").(int)),
}
allow_unverified_ssl := d.Get("allow_unverified_ssl").(bool)
if ret_config.controller_url == "" {
return nil, fmt.Errorf("Empty DECORT cloud controller URL provided.")
return nil, fmt.Errorf("empty DECORT cloud controller URL provided")
}
// this should have already been done by StateFunc defined in Schema, but we want to be sure
@@ -105,33 +116,53 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
switch ret_config.auth_mode_txt {
case "jwt":
if ret_config.jwt == "" {
return nil, fmt.Errorf("Authenticator mode 'jwt' specified but no JWT provided.")
return nil, fmt.Errorf("authenticator mode 'jwt' specified but no JWT provided")
}
ret_config.auth_mode_code = MODE_JWT
case "oauth2":
case "decs3o":
if ret_config.oauth2_url == "" {
return nil, fmt.Errorf("Authenticator mode 'oauth2' specified but no OAuth2 URL provided.")
return nil, fmt.Errorf("authenticator mode 'decs3o' specified but no OAuth2 URL provided")
}
if ret_config.app_id == "" {
return nil, fmt.Errorf("Authenticator mode 'oauth2' specified but no Application ID provided.")
return nil, fmt.Errorf("authenticator mode 'decs3o' specified but no Application ID provided")
}
if ret_config.app_secret == "" {
return nil, fmt.Errorf("Authenticator mode 'oauth2' specified but no Secret ID provided.")
return nil, fmt.Errorf("authenticator mode 'decs3o' specified but no Secret ID provided")
}
ret_config.auth_mode_code = MODE_OAUTH2
ret_config.auth_mode_code = MODE_DECS3O
case "legacy":
//
ret_config.legacy_user = d.Get("user").(string)
if ret_config.legacy_user == "" {
return nil, fmt.Errorf("Authenticator mode 'legacy' specified but no user provided.")
return nil, fmt.Errorf("authenticator mode 'legacy' specified but no user provided")
}
ret_config.legacy_password = d.Get("password").(string)
if ret_config.legacy_password == "" {
return nil, fmt.Errorf("Authenticator mode 'legacy' specified but no password provided.")
return nil, fmt.Errorf("authenticator mode 'legacy' specified but no password provided")
}
ret_config.auth_mode_code = MODE_LEGACY
case "bvs":
if ret_config.bvs_user == "" {
return nil, fmt.Errorf("authenticator mode 'bvs' specified but no user provided")
}
if ret_config.bvs_password == "" {
return nil, fmt.Errorf("authenticator mode 'bvs' specified but no password provided")
}
if ret_config.oauth2_url == "" {
return nil, fmt.Errorf("authenticator mode 'bvs' specified but no bvs URL provided")
}
if ret_config.app_id == "" {
return nil, fmt.Errorf("authenticator mode 'bvs' specified but no Application ID provided")
}
if ret_config.app_secret == "" {
return nil, fmt.Errorf("authenticator mode 'bvs' specified but no Secret ID provided")
}
if ret_config.domain == "" {
return nil, fmt.Errorf("authenticator mode 'bvs' specified but no Domain provided")
}
ret_config.auth_mode_code = MODE_BVS
default:
return nil, fmt.Errorf("Unknown authenticator mode %q provided.", ret_config.auth_mode_txt)
return nil, fmt.Errorf("unknown authenticator mode %q provided", ret_config.auth_mode_txt)
}
if allow_unverified_ssl {
@@ -167,30 +198,30 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
if !ok {
return nil, err
}
case MODE_OAUTH2:
// on success getOAuth2JWT will set config.jwt to the obtained JWT, so there is no
case MODE_DECS3O:
// on success getDECS3OJWT will set config.jwt to the obtained JWT, so there is no
// need to set it once again here
_, err := ret_config.getOAuth2JWT()
if err != nil {
return nil, err
}
// _, err := ret_config.getDECS3OJWT()
// if err != nil {
// return nil, err
// }
// we are not verifying the JWT when parsing because actual verification is done on the
// OVC controller side. Here we do parsing solely to extract Oauth2 user name (claim "user")
// and JWT issuer name (claim "iss")
parser := jwt.Parser{}
token, _, err := parser.ParseUnverified(ret_config.jwt, jwt.MapClaims{})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(jwt.MapClaims); ok {
var tbuf bytes.Buffer
tbuf.WriteString(claims["username"].(string))
tbuf.WriteString("@")
tbuf.WriteString(claims["iss"].(string))
ret_config.decort_username = tbuf.String()
} else {
return nil, fmt.Errorf("Failed to extract user and iss fields from JWT token in oauth2 mode.")
}
// parser := jwt.Parser{}
// token, _, err := parser.ParseUnverified(ret_config.jwt, jwt.MapClaims{})
// if err != nil {
// return nil, err
// }
// if claims, ok := token.Claims.(jwt.MapClaims); ok {
// var tbuf bytes.Buffer
// tbuf.WriteString(claims["username"].(string))
// tbuf.WriteString("@")
// tbuf.WriteString(claims["iss"].(string))
// ret_config.decort_username = tbuf.String()
// } else {
// return nil, fmt.Errorf("failed to extract user and iss fields from JWT token in oauth2 mode")
// }
sdkConf := config.Config{
AppID: ret_config.app_id,
@@ -201,10 +232,27 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
}
ret_config.caller = decort.New(sdkConf)
case MODE_BVS:
sdkConf := config.BVSConfig{
AppID: ret_config.app_id,
AppSecret: ret_config.app_secret,
SSOURL: ret_config.oauth2_url,
DecortURL: ret_config.controller_url,
SSLSkipVerify: allow_unverified_ssl,
Username: ret_config.bvs_user,
Password: ret_config.bvs_password,
Domain: ret_config.domain,
Token: ret_config.token,
PathCfg: ret_config.path_cfg,
PathToken: ret_config.path_token,
TimeToRefresh: ret_config.time_to_refresh,
}
ret_config.caller = decort.NewBVS(sdkConf)
default:
// FYI, this should never happen due to all above checks, but we want to be fool proof
return nil, fmt.Errorf("Unknown authenticator mode code %d provided.", ret_config.auth_mode_code)
return nil, fmt.Errorf("unknown authenticator mode code %d provided", ret_config.auth_mode_code)
}
// All checks passed successfully, credentials corresponding to the selected authenticator mode
@@ -212,57 +260,57 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
return ret_config, nil
}
func (config *ControllerCfg) GetDecortUsername() string {
return config.decort_username
}
// func (config *ControllerCfg) GetDecortUsername() string {
// return config.decort_username
// }
func (config *ControllerCfg) getOAuth2JWT() (string, error) {
// Obtain JWT from the Oauth2 provider using application ID and application secret provided in config.
if config.auth_mode_code == MODE_UNDEF {
return "", fmt.Errorf("getOAuth2JWT method called for undefined authorization mode.")
}
if config.auth_mode_code != MODE_OAUTH2 {
return "", fmt.Errorf("getOAuth2JWT method called for incompatible authorization mode %q.", config.auth_mode_txt)
}
// func (config *ControllerCfg) getDECS3OJWT() (string, error) {
// // Obtain JWT from the Oauth2 provider using application ID and application secret provided in config.
// if config.auth_mode_code == MODE_UNDEF {
// return "", fmt.Errorf("getOAuth2JWT method called for undefined authorization mode")
// }
// if config.auth_mode_code != MODE_DECS3O {
// return "", fmt.Errorf("getOAuth2JWT method called for incompatible authorization mode %q", config.auth_mode_txt)
// }
params := url.Values{}
params.Add("grant_type", "client_credentials")
params.Add("client_id", config.app_id)
params.Add("client_secret", config.app_secret)
params.Add("response_type", "id_token")
params.Add("validity", "3600")
params_str := params.Encode()
// params := url.Values{}
// params.Add("grant_type", "client_credentials")
// params.Add("client_id", config.app_id)
// params.Add("client_secret", config.app_secret)
// params.Add("response_type", "id_token")
// params.Add("validity", "3600")
// params_str := params.Encode()
req, err := http.NewRequest("POST", config.oauth2_url+"/v1/oauth/access_token", strings.NewReader(params_str))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
// req, err := http.NewRequest("POST", config.oauth2_url+"/v1/oauth/access_token", strings.NewReader(params_str))
// if err != nil {
// return "", err
// }
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
resp, err := config.cc_client.Do(req)
if err != nil {
return "", err
}
if resp.StatusCode != http.StatusOK {
// fmt.Println("response Status:", resp.Status)
// fmt.Println("response Headers:", resp.Header)
// fmt.Println("response Headers:", req.URL)
return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q",
resp.StatusCode, req.URL, config.app_id, params_str)
}
defer resp.Body.Close()
// resp, err := config.cc_client.Do(req)
// if err != nil {
// return "", err
// }
// if resp.StatusCode != http.StatusOK {
// // fmt.Println("response Status:", resp.Status)
// // fmt.Println("response Headers:", resp.Header)
// // fmt.Println("response Headers:", req.URL)
// return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q",
// resp.StatusCode, req.URL, config.app_id, params_str)
// }
// defer resp.Body.Close()
responseData, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
// responseData, err := io.ReadAll(resp.Body)
// if err != nil {
// return "", err
// }
// validation successful - store JWT in the corresponding field of the ControllerCfg structure
config.jwt = strings.TrimSpace(string(responseData))
// // validation successful - store JWT in the corresponding field of the ControllerCfg structure
// config.jwt = strings.TrimSpace(string(responseData))
return config.jwt, nil
}
// return config.jwt, nil
// }
func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
/*
@@ -273,13 +321,13 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
*/
if jwt == "" {
if config.jwt == "" {
return false, fmt.Errorf("validateJWT method called, but no meaningful JWT provided.")
return false, fmt.Errorf("validateJWT method called, but no meaningful JWT provided")
}
jwt = config.jwt
}
if config.oauth2_url == "" {
return false, fmt.Errorf("validateJWT method called, but no OAuth2 URL provided.")
return false, fmt.Errorf("validateJWT method called, but no OAuth2 URL provided")
}
req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/account/list", nil)
@@ -296,7 +344,7 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
return false, err
}
if resp.StatusCode != http.StatusOK {
return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q.",
return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q",
resp.StatusCode, req.URL)
}
defer resp.Body.Close()
@@ -312,10 +360,10 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
reason, the method will return false and error.
*/
if config.auth_mode_code == MODE_UNDEF {
return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode.")
return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode")
}
if config.auth_mode_code != MODE_LEGACY {
return false, fmt.Errorf("validateLegacyUser method called for incompatible authorization mode %q.", config.auth_mode_txt)
return false, fmt.Errorf("validateLegacyUser method called for incompatible authorization mode %q", config.auth_mode_txt)
}
params := url.Values{}
@@ -336,12 +384,12 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
return false, err
}
if resp.StatusCode != http.StatusOK {
return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q.",
return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q",
resp.StatusCode, config.legacy_user, config.controller_url)
}
defer resp.Body.Close()
responseData, err := ioutil.ReadAll(resp.Body)
responseData, err := io.ReadAll(req.Body)
if err != nil {
log.Fatal(err)
}
@@ -353,21 +401,32 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
}
func (config *ControllerCfg) CloudAPI() *cloudapi.CloudAPI {
if config.auth_mode_code == MODE_LEGACY {
switch config.auth_mode_code {
case MODE_LEGACY:
client, _ := config.caller.(*decort.LegacyDecortClient)
return client.CloudAPI()
}
case MODE_DECS3O:
client, _ := config.caller.(*decort.DecortClient)
return client.CloudAPI()
case MODE_BVS:
client, _ := config.caller.(*decort.BVSDecortClient)
return client.CloudAPI()
default:
return &cloudapi.CloudAPI{}
}
}
func (config *ControllerCfg) CloudBroker() *cloudbroker.CloudBroker {
if config.auth_mode_code == MODE_LEGACY {
switch config.auth_mode_code {
case MODE_LEGACY:
client, _ := config.caller.(*decort.LegacyDecortClient)
return client.CloudBroker()
}
case MODE_DECS3O:
client, _ := config.caller.(*decort.DecortClient)
return client.CloudBroker()
case MODE_BVS:
client, _ := config.caller.(*decort.BVSDecortClient)
return client.CloudBroker()
default:
return &cloudbroker.CloudBroker{}
}
}

View File

@@ -1,8 +1,12 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Nikita Sorokin, <nesorokin@basistech.ru>
Tim Tkachev, <tvtkachev@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -29,9 +33,33 @@ builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package snapshot
package dc
const snapshotCreateAPI = "/restmachine/cloudbroker/compute/snapshotCreate"
const snapshotDeleteAPI = "/restmachine/cloudbroker/compute/snapshotDelete"
const snapshotRollbackAPI = "/restmachine/cloudbroker/compute/snapshotRollback"
const snapshotListAPI = "/restmachine/cloudbroker/compute/snapshotList"
import "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
func ErrorsToDiagnostics(errs []error) diag.Diagnostics {
if len(errs) == 0 {
return nil
}
diags := diag.Diagnostics{}
for _, err := range errs {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: err.Error(),
})
}
return diags
}
func ErrorsToWarnings(errs []error) Warnings {
w := Warnings{}
for _, err := range errs {
w.Add(err)
}
return w
}

View File

@@ -38,25 +38,31 @@ import (
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vins"
cb_account "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/account"
cb_audit "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/audit"
cb_disks "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/disks"
cb_extnet "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/extnet"
cb_flipgroup "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/flipgroup"
cb_grid "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/grid"
cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image"
cb_kvmvm "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/kvmvm"
cb_lb "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/lb"
cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice"
cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg"
cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep"
cb_vgpu "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vgpu"
cb_stack "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/stack"
cb_vins "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins"
// cb_vgpu "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vgpu"
cb_k8ci "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8ci"
cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s"
)
func newDataSourcesMap() map[string]*schema.Resource {
return map[string]*schema.Resource{
"decort_account": account.DataSourceAccount(),
"decort_account_resource_consumption_list": account.DataSourceAccountResourceConsumptionList(),
"decort_account_resource_consumption_get": account.DataSourceAccountResourceConsumptionGet(),
"decort_resgroup": rg.DataSourceResgroup(),
"decort_kvmvm": kvmvm.DataSourceCompute(),
"decort_kvmvm_list": kvmvm.DataSourceComputeList(),
"decort_kvmvm_list_deleted": kvmvm.DataSourceComputeListDeleted(),
"decort_kvmvm_audits": kvmvm.DataSourceComputeAudits(),
"decort_kvmvm_get_audits": kvmvm.DataSourceComputeGetAudits(),
"decort_kvmvm_get_console_url": kvmvm.DataSourceComputeGetConsoleUrl(),
@@ -64,15 +70,12 @@ func newDataSourcesMap() map[string]*schema.Resource {
"decort_kvmvm_pfw_list": kvmvm.DataSourceComputePfwList(),
"decort_kvmvm_user_list": kvmvm.DataSourceComputeUserList(),
"decort_kvmvm_snapshot_usage": kvmvm.DataSourceComputeSnapshotUsage(),
"decort_kvmvm_vgpu_list": kvmvm.DataSourceComputeVGPUList(),
"decort_kvmvm_pci_device_list": kvmvm.DataSourceComputePCIDeviceList(),
"decort_k8s": k8s.DataSourceK8s(),
"decort_k8s_list": k8s.DataSourceK8sList(),
"decort_k8s_list_deleted": k8s.DataSourceK8sListDeleted(),
"decort_k8s_wg": k8s.DataSourceK8sWg(),
"decort_k8s_wg_list": k8s.DataSourceK8sWgList(),
"decort_k8s_computes": k8s.DataSourceK8sComputes(),
"decort_k8s_wg_cloud_init": k8s.DataSourceK8sWgCloudInit(),
"decort_k8ci_list": k8s.DataSourceK8CIList(),
"decort_vins": vins.DataSourceVins(),
"decort_vins_list": vins.DataSourceVinsList(),
@@ -96,8 +99,6 @@ func newDataSourcesMap() map[string]*schema.Resource {
"decort_rg_list_lb": rg.DataSourceRgListLb(),
"decort_rg_list_pfw": rg.DataSourceRgListPfw(),
"decort_rg_list_vins": rg.DataSourceRgListVins(),
"decort_rg_resource_consumption_list": rg.DataSourceRGResourceConsumptionList(),
"decort_rg_resource_consumption_get": rg.DataSourceRGResourceConsumptionGet(),
"decort_rg_usage": rg.DataSourceRgUsage(),
"decort_disk_list_types_detailed": disks.DataSourceDiskListTypesDetailed(),
"decort_disk_list_types": disks.DataSourceDiskListTypes(),
@@ -137,36 +138,117 @@ func newDataSourcesMap() map[string]*schema.Resource {
"decort_flipgroup_list": flipgroup.DataSourceFlipGroupList(),
"decort_stack": stack.DataSourceStack(),
"decort_stack_list": stack.DataSourceStackList(),
"decort_account_resource_consumption_list": account.DataSourceAccountResourceConsumptionList(),
"decort_account_resource_consumption_get": account.DataSourceAccountResourceConsumptionGet(),
"decort_kvmvm_list_deleted": kvmvm.DataSourceComputeListDeleted(),
"decort_kvmvm_vgpu_list": kvmvm.DataSourceComputeVGPUList(),
"decort_kvmvm_pci_device_list": kvmvm.DataSourceComputePCIDeviceList(),
"decort_k8s_wg_cloud_init": k8s.DataSourceK8sWgCloudInit(),
"decort_rg_resource_consumption_list": rg.DataSourceRGResourceConsumptionList(),
"decort_rg_resource_consumption_get": rg.DataSourceRGResourceConsumptionGet(),
"decort_cb_account": cb_account.DataSourceAccount(),
"decort_cb_account_list": cb_account.DataSourceAccountList(),
"decort_cb_account_computes_list": cb_account.DataSourceAccountComputesList(),
"decort_cb_account_deleted_list": cb_account.DataSourceAccountDeletedList(),
"decort_cb_account_list_deleted": cb_account.DataSourceAccountDeletedList(),
"decort_cb_account_disks_list": cb_account.DataSourceAccountDisksList(),
"decort_cb_account_flipgroups_list": cb_account.DataSourceAccountFlipGroupsList(),
"decort_cb_account_rg_list": cb_account.DataSourceAccountRGList(),
"decort_cb_account_vins_list": cb_account.DataSourceAccountVinsList(),
"decort_cb_account_resource_consumption_get": cb_account.DataSourceAccountResourceConsumptionGet(),
"decort_cb_account_resource_consumption_list": cb_account.DataSourceAccountResourceConsumptionList(),
"decort_cb_account_audits_list": cb_account.DataSourceAccountAuditsList(),
"decort_cb_audit": cb_audit.DataSourceAudit(),
"decort_cb_audit_list": cb_audit.DataSourceAuditList(),
"decort_cb_audit_linked_jobs": cb_audit.DataSourceAuditLinkedJobs(),
"decort_cb_extnet": cb_extnet.DataSourceExtnetCB(),
"decort_cb_extnet_list": cb_extnet.DataSourceExtnetListCB(),
"decort_cb_extnet_default": cb_extnet.DataSourceExtnetDefaultCB(),
"decort_cb_disk": cb_disks.DataSourceDisk(),
"decort_cb_disk_list": cb_disks.DataSourceDiskList(),
"decort_cb_extnet_static_route_list": cb_extnet.DataSourceStaticRouteList(),
"decort_cb_extnet_static_route": cb_extnet.DataSourceStaticRoute(),
"decort_cb_image": cb_image.DataSourceImage(),
"decort_cb_grid": cb_grid.DataSourceGrid(),
"decort_cb_grid_get_status": cb_grid.DataSourceGridGetStatus(),
"decort_cb_grid_post_status": cb_grid.DataSourceGridPostStatus(),
"decort_cb_grid_get_diagnosis": cb_grid.DataSourceGridGetDiagnosis(),
"decort_cb_grid_post_diagnosis": cb_grid.DataSourceGridPostDiagnosis(),
"decort_cb_grid_list": cb_grid.DataSourceGridList(),
"decort_cb_grid_list_emails": cb_grid.DataSourceGridListEmails(),
"decort_cb_grid_list_consumption": cb_grid.DataSourceGridListConsumption(),
"decort_cb_grid_get_consumption": cb_grid.DataSourceGridGetConsumption(),
"decort_cb_image_list": cb_image.DataSourceImageList(),
"decort_cb_image_list_stacks": cb_image.DataSourceImageListStacks(),
"decort_cb_kvmvm": cb_kvmvm.DataSourceCompute(),
"decort_cb_kvmvm_affinity_relations": cb_kvmvm.DataSourceComputeAffinityRelations(),
"decort_cb_kvmvm_audits": cb_kvmvm.DataSourceComputeAudits(),
"decort_cb_kvmvm_boot_order_get": cb_kvmvm.DataSourceComputeBootOrderGet(),
"decort_cb_kvmvm_get_audits": cb_kvmvm.DataSourceComputeGetAudits(),
"decort_cb_kvmvm_get_console_url": cb_kvmvm.DataSourceComputeGetConsoleUrl(),
"decort_cb_kvmvm_get_log": cb_kvmvm.DataSourceComputeGetLog(),
"decort_cb_kvmvm_list": cb_kvmvm.DataSourceComputeList(),
"decort_cb_kvmvm_list_deleted": cb_kvmvm.DataSourceComputeListDeleted(),
"decort_cb_kvmvm_migrate_storage_info": cb_kvmvm.DataSourceComputeMigrateStorageInfo(),
"decort_cb_kvmvm_pci_device_list": cb_kvmvm.DataSourceComputePCIDeviceList(),
"decort_cb_kvmvm_pfw_list": cb_kvmvm.DataSourceComputePfwList(),
"decort_cb_kvmvm_snapshot_list": cb_kvmvm.DataSourceComputeSnapshotList(),
"decort_cb_kvmvm_snapshot_usage": cb_kvmvm.DataSourceComputeSnapshotUsage(),
"decort_cb_kvmvm_user_list": cb_kvmvm.DataSourceComputeUserList(),
"decort_cb_kvmvm_vgpu_list": cb_kvmvm.DataSourceComputeVGPUList(),
"decort_cb_disk": cb_disks.DataSourceDisk(),
"decort_cb_disk_list": cb_disks.DataSourceDiskList(),
"decort_cb_disk_list_deleted": cb_disks.DataSourceDiskListDeleted(),
"decort_cb_disk_list_types": cb_disks.DataSourceDiskListTypes(),
"decort_cb_disk_list_types_detailed": cb_disks.DataSourceDiskListTypesDetailed(),
"decort_cb_disk_list_unattached": cb_disks.DataSourceDiskListUnattached(),
"decort_cb_disk_snapshot": cb_disks.DataSourceDiskSnapshot(),
"decort_cb_disk_snapshot_list": cb_disks.DataSourceDiskSnapshotList(),
"decort_cb_pcidevice": cb_pcidevice.DataSourcePcidevice(),
"decort_cb_pcidevice_list": cb_pcidevice.DataSourcePcideviceList(),
"decort_cb_rg": cb_rg.DataSourceResgroup(),
"decort_cb_rg_affinity_group_computes": cb_rg.DataSourceRgAffinityGroupComputes(),
"decort_cb_rg_affinity_groups_get": cb_rg.DataSourceRgAffinityGroupsGet(),
"decort_cb_rg_affinity_groups_list": cb_rg.DataSourceRgAffinityGroupsList(),
"decort_cb_rg_resource_consumption_get": cb_rg.DataSourceRGResourceConsumptionGet(),
"decort_cb_rg_resource_consumption_list": cb_rg.DataSourceRGResourceConsumptionList(),
"decort_cb_rg_audits": cb_rg.DataSourceRgAudits(),
"decort_cb_rg_list": cb_rg.DataSourceRgList(),
"decort_cb_rg_list_deleted": cb_rg.DataSourceRgListDeleted(),
"decort_cb_rg_list_computes": cb_rg.DataSourceRgListComputes(),
"decort_cb_rg_list_lb": cb_rg.DataSourceRgListLb(),
"decort_cb_rg_list_pfw": cb_rg.DataSourceRgListPfw(),
"decort_cb_rg_list_vins": cb_rg.DataSourceRgListVins(),
"decort_cb_rg_usage": cb_rg.DataSourceRgUsage(),
"decort_cb_sep_list": cb_sep.DataSourceSepList(),
"decort_cb_sep": cb_sep.DataSourceSep(),
"decort_cb_sep_consumption": cb_sep.DataSourceSepConsumption(),
"decort_cb_sep_disk_list": cb_sep.DataSourceSepDiskList(),
"decort_cb_sep_config": cb_sep.DataSourceSepConfig(),
"decort_cb_sep_pool": cb_sep.DataSourceSepPool(),
"decort_cb_vgpu": cb_vgpu.DataSourceVGPU(),
"decort_cb_rg_list": cb_rg.DataSourceRgList(),
"decort_cb_lb": cb_lb.DataSourceLB(),
"decort_cb_lb_list": cb_lb.DataSourceLBList(),
"decort_cb_lb_list_deleted": cb_lb.DataSourceLBListDeleted(),
"decort_cb_flipgroup_list": cb_flipgroup.DataSourceFlipgroupList(),
"decort_cb_flipgroup": cb_flipgroup.DataSourceFlipgroup(),
"decort_cb_stack_list": cb_stack.DataSourceStacksList(),
"decort_cb_stack": cb_stack.DataSourceStack(),
"decort_cb_vins": cb_vins.DataSourceVins(),
"decort_cb_vins_list": cb_vins.DataSourceVinsList(),
"decort_cb_vins_audits": cb_vins.DataSourceVinsAudits(),
"decort_cb_vins_ip_list": cb_vins.DataSourceVinsIpList(),
"decort_cb_vins_list_deleted": cb_vins.DataSourceVinsListDeleted(),
"decort_cb_vins_ext_net_list": cb_vins.DataSourceVinsExtNetList(),
"decort_cb_vins_nat_rule_list": cb_vins.DataSourceVinsNatRuleList(),
"decort_cb_vins_static_route": cb_vins.DataSourceStaticRoute(),
"decort_cb_vins_static_route_list": cb_vins.DataSourceStaticRouteList(),
"decort_cb_k8ci": cb_k8ci.DataSourceK8CI(),
"decort_cb_k8ci_list": cb_k8ci.DataSourceK8CIList(),
"decort_cb_k8ci_list_deleted": cb_k8ci.DataSourceK8CIListDeleted(),
"decort_cb_k8s": cb_k8s.DataSourceK8s(),
"decort_cb_k8s_list": cb_k8s.DataSourceK8sList(),
"decort_cb_k8s_list_deleted": cb_k8s.DataSourceK8sListDeleted(),
"decort_cb_k8s_wg": cb_k8s.DataSourceK8sWg(),
"decort_cb_k8s_wg_cloud_init": cb_k8s.DataSourceK8sWgCloudInit(),
"decort_cb_k8s_wg_list": cb_k8s.DataSourceK8sWgList(),
"decort_cb_k8s_computes": cb_k8s.DataSourceK8sComputes(),
}
}

View File

@@ -40,8 +40,8 @@ func Provider() *schema.Provider {
Type: schema.TypeString,
Required: true,
StateFunc: statefuncs.StateFuncToLower,
ValidateFunc: validation.StringInSlice([]string{"oauth2", "legacy", "jwt"}, true), // ignore case while validating
Description: "Authentication mode to use when connecting to DECORT cloud API. Should be one of 'oauth2', 'legacy' or 'jwt'.",
ValidateFunc: validation.StringInSlice([]string{"decs3o", "legacy", "jwt", "bvs"}, true), // ignore case while validating
Description: "Authentication mode to use when connecting to DECORT cloud API. Should be one of 'decs3o', 'legacy', 'jwt' or 'bvs'.",
},
"oauth2_url": {
@@ -49,7 +49,7 @@ func Provider() *schema.Provider {
Optional: true,
StateFunc: statefuncs.StateFuncToLower,
DefaultFunc: schema.EnvDefaultFunc("DECORT_OAUTH2_URL", nil),
Description: "OAuth2 application URL in 'oauth2' authentication mode.",
Description: "OAuth2 application URL in 'decs3o' and 'bvs' authentication mode.",
},
"controller_url": {
@@ -74,18 +74,39 @@ func Provider() *schema.Provider {
Description: "User password for DECORT cloud API operations in 'legacy' authentication mode.",
},
"bvs_user": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_BVS_USER", nil),
Description: "User name for DECORT cloud API operations in 'bvs' authentication mode.",
},
"bvs_password": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_BVS_PASSWORD", nil),
Description: "User password for DECORT cloud API operations in 'bvs' authentication mode.",
},
"domain": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_DOMAIN", nil),
Description: "User password for DECORT cloud API operations in 'bvs' authentication mode.",
},
"app_id": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_ID", nil),
Description: "Application ID to access DECORT cloud API in 'oauth2' authentication mode.",
Description: "Application ID to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode.",
},
"app_secret": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_SECRET", nil),
Description: "Application secret to access DECORT cloud API in 'oauth2' authentication mode.",
Description: "Application secret to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode.",
},
"jwt": {
@@ -101,6 +122,24 @@ func Provider() *schema.Provider {
Default: false,
Description: "If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only!",
},
"path_cfg": {
Type: schema.TypeString,
Optional: true,
Description: "The path of the configuration file entry",
},
"path_token": {
Type: schema.TypeString,
Optional: true,
Description: "The path of the token file entry",
},
"time_to_refresh": {
Type: schema.TypeInt,
Optional: true,
Description: "The number of minutes before the expiration of the token, a refresh will be made",
},
},
ResourcesMap: newResourcesMap(),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -148,7 +148,7 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf
case status.Destroying:
return diag.Errorf("The account is in progress with status: %s", acc.Status)
case status.Deleted:
if d.Get("restore").(bool) {
req := account.RestoreRequest{
AccountID: accountId,
}
@@ -159,6 +159,7 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf
}
hasChanged = true
}
case status.Disabled:
log.Debugf("The account is in status: %s, troubles may occur with update. Please, enable account first.", acc.Status)
case status.Confirmed:
@@ -184,6 +185,7 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf
if err != nil {
return diag.FromErr(err)
}
} else {
_, err := c.CloudAPI().Account().Disable(ctx, reqSwitch)
@@ -193,7 +195,6 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf
}
}
}
req := account.UpdateRequest{
AccountID: accountId,
@@ -280,8 +281,7 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf
if d.HasChange("restore") {
restore := d.Get("restore").(bool)
if restore {
if acc.Status == "DELETED" {
if restore && acc.Status == "DELETED" {
req := account.RestoreRequest{
AccountID: accountId,
}
@@ -291,7 +291,6 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf
}
}
}
}
if d.HasChange("users") {
deletedUsers := make([]interface{}, 0)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -111,7 +111,7 @@ func flattenBasicServiceComputes(bscs bservice.ListComputes) []map[string]interf
}
func flattenBasicServiceSnapshots(bsrvss bservice.ListSnapshots) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
res := make([]map[string]interface{}, 0, len(bsrvss))
for _, bsrvs := range bsrvss {
temp := map[string]interface{}{
"guid": bsrvs.GUID,
@@ -123,3 +123,17 @@ func flattenBasicServiceSnapshots(bsrvss bservice.ListSnapshots) []map[string]in
}
return res
}
func flattenBasicServiceSnapshotsList(bsrvss *bservice.ListInfoSnapshots) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(bsrvss.Data))
for _, bsrvs := range bsrvss.Data {
temp := map[string]interface{}{
"guid": bsrvs.GUID,
"label": bsrvs.Label,
"timestamp": bsrvs.Timestamp,
"valid": bsrvs.Valid,
}
res = append(res, temp)
}
return res
}

View File

@@ -94,7 +94,7 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i
}
}
if d.Get("start").(bool) && d.Get("enable").(bool) {
log.Debugf("trying to start bservice %v", serviceId)
log.Debugf("trying to enable bservice %v", serviceId)
_, err := c.CloudAPI().BService().Enable(ctx, bservice.EnableRequest{
ServiceID: serviceId,
})
@@ -102,6 +102,15 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i
if err != nil {
return diag.FromErr(err)
}
log.Debugf("trying to start bservice %v", serviceId)
_, err = c.CloudAPI().BService().Start(ctx, bservice.StartRequest{
ServiceID: serviceId,
})
if err != nil {
return diag.FromErr(err)
}
}
return resourceBasicServiceRead(ctx, d, m)
@@ -231,24 +240,45 @@ func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m i
log.Debugf("The basic service is in status: %s, troubles can occur with the update.", bs.Status)
case status.Deleted:
id, _ := strconv.ParseUint(d.Id(), 10, 64)
if restore, ok := d.GetOk("restore"); ok {
if restore.(bool) {
restoreReq := bservice.RestoreRequest{
ServiceID: id,
}
enableReq := bservice.EnableRequest{
ServiceID: id,
}
_, err := c.CloudAPI().BService().Restore(ctx, restoreReq)
if err != nil {
return diag.FromErr(err)
}
}
hasChanged = true
}
if enable, ok := d.GetOk("enable"); ok {
if enable.(bool) {
enableReq := bservice.EnableRequest{
ServiceID: id,
}
_, err = c.CloudAPI().BService().Enable(ctx, enableReq)
if err != nil {
return diag.FromErr(err)
}
hasChanged = true
}
}
if start, ok := d.GetOk("start"); ok {
if start.(bool) {
startReq := bservice.StartRequest{
ServiceID: id,
}
_, err = c.CloudAPI().BService().Start(ctx, startReq)
if err != nil {
return diag.FromErr(err)
}
hasChanged = true
}
}
case status.Deleting:
case status.Destroyed:
d.SetId("")
@@ -291,19 +321,6 @@ func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m i
}
}
if d.HasChange("restore") {
restore := d.Get("restore").(bool)
if restore {
req := bservice.RestoreRequest{
ServiceID: uint64(d.Get("service_id").(int)),
}
_, err := c.CloudAPI().BService().Restore(ctx, req)
if err != nil {
return diag.FromErr(err)
}
}
}
if d.HasChange("start") {
start := d.Get("start").(bool)
if start {
@@ -394,10 +411,9 @@ func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m i
}
}
}
}
return nil
return resourceBasicServiceRead(ctx, d, m)
}
func isContainsSnapshot(els []interface{}, el interface{}) bool {

View File

@@ -107,7 +107,7 @@ func resourceBasicServiceGroupCreate(ctx context.Context, d *schema.ResourceData
d.SetId(strconv.FormatUint(compgroupId, 10))
d.Set("compgroup_id", compgroupId)
serviceId:= uint64(d.Get("service_id").(int))
serviceId := uint64(d.Get("service_id").(int))
if d.Get("start").(bool) {
log.Debugf("trying to start bservice group %v", compgroupId)
@@ -143,6 +143,7 @@ func resourceBasicServiceGroupDelete(ctx context.Context, d *schema.ResourceData
bsg, err := utilityBasicServiceGroupCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
@@ -334,7 +335,7 @@ func resourceBasicServiceGroupUpdate(ctx context.Context, d *schema.ResourceData
}
}
return nil
return resourceBasicServiceGroupRead(ctx, d, m)
}
func isContainsParent(els []interface{}, el interface{}) bool {

View File

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

View File

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

View File

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

View File

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

View File

@@ -74,6 +74,7 @@ func flattenListTypesDetailedPools(pools []interface{}) []interface{} {
func dataSourceDiskListTypesDetailedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
listTypesDetailed, err := utilityDiskListTypesDetailedCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -92,7 +92,7 @@ func flattenExtnetVNFS(evnfs extnet.VNFs) []map[string]interface{} {
}
func flattenExtnetsComputes(ecs extnet.ListExtNetExtends) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len (ecs))
res := make([]map[string]interface{}, 0, len(ecs))
for _, ec := range ecs {
temp := map[string]interface{}{
"net_id": ec.ID,
@@ -129,6 +129,7 @@ func flattenExtnetList(el *extnet.ListExtNets) []map[string]interface{} {
"net_id": e.ID,
"ipcidr": e.IPCIDR,
"name": e.Name,
"status": e.Status,
}
res = append(res, temp)
}

View File

@@ -66,6 +66,10 @@ func dataSourceFlipgroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt,
Computed: true,
},
"account_name": {
Type: schema.TypeString,
Computed: true,
},
"client_ids": {
Type: schema.TypeList,
Computed: true,
@@ -85,10 +89,26 @@ func dataSourceFlipgroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString,
Computed: true,
},
"created_by": {
Type: schema.TypeString,
Computed: true,
},
"created_time": {
Type: schema.TypeInt,
Computed: true,
},
"default_gw": {
Type: schema.TypeString,
Computed: true,
},
"deleted_by": {
Type: schema.TypeString,
Computed: true,
},
"deleted_time": {
Type: schema.TypeInt,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
@@ -121,16 +141,28 @@ func dataSourceFlipgroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString,
Computed: true,
},
"network": {
Type: schema.TypeString,
Computed: true,
},
"rg_id": {
Type: schema.TypeInt,
Computed: true,
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"net_mask": {
Type: schema.TypeInt,
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
"ckey": {
Type: schema.TypeString,
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
}

View File

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

View File

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

View File

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

View File

@@ -34,8 +34,8 @@ package image
import (
"context"
"strconv"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
@@ -44,12 +44,11 @@ import (
func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
image, err := utilityImageCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.SetId(strconv.Itoa(int(image.ID)))
flattenImage(d, image)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -106,7 +106,7 @@ func flattenWorkerComputes(cluster *k8s.RecordK8S) []map[string]interface{} {
}
func flattenAclList(aclList k8s.ListACL) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len (aclList))
res := make([]map[string]interface{}, 0, len(aclList))
for _, acl := range aclList {
temp := map[string]interface{}{
"explicit": acl.Explicit,
@@ -134,7 +134,7 @@ func flattenAcl(acl k8s.RecordACL) []map[string]interface{} {
}
func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len (interfaces))
res := make([]map[string]interface{}, 0, len(interfaces))
for _, interfaceCompute := range interfaces {
temp := map[string]interface{}{
"def_gw": interfaceCompute.DefGW,
@@ -147,7 +147,7 @@ func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface
}
func flattenDetailedInfo(detailedInfoList k8s.ListDetailedInfo, computes []compute.RecordCompute) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len (detailedInfoList))
res := make([]map[string]interface{}, 0, len(detailedInfoList))
if computes != nil {
for i, detailedInfo := range detailedInfoList {
temp := map[string]interface{}{
@@ -247,6 +247,7 @@ func flattenK8sData(d *schema.ResourceData, cluster k8s.RecordK8S, masters []com
d.Set("workers", flattenK8sGroup(cluster.K8SGroups.Workers, workers))
d.Set("lb_id", cluster.LBID)
d.Set("name", cluster.Name)
d.Set("network_plugin", cluster.NetworkPlugin)
d.Set("rg_id", cluster.RGID)
d.Set("rg_name", cluster.RGName)
d.Set("status", cluster.Status)
@@ -267,7 +268,7 @@ func flattenServiceAccount(serviceAccount k8s.RecordServiceAccount) []map[string
}
func flattenWorkersGroup(workersGroups k8s.ListK8SGroups) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len (workersGroups))
res := make([]map[string]interface{}, 0, len(workersGroups))
for _, worker := range workersGroups {
temp := map[string]interface{}{
"annotations": worker.Annotations,
@@ -288,11 +289,11 @@ func flattenWorkersGroup(workersGroups k8s.ListK8SGroups) []map[string]interface
}
func flattenK8sItems(k8sItems *k8s.ListK8SClusters) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len (k8sItems.Data))
res := make([]map[string]interface{}, 0, len(k8sItems.Data))
for _, item := range k8sItems.Data {
temp := map[string]interface{}{
"account_id": item.AccountID,
"account_name": item.Name,
"account_name": item.AccountName,
"acl": item.ACL,
"bservice_id": item.BServiceID,
"ci_id": item.CIID,
@@ -308,6 +309,7 @@ func flattenK8sItems(k8sItems *k8s.ListK8SClusters) []map[string]interface{} {
"lb_id": item.LBID,
"milestones": item.Milestones,
"k8s_name": item.Name,
"network_plugin": item.NetworkPlugin,
"rg_id": item.RGID,
"rg_name": item.RGName,
"service_account": flattenServiceAccount(item.ServiceAccount),

View File

@@ -87,19 +87,19 @@ func mastersSchemaMake() map[string]*schema.Schema {
masters["cpu"] = &schema.Schema{
Type: schema.TypeInt,
Required: true,
ForceNew: true,
//ForceNew: true,
Description: "Node CPU count.",
}
masters["ram"] = &schema.Schema{
Type: schema.TypeInt,
Required: true,
ForceNew: true,
//ForceNew: true,
Description: "Node RAM in MB.",
}
masters["disk"] = &schema.Schema{
Type: schema.TypeInt,
Required: true,
ForceNew: true,
//ForceNew: true,
Description: "Node boot disk size in GB.",
}

View File

@@ -0,0 +1,396 @@
package k8s
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
func resourceK8sCPSchemaV1() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of the cluster.",
},
"rg_id": {
Type: schema.TypeInt,
Required: true,
//ForceNew: true,
Description: "Resource group ID that this instance belongs to.",
},
"k8sci_id": {
Type: schema.TypeInt,
Required: true,
//ForceNew: true,
Description: "ID of the k8s catalog item to base this instance on.",
},
"network_plugin": {
Type: schema.TypeString,
Required: true,
Description: "Network plugin to be used",
ValidateFunc: validation.StringInSlice([]string{"flannel", "weavenet", "calico"}, true),
},
"num": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ValidateFunc: validation.IntInSlice([]int{1, 3}),
Description: "Number of VMs to create. Can be either 1 or 3",
},
"cpu": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "Node CPU count.",
},
"ram": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "Node RAM in MB.",
},
"disk": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "Node boot disk size in GB.",
},
"sep_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "Storage Endpoint ID",
},
"sep_pool": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "Storage Endpoint Pool",
},
"with_lb": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Description: "Create k8s with load balancer if true.",
},
"extnet_only": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Use only selected ExtNet for infrastructure connections",
},
// /4.4.0
"cloud_init": {
Type: schema.TypeString,
Optional: true,
Description: "Meta data for working group computes, format YAML 'user_data': 1111",
},
"join_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting.",
},
"kube_proxy_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting.",
},
"kubelet_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. insert a valid JSON string with all levels of nesting.",
},
"cluster_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to define global settings and configurations for the entire cluster. It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. insert a valid JSON string with all levels of nesting.",
},
"init_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting.",
},
"additional_sans": {
Type: schema.TypeList,
Optional: true,
Description: "Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"ha_mode": {
Type: schema.TypeBool,
Optional: true,
Description: "Use Highly Available schema for LB deploy",
},
"lb_sysctl_params": {
Type: schema.TypeString,
Optional: true,
Description: "Custom sysctl values for Load Balancer instance. Applied on boot.",
},
"oidc_cert": {
Type: schema.TypeString,
Optional: true,
Description: "insert ssl certificate in x509 pem format",
},
////
"extnet_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
//ForceNew: true,
Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.",
},
"desc": {
Type: schema.TypeString,
Optional: true,
Description: "Text description of this instance.",
},
"start": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Description: "Start k8s cluster.",
},
"detailed_info": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"compute_id": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"interfaces": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"def_gw": {
Type: schema.TypeString,
Computed: true,
},
"ip_address": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"natable_vins_ip": {
Type: schema.TypeString,
Computed: true,
},
"natable_vins_network": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"master_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Master group ID.",
},
"master_name": {
Type: schema.TypeString,
Computed: true,
Description: "Master group name.",
},
"acl": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"account_acl": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"explicit": {
Type: schema.TypeBool,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"right": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"user_group_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"k8s_acl": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"explicit": {
Type: schema.TypeBool,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"right": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"user_group_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"rg_acl": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"explicit": {
Type: schema.TypeBool,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"right": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"user_group_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
},
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"account_name": {
Type: schema.TypeString,
Computed: true,
},
"bservice_id": {
Type: schema.TypeInt,
Computed: true,
},
"created_by": {
Type: schema.TypeString,
Computed: true,
},
"created_time": {
Type: schema.TypeInt,
Computed: true,
},
"deleted_by": {
Type: schema.TypeString,
Computed: true,
},
"deleted_time": {
Type: schema.TypeInt,
Computed: true,
},
"k8s_ci_name": {
Type: schema.TypeString,
Computed: true,
},
"lb_id": {
Type: schema.TypeInt,
Computed: true,
},
"k8s_id": {
Type: schema.TypeInt,
Computed: true,
},
"lb_ip": {
Type: schema.TypeString,
Computed: true,
Description: "IP address of default load balancer.",
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
"kubeconfig": {
Type: schema.TypeString,
Computed: true,
Description: "Kubeconfig for cluster access.",
},
"vins_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "ID of default vins for this instace.",
},
},
}
}

View File

@@ -199,12 +199,19 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{
createReq.ExtNetID = 0
}
if vins, ok := d.GetOk("vins_id"); ok {
createReq.VinsId = uint64(vins.(int))
} else {
createReq.VinsId = 0
}
if desc, ok := d.GetOk("desc"); ok {
createReq.Description = desc.(string)
}
resp, err := c.CloudAPI().K8S().Create(ctx, createReq)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
@@ -310,7 +317,7 @@ func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{})
}
}
k8sList, err := utilityK8sListCheckPresence(ctx, d, m)
k8sList, err := utilityK8sListForResourceCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
@@ -509,7 +516,7 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{
}
}
return nil
return resourceK8sRead(ctx, d, m)
}
func resourceK8sDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
@@ -544,13 +551,13 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
"rg_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
//ForceNew: true,
Description: "Resource group ID that this instance belongs to.",
},
"k8sci_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
//ForceNew: true,
Description: "ID of the k8s catalog item to base this instance on.",
},
"wg_name": {
@@ -589,7 +596,7 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
Type: schema.TypeList,
Optional: true,
Computed: true,
ForceNew: true,
//ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: mastersSchemaMake(),
@@ -621,7 +628,7 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ForceNew: true,
//ForceNew: true,
Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.",
},

View File

@@ -158,9 +158,9 @@ func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interfac
createReq.JoinConfiguration = joinConfig.(string)
}
if cloudInit, ok := d.GetOk("cloud_init"); ok {
createReq.UserData = cloudInit.(string)
}
// if cloudInit, ok := d.GetOk("cloud_init"); ok {
// createReq.UserData = cloudInit.(string)
// }
if initConfig, ok := d.GetOk("init_config"); ok {
createReq.InitConfiguration = initConfig.(string)
@@ -185,12 +185,19 @@ func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interfac
createReq.ExtNetID = 0
}
if vins, ok := d.GetOk("vins_id"); ok {
createReq.VinsId = uint64(vins.(int))
} else {
createReq.VinsId = 0
}
if desc, ok := d.GetOk("desc"); ok {
createReq.Description = desc.(string)
}
resp, err := c.CloudAPI().K8S().Create(ctx, createReq)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
@@ -311,7 +318,7 @@ func resourceK8sCPRead(ctx context.Context, d *schema.ResourceData, m interface{
}
}
k8sList, err := utilityK8sListCheckPresence(ctx, d, m)
k8sList, err := utilityK8sListForResourceCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
@@ -526,7 +533,7 @@ func resourceK8sCPUpdate(ctx context.Context, d *schema.ResourceData, m interfac
}
}
return nil
return resourceK8sCPRead(ctx, d, m)
}
func resourceK8sCPDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
@@ -534,6 +541,7 @@ func resourceK8sCPDelete(ctx context.Context, d *schema.ResourceData, m interfac
cluster, err := utilityK8sCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
@@ -548,6 +556,8 @@ func resourceK8sCPDelete(ctx context.Context, d *schema.ResourceData, m interfac
return diag.FromErr(err)
}
d.SetId("")
return nil
}
@@ -561,13 +571,13 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
"rg_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
//ForceNew: true,
Description: "Resource group ID that this instance belongs to.",
},
"k8sci_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
//ForceNew: true,
Description: "ID of the k8s catalog item to base this instance on.",
},
"network_plugin": {
@@ -625,12 +635,6 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
Default: false,
Description: "Use only selected ExtNet for infrastructure connections",
},
///4.4.0
"cloud_init": {
Type: schema.TypeString,
Optional: true,
Description: "Meta data for working group computes, format YAML 'user_data': 1111",
},
"join_config": {
Type: schema.TypeString,
Optional: true,
@@ -684,7 +688,7 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ForceNew: true,
//ForceNew: true,
Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.",
},
"desc": {
@@ -794,6 +798,7 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
},
"vins_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "ID of default vins for this instace.",
},
@@ -802,7 +807,7 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
func ResourceK8sCP() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
SchemaVersion: 2,
CreateContext: resourceK8sCPCreate,
ReadContext: resourceK8sCPRead,
@@ -822,5 +827,12 @@ func ResourceK8sCP() *schema.Resource {
},
Schema: resourceK8sCPSchemaMake(),
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceK8sCPSchemaV1().CoreConfigSchema().ImpliedType(),
Upgrade: resourceK8sCPStateUpgradeV1,
Version: 1,
},
},
}
}

View File

@@ -201,7 +201,7 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac
}
}
return nil
return resourceK8sWgRead(ctx, d, m)
}
func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
@@ -209,6 +209,7 @@ func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interfac
wg, err := utilityK8sWgCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
@@ -223,6 +224,8 @@ func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interfac
return diag.FromErr(err)
}
d.SetId("")
return nil
}
@@ -231,14 +234,14 @@ func resourceK8sWgSchemaMake() map[string]*schema.Schema {
"k8s_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
//ForceNew: true,
Description: "ID of k8s instance.",
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
//ForceNew: true,
Description: "Name of the worker group.",
},
@@ -252,7 +255,7 @@ func resourceK8sWgSchemaMake() map[string]*schema.Schema {
"cpu": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
//ForceNew: true,
Default: 1,
Description: "Worker node CPU count.",
},
@@ -260,7 +263,7 @@ func resourceK8sWgSchemaMake() map[string]*schema.Schema {
"ram": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
//ForceNew: true,
Default: 1024,
Description: "Worker node RAM in MB.",
},

View File

@@ -0,0 +1,15 @@
package k8s
import (
"context"
log "github.com/sirupsen/logrus"
)
func resourceK8sCPStateUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) {
log.Debug("resourceK8sCPStateUpgradeV1: upgrading state")
delete(rawState, "cloud_init")
return rawState, nil
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -44,6 +44,7 @@ import (
func dataSourceComputeVGPUListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
computeVGPUList, err := utilityComputeVGPUListCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
id := uuid.New()
@@ -94,7 +95,6 @@ func dataSourceComputeVGPUListSchemaMake() map[string]*schema.Schema {
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"entry_count": {

View File

@@ -72,6 +72,7 @@ func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface
"conn_id": interfaceItem.ConnID,
"conn_type": interfaceItem.ConnType,
"def_gw": interfaceItem.DefGW,
"enabled": interfaceItem.Enabled,
"flip_group_id": interfaceItem.FLIPGroupID,
"guid": interfaceItem.GUID,
"ip_address": interfaceItem.IPAddress,
@@ -362,7 +363,7 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute) er
d.Set("stateless_sep_id", computeRec.StatelessSepID)
d.Set("stateless_sep_type", computeRec.StatelessSepType)
d.Set("status", computeRec.Status)
d.Set("tags", flattenTags(computeRec.Tags))
// d.Set("tags", flattenTags(computeRec.Tags))
d.Set("tech_status", computeRec.TechStatus)
d.Set("updated_by", computeRec.UpdatedBy)
d.Set("updated_time", computeRec.UpdatedTime)
@@ -554,6 +555,7 @@ func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute
d.Set("guid", computeRec.GUID)
d.Set("compute_id", computeRec.ID)
d.Set("image_id", computeRec.ImageID)
d.Set("image_name", computeRec.ImageName)
d.Set("interfaces", flattenInterfaces(computeRec.Interfaces))
d.Set("lock_status", computeRec.LockStatus)
d.Set("manager_id", computeRec.ManagerID)
@@ -653,19 +655,19 @@ func flattenSnapshotUsage(computeSnapshotUsages compute.ListUsageSnapshots) []ma
return res
}
func flattenSnapshotList(computeSnapshotUsages *compute.ListSnapShots) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(computeSnapshotUsages.Data))
for _, computeUsage := range computeSnapshotUsages.Data {
temp := map[string]interface{}{
"disks": computeUsage.Disks,
"guid": computeUsage.GUID,
"label": computeUsage.Label,
"timestamp": computeUsage.Timestamp,
}
res = append(res, temp)
}
return res
}
// func flattenSnapshotList(computeSnapshotUsages *compute.ListSnapShots) []map[string]interface{} {
// res := make([]map[string]interface{}, 0, len(computeSnapshotUsages.Data))
// for _, computeUsage := range computeSnapshotUsages.Data {
// temp := map[string]interface{}{
// "disks": computeUsage.Disks,
// "guid": computeUsage.GUID,
// "label": computeUsage.Label,
// "timestamp": computeUsage.Timestamp,
// }
// res = append(res, temp)
// }
// return res
// }
func flattenVGPU(m []interface{}) []string {
output := []string{}

View File

@@ -548,3 +548,882 @@ func resourceComputeResourceV1() *schema.Resource {
},
}
}
func resourceComputeResourceV2() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.",
},
"rg_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
ValidateFunc: validation.IntAtLeast(1),
Description: "ID of the resource group where this compute should be deployed.",
},
"driver": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
StateFunc: statefuncs.StateFuncToUpper,
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86", "KVM_PPC"}, false), // observe case while validating
Description: "Hardware architecture of this compute instance.",
},
"cpu": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntBetween(1, constants.MaxCpusPerCompute),
Description: "Number of CPUs to allocate to this compute instance.",
},
"ram": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(constants.MinRamPerCompute),
Description: "Amount of RAM in MB to allocate to this compute instance.",
},
"image_id": {
Type: schema.TypeInt,
Required: true,
//ForceNew: true, //REDEPLOY
Description: "ID of the OS image to base this compute instance on.",
},
"boot_disk_size": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.",
},
"affinity_label": {
Type: schema.TypeString,
Optional: true,
Description: "Set affinity label for compute",
},
"affinity_rules": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"topology": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false),
Description: "compute or node, for whom rule applies",
},
"policy": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false),
Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule",
},
"mode": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false),
Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'",
},
"key": {
Type: schema.TypeString,
Required: true,
Description: "key that are taken into account when analyzing this rule will be identified",
},
"value": {
Type: schema.TypeString,
Required: true,
Description: "value that must match the key to be taken into account when analyzing this rule",
},
},
},
},
"anti_affinity_rules": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"topology": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false),
Description: "compute or node, for whom rule applies",
},
"policy": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false),
Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule",
},
"mode": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false),
Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'",
},
"key": {
Type: schema.TypeString,
Required: true,
Description: "key that are taken into account when analyzing this rule will be identified",
},
"value": {
Type: schema.TypeString,
Required: true,
Description: "value that must match the key to be taken into account when analyzing this rule",
},
},
},
},
"disks": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"disk_name": {
Type: schema.TypeString,
Required: true,
Description: "Name for disk",
},
"size": {
Type: schema.TypeInt,
Required: true,
Description: "Disk size in GiB",
},
"sep_id": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
Description: "Storage endpoint provider ID; by default the same with boot disk",
},
"disk_type": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false),
Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'",
},
"pool": {
Type: schema.TypeString,
Computed: true,
Optional: true,
Description: "Pool name; by default will be chosen automatically",
},
"desc": {
Type: schema.TypeString,
Computed: true,
Optional: true,
Description: "Optional description",
},
"image_id": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
Description: "Specify image id for create disk from template",
},
"permanently": {
Type: schema.TypeBool,
Computed: true,
Optional: true,
Description: "Disk deletion status",
},
"disk_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Disk ID",
},
"shareable": {
Type: schema.TypeBool,
Computed: true,
},
"size_max": {
Type: schema.TypeInt,
Computed: true,
},
"size_used": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"custom_fields": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"stateless": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Compute will be stateless (SVA_KVM_X86) if set to True",
},
"with_default_vins": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Description: "Create compute with default resgroup ViNS (true) or without any interfaces (false). This parameter is ignored if network block is specified",
},
"boot_disk": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"disk_name": {
Type: schema.TypeString,
Required: true,
Description: "Name for disk",
},
"size": {
Type: schema.TypeInt,
Required: true,
Description: "Disk size in GiB",
},
"sep_id": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
Description: "Storage endpoint provider ID; by default the same with boot disk",
},
"disk_type": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false),
Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'",
},
"pool": {
Type: schema.TypeString,
Computed: true,
Optional: true,
Description: "Pool name; by default will be chosen automatically",
},
"desc": {
Type: schema.TypeString,
Computed: true,
Optional: true,
Description: "Optional description",
},
"image_id": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
Description: "Specify image id for create disk from template",
},
"permanently": {
Type: schema.TypeBool,
Computed: true,
Optional: true,
Description: "Disk deletion status",
},
"disk_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Disk ID",
},
"shareable": {
Type: schema.TypeBool,
Computed: true,
},
"size_max": {
Type: schema.TypeInt,
Computed: true,
},
"size_used": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"sep_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ForceNew: true,
Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.",
},
"pool": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.",
},
"extra_disks": {
Type: schema.TypeSet,
Optional: true,
Computed: true,
MaxItems: constants.MaxExtraDisksPerCompute,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
Description: "Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.",
},
"network": {
Type: schema.TypeSet,
Optional: true,
MinItems: 1,
MaxItems: constants.MaxNetworksPerCompute,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"net_type": {
Type: schema.TypeString,
Required: true,
StateFunc: statefuncs.StateFuncToUpper,
ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS"}, false), // observe case while validating
Description: "Type of the network for this connection, either EXTNET or VINS.",
},
"net_id": {
Type: schema.TypeInt,
Required: true,
Description: "ID of the network for this connection.",
},
"ip_address": {
Type: schema.TypeString,
Optional: true,
Computed: true,
DiffSuppressFunc: networkSubresIPAddreDiffSupperss,
Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.",
},
"mac": {
Type: schema.TypeString,
Computed: true,
Description: "MAC address associated with this connection. MAC address is assigned automatically.",
},
},
},
Description: "Optional network connection(s) for this compute. You may specify several network blocks, one for each connection.",
},
"tags": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"key": {
Type: schema.TypeString,
Required: true,
},
"value": {
Type: schema.TypeString,
Required: true,
},
},
},
},
"port_forwarding": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"public_port_start": {
Type: schema.TypeInt,
Required: true,
},
"public_port_end": {
Type: schema.TypeInt,
Optional: true,
Default: -1,
},
"local_port": {
Type: schema.TypeInt,
Required: true,
},
"proto": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false),
},
},
},
},
"user_access": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"username": {
Type: schema.TypeString,
Required: true,
},
"access_type": {
Type: schema.TypeString,
Required: true,
},
},
},
},
"snapshot": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"label": {
Type: schema.TypeString,
Required: true,
},
},
},
},
"rollback": {
Type: schema.TypeSet,
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"label": {
Type: schema.TypeString,
Required: true,
},
},
},
},
"cd": {
Type: schema.TypeSet,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cdrom_id": {
Type: schema.TypeInt,
Required: true,
},
},
},
},
"pin_to_stack": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"description": {
Type: schema.TypeString,
Optional: true,
Description: "Optional text description of this compute instance.",
},
"cloud_init": {
Type: schema.TypeString,
Optional: true,
Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.",
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "If true - enable compute, else - disable",
},
"pause": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"reset": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"auto_start": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Flag for redeploy compute",
},
"force_stop": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Flag for redeploy compute",
},
"data_disks": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"KEEP", "DETACH", "DESTROY"}, false),
Default: "DETACH",
Description: "Flag for redeploy compute",
},
"started": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Description: "Is compute started.",
},
"detach_disks": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"permanently": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"is": {
Type: schema.TypeString,
Optional: true,
Description: "system name",
},
"ipa_type": {
Type: schema.TypeString,
Optional: true,
Description: "compute purpose",
},
// The rest are Compute properties, which are "computed" once it is created
"account_id": {
Type: schema.TypeInt,
Computed: true,
Description: "ID of the account this compute instance belongs to.",
},
"account_name": {
Type: schema.TypeString,
Computed: true,
Description: "Name of the account this compute instance belongs to.",
},
"affinity_weight": {
Type: schema.TypeInt,
Computed: true,
},
"arch": {
Type: schema.TypeString,
Computed: true,
},
"boot_order": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"boot_disk_id": {
Type: schema.TypeInt,
Computed: true,
Description: "This compute instance boot disk ID.",
},
"clone_reference": {
Type: schema.TypeInt,
Computed: true,
},
"clones": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"computeci_id": {
Type: schema.TypeInt,
Computed: true,
},
"created_by": {
Type: schema.TypeString,
Computed: true,
},
"created_time": {
Type: schema.TypeInt,
Computed: true,
},
"deleted_by": {
Type: schema.TypeString,
Computed: true,
},
"deleted_time": {
Type: schema.TypeInt,
Computed: true,
},
"devices": {
Type: schema.TypeString,
Computed: true,
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"compute_id": {
Type: schema.TypeInt,
Computed: true,
},
"interfaces": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"conn_id": {
Type: schema.TypeInt,
Computed: true,
},
"conn_type": {
Type: schema.TypeString,
Computed: true,
},
"def_gw": {
Type: schema.TypeString,
Computed: true,
},
"flip_group_id": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"ip_address": {
Type: schema.TypeString,
Computed: true,
},
"listen_ssh": {
Type: schema.TypeBool,
Computed: true,
},
"mac": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"net_id": {
Type: schema.TypeInt,
Computed: true,
},
"netmask": {
Type: schema.TypeInt,
Computed: true,
},
"net_type": {
Type: schema.TypeString,
Computed: true,
},
"pci_slot": {
Type: schema.TypeInt,
Computed: true,
},
"qos": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"e_rate": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"in_brust": {
Type: schema.TypeInt,
Computed: true,
},
"in_rate": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"target": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"vnfs": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
},
},
},
"lock_status": {
Type: schema.TypeString,
Computed: true,
},
"manager_id": {
Type: schema.TypeInt,
Computed: true,
},
"manager_type": {
Type: schema.TypeString,
Computed: true,
},
"migrationjob": {
Type: schema.TypeInt,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"natable_vins_id": {
Type: schema.TypeInt,
Computed: true,
},
"natable_vins_ip": {
Type: schema.TypeString,
Computed: true,
},
"natable_vins_name": {
Type: schema.TypeString,
Computed: true,
},
"natable_vins_network": {
Type: schema.TypeString,
Computed: true,
},
"natable_vins_network_name": {
Type: schema.TypeString,
Computed: true,
},
"os_users": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"guid": {
Type: schema.TypeString,
Computed: true,
Description: "GUID of this guest OS user.",
},
"login": {
Type: schema.TypeString,
Computed: true,
Description: "Login name of this guest OS user.",
},
"password": {
Type: schema.TypeString,
Computed: true,
//Sensitive: true,
Description: "Password of this guest OS user.",
},
"public_key": {
Type: schema.TypeString,
Computed: true,
Description: "SSH public key of this guest OS user.",
},
},
},
Description: "Guest OS users provisioned on this compute instance.",
},
"pinned": {
Type: schema.TypeBool,
Computed: true,
},
"reference_id": {
Type: schema.TypeString,
Computed: true,
},
"registered": {
Type: schema.TypeBool,
Computed: true,
},
"res_name": {
Type: schema.TypeString,
Computed: true,
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
Description: "Name of the resource group where this compute instance is located.",
},
"snap_sets": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"disks": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"label": {
Type: schema.TypeString,
Computed: true,
},
"timestamp": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"stateless_sep_id": {
Type: schema.TypeInt,
Computed: true,
},
"stateless_sep_type": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
},
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
"user_managed": {
Type: schema.TypeBool,
Computed: true,
},
"vgpus": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"virtual_image_id": {
Type: schema.TypeInt,
Computed: true,
},
"virtual_image_name": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

View File

@@ -155,6 +155,32 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
}
createReqPPC.Interfaces = make([]kvmppc.Interface, 0)
if networks, ok := d.GetOk("network"); ok {
if networks.(*schema.Set).Len() > 0 {
ns := networks.(*schema.Set).List()
interfaces := make([]kvmppc.Interface, 0)
for _, elem := range ns {
netInterfaceVal := elem.(map[string]interface{})
reqInterface := kvmppc.Interface{
NetType: netInterfaceVal["net_type"].(string),
NetID: uint64(netInterfaceVal["net_id"].(int)),
}
ipaddr, ipSet := netInterfaceVal["ip_address"]
if ipSet {
reqInterface.IPAddr = ipaddr.(string)
}
interfaces = append(interfaces, reqInterface)
}
createReqPPC.Interfaces = interfaces
}
}
argVal, ok = d.GetOk("cloud_init")
if ok {
userdata := argVal.(string)
@@ -242,45 +268,6 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
}
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface),
// now we need to start it before we report the sequence complete
if d.Get("started").(bool) {
req := compute.StartRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", computeId)
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
warnings.Add(err)
}
}
if enabled, ok := d.GetOk("enabled"); ok {
if enabled.(bool) {
req := compute.EnableRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId)
if _, err := c.CloudAPI().Compute().Enable(ctx, req); err != nil {
warnings.Add(err)
}
} else {
req := compute.DisableRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId)
if _, err := c.CloudAPI().Compute().Disable(ctx, req); err != nil {
warnings.Add(err)
}
}
}
if !cleanup {
if affinityLabel, ok := d.GetOk("affinity_label"); ok {
req := compute.AffinityLabelSetRequest{
ComputeID: computeId,
AffinityLabel: affinityLabel.(string),
}
_, err := c.CloudAPI().Compute().AffinityLabelSet(ctx, req)
if err != nil {
warnings.Add(err)
}
}
if disks, ok := d.GetOk("disks"); ok {
log.Debugf("resourceComputeCreate: Create disks on ComputeID: %d", computeId)
addedDisks := disks.([]interface{})
@@ -291,9 +278,11 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
ComputeID: computeId,
DiskName: diskConv["disk_name"].(string),
Size: uint64(diskConv["size"].(int)),
SepID: uint64(diskConv["sep_id"].(int)),
}
if diskConv["sep_id"].(int) != 0 {
req.SepID = uint64(diskConv["sep_id"].(int))
}
if diskConv["disk_type"].(string) != "" {
req.DiskType = diskConv["disk_type"].(string)
}
@@ -316,6 +305,54 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
}
if !cleanup {
if enabled, ok := d.GetOk("enabled"); ok {
if enabled.(bool) {
req := compute.EnableRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId)
if _, err := c.CloudAPI().Compute().Enable(ctx, req); err != nil {
warnings.Add(err)
}
} else {
req := compute.DisableRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", enabled, computeId)
if _, err := c.CloudAPI().Compute().Disable(ctx, req); err != nil {
warnings.Add(err)
}
}
}
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface),
// now we need to start it before we report the sequence complete
if start, ok := d.GetOk("started"); ok {
if start.(bool) {
req := compute.StartRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", computeId)
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
warnings.Add(err)
}
}
if !start.(bool) {
req := compute.StopRequest{ComputeID: computeId}
log.Debugf("resourceComputeCreate: stoping Compute ID %d after completing its resource configuration", computeId)
if _, err := c.CloudAPI().Compute().Stop(ctx, req); err != nil {
warnings.Add(err)
}
}
}
if affinityLabel, ok := d.GetOk("affinity_label"); ok {
req := compute.AffinityLabelSetRequest{
ComputeID: computeId,
AffinityLabel: affinityLabel.(string),
}
_, err := c.CloudAPI().Compute().AffinityLabelSet(ctx, req)
if err != nil {
warnings.Add(err)
}
}
if ars, ok := d.GetOk("affinity_rules"); ok {
log.Debugf("resourceComputeCreate: Create affinity rules on ComputeID: %d", computeId)
addedAR := ars.([]interface{})
@@ -361,7 +398,6 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
}
}
}
if tags, ok := d.GetOk("tags"); ok {
log.Debugf("resourceComputeCreate: Create tags on ComputeID: %d", computeId)
@@ -392,10 +428,12 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
req := compute.PFWAddRequest{
ComputeID: computeId,
PublicPortStart: uint64(pfwItem["public_port_start"].(int)),
PublicPortEnd: int64(pfwItem["public_port_end"].(int)),
LocalBasePort: uint64(pfwItem["local_port"].(int)),
Proto: pfwItem["proto"].(string),
}
if pfwItem["public_port_end"].(int) != 0 {
req.PublicPortEnd = int64(pfwItem["public_port_end"].(int))
}
_, err := c.CloudAPI().Compute().PFWAdd(ctx, req)
if err != nil {
@@ -404,6 +442,7 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
}
}
if userAcess, ok := d.GetOk("user_access"); ok {
log.Debugf("resourceComputeCreate: Create user access on ComputeID: %d", computeId)
usersAcess := userAcess.(*schema.Set).List()
@@ -460,7 +499,7 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
}
if d.Get("pin_to_stack").(bool) == true {
if d.Get("pin_to_stack").(bool) {
req := compute.PinToStackRequest{
ComputeID: computeId,
}
@@ -470,7 +509,7 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
}
if d.Get("pause").(bool) == true {
if d.Get("pause").(bool) {
req := compute.PauseRequest{
ComputeID: computeId,
}
@@ -479,15 +518,14 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
warnings.Add(err)
}
}
}
log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", computeId, d.Get("name").(string))
// We may reuse dataSourceComputeRead here as we maintain similarity
// between Compute resource and Compute data source schemas
// Compute read function will also update resource ID on success, so that Terraform
// will know the resource exists
defer resourceComputeRead(ctx, d, m)
return warnings.Get()
return append(warnings.Get(), resourceComputeRead(ctx, d, m)...)
}
func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
@@ -498,6 +536,7 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
computeRec, err := utilityComputeCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
@@ -601,6 +640,76 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
return diag.FromErr(err)
}
hasChanged := false
// check compute statuses
switch computeRec.Status {
case status.Deleted:
if restore, ok := d.GetOk("restore"); ok && restore.(bool) {
restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID}
_, err := c.CloudAPI().Compute().Restore(ctx, restoreReq)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
}
if enabled, ok := d.GetOk("enabled"); ok {
if enabled.(bool) {
enableReq := compute.EnableRequest{ComputeID: computeRec.ID}
_, err = c.CloudAPI().Compute().Enable(ctx, enableReq)
if err != nil {
return diag.FromErr(err)
}
}
if !enabled.(bool) {
enableReq := compute.DisableRequest{ComputeID: computeRec.ID}
_, err = c.CloudAPI().Compute().Disable(ctx, enableReq)
if err != nil {
return diag.FromErr(err)
}
}
}
if start, ok := d.GetOk("started"); ok {
if start.(bool) {
req := compute.StartRequest{ComputeID: computeRec.ID}
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
return diag.FromErr(err)
}
}
if !start.(bool) {
req := compute.StopRequest{ComputeID: computeRec.ID}
if _, err := c.CloudAPI().Compute().Stop(ctx, req); err != nil {
return diag.FromErr(err)
}
}
}
hasChanged = true
case status.Destroyed:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceComputeCreate(ctx, d, m)
case status.Disabled:
log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", computeRec.Status)
case status.Redeploying:
case status.Deleting:
case status.Destroying:
return diag.Errorf("The compute is in progress with status: %s", computeRec.Status)
case status.Modeled:
return diag.Errorf("The compute is in status: %s, please, contant the support for more information", computeRec.Status)
}
if hasChanged {
computeRec, err = utilityComputeCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("enabled") {
enabled := d.Get("enabled").(bool)
if enabled {
@@ -623,34 +732,22 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
log.Debugf("resourceComputeUpdate: enable=%s Compute ID %v after completing its resource configuration", d.Id(), enabled)
}
// check compute statuses
switch computeRec.Status {
case status.Deleted:
restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID}
enableReq := compute.EnableRequest{ComputeID: computeRec.ID}
if d.HasChange("started") {
start := d.Get("started").(bool)
if start {
req := compute.StartRequest{ComputeID: computeRec.ID}
_, err := c.CloudAPI().Compute().Restore(ctx, restoreReq)
if err != nil {
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
return diag.FromErr(err)
}
}
if !start {
req := compute.StopRequest{ComputeID: computeRec.ID}
_, err = c.CloudAPI().Compute().Enable(ctx, enableReq)
if err != nil {
if _, err := c.CloudAPI().Compute().Stop(ctx, req); err != nil {
return diag.FromErr(err)
}
case status.Destroyed:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
// return resourceComputeCreate(ctx, d, m)
case status.Disabled:
log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", computeRec.Status)
case status.Redeploying:
case status.Deleting:
case status.Destroying:
return diag.Errorf("The compute is in progress with status: %s", computeRec.Status)
case status.Modeled:
return diag.Errorf("The compute is in status: %s, please, contant the support for more information", computeRec.Status)
}
}
doUpdate := false
@@ -729,14 +826,16 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
}
}
if d.HasChange("description") || d.HasChange("name") {
if d.HasChanges("description", "name") {
req := compute.UpdateRequest{
ComputeID: computeRec.ID,
Name: d.Get("name").(string),
}
if desc, ok := d.GetOk("desc"); ok {
req.Description = desc.(string)
if d.HasChange("name") {
req.Name = d.Get("name").(string)
}
if d.HasChange("description") {
req.Description = d.Get("description").(string)
}
if _, err := c.CloudAPI().Compute().Update(ctx, req); err != nil {
@@ -835,9 +934,11 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
ComputeID: computeRec.ID,
DiskName: diskConv["disk_name"].(string),
Size: uint64(diskConv["size"].(int)),
SepID: uint64(diskConv["sep_id"].(int)),
}
if diskConv["sep_id"].(int) != 0 {
req.SepID = uint64(diskConv["sep_id"].(int))
}
if diskConv["disk_type"].(string) != "" {
req.DiskType = diskConv["disk_type"].(string)
}
@@ -1267,7 +1368,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if d.HasChange("pin_to_stack") {
oldPin, newPin := d.GetChange("pin_to_stack")
if oldPin.(bool) == true && newPin.(bool) == false {
if !newPin.(bool) {
req := compute.UnpinFromStackRequest{
ComputeID: computeRec.ID,
}
@@ -1277,7 +1378,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
return diag.FromErr(err)
}
}
if oldPin.(bool) == false && newPin.(bool) == true {
if !oldPin.(bool) {
req := compute.PinToStackRequest{
ComputeID: computeRec.ID,
}
@@ -1291,7 +1392,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if d.HasChange("pause") {
oldPause, newPause := d.GetChange("pause")
if oldPause.(bool) == true && newPause.(bool) == false {
if !newPause.(bool) {
req := compute.ResumeRequest{
ComputeID: computeRec.ID,
}
@@ -1300,7 +1401,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
return diag.FromErr(err)
}
}
if oldPause.(bool) == false && newPause.(bool) == true {
if !oldPause.(bool) {
req := compute.PauseRequest{
ComputeID: computeRec.ID,
}
@@ -1313,8 +1414,8 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
}
if d.HasChange("reset") {
oldReset, newReset := d.GetChange("reset")
if oldReset.(bool) == false && newReset.(bool) == true {
_, newReset := d.GetChange("reset")
if newReset.(bool) {
req := compute.ResetRequest{
ComputeID: computeRec.ID,
}
@@ -1394,8 +1495,8 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
// we may reuse dataSourceComputeRead here as we maintain similarity
// between Compute resource and Compute data source schemas
defer resourceComputeRead(ctx, d, m)
return warnings.Get()
return append(warnings.Get(), resourceComputeRead(ctx, d, m)...)
}
func isChangeDisk(els []interface{}, el interface{}) bool {
@@ -1456,6 +1557,8 @@ func resourceComputeDelete(ctx context.Context, d *schema.ResourceData, m interf
return diag.FromErr(err)
}
d.SetId("")
return nil
}
@@ -1504,7 +1607,6 @@ func disksSubresourceSchemaMake() map[string]*schema.Schema {
},
"permanently": {
Type: schema.TypeBool,
Computed: true,
Optional: true,
Description: "Disk deletion status",
},
@@ -1615,14 +1717,14 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
"rg_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
// ForceNew: true,
ValidateFunc: validation.IntAtLeast(1),
Description: "ID of the resource group where this compute should be deployed.",
},
"driver": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
// ForceNew: true,
StateFunc: statefuncs.StateFuncToUpper,
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86", "KVM_PPC"}, false), // observe case while validating
Description: "Hardware architecture of this compute instance.",
@@ -1757,14 +1859,14 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ForceNew: true,
// ForceNew: true,
Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.",
},
"pool": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
// ForceNew: true,
Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.",
},
@@ -1877,6 +1979,12 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Default: false,
},
"restore": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"auto_start": {
Type: schema.TypeBool,
Optional: true,
@@ -2132,7 +2240,7 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
func ResourceCompute() *schema.Resource {
return &schema.Resource{
SchemaVersion: 2,
SchemaVersion: 3,
CreateContext: resourceComputeCreate,
ReadContext: resourceComputeRead,
@@ -2158,6 +2266,11 @@ func ResourceCompute() *schema.Resource {
Upgrade: resourceCompueteStateUpgradeV1,
Version: 1,
},
{
Type: resourceComputeResourceV2().CoreConfigSchema().ImpliedType(),
Upgrade: resourceComputeStateUpgradeV2,
Version: 2,
},
},
}
}

View File

@@ -31,3 +31,11 @@ func resourceCompueteStateUpgradeV1(ctx context.Context, rawState map[string]int
return rawState, nil
}
func resourceComputeStateUpgradeV2(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) {
log.Debug("resourceComputeStateUpgradeV2: upgrading state")
delete(rawState, "with_default_vins")
return rawState, nil
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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