4.8.0
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,4 +4,5 @@ url_scrapping/
|
||||
terraform-provider-decort*
|
||||
.vscode/
|
||||
.DS_Store
|
||||
|
||||
vendor/
|
||||
.idea/
|
||||
48
CHANGELOG.md
48
CHANGELOG.md
@@ -1,16 +1,54 @@
|
||||
## Version 4.7.3
|
||||
## Version 4.8.0
|
||||
|
||||
### Добавлено
|
||||
|
||||
#### extnet
|
||||
| Идентификатор<br>задачи | Описание |
|
||||
| --- | --- |
|
||||
| BATF-656 | Вычисляемое поле `account_id` в блоке `reservations` в resource `decort_cb_extnet` и data sources `decort_extnet, decort_cb_extnet` в cloudapi/extnet и cloudbroker/extnet |
|
||||
| BATF-658 | Data sources `decort_extnet_reserved_ip_list, decort_cb_extnet_reserved_ip_list` в cloudapi/extnet и cloudbroker/extnet |
|
||||
| BATF-658 | Опциональный блок `reserved_ip`в resource `decort_cb_extnet` в cloudbroker/extnet |
|
||||
|
||||
#### image
|
||||
| Идентификатор<br>задачи | Описание |
|
||||
| --- | --- |
|
||||
| BATF-667 | Вычисляемое поле `snapshot_id` в resources `decort_cb_image, decort_cb_image_from_blank_compute, decort_cb_image_from_platform_disk, decort_cb_virtual_image, decort_cb_cdrom_image` и data sources `decort_cb_image, decort_cb_image_list` в cloudbroker/image |
|
||||
|
||||
#### grid
|
||||
| Идентификатор<br>задачи | Описание |
|
||||
| --- | --- |
|
||||
| BATF-669 | Обязательно поле `file_path` в data source `decort_cb_grid_post_diagnosis` в cloudbroker/grid |
|
||||
|
||||
#### kvmvm
|
||||
| Идентификатор<br>задачи | Описание |
|
||||
| --- | --- |
|
||||
| BATF-648 | Обязательные поля `net_type, net_id` в опциональный блок `libvirt_settings` в resource `decort_cb_kvmvm` в cloudbroker/kvmvm |
|
||||
| BATF-648 | Опциональное поле `mtu` в опциональный блок `network` в resources `decort_cb_kvmvm, decort_kvmvm` в cloudbroker/kvmvm и cloudapi/kvmvm |
|
||||
| BATF-656 | Вычисляемое поле `vnc_password` в resources `decort_kvmvm, decort_cb_kvmvm` и data sources `decort_kvmvm, decort_cb_kvmvm` в cloudapi/kvmvm и cloudbroker/kvmvm |
|
||||
| BATF-656 | Опциональное поле `cd_image_id`в data_source `decort_cb_kvmvm_list` в cloudbroker/kvmvm |
|
||||
| BATF-666 | Опциональное поле `auto_start_w_node`в resources `decort_kvmvm, decort_cb_kvmvm` в cloudapi/kvmvm и cloudbroker/kvmvm |
|
||||
| BATF-666 | Вычисляемое поле `auto_start_w_node`в data_sources `decort_kvmvm, decort_kvmvm_list, decort_kvmvm_list_deleted, decort_cb_kvmvm, decort_cb_kvmvm_list, decort_cb_kvmvm_list_deleted ` в cloudapi/kvmvm и cloudbroker/kvmvm |
|
||||
|
||||
#### node
|
||||
| Идентификатор<br>задачи | Описание |
|
||||
| --- | --- |
|
||||
| BATF-663 | Вычисляемый блок `net_addr` в data source `decort_cb_node` в cloudbroker/node |
|
||||
|
||||
#### vins
|
||||
| Идентификатор<br>задачи | Описание |
|
||||
| --- | --- |
|
||||
| BATF-656 | Вычисляемое поле `vnc_password` в блоке `vnf_dev` в resources `decort_vins, decort_cb_vins` и data sources `decort_vins, decort_cb_vins` в cloudapi/vins и cloudbroker/vins |
|
||||
| BATF-656 | Вычисляемое поле `account_id` в блоке `reservations` в resource `decort_vins` и data source `decort_vins` в cloudapi/vins |
|
||||
|
||||
### Удалено
|
||||
|
||||
#### kvmvm
|
||||
#### grid
|
||||
| Идентификатор<br>задачи | Описание |
|
||||
| --- | --- |
|
||||
| BATF-648 | Обязательное поле `mac` в опциональном блок `libvirt_settings` в resource `decort_cb_kvmvm` в cloudbroker/kvmvm |
|
||||
| BATF-669 | Data source `decort_cb_grid_post_diagnosis` в cloudbroker/grid |
|
||||
| BATF-669 | Вычисляемое поле `diagnosis` в data source `decort_cb_grid_get_diagnosis` в cloudbroker/grid |
|
||||
|
||||
|
||||
#### vins
|
||||
| Идентификатор<br>задачи | Описание |
|
||||
| --- | --- |
|
||||
| BATF-656 | Вычисляемые поля `client_type, description, domain_name, hostname` в блоке `reservations` в resources `decort_vins, decort_cb_vins` и data sources `decort_vins, decort_cb_vins` в cloudapi/vins и cloudbroker/vins |
|
||||
| BATF-656 | Опциональное поле `compute_ids` в resources `decort_vins_static_route, decort_cb_vins_static_route` в cloudapi/vins и cloudbroker/vins |
|
||||
2
Makefile
2
Makefile
@@ -7,7 +7,7 @@ ZIPDIR = ./zip
|
||||
BINARY=${NAME}
|
||||
WORKPATH= ./examples/terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH}
|
||||
MAINPATH = ./cmd/decort/
|
||||
VERSION=4.7.3
|
||||
VERSION=4.8.0
|
||||
OS_ARCH=$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH)
|
||||
|
||||
FILES = ${BINARY}_${VERSION}_darwin_amd64\
|
||||
|
||||
@@ -6,6 +6,7 @@ Terraform provider для платформы Digital Energy Cloud Orchestration
|
||||
|
||||
| Версия DECORT API | Версия провайдера Terraform |
|
||||
| ------ | ------ |
|
||||
| 4.2.0 | 4.8.x |
|
||||
| 4.1.0 | 4.7.x |
|
||||
| 4.0.0 | 4.6.x |
|
||||
| 3.8.9 | 4.5.x |
|
||||
|
||||
@@ -93,6 +93,7 @@ Read-Only:
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `client_type` (String)
|
||||
- `desc` (String)
|
||||
- `domain_name` (String)
|
||||
|
||||
61
docs/data-sources/cb_extnet_reserved_ip_list.md
Normal file
61
docs/data-sources/cb_extnet_reserved_ip_list.md
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_cb_extnet_reserved_ip_list Data Source - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_cb_extnet_reserved_ip_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `extnet_id` (Number)
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `extnet_id` (Number)
|
||||
- `reservations` (List of Object) (see [below for nested schema](#nestedobjatt--items--reservations))
|
||||
|
||||
<a id="nestedobjatt--items--reservations"></a>
|
||||
### Nested Schema for `items.reservations`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `client_type` (String)
|
||||
- `domain_name` (String)
|
||||
- `hostname` (String)
|
||||
- `ip` (String)
|
||||
- `mac` (String)
|
||||
- `type` (String)
|
||||
- `vm_id` (Number)
|
||||
@@ -17,6 +17,7 @@ description: |-
|
||||
|
||||
### Required
|
||||
|
||||
- `file_path` (String)
|
||||
- `gid` (Number)
|
||||
|
||||
### Optional
|
||||
@@ -25,7 +26,6 @@ description: |-
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `diagnosis` (String)
|
||||
- `id` (String) The ID of this resource.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_cb_grid_post_diagnosis Data Source - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_cb_grid_post_diagnosis (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `gid` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `diagnosis` (String)
|
||||
- `id` (String) The ID of this resource.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
@@ -59,6 +59,7 @@ description: |-
|
||||
- `rescuecd` (Boolean)
|
||||
- `sep_id` (Number) storage endpoint provider ID
|
||||
- `size` (Number) image size
|
||||
- `snapshot_id` (String) snapshot id
|
||||
- `status` (String) status
|
||||
- `tech_status` (String) tech atatus
|
||||
- `unc_path` (String) unc path
|
||||
|
||||
@@ -89,6 +89,7 @@ Read-Only:
|
||||
- `sep_id` (Number)
|
||||
- `shared_with` (List of Number)
|
||||
- `size` (Number)
|
||||
- `snapshot_id` (String)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `unc_path` (String)
|
||||
|
||||
@@ -33,6 +33,7 @@ description: |-
|
||||
- `affinity_weight` (Number)
|
||||
- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedatt--anti_affinity_rules))
|
||||
- `arch` (String)
|
||||
- `auto_start_w_node` (Boolean)
|
||||
- `boot_disk_id` (Number)
|
||||
- `boot_disk_size` (Number)
|
||||
- `boot_order` (List of String)
|
||||
@@ -100,6 +101,7 @@ description: |-
|
||||
- `vgpus` (List of Number)
|
||||
- `virtual_image_id` (Number)
|
||||
- `virtual_image_name` (String)
|
||||
- `vnc_password` (String)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
@@ -19,6 +19,7 @@ description: |-
|
||||
|
||||
- `account_id` (Number) Find by AccountID
|
||||
- `by_id` (Number) Find by ID
|
||||
- `cd_image_id` (Number) Find by CD image ID
|
||||
- `extnet_id` (Number) Find by Extnet ID
|
||||
- `extnet_name` (String) Find by Extnet name
|
||||
- `ignore_k8s` (Boolean) If set to true, ignores any VMs associated with any k8s cluster
|
||||
@@ -64,6 +65,7 @@ Read-Only:
|
||||
- `affinity_weight` (Number)
|
||||
- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--anti_affinity_rules))
|
||||
- `arch` (String)
|
||||
- `auto_start_w_node` (Boolean)
|
||||
- `boot_order` (List of String)
|
||||
- `bootdisk_size` (Number)
|
||||
- `cd_image_id` (Number)
|
||||
|
||||
@@ -60,6 +60,7 @@ Read-Only:
|
||||
- `affinity_weight` (Number)
|
||||
- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--anti_affinity_rules))
|
||||
- `arch` (String)
|
||||
- `auto_start_w_node` (Boolean)
|
||||
- `boot_order` (List of String)
|
||||
- `bootdisk_size` (Number)
|
||||
- `cd_image_id` (Number)
|
||||
|
||||
@@ -34,6 +34,7 @@ description: |-
|
||||
- `isolated_cpus` (List of String)
|
||||
- `name` (String)
|
||||
- `need_reboot` (Boolean)
|
||||
- `net_addr` (List of Object) (see [below for nested schema](#nestedatt--net_addr))
|
||||
- `nic_info` (List of Object) (see [below for nested schema](#nestedatt--nic_info))
|
||||
- `numa_topology` (List of Object) (see [below for nested schema](#nestedatt--numa_topology))
|
||||
- `reserved_cpus` (List of String)
|
||||
@@ -109,6 +110,15 @@ Read-Only:
|
||||
- `phys_count` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--net_addr"></a>
|
||||
### Nested Schema for `net_addr`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `ip` (List of String)
|
||||
- `name` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--nic_info"></a>
|
||||
### Nested Schema for `nic_info`
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ Read-Only:
|
||||
- `tech_status` (String)
|
||||
- `type` (String)
|
||||
- `vins` (List of Number)
|
||||
- `vnc_password` (String)
|
||||
|
||||
<a id="nestedobjatt--vnf_dev--config"></a>
|
||||
### Nested Schema for `vnf_dev.config`
|
||||
|
||||
@@ -90,6 +90,7 @@ Read-Only:
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `client_type` (String)
|
||||
- `desc` (String)
|
||||
- `domainname` (String)
|
||||
|
||||
61
docs/data-sources/extnet_reserved_ip_list.md
Normal file
61
docs/data-sources/extnet_reserved_ip_list.md
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_extnet_reserved_ip_list Data Source - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_extnet_reserved_ip_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `extnet_id` (Number)
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `extnet_id` (Number)
|
||||
- `reservations` (List of Object) (see [below for nested schema](#nestedobjatt--items--reservations))
|
||||
|
||||
<a id="nestedobjatt--items--reservations"></a>
|
||||
### Nested Schema for `items.reservations`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `client_type` (String)
|
||||
- `domain_name` (String)
|
||||
- `hostname` (String)
|
||||
- `ip` (String)
|
||||
- `mac` (String)
|
||||
- `type` (String)
|
||||
- `vm_id` (Number)
|
||||
@@ -33,6 +33,7 @@ description: |-
|
||||
- `affinity_weight` (Number)
|
||||
- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedatt--anti_affinity_rules))
|
||||
- `arch` (String)
|
||||
- `auto_start_w_node` (Boolean)
|
||||
- `boot_order` (List of String)
|
||||
- `bootdisk_size` (Number)
|
||||
- `cd_image_id` (Number)
|
||||
@@ -94,6 +95,7 @@ description: |-
|
||||
- `vgpus` (List of Number)
|
||||
- `virtual_image_id` (Number)
|
||||
- `virtual_image_name` (String)
|
||||
- `vnc_password` (String)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
@@ -62,6 +62,7 @@ Read-Only:
|
||||
- `affinity_weight` (Number)
|
||||
- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--anti_affinity_rules))
|
||||
- `arch` (String)
|
||||
- `auto_start_w_node` (Boolean)
|
||||
- `boot_order` (List of String)
|
||||
- `bootdisk_size` (Number)
|
||||
- `cd_image_id` (Number)
|
||||
|
||||
@@ -60,6 +60,7 @@ Read-Only:
|
||||
- `affinity_weight` (Number)
|
||||
- `anti_affinity_rules` (List of Object) (see [below for nested schema](#nestedobjatt--items--anti_affinity_rules))
|
||||
- `arch` (String)
|
||||
- `auto_start_w_node` (Boolean)
|
||||
- `boot_order` (List of String)
|
||||
- `bootdisk_size` (Number)
|
||||
- `cd_image_id` (Number)
|
||||
|
||||
@@ -108,6 +108,7 @@ Read-Only:
|
||||
- `tech_status` (String)
|
||||
- `type` (String)
|
||||
- `vins` (List of Number)
|
||||
- `vnc_password` (String)
|
||||
- `vnf_id` (Number)
|
||||
- `vnf_name` (String)
|
||||
|
||||
@@ -248,10 +249,7 @@ Read-Only:
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `client_type` (String)
|
||||
- `desc` (String)
|
||||
- `domainname` (String)
|
||||
- `hostname` (String)
|
||||
- `account_id` (Number)
|
||||
- `ip` (String)
|
||||
- `mac` (String)
|
||||
- `type` (String)
|
||||
|
||||
@@ -62,6 +62,7 @@ description: |-
|
||||
- `res_name` (String)
|
||||
- `rescuecd` (Boolean)
|
||||
- `size` (Number) image size
|
||||
- `snapshot_id` (String) snapshot id
|
||||
- `status` (String) status
|
||||
- `tech_status` (String) tech atatus
|
||||
- `unc_path` (String) unc path
|
||||
|
||||
@@ -37,6 +37,7 @@ description: |-
|
||||
- `ntp` (List of String) List of NTP addresses
|
||||
- `ovs_bridge` (String) OpenvSwith bridge name for ExtNet connection
|
||||
- `pre_reservations_num` (Number) Number of pre created reservations
|
||||
- `reserved_ip` (Block Set) (see [below for nested schema](#nestedblock--reserved_ip))
|
||||
- `restart` (Boolean) restart extnet vnf device
|
||||
- `set_default` (Boolean) Set current extnet as default (can not be undone)
|
||||
- `shared_with` (Set of Number)
|
||||
@@ -88,6 +89,19 @@ Required:
|
||||
- `ip_start` (String)
|
||||
|
||||
|
||||
<a id="nestedblock--reserved_ip"></a>
|
||||
### Nested Schema for `reserved_ip`
|
||||
|
||||
Required:
|
||||
|
||||
- `account_id` (Number)
|
||||
|
||||
Optional:
|
||||
|
||||
- `ip_count` (Number)
|
||||
- `ips` (Set of String)
|
||||
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
@@ -119,6 +133,7 @@ Read-Only:
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `client_type` (String)
|
||||
- `desc` (String)
|
||||
- `domain_name` (String)
|
||||
|
||||
@@ -67,6 +67,7 @@ description: |-
|
||||
- `res_name` (String)
|
||||
- `rescuecd` (Boolean)
|
||||
- `size` (Number) image size
|
||||
- `snapshot_id` (String) snapshot id
|
||||
- `status` (String) status
|
||||
- `tech_status` (String) tech atatus
|
||||
- `unc_path` (String) unc path
|
||||
|
||||
@@ -64,6 +64,7 @@ description: |-
|
||||
- `res_name` (String)
|
||||
- `rescuecd` (Boolean)
|
||||
- `size` (Number)
|
||||
- `snapshot_id` (String) snapshot id
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `unc_path` (String)
|
||||
|
||||
@@ -64,6 +64,7 @@ description: |-
|
||||
- `res_name` (String)
|
||||
- `rescuecd` (Boolean)
|
||||
- `size` (Number)
|
||||
- `snapshot_id` (String) snapshot id
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `unc_path` (String)
|
||||
|
||||
@@ -30,6 +30,7 @@ description: |-
|
||||
- `alt_boot_id` (Number) ID of CD-ROM live image to boot
|
||||
- `anti_affinity_rules` (Block List) (see [below for nested schema](#nestedblock--anti_affinity_rules))
|
||||
- `auto_start` (Boolean) Flag for redeploy compute
|
||||
- `auto_start_w_node` (Boolean)
|
||||
- `boot_disk_size` (Number) This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.
|
||||
- `cd` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--cd))
|
||||
- `chipset` (String) Type of the emulated system.
|
||||
@@ -128,6 +129,7 @@ description: |-
|
||||
- `vgpus` (List of Number)
|
||||
- `virtual_image_id` (Number)
|
||||
- `virtual_image_name` (String)
|
||||
- `vnc_password` (String)
|
||||
|
||||
<a id="nestedblock--affinity_rules"></a>
|
||||
### Nested Schema for `affinity_rules`
|
||||
|
||||
@@ -167,6 +167,7 @@ Read-Only:
|
||||
- `tech_status` (String)
|
||||
- `type` (String)
|
||||
- `vins` (List of Number)
|
||||
- `vnc_password` (String)
|
||||
|
||||
<a id="nestedobjatt--vnf_dev--config"></a>
|
||||
### Nested Schema for `vnf_dev.config`
|
||||
|
||||
@@ -24,11 +24,11 @@ description: |-
|
||||
|
||||
### Optional
|
||||
|
||||
- `compute_ids` (List of Number)
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `compute_ids` (List of Number)
|
||||
- `guid` (String)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `route_id` (Number) Unique ID of the static route
|
||||
|
||||
@@ -61,6 +61,7 @@ description: |-
|
||||
- `rescuecd` (Boolean)
|
||||
- `sep_id` (Number) storage endpoint provider ID
|
||||
- `size` (Number) image size
|
||||
- `snapshot_id` (String) snapshot id
|
||||
- `status` (String) status
|
||||
- `tech_status` (String) tech atatus
|
||||
- `unc_path` (String) unc path
|
||||
|
||||
@@ -29,6 +29,7 @@ description: |-
|
||||
- `affinity_rules` (Block List) (see [below for nested schema](#nestedblock--affinity_rules))
|
||||
- `anti_affinity_rules` (Block List) (see [below for nested schema](#nestedblock--anti_affinity_rules))
|
||||
- `auto_start` (Boolean) Flag for redeploy compute
|
||||
- `auto_start_w_node` (Boolean) Flag for start compute after node exits from MAINTENANCE state
|
||||
- `boot_disk_size` (Number) This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.
|
||||
- `cd` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--cd))
|
||||
- `chipset` (String) Type of the emulated system.
|
||||
@@ -121,6 +122,7 @@ description: |-
|
||||
- `vgpus` (List of Number)
|
||||
- `virtual_image_id` (Number)
|
||||
- `virtual_image_name` (String)
|
||||
- `vnc_password` (String)
|
||||
|
||||
<a id="nestedblock--affinity_rules"></a>
|
||||
### Nested Schema for `affinity_rules`
|
||||
|
||||
@@ -163,6 +163,7 @@ Read-Only:
|
||||
- `tech_status` (String)
|
||||
- `type` (String)
|
||||
- `vins` (List of Number)
|
||||
- `vnc_password` (String)
|
||||
- `vnf_id` (Number)
|
||||
- `vnf_name` (String)
|
||||
|
||||
@@ -303,10 +304,7 @@ Read-Only:
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `client_type` (String)
|
||||
- `desc` (String)
|
||||
- `domainname` (String)
|
||||
- `hostname` (String)
|
||||
- `account_id` (Number)
|
||||
- `ip` (String)
|
||||
- `mac` (String)
|
||||
- `type` (String)
|
||||
|
||||
@@ -24,12 +24,12 @@ description: |-
|
||||
|
||||
### Optional
|
||||
|
||||
- `compute_ids` (List of Number)
|
||||
- `route_id` (Number)
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `compute_ids` (List of Number)
|
||||
- `guid` (String)
|
||||
- `id` (String) The ID of this resource.
|
||||
|
||||
|
||||
2
go.mod
2
go.mod
@@ -8,7 +8,7 @@ require (
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
golang.org/x/net v0.23.0
|
||||
repository.basistech.ru/BASIS/decort-golang-sdk v1.9.2
|
||||
repository.basistech.ru/BASIS/decort-golang-sdk v1.10.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@@ -137,6 +137,7 @@ func newDataSourcesMap() map[string]*schema.Resource {
|
||||
"decort_extnet_computes_list": extnet.DataSourceExtnetComputesList(),
|
||||
"decort_extnet": extnet.DataSourceExtnet(),
|
||||
"decort_extnet_default": extnet.DataSourceExtnetDefault(),
|
||||
"decort_extnet_reserved_ip_list": extnet.DataSourceExtnetReservedIp(),
|
||||
"decort_locations_list": locations.DataSourceLocationsList(),
|
||||
"decort_location_url": locations.DataSourceLocationUrl(),
|
||||
"decort_image_list": image.DataSourceImageList(),
|
||||
@@ -180,6 +181,7 @@ func newDataSourcesMap() map[string]*schema.Resource {
|
||||
"decort_cb_extnet": cb_extnet.DataSourceExtnetCB(),
|
||||
"decort_cb_extnet_list": cb_extnet.DataSourceExtnetListCB(),
|
||||
"decort_cb_extnet_default": cb_extnet.DataSourceExtnetDefaultCB(),
|
||||
"decort_cb_extnet_reserved_ip_list": cb_extnet.DataSourceExtnetReservedIp(),
|
||||
"decort_cb_extnet_static_route_list": cb_extnet.DataSourceStaticRouteList(),
|
||||
"decort_cb_extnet_static_route": cb_extnet.DataSourceStaticRoute(),
|
||||
"decort_cb_image": cb_image.DataSourceImage(),
|
||||
@@ -187,7 +189,6 @@ func newDataSourcesMap() map[string]*schema.Resource {
|
||||
"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_get_settings": cb_grid.DataSourceGridGetSettings(),
|
||||
"decort_cb_grid_list": cb_grid.DataSourceGridList(),
|
||||
"decort_cb_grid_list_emails": cb_grid.DataSourceGridListEmails(),
|
||||
|
||||
@@ -204,6 +204,10 @@ func dataSourceExtnetSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"client_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
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.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func dataSourceExtnetReservedIpRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
reservedList, err := utilityExtnetReservedIpCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
d.Set("items", flattenExtnetReservedIp(reservedList))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceExtnetReservedIpSchemaMake() map[string]*schema.Schema {
|
||||
res := map[string]*schema.Schema{
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"extnet_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
"items": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"extnet_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"reservations": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"client_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"domain_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"hostname": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"ip": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"mac": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vm_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func DataSourceExtnetReservedIp() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceExtnetReservedIpRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceExtnetReservedIpSchemaMake(),
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,7 @@ func flattenExtnetReservations(ers extnet.ListReservations) []map[string]interfa
|
||||
res := make([]map[string]interface{}, 0, len(ers))
|
||||
for _, er := range ers {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": er.AccountID,
|
||||
"client_type": er.ClientType,
|
||||
"domainname": er.DomainName,
|
||||
"hostname": er.Hostname,
|
||||
@@ -135,3 +136,29 @@ func flattenExtnetList(el *extnet.ListExtNets) []map[string]interface{} {
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenExtnetReservedIp(el []extnet.RecordReservedIP) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0, len(el))
|
||||
for _, e := range el {
|
||||
reservations := make([]map[string]interface{}, 0, len(e.Reservations))
|
||||
for _, r := range e.Reservations {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": r.AccountID,
|
||||
"client_type": r.ClientType,
|
||||
"domain_name": r.DomainName,
|
||||
"hostname": r.Hostname,
|
||||
"ip": r.IP,
|
||||
"mac": r.Mac,
|
||||
"type": r.Type,
|
||||
"vm_id": r.VMID,
|
||||
}
|
||||
reservations = append(reservations, temp)
|
||||
}
|
||||
item := map[string]interface{}{
|
||||
"extnet_id": e.ExtnetID,
|
||||
"reservations": reservations,
|
||||
}
|
||||
res = append(res, item)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityExtnetReservedIpCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]extnet.RecordReservedIP, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := extnet.GetReservedIP{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
}
|
||||
|
||||
if extNetID, ok := d.GetOk("extnet_id"); ok {
|
||||
req.ExtNetID = uint64(extNetID.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityExtnetReservedIpCheckPresence")
|
||||
res, err := c.CloudAPI().ExtNet().GetReservedIP(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
@@ -703,6 +703,10 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"auto_start_w_node": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"chipset": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@@ -950,6 +954,10 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vnc_password": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vgpus": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
|
||||
@@ -121,6 +121,10 @@ func itemComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"auto_start_w_node": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"boot_order": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
|
||||
@@ -183,6 +183,7 @@ func flattenComputeList(computes *compute.ListComputes) []map[string]interface{}
|
||||
"affinity_weight": compute.AffinityWeight,
|
||||
"anti_affinity_rules": flattenListRules(compute.AntiAffinityRules),
|
||||
"arch": compute.Architecture,
|
||||
"auto_start_w_node": compute.AutoStart,
|
||||
"boot_order": compute.BootOrder,
|
||||
"bootdisk_size": compute.BootDiskSize,
|
||||
"chipset": compute.Chipset,
|
||||
@@ -362,6 +363,7 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute, pc
|
||||
d.Set("account_name", computeRec.AccountName)
|
||||
d.Set("affinity_weight", computeRec.AffinityWeight)
|
||||
d.Set("arch", computeRec.Architecture)
|
||||
d.Set("auto_start_w_node", computeRec.AutoStart)
|
||||
d.Set("boot_order", computeRec.BootOrder)
|
||||
// we intentionally use the SizeMax field, do not change it until the BootDiskSize field is fixed on the platform
|
||||
d.Set("boot_disk_size", bootDisk.SizeMax)
|
||||
@@ -429,6 +431,7 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute, pc
|
||||
d.Set("updated_by", computeRec.UpdatedBy)
|
||||
d.Set("updated_time", computeRec.UpdatedTime)
|
||||
d.Set("user_managed", computeRec.UserManaged)
|
||||
d.Set("vnc_password", computeRec.VNCPassword)
|
||||
d.Set("vgpus", computeRec.VGPUs)
|
||||
d.Set("virtual_image_id", computeRec.VirtualImageID)
|
||||
d.Set("virtual_image_name", computeRec.VirtualImageName)
|
||||
@@ -613,6 +616,7 @@ func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute
|
||||
d.Set("affinity_rules", flattenAffinityRules(computeRec.AffinityRules))
|
||||
d.Set("affinity_weight", computeRec.AffinityWeight)
|
||||
d.Set("anti_affinity_rules", flattenListRules(computeRec.AntiAffinityRules))
|
||||
d.Set("auto_start_w_node", computeRec.AutoStart)
|
||||
d.Set("arch", computeRec.Architecture)
|
||||
d.Set("chipset", computeRec.Chipset)
|
||||
d.Set("boot_order", computeRec.BootOrder)
|
||||
@@ -672,6 +676,7 @@ func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute
|
||||
d.Set("updated_time", computeRec.UpdatedTime)
|
||||
d.Set("user_managed", computeRec.UserManaged)
|
||||
d.Set("userdata", string(userdata))
|
||||
d.Set("vnc_password", computeRec.VNCPassword)
|
||||
d.Set("vgpus", computeRec.VGPUs)
|
||||
d.Set("virtual_image_id", computeRec.VirtualImageID)
|
||||
d.Set("virtual_image_name", computeRec.VirtualImageName)
|
||||
|
||||
@@ -491,12 +491,26 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
req := compute.PinToStackRequest{
|
||||
ComputeID: computeId,
|
||||
}
|
||||
req.AutoStart = d.Get("auto_start_w_node").(bool)
|
||||
_, err := c.CloudAPI().Compute().PinToStack(ctx, req)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if !d.Get("pin_to_stack").(bool) && d.Get("auto_start_w_node").(bool) {
|
||||
req := compute.UpdateRequest{
|
||||
ComputeID: computeId,
|
||||
AutoStart: d.Get("auto_start_w_node").(bool),
|
||||
CPUPin: d.Get("cpu_pin").(bool),
|
||||
HPBacked: d.Get("hp_backed").(bool),
|
||||
}
|
||||
_, err := c.CloudAPI().Compute().Update(ctx, req)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.Get("pause").(bool) {
|
||||
req := compute.PauseRequest{
|
||||
ComputeID: computeId,
|
||||
@@ -619,7 +633,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
}
|
||||
|
||||
if !hasRG {
|
||||
return diag.Errorf("resourceComputeUpdate: can't update Compute bacause rgID %d not allowed or does not exist", d.Get("rg_id").(int))
|
||||
return diag.Errorf("resourceComputeUpdate: can't update Compute because rgID %d not allowed or does not exist", d.Get("rg_id").(int))
|
||||
}
|
||||
|
||||
hasImage, err := existImageId(ctx, d, m)
|
||||
@@ -628,7 +642,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
}
|
||||
|
||||
if !hasImage {
|
||||
return diag.Errorf("resourceComputeUpdate: can't update Compute bacause imageID %d not allowed or does not exist", d.Get("image_id").(int))
|
||||
return diag.Errorf("resourceComputeUpdate: can't update Compute because imageID %d not allowed or does not exist", d.Get("image_id").(int))
|
||||
}
|
||||
|
||||
if disks, ok := d.GetOk("disks"); ok {
|
||||
@@ -862,7 +876,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChanges("description", "name", "numa_affinity", "cpu_pin", "hp_backed") {
|
||||
if d.HasChanges("description", "name", "numa_affinity", "cpu_pin", "hp_backed", "chipset", "auto_start_w_node") {
|
||||
req := compute.UpdateRequest{
|
||||
ComputeID: computeRec.ID,
|
||||
}
|
||||
@@ -876,21 +890,17 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
if d.HasChange("numa_affinity") {
|
||||
req.NumaAffinity = d.Get("numa_affinity").(string)
|
||||
}
|
||||
if d.HasChange("cpu_pin") {
|
||||
req.CPUPin = d.Get("cpu_pin").(bool)
|
||||
}
|
||||
if d.HasChange("hp_backed") {
|
||||
req.HPBacked = d.Get("hp_backed").(bool)
|
||||
}
|
||||
|
||||
if d.HasChange("chipset") {
|
||||
req.Chipset = d.Get("chipset").(string)
|
||||
}
|
||||
req.CPUPin = d.Get("cpu_pin").(bool)
|
||||
req.HPBacked = d.Get("hp_backed").(bool)
|
||||
req.AutoStart = d.Get("auto_start_w_node").(bool)
|
||||
|
||||
// Note bene: numa_affinity, cpu_pin and hp_backed are not allowed to be changed for compute in STARTED tech status.
|
||||
// If STARTED, we need to stop it before update
|
||||
var isStopRequired bool
|
||||
if d.HasChanges("numa_affinity", "cpu_pin", "hp_backed") && d.Get("started").(bool) {
|
||||
if d.HasChanges("numa_affinity", "cpu_pin", "hp_backed", "chipset") && d.Get("started").(bool) {
|
||||
isStopRequired = true
|
||||
}
|
||||
if isStopRequired {
|
||||
@@ -1481,7 +1491,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
req := compute.PinToStackRequest{
|
||||
ComputeID: computeRec.ID,
|
||||
}
|
||||
|
||||
req.AutoStart = d.Get("auto_start_w_node").(bool)
|
||||
_, err := c.CloudAPI().Compute().PinToStack(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
@@ -2123,6 +2133,12 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Optional: true,
|
||||
Default: false,
|
||||
},
|
||||
"auto_start_w_node": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Flag for start compute after node exits from MAINTENANCE state",
|
||||
},
|
||||
"auto_start": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
@@ -2411,6 +2427,10 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"vnc_password": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vgpus": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
@@ -2444,11 +2464,14 @@ func ResourceCompute() *schema.Resource {
|
||||
},
|
||||
|
||||
CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error {
|
||||
if diff.HasChanges() || diff.HasChanges("network", "affinity_rules", "anti_affinity_rules",
|
||||
if diff.HasChanges() || diff.HasChanges("chipset", "pin_to_stack", "auto_start_w_node", "network", "affinity_rules", "anti_affinity_rules",
|
||||
"disks", "extra_disks", "tags", "port_forwarding", "user_access", "snapshot", "pci_devices") {
|
||||
diff.SetNewComputed("updated_time")
|
||||
diff.SetNewComputed("updated_by")
|
||||
}
|
||||
if diff.HasChanges("pin_to_stack") {
|
||||
diff.SetNewComputed("pinned")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
|
||||
|
||||
@@ -347,6 +347,10 @@ func vnfDevSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vnc_password": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vins": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
@@ -372,20 +376,8 @@ func vinsComputeSchemaMake() map[string]*schema.Schema {
|
||||
|
||||
func reservationSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"client_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"domainname": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"hostname": {
|
||||
Type: schema.TypeString,
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"ip": {
|
||||
|
||||
@@ -151,6 +151,7 @@ func flattenVNFDev(vnfDev vins.RecordVNFDev) []map[string]interface{} {
|
||||
"status": vnfDev.Status,
|
||||
"tech_status": vnfDev.TechStatus,
|
||||
"type": vnfDev.Type,
|
||||
"vnc_password": vnfDev.VNCPassword,
|
||||
"vins": vnfDev.VINS,
|
||||
}
|
||||
|
||||
@@ -176,14 +177,11 @@ func flattenReservations(reservations vins.ListReservations) []map[string]interf
|
||||
res := make([]map[string]interface{}, 0, len(reservations))
|
||||
for _, reservation := range reservations {
|
||||
temp := map[string]interface{}{
|
||||
"client_type": reservation.ClientType,
|
||||
"desc": reservation.Description,
|
||||
"domainname": reservation.DomainName,
|
||||
"hostname": reservation.Hostname,
|
||||
"ip": reservation.IP,
|
||||
"mac": reservation.MAC,
|
||||
"type": reservation.Type,
|
||||
"vm_id": reservation.VMID,
|
||||
"account_id": reservation.AccountID,
|
||||
"ip": reservation.IP,
|
||||
"mac": reservation.MAC,
|
||||
"type": reservation.Type,
|
||||
"vm_id": reservation.VMID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
@@ -1,277 +1,194 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
if _, ok := d.GetOk("vins_id"); ok {
|
||||
haveVinsID, err := existVinsID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveVinsID {
|
||||
return diag.Errorf("resourceStaticRouteCreate: can't create Static Route because Vins ID %d is not allowed or does not exist", d.Get("vins_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
req := vins.StaticRouteAddRequest{
|
||||
VINSID: uint64(d.Get("vins_id").(int)),
|
||||
Destination: d.Get("destination").(string),
|
||||
Netmask: d.Get("netmask").(string),
|
||||
Gateway: d.Get("gateway").(string),
|
||||
}
|
||||
|
||||
if computesIDS, ok := d.GetOk("compute_ids"); ok {
|
||||
ids := computesIDS.([]interface{})
|
||||
|
||||
res := make([]uint64, 10)
|
||||
|
||||
for _, id := range ids {
|
||||
computeId := uint64(id.(int))
|
||||
res = append(res, computeId)
|
||||
}
|
||||
|
||||
req.ComputeIds = res
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().VINS().StaticRouteAdd(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
staticRouteData, err := getStaticRouteData(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(fmt.Sprintf("%d#%d", req.VINSID, staticRouteData.ID))
|
||||
|
||||
return resourceStaticRouteRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
warnings := dc.Warnings{}
|
||||
|
||||
staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
flattenStaticRouteData(d, staticRouteData)
|
||||
|
||||
return warnings.Get()
|
||||
}
|
||||
|
||||
func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
warnings := dc.Warnings{}
|
||||
|
||||
if _, ok := d.GetOk("vins_id"); ok {
|
||||
haveVinsID, err := existVinsID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveVinsID {
|
||||
return diag.Errorf("resourceVinsUpdate: can't update Static Route because VinsID %d is not allowed or does not exist", d.Get("vins_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if d.HasChange("compute_ids") {
|
||||
deletedIds := make([]uint64, 0)
|
||||
addedIds := make([]uint64, 0)
|
||||
|
||||
oldComputeIds, newComputeIds := d.GetChange("compute_ids")
|
||||
oldComputeIdsSlice := oldComputeIds.([]interface{})
|
||||
newComputeIdsSlice := newComputeIds.([]interface{})
|
||||
|
||||
for _, el := range oldComputeIdsSlice {
|
||||
if !isContainsIds(newComputeIdsSlice, el) {
|
||||
convertedEl := uint64(el.(int))
|
||||
deletedIds = append(deletedIds, convertedEl)
|
||||
}
|
||||
}
|
||||
|
||||
for _, el := range newComputeIdsSlice {
|
||||
if !isContainsIds(oldComputeIdsSlice, el) {
|
||||
convertedEl := uint64(el.(int))
|
||||
addedIds = append(addedIds, convertedEl)
|
||||
}
|
||||
}
|
||||
|
||||
if len(deletedIds) > 0 {
|
||||
req := vins.StaticRouteAccessRevokeRequest{
|
||||
VINSID: uint64(d.Get("vins_id").(int)),
|
||||
RouteId: staticRouteData.ID,
|
||||
ComputeIds: deletedIds,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().VINS().StaticRouteAccessRevoke(ctx, req)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(addedIds) > 0 {
|
||||
req := vins.StaticRouteAccessGrantRequest{
|
||||
VINSID: uint64(d.Get("vins_id").(int)),
|
||||
RouteId: staticRouteData.ID,
|
||||
ComputeIds: addedIds,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().VINS().StaticRouteAccessGrant(ctx, req)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return append(warnings.Get(), resourceStaticRouteRead(ctx, d, m)...)
|
||||
}
|
||||
|
||||
func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
arr := strings.Split(d.Id(), "#")
|
||||
if len(arr) != 2 {
|
||||
return diag.FromErr(fmt.Errorf("broken state id"))
|
||||
}
|
||||
|
||||
vinsId, _ := strconv.ParseUint(arr[0], 10, 64)
|
||||
routeId, _ := strconv.ParseUint(arr[1], 10, 64)
|
||||
|
||||
req := vins.StaticRouteDelRequest{
|
||||
VINSID: vinsId,
|
||||
RouteId: routeId,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().VINS().StaticRouteDel(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceStaticRouteSchemaMake() map[string]*schema.Schema {
|
||||
rets := dataSourceStaticRouteSchemaMake()
|
||||
rets["route_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
}
|
||||
rets["compute_ids"] = &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
}
|
||||
rets["destination"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
}
|
||||
|
||||
rets["gateway"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
}
|
||||
rets["netmask"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
func isContainsIds(els []interface{}, el interface{}) bool {
|
||||
convEl := el.(int)
|
||||
for _, elOld := range els {
|
||||
if convEl == elOld.(int) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ResourceStaticRoute() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
CreateContext: resourceStaticRouteCreate,
|
||||
ReadContext: resourceStaticRouteRead,
|
||||
UpdateContext: resourceStaticRouteUpdate,
|
||||
DeleteContext: resourceStaticRouteDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &constants.Timeout20m,
|
||||
Read: &constants.Timeout600s,
|
||||
Update: &constants.Timeout20m,
|
||||
Delete: &constants.Timeout600s,
|
||||
Default: &constants.Timeout600s,
|
||||
},
|
||||
|
||||
Schema: resourceStaticRouteSchemaMake(),
|
||||
}
|
||||
}
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
if _, ok := d.GetOk("vins_id"); ok {
|
||||
haveVinsID, err := existVinsID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveVinsID {
|
||||
return diag.Errorf("resourceStaticRouteCreate: can't create Static Route because Vins ID %d is not allowed or does not exist", d.Get("vins_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
req := vins.StaticRouteAddRequest{
|
||||
VINSID: uint64(d.Get("vins_id").(int)),
|
||||
Destination: d.Get("destination").(string),
|
||||
Netmask: d.Get("netmask").(string),
|
||||
Gateway: d.Get("gateway").(string),
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().VINS().StaticRouteAdd(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
staticRouteData, err := getStaticRouteData(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(fmt.Sprintf("%d#%d", req.VINSID, staticRouteData.ID))
|
||||
|
||||
return resourceStaticRouteRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
warnings := dc.Warnings{}
|
||||
|
||||
staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
flattenStaticRouteData(d, staticRouteData)
|
||||
|
||||
return warnings.Get()
|
||||
}
|
||||
|
||||
func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
arr := strings.Split(d.Id(), "#")
|
||||
if len(arr) != 2 {
|
||||
return diag.FromErr(fmt.Errorf("broken state id"))
|
||||
}
|
||||
|
||||
vinsId, _ := strconv.ParseUint(arr[0], 10, 64)
|
||||
routeId, _ := strconv.ParseUint(arr[1], 10, 64)
|
||||
|
||||
req := vins.StaticRouteDelRequest{
|
||||
VINSID: vinsId,
|
||||
RouteId: routeId,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().VINS().StaticRouteDel(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceStaticRouteSchemaMake() map[string]*schema.Schema {
|
||||
rets := dataSourceStaticRouteSchemaMake()
|
||||
rets["route_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
}
|
||||
rets["compute_ids"] = &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
}
|
||||
rets["destination"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
}
|
||||
|
||||
rets["gateway"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
}
|
||||
rets["netmask"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
func isContainsIds(els []interface{}, el interface{}) bool {
|
||||
convEl := el.(int)
|
||||
for _, elOld := range els {
|
||||
if convEl == elOld.(int) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ResourceStaticRoute() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
CreateContext: resourceStaticRouteCreate,
|
||||
ReadContext: resourceStaticRouteRead,
|
||||
UpdateContext: resourceStaticRouteUpdate,
|
||||
DeleteContext: resourceStaticRouteDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &constants.Timeout20m,
|
||||
Read: &constants.Timeout600s,
|
||||
Update: &constants.Timeout20m,
|
||||
Delete: &constants.Timeout600s,
|
||||
Default: &constants.Timeout600s,
|
||||
},
|
||||
|
||||
Schema: resourceStaticRouteSchemaMake(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
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.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func dataSourceExtnetReservedIpRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
reservedList, err := utilityExtnetReservedIpCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
d.Set("items", flattenExtnetReservedIp(reservedList))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func DataSourceExtnetReservedIp() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceExtnetReservedIpRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceExtnetReservedIpSchemaMake(),
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,6 @@ func flattenRecordExtnetResource(d *schema.ResourceData, recNet *extnet.RecordEx
|
||||
d.Set("routes", flattenStaticRouteList(staticRouteList))
|
||||
}
|
||||
|
||||
|
||||
func flattenExtnetExcluded(ers extnet.ListReservations) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, er := range ers {
|
||||
@@ -157,6 +156,7 @@ func flattenExtnetReservations(ers extnet.ListReservations) []map[string]interfa
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, er := range ers {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": er.AccountID,
|
||||
"client_type": er.ClientType,
|
||||
"domain_name": er.DomainName,
|
||||
"hostname": er.Hostname,
|
||||
@@ -217,4 +217,30 @@ func flattenStaticRouteData(d *schema.ResourceData, route *extnet.ItemRoutes) {
|
||||
d.Set("netmask", route.Netmask)
|
||||
d.Set("compute_ids", route.ComputeIds)
|
||||
d.Set("route_id", route.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func flattenExtnetReservedIp(el []extnet.RecordReservedIP) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0, len(el))
|
||||
for _, e := range el {
|
||||
reservations := make([]map[string]interface{}, 0, len(e.Reservations))
|
||||
for _, r := range e.Reservations {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": r.AccountID,
|
||||
"client_type": r.ClientType,
|
||||
"domain_name": r.DomainName,
|
||||
"hostname": r.Hostname,
|
||||
"ip": r.IP,
|
||||
"mac": r.Mac,
|
||||
"type": r.Type,
|
||||
"vm_id": r.VMID,
|
||||
}
|
||||
reservations = append(reservations, temp)
|
||||
}
|
||||
item := map[string]interface{}{
|
||||
"extnet_id": e.ExtnetID,
|
||||
"reservations": reservations,
|
||||
}
|
||||
res = append(res, item)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -54,6 +54,9 @@ func resourceExtnetCreate(ctx context.Context, d *schema.ResourceData, m interfa
|
||||
if err := ic.ExistGID(ctx, uint64(d.Get("gid").(int)), c); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
if err := checkReserveIp(ctx, d, c); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
req := extnet.CreateRequest{
|
||||
Name: d.Get("name").(string),
|
||||
@@ -191,6 +194,34 @@ func resourceExtnetCreate(ctx context.Context, d *schema.ResourceData, m interfa
|
||||
}
|
||||
}
|
||||
|
||||
// for reserve IP extnet must be enabled
|
||||
if d.Get("reserved_ip").(*schema.Set).Len() > 0 {
|
||||
for _, reservedIP := range d.Get("reserved_ip").(*schema.Set).List() {
|
||||
reservedIPMap := reservedIP.(map[string]interface{})
|
||||
req := extnet.AddReserveIPRequest{
|
||||
AccountID: uint64(reservedIPMap["account_id"].(int)),
|
||||
ExtNetID: netID,
|
||||
}
|
||||
if ipCount, ok := reservedIPMap["ip_count"]; ok {
|
||||
req.IPCount = uint64(ipCount.(int))
|
||||
}
|
||||
if reservedIPMap["ips"].(*schema.Set).Len() > 0 {
|
||||
ips := reservedIPMap["ips"].(*schema.Set).List()
|
||||
for i, ip := range ips {
|
||||
if i >= int(req.IPCount) {
|
||||
break
|
||||
}
|
||||
req.IPs = append(req.IPs, ip.(string))
|
||||
}
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().ExtNet().AddReserveIP(ctx, req)
|
||||
if err != nil {
|
||||
w.Add(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resourceExtnetRead(ctx, d, m)
|
||||
}
|
||||
|
||||
@@ -215,6 +246,10 @@ func resourceExtnetUpdate(ctx context.Context, d *schema.ResourceData, m interfa
|
||||
log.Debugf("cloudbroker: resourceExtnetUpdate called with id %s", d.Id())
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
if err := checkReserveIp(ctx, d, c); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
recNet, err := utilityExtnetCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
@@ -267,6 +302,12 @@ func resourceExtnetUpdate(ctx context.Context, d *schema.ResourceData, m interfa
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("reserved_ip") {
|
||||
if err := reservedIPsUpdate(ctx, d, c, recNet); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("shared_with") {
|
||||
if err := handleSharedWithUpdate(ctx, d, c); err != nil {
|
||||
return diag.FromErr(err)
|
||||
@@ -330,6 +371,8 @@ func ResourceExtnetCB() *schema.Resource {
|
||||
Default: &constants.Timeout300s,
|
||||
},
|
||||
|
||||
CustomizeDiff: validateReserveIPs,
|
||||
|
||||
Schema: resourceExtnetSchemaMake(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package extnet
|
||||
|
||||
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
)
|
||||
|
||||
func dataSourceExtnetDefaultSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
@@ -474,6 +477,10 @@ func dataSourceExtnetSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"client_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@@ -728,6 +735,30 @@ func resourceExtnetSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"reserved_ip": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"ip_count": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
ValidateFunc: validation.IntBetween(1, 255),
|
||||
},
|
||||
"ips": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"ckey": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@@ -868,6 +899,10 @@ func resourceExtnetSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"client_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@@ -905,3 +940,69 @@ func resourceExtnetSchemaMake() map[string]*schema.Schema {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceExtnetReservedIpSchemaMake() map[string]*schema.Schema {
|
||||
res := map[string]*schema.Schema{
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"extnet_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
"items": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"extnet_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"reservations": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"client_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"domain_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"hostname": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"ip": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"mac": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vm_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package extnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/extnet"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityExtnetReservedIpCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]extnet.RecordReservedIP, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := extnet.GetReservedIP{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
}
|
||||
|
||||
if extNetID, ok := d.GetOk("extnet_id"); ok {
|
||||
req.ExtNetID = uint64(extNetID.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityExtnetReservedIpCheckPresence")
|
||||
res, err := c.CloudBroker().ExtNet().GetReservedIP(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
@@ -35,6 +35,8 @@ package extnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -341,3 +343,255 @@ func handleMigrateUpdate(ctx context.Context, d *schema.ResourceData, c *control
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkReserveIp(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) error {
|
||||
var err error
|
||||
if d.Get("reserved_ip").(*schema.Set).Len() > 0 {
|
||||
reservedIPList := d.Get("reserved_ip").(*schema.Set).List()
|
||||
accountMap := make(map[int]struct{}, len(reservedIPList))
|
||||
for _, reservedIP := range reservedIPList {
|
||||
reservedIPMap := reservedIP.(map[string]interface{})
|
||||
accountId := reservedIPMap["account_id"].(int)
|
||||
if _, ok := accountMap[accountId]; ok {
|
||||
err = errors.Join(err, fmt.Errorf("checkReserveIp: you must have only one block with id %d", accountId))
|
||||
}
|
||||
accountMap[accountId] = struct{}{}
|
||||
_, okCount := reservedIPMap["ip_count"]
|
||||
if !okCount && reservedIPMap["ips"].(*schema.Set).Len() == 0 {
|
||||
err = errors.Join(err, fmt.Errorf("checkReserveIp: either ip_count or set of ips must be specified"))
|
||||
}
|
||||
existErr := ic.ExistAccount(ctx, uint64(accountId), c)
|
||||
if existErr != nil {
|
||||
err = errors.Join(err, existErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func reservedIPsUpdate(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, recNet *extnet.RecordExtNet) error {
|
||||
|
||||
addSet, delSet, err := differenceIPReserved(ctx, d, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(delSet) > 0 {
|
||||
for _, del := range delSet {
|
||||
delMap := del.(map[string]interface{})
|
||||
|
||||
log.Debugf("reservedIPsUpdate: removing reserved IPs for account %d", delMap["account_id"].(int))
|
||||
|
||||
req := extnet.DelReserveIPRequest{
|
||||
AccountID: uint64(delMap["account_id"].(int)),
|
||||
ExtNetID: recNet.ID,
|
||||
}
|
||||
if ipCount, ok := delMap["ip_count"]; ok {
|
||||
req.IPCount = uint64(ipCount.(int))
|
||||
}
|
||||
if delIPs, ok := delMap["ips"]; ok {
|
||||
ips := delIPs.(*schema.Set).List()
|
||||
for _, ip := range ips {
|
||||
req.IPs = append(req.IPs, ip.(string))
|
||||
}
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().ExtNet().DelReserveIP(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(addSet) > 0 {
|
||||
for _, add := range addSet {
|
||||
addMap := add.(map[string]interface{})
|
||||
|
||||
log.Debugf("reservedIPsUpdate: add reserved IPs for account %d", addMap["account_id"].(int))
|
||||
|
||||
req := extnet.AddReserveIPRequest{
|
||||
AccountID: uint64(addMap["account_id"].(int)),
|
||||
ExtNetID: recNet.ID,
|
||||
}
|
||||
if ipCount, ok := addMap["ip_count"]; ok {
|
||||
req.IPCount = uint64(ipCount.(int))
|
||||
}
|
||||
if addIPs, ok := addMap["ips"]; ok {
|
||||
ips := addIPs.(*schema.Set).List()
|
||||
for _, ip := range ips {
|
||||
req.IPs = append(req.IPs, ip.(string))
|
||||
}
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().ExtNet().AddReserveIP(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func differenceIPReserved(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) (addList, delList []interface{}, errs error) {
|
||||
addList = make([]interface{}, 0)
|
||||
delList = make([]interface{}, 0)
|
||||
oldSet, newSet := d.GetChange("reserved_ip")
|
||||
oldList := oldSet.(*schema.Set).List()
|
||||
newList := newSet.(*schema.Set).List()
|
||||
for _, oldReservedIP := range oldList {
|
||||
oldMap := oldReservedIP.(map[string]interface{})
|
||||
found := false
|
||||
for _, newReservedIP := range newList {
|
||||
newMap := newReservedIP.(map[string]interface{})
|
||||
if newMap["account_id"] == oldMap["account_id"] && newMap["ip_count"] == oldMap["ip_count"] && newMap["ips"] == oldMap["ips"] {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
if newMap["account_id"] == oldMap["account_id"] {
|
||||
add := make(map[string]interface{}, 0)
|
||||
del := make(map[string]interface{}, 0)
|
||||
delSet := oldMap["ips"].(*schema.Set).Difference(newMap["ips"].(*schema.Set))
|
||||
addSet := newMap["ips"].(*schema.Set).Difference(oldMap["ips"].(*schema.Set))
|
||||
if delSet.Len() > 0 {
|
||||
del["account_id"] = oldMap["account_id"].(int)
|
||||
del["ips"] = delSet
|
||||
if oldMap["ip_count"].(int)-newMap["ip_count"].(int) >= delSet.Len() {
|
||||
del["ip_count"] = oldMap["ip_count"].(int) - newMap["ip_count"].(int)
|
||||
} else {
|
||||
del["ip_count"] = delSet.Len()
|
||||
newMap["ip_count"] = newMap["ip_count"].(int) + delSet.Len()
|
||||
}
|
||||
} else if newMap["ip_count"].(int) < oldMap["ip_count"].(int) {
|
||||
del["account_id"] = oldMap["account_id"].(int)
|
||||
del["ip_count"] = oldMap["ip_count"].(int) - newMap["ip_count"].(int)
|
||||
}
|
||||
if addSet.Len() > 0 {
|
||||
add["account_id"] = oldMap["account_id"].(int)
|
||||
add["ips"] = addSet
|
||||
add["ip_count"] = newMap["ip_count"].(int) - oldMap["ip_count"].(int)
|
||||
if add["ip_count"].(int) < 0 {
|
||||
add["ip_count"] = 0
|
||||
}
|
||||
if add["ip_count"].(int)-addSet.Len() < 0 {
|
||||
del["account_id"] = oldMap["account_id"].(int)
|
||||
if _, ok := del["ip_count"]; ok {
|
||||
del["ip_count"] = del["ip_count"].(int) + addSet.Len()
|
||||
} else {
|
||||
del["ip_count"] = addSet.Len()
|
||||
}
|
||||
}
|
||||
} else if newMap["ip_count"].(int)-oldMap["ip_count"].(int) > 0 {
|
||||
add["account_id"] = oldMap["account_id"].(int)
|
||||
add["ip_count"] = newMap["ip_count"].(int) - oldMap["ip_count"].(int)
|
||||
}
|
||||
if _, ok := add["account_id"]; ok {
|
||||
addList = append(addList, add)
|
||||
}
|
||||
if _, ok := del["account_id"]; ok {
|
||||
ipsLen := 0
|
||||
if _, ok := del["ips"]; ok {
|
||||
ipsLen = del["ips"].(*schema.Set).Len()
|
||||
}
|
||||
freeCount := del["ip_count"].(int) - ipsLen
|
||||
if freeCount > 0 {
|
||||
req := extnet.GetReservedIP{
|
||||
AccountID: uint64(del["account_id"].(int)),
|
||||
ExtNetID: uint64(d.Get("extnet_id").(int)),
|
||||
}
|
||||
resIpsList, err := c.CloudBroker().ExtNet().GetReservedIP(ctx, req)
|
||||
if err != nil {
|
||||
errs = errors.Join(errs, err)
|
||||
}
|
||||
freeIPs := getFreeIps(resIpsList[0].Reservations, newMap["ips"], del["ips"])
|
||||
if _, ok := del["ips"]; !ok {
|
||||
del["ips"] = schema.NewSet(schema.HashString, []interface{}{})
|
||||
}
|
||||
for i := 0; i < freeCount; i++ {
|
||||
del["ips"].(*schema.Set).Add(freeIPs[i])
|
||||
}
|
||||
}
|
||||
delList = append(delList, del)
|
||||
}
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if found {
|
||||
continue
|
||||
}
|
||||
delList = append(delList, oldReservedIP)
|
||||
}
|
||||
|
||||
for _, newReservedIP := range newList {
|
||||
newMap := newReservedIP.(map[string]interface{})
|
||||
found := false
|
||||
for _, oldReservedIP := range oldList {
|
||||
oldMap := oldReservedIP.(map[string]interface{})
|
||||
if newMap["account_id"] == oldMap["account_id"] {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if found {
|
||||
continue
|
||||
}
|
||||
addList = append(addList, newReservedIP)
|
||||
}
|
||||
|
||||
if errs != nil {
|
||||
d.Set("reserved_ip", oldSet)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// getFreeIps returns array IPs which can be deleted
|
||||
func getFreeIps(reserved []extnet.Reservations, newIps, delIps interface{}) []string {
|
||||
newIpsList := make([]interface{}, 0)
|
||||
delIpsList := make([]interface{}, 0)
|
||||
if newIps != nil {
|
||||
newIpsList = newIps.(*schema.Set).List()
|
||||
}
|
||||
if delIps != nil {
|
||||
delIpsList = delIps.(*schema.Set).List()
|
||||
}
|
||||
newIpsMap := make(map[string]struct{}, len(newIpsList))
|
||||
delIpsMap := make(map[string]struct{}, len(delIpsList))
|
||||
freeIPs := make([]string, 0)
|
||||
for _, ip := range newIpsList {
|
||||
newIpsMap[ip.(string)] = struct{}{}
|
||||
}
|
||||
for _, ip := range delIpsList {
|
||||
delIpsMap[ip.(string)] = struct{}{}
|
||||
}
|
||||
for _, item := range reserved {
|
||||
if _, ok := newIpsMap[item.IP]; ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := delIpsMap[item.IP]; ok {
|
||||
continue
|
||||
}
|
||||
freeIPs = append(freeIPs, item.IP)
|
||||
}
|
||||
return freeIPs
|
||||
}
|
||||
|
||||
func validateReserveIPs(ctx context.Context, d *schema.ResourceDiff, m interface{}) error {
|
||||
list := d.Get("reserved_ip").(*schema.Set).List()
|
||||
var errs error
|
||||
for _, reservedIP := range list {
|
||||
reservedIPMap := reservedIP.(map[string]interface{})
|
||||
var countIP, ipsLen int
|
||||
if _, ok := reservedIPMap["ip_count"]; ok {
|
||||
countIP = reservedIPMap["ip_count"].(int)
|
||||
}
|
||||
if _, ok := reservedIPMap["ips"]; ok {
|
||||
ipsLen = reservedIPMap["ips"].(*schema.Set).Len()
|
||||
}
|
||||
if ipsLen > countIP {
|
||||
errs = errors.Join(errs, fmt.Errorf("for the reserved_ip block with account_id %d the count parameter must be greater than or equal to len the ips array", reservedIPMap["account_id"].(int)))
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
@@ -34,21 +34,45 @@ package grid
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"os"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func dataSourceGridGetDiagnosisRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
filePath := "diagnosis.tar.gz"
|
||||
if userPath, ok := d.GetOk("file_path"); ok {
|
||||
filePath = userPath.(string)
|
||||
}
|
||||
|
||||
log.Debugf("dataSourceGridGetDiagnosisRead: create file with name: %s", filePath)
|
||||
file, err := os.Create(filePath)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
d.SetId("") // ensure ID is empty in this case
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
diagnosis, err := utilityGridGetDiagnosisCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
d.SetId(strconv.Itoa(d.Get("gid").(int)))
|
||||
d.Set("diagnosis", diagnosis)
|
||||
|
||||
log.Debugf("dataSourceGridGetDiagnosisRead: write data to file with name: %s", filePath)
|
||||
_, err = file.WriteString(diagnosis)
|
||||
if err != nil {
|
||||
d.SetId("") // ensure ID is empty in this case
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -66,29 +90,3 @@ func DataSourceGridGetDiagnosis() *schema.Resource {
|
||||
Schema: dataSourceGridGetDiagnosisSchemaMake(),
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceGridPostDiagnosisRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
diagnosis, err := utilityGridPostDiagnosisCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
d.SetId(strconv.Itoa(d.Get("gid").(int)))
|
||||
d.Set("diagnosis", diagnosis)
|
||||
return nil
|
||||
}
|
||||
|
||||
func DataSourceGridPostDiagnosis() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceGridPostDiagnosisRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceGridPostDiagnosisSchemaMake(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,23 +586,10 @@ func dataSourceGridGetDiagnosisSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"diagnosis": {
|
||||
"file_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceGridPostDiagnosisSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"diagnosis": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,23 +62,3 @@ func utilityGridGetDiagnosisCheckPresence(ctx context.Context, d *schema.Resourc
|
||||
|
||||
return gridGetDiagnosis, nil
|
||||
}
|
||||
|
||||
func utilityGridPostDiagnosisCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := grid.GetDiagnosisRequest{}
|
||||
|
||||
if d.Id() != "" {
|
||||
id, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
req.GID = id
|
||||
} else {
|
||||
req.GID = uint64(d.Get("gid").(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityGridPostDiagnosisCheckPresence: load grid post diagnosis")
|
||||
gridPostDiagnosis, err := c.CloudBroker().Grid().GetDiagnosis(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return gridPostDiagnosis, nil
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ func flattenImage(d *schema.ResourceData, img *image.RecordImage) {
|
||||
d.Set("sep_id", img.SEPID)
|
||||
d.Set("shared_with", img.SharedWith)
|
||||
d.Set("size", img.Size)
|
||||
d.Set("snapshot_id", img.SnapshotID)
|
||||
d.Set("status", img.Status)
|
||||
d.Set("tech_status", img.TechStatus)
|
||||
d.Set("image_type", img.Type)
|
||||
@@ -92,47 +93,48 @@ func flattenImageList(il *image.ListImages) []map[string]interface{} {
|
||||
cdPresentedTo, _ := json.Marshal(item.CdPresentedTo)
|
||||
|
||||
temp := map[string]interface{}{
|
||||
"image_id": item.ID,
|
||||
"unc_path": item.UNCPath,
|
||||
"account_id": item.AccountID,
|
||||
"acl": flattenAcl(item.ACL),
|
||||
"architecture": item.Architecture,
|
||||
"boot_type": item.BootType,
|
||||
"bootable": item.Bootable,
|
||||
"computeci_id": item.ComputeCIID,
|
||||
"cd_presented_to": string(cdPresentedTo),
|
||||
"deleted_time": item.DeletedTime,
|
||||
"desc": item.Description,
|
||||
"drivers": item.Drivers,
|
||||
"enabled": item.Enabled,
|
||||
"gid": item.GID,
|
||||
"guid": item.GUID,
|
||||
"history": flattenHistory(item.History),
|
||||
"hot_resize": item.HotResize,
|
||||
"last_modified": item.LastModified,
|
||||
"link_to": item.LinkTo,
|
||||
"milestones": item.Milestones,
|
||||
"name": item.Name,
|
||||
"image_id": item.ID,
|
||||
"unc_path": item.UNCPath,
|
||||
"account_id": item.AccountID,
|
||||
"acl": flattenAcl(item.ACL),
|
||||
"architecture": item.Architecture,
|
||||
"boot_type": item.BootType,
|
||||
"bootable": item.Bootable,
|
||||
"computeci_id": item.ComputeCIID,
|
||||
"cd_presented_to": string(cdPresentedTo),
|
||||
"deleted_time": item.DeletedTime,
|
||||
"desc": item.Description,
|
||||
"drivers": item.Drivers,
|
||||
"enabled": item.Enabled,
|
||||
"gid": item.GID,
|
||||
"guid": item.GUID,
|
||||
"history": flattenHistory(item.History),
|
||||
"hot_resize": item.HotResize,
|
||||
"last_modified": item.LastModified,
|
||||
"link_to": item.LinkTo,
|
||||
"milestones": item.Milestones,
|
||||
"name": item.Name,
|
||||
"network_interface_naming": item.NetworkInterfaceNaming,
|
||||
"password": item.Password,
|
||||
"pool_name": item.Pool,
|
||||
"present_to": item.PresentTo,
|
||||
"provider_name": item.ProviderName,
|
||||
"purge_attempts": item.PurgeAttempts,
|
||||
"reference_id": item.ReferenceID,
|
||||
"res_id": item.ResID,
|
||||
"res_name": item.ResName,
|
||||
"rescuecd": item.RescueCD,
|
||||
"sep_id": item.SEPID,
|
||||
"shared_with": item.SharedWith,
|
||||
"size": item.Size,
|
||||
"status": item.Status,
|
||||
"tech_status": item.TechStatus,
|
||||
"image_type": item.Type,
|
||||
"url": item.URL,
|
||||
"username": item.Username,
|
||||
"version": item.Version,
|
||||
"virtual": item.Virtual,
|
||||
"password": item.Password,
|
||||
"pool_name": item.Pool,
|
||||
"present_to": item.PresentTo,
|
||||
"provider_name": item.ProviderName,
|
||||
"purge_attempts": item.PurgeAttempts,
|
||||
"reference_id": item.ReferenceID,
|
||||
"res_id": item.ResID,
|
||||
"res_name": item.ResName,
|
||||
"rescuecd": item.RescueCD,
|
||||
"sep_id": item.SEPID,
|
||||
"shared_with": item.SharedWith,
|
||||
"size": item.Size,
|
||||
"snapshot_id": item.SnapshotID,
|
||||
"status": item.Status,
|
||||
"tech_status": item.TechStatus,
|
||||
"image_type": item.Type,
|
||||
"url": item.URL,
|
||||
"username": item.Username,
|
||||
"version": item.Version,
|
||||
"virtual": item.Virtual,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
@@ -622,6 +622,11 @@ func dataSourceImageListSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Description: "image size",
|
||||
},
|
||||
"snapshot_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "snapshot id",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@@ -875,6 +880,11 @@ func dataSourceImageSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Description: "image size",
|
||||
},
|
||||
"snapshot_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "snapshot id",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@@ -1124,6 +1134,11 @@ func resourceCDROMImageSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"snapshot_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "snapshot id",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@@ -1415,6 +1430,11 @@ func resourceImageSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"snapshot_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "snapshot id",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@@ -1689,6 +1709,11 @@ func resourceVirtualImageSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Description: "image size",
|
||||
},
|
||||
"snapshot_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "snapshot id",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@@ -1967,6 +1992,11 @@ func resourceImageFromBlankComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"snapshot_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "snapshot id",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@@ -2241,6 +2271,11 @@ func resourceImageFromPlatformDiskSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"snapshot_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "snapshot id",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
|
||||
@@ -34,6 +34,7 @@ func flattenCompute(d *schema.ResourceData, computeRec *compute.RecordCompute, p
|
||||
d.Set("affinity_rules", flattenAffinityRules(computeRec.AffinityRules))
|
||||
d.Set("anti_affinity_rules", flattenAffinityRules(computeRec.AntiAffinityRules))
|
||||
d.Set("arch", computeRec.Arch)
|
||||
d.Set("auto_start_w_node", computeRec.AutoStart)
|
||||
d.Set("boot_order", computeRec.BootOrder)
|
||||
d.Set("boot_disk_id", bootDisk.ID)
|
||||
// we intentionally use the SizeMax field, do not change it until the BootDiskSize field is fixed on the platform
|
||||
@@ -92,6 +93,7 @@ func flattenCompute(d *schema.ResourceData, computeRec *compute.RecordCompute, p
|
||||
d.Set("updated_time", computeRec.UpdatedTime)
|
||||
d.Set("user_data", string(userData))
|
||||
d.Set("user_managed", computeRec.UserManaged)
|
||||
d.Set("vnc_password", computeRec.VNCPassword)
|
||||
d.Set("vgpus", computeRec.VGPUs)
|
||||
d.Set("virtual_image_id", computeRec.VirtualImageID)
|
||||
d.Set("virtual_image_name", computeRec.VirtualImageName)
|
||||
@@ -294,6 +296,7 @@ func flattenComputeList(computes *compute.ListComputes) []map[string]interface{}
|
||||
"affinity_weight": computeItem.AffinityWeight,
|
||||
"anti_affinity_rules": flattenListRules(computeItem.AntiAffinityRules),
|
||||
"arch": computeItem.Arch,
|
||||
"auto_start_w_node": computeItem.AutoStart,
|
||||
"chipset": computeItem.Chipset,
|
||||
"cd_image_id": computeItem.CdImageId,
|
||||
"boot_order": computeItem.BootOrder,
|
||||
@@ -613,6 +616,7 @@ func flattenDataCompute(d *schema.ResourceData, compFacts *compute.RecordCompute
|
||||
d.Set("affinity_weight", compFacts.AffinityWeight)
|
||||
d.Set("anti_affinity_rules", flattenAffinityRules(compFacts.AntiAffinityRules))
|
||||
d.Set("arch", compFacts.Arch)
|
||||
d.Set("auto_start_w_node", compFacts.AutoStart)
|
||||
d.Set("boot_order", compFacts.BootOrder)
|
||||
d.Set("chipset", compFacts.Chipset)
|
||||
d.Set("cd_image_id", compFacts.CdImageId)
|
||||
@@ -671,6 +675,7 @@ func flattenDataCompute(d *schema.ResourceData, compFacts *compute.RecordCompute
|
||||
d.Set("updated_time", compFacts.UpdatedTime)
|
||||
d.Set("user_data", string(userData))
|
||||
d.Set("user_managed", compFacts.UserManaged)
|
||||
d.Set("vnc_password", compFacts.VNCPassword)
|
||||
d.Set("vgpus", compFacts.VGPUs)
|
||||
d.Set("virtual_image_id", compFacts.VirtualImageID)
|
||||
d.Set("virtual_image_name", compFacts.VirtualImageName)
|
||||
|
||||
@@ -484,12 +484,29 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
req.Force = force
|
||||
}
|
||||
|
||||
if autoStart, ok := d.Get("auto_start_w_node").(bool); ok {
|
||||
req.AutoStart = autoStart
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Compute().PinToStack(ctx, req)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if !d.Get("pin_to_stack").(bool) && d.Get("auto_start_w_node").(bool) {
|
||||
req := compute.UpdateRequest{
|
||||
ComputeID: computeId,
|
||||
AutoStart: d.Get("auto_start_w_node").(bool),
|
||||
CPUPin: d.Get("cpu_pin").(bool),
|
||||
HPBacked: d.Get("hp_backed").(bool),
|
||||
}
|
||||
_, err := c.CloudBroker().Compute().Update(ctx, req)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.Get("pause").(bool) {
|
||||
req := compute.PauseRequest{
|
||||
ComputeID: computeId,
|
||||
@@ -686,7 +703,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChanges("description", "name", "numa_affinity", "cpu_pin", "hp_backed") {
|
||||
if d.HasChanges("description", "name", "numa_affinity", "cpu_pin", "hp_backed", "chipset", "auto_start_w_node") {
|
||||
if err := utilityComputeUpdate(ctx, d, m); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -839,11 +856,14 @@ func ResourceCompute() *schema.Resource {
|
||||
SchemaVersion: 1,
|
||||
|
||||
CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error {
|
||||
if diff.HasChanges() || diff.HasChanges("libvirt_settings", "network", "affinity_rules", "anti_affinity_rules",
|
||||
if diff.HasChanges() || diff.HasChanges("chipset", "pin_to_stack", "auto_start_w_node", "libvirt_settings", "network", "affinity_rules", "anti_affinity_rules",
|
||||
"disks", "extra_disks", "tags", "port_forwarding", "user_access", "snapshot", "pci_devices") {
|
||||
diff.SetNewComputed("updated_time")
|
||||
diff.SetNewComputed("updated_by")
|
||||
}
|
||||
if diff.HasChanges("pin_to_stack") {
|
||||
diff.SetNewComputed("pinned")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
|
||||
|
||||
@@ -134,6 +134,10 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"auto_start_w_node": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"boot_order": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
@@ -902,6 +906,10 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"vnc_password": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vgpus": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
@@ -990,6 +998,11 @@ func dataSourceComputeListSchemaMake() map[string]*schema.Schema {
|
||||
Optional: true,
|
||||
Description: "Find by image ID",
|
||||
},
|
||||
"cd_image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Find by CD image ID",
|
||||
},
|
||||
"extnet_name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
@@ -1145,6 +1158,10 @@ func dataSourceComputeListSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"auto_start_w_node": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"boot_order": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
@@ -1802,6 +1819,10 @@ func dataSourceComputeListDeletedSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"auto_start_w_node": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"boot_order": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
@@ -3375,6 +3396,11 @@ func resourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Optional: true,
|
||||
Default: false,
|
||||
},
|
||||
"auto_start_w_node": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"target_stack_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
@@ -3906,6 +3932,10 @@ func resourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"vnc_password": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vgpus": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
|
||||
@@ -852,21 +852,17 @@ func utilityComputeUpdate(ctx context.Context, d *schema.ResourceData, m interfa
|
||||
if d.HasChange("numa_affinity") {
|
||||
req.NumaAffinity = d.Get("numa_affinity").(string)
|
||||
}
|
||||
if d.HasChange("cpu_pin") {
|
||||
req.CPUPin = d.Get("cpu_pin").(bool)
|
||||
}
|
||||
if d.HasChange("hp_backed") {
|
||||
req.HPBacked = d.Get("hp_backed").(bool)
|
||||
}
|
||||
|
||||
if d.HasChange("chipset") {
|
||||
req.Chipset = d.Get("chipset").(string)
|
||||
}
|
||||
req.CPUPin = d.Get("cpu_pin").(bool)
|
||||
req.HPBacked = d.Get("hp_backed").(bool)
|
||||
req.AutoStart = d.Get("auto_start_w_node").(bool)
|
||||
|
||||
// Note bene: numa_affinity, cpu_pin and hp_backed are not allowed to be changed for compute in STARTED tech status.
|
||||
// If STARTED, we need to stop it before update
|
||||
var isStopRequired bool
|
||||
if d.HasChanges("numa_affinity", "cpu_pin", "hp_backed") && d.Get("started").(bool) {
|
||||
if d.HasChanges("numa_affinity", "cpu_pin", "hp_backed", "chipset") && d.Get("started").(bool) {
|
||||
isStopRequired = true
|
||||
}
|
||||
if isStopRequired {
|
||||
@@ -1434,6 +1430,11 @@ func utilityComputePinToStack(ctx context.Context, d *schema.ResourceData, m int
|
||||
if force, ok := d.Get("force_pin").(bool); ok {
|
||||
req.Force = force
|
||||
}
|
||||
|
||||
if autoStart, ok := d.Get("auto_start_w_node").(bool); ok {
|
||||
req.AutoStart = autoStart
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Compute().PinToStack(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -75,6 +75,9 @@ func utilityDataComputeListCheckPresence(ctx context.Context, d *schema.Resource
|
||||
if imageID, ok := d.GetOk("image_id"); ok {
|
||||
req.ImageID = imageID.(uint64)
|
||||
}
|
||||
if cdImageID, ok := d.GetOk("cd_image_id"); ok {
|
||||
req.CDImageID = cdImageID.(uint64)
|
||||
}
|
||||
if extNetName, ok := d.GetOk("extnet_name"); ok {
|
||||
req.ExtNetName = extNetName.(string)
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ func flattenNode(d *schema.ResourceData, item *node.RecordNode) {
|
||||
d.Set("isolated_cpus", flattenNodeItem(item.IsolatedCpus))
|
||||
d.Set("name", item.Name)
|
||||
d.Set("need_reboot", item.NeedReboot)
|
||||
d.Set("net_addr", flattenGetNetAddr(item.NetAddr))
|
||||
d.Set("nic_info", flattenNicInfo(item.NicInfo))
|
||||
d.Set("numa_topology", flattenNumaTopology(item.NumaTopology))
|
||||
d.Set("reserved_cpus", flattenNodeItem(item.ReservedCPUs))
|
||||
@@ -205,9 +206,9 @@ func flattenVFList(vfList []interface{}) []map[string]interface{} {
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenNetAddr(adresses node.ListNetAddr) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0, len(adresses))
|
||||
for _, item := range adresses {
|
||||
func flattenNetAddr(addresses node.ListNetAddr) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0, len(addresses))
|
||||
for _, item := range addresses {
|
||||
temp := map[string]interface{}{
|
||||
"cidr": item.CIDR,
|
||||
"index": item.Index,
|
||||
@@ -221,6 +222,16 @@ func flattenNetAddr(adresses node.ListNetAddr) []map[string]interface{} {
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenGetNetAddr(address node.NetAddr) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 1)
|
||||
temp := map[string]interface{}{
|
||||
"ip": address.IP,
|
||||
"name": address.Name,
|
||||
}
|
||||
res[0] = temp
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenCpuInfo(info node.CpuInfo) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 1)
|
||||
temp := map[string]interface{}{
|
||||
|
||||
@@ -131,6 +131,25 @@ func dataSourceNodeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"net_addr": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"ip": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"nic_info": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
|
||||
@@ -150,6 +150,7 @@ func flattenVinsVNFDev(vd vins.VNFDev) []map[string]interface{} {
|
||||
"status": vd.Status,
|
||||
"tech_status": vd.TechStatus,
|
||||
"type": vd.Type,
|
||||
"vnc_password": vd.VNCPassword,
|
||||
"vins": vd.VINS,
|
||||
}
|
||||
res = append(res, temp)
|
||||
@@ -371,14 +372,12 @@ func flattenVinsListReservations(li vins.ListReservations) []map[string]interfac
|
||||
res := make([]map[string]interface{}, 0, len(li))
|
||||
for _, v := range li {
|
||||
temp := map[string]interface{}{
|
||||
"client_type": v.ClientType,
|
||||
"description": v.Description,
|
||||
"domain_name": v.DomainName,
|
||||
"host_name": v.Hostname,
|
||||
"ip": v.IP,
|
||||
"mac": v.MAC,
|
||||
"type": v.Type,
|
||||
"vm_id": v.VMID,
|
||||
//TODO
|
||||
//"account_id": v.AccountID,
|
||||
"ip": v.IP,
|
||||
"mac": v.MAC,
|
||||
"type": v.Type,
|
||||
"vm_id": v.VMID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
@@ -38,14 +38,12 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -64,19 +62,6 @@ func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m in
|
||||
Gateway: d.Get("gateway").(string),
|
||||
}
|
||||
|
||||
if computesIDS, ok := d.GetOk("compute_ids"); ok {
|
||||
ids := computesIDS.([]interface{})
|
||||
|
||||
res := make([]uint64, 10)
|
||||
|
||||
for _, id := range ids {
|
||||
computeId := uint64(id.(int))
|
||||
res = append(res, computeId)
|
||||
}
|
||||
|
||||
req.ComputeIds = res
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().StaticRouteAdd(ctx, req)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
@@ -108,30 +93,7 @@ func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m inte
|
||||
}
|
||||
|
||||
func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceStaticRouteUpdate: called for static route id %s", d.Id())
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
if diags := checkParamsExistenceStaticRoute(ctx, d, c); diags != nil {
|
||||
return diags
|
||||
}
|
||||
|
||||
staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
warnings := dc.Warnings{}
|
||||
if d.HasChange("compute_ids") {
|
||||
if errs := resourceStaticRouteChangeComputeIds(ctx, d, m, staticRouteData); len(errs) != 0 {
|
||||
for _, err := range errs {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return append(warnings.Get(), resourceStaticRouteRead(ctx, d, m)...)
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -158,61 +120,6 @@ func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, m in
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceStaticRouteChangeComputeIds(ctx context.Context, d *schema.ResourceData, m interface{}, staticRouteData *vins.ItemRoutes) []error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
var errs []error
|
||||
|
||||
vinsId := uint64(d.Get("vins_id").(int))
|
||||
|
||||
deletedIds := make([]uint64, 0)
|
||||
addedIds := make([]uint64, 0)
|
||||
|
||||
oldComputeIds, newComputeIds := d.GetChange("compute_ids")
|
||||
oldComputeIdsSlice := oldComputeIds.([]interface{})
|
||||
newComputeIdsSlice := newComputeIds.([]interface{})
|
||||
|
||||
for _, el := range oldComputeIdsSlice {
|
||||
if !isContainsIds(newComputeIdsSlice, el) {
|
||||
convertedEl := uint64(el.(int))
|
||||
deletedIds = append(deletedIds, convertedEl)
|
||||
}
|
||||
}
|
||||
|
||||
for _, el := range newComputeIdsSlice {
|
||||
if !isContainsIds(oldComputeIdsSlice, el) {
|
||||
convertedEl := uint64(el.(int))
|
||||
addedIds = append(addedIds, convertedEl)
|
||||
}
|
||||
}
|
||||
|
||||
if len(deletedIds) > 0 {
|
||||
req := vins.StaticRouteAccessRevokeRequest{
|
||||
VINSID: vinsId,
|
||||
RouteId: staticRouteData.ID,
|
||||
ComputeIds: deletedIds,
|
||||
}
|
||||
|
||||
if _, err := c.CloudBroker().VINS().StaticRouteAccessRevoke(ctx, req); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(addedIds) > 0 {
|
||||
req := vins.StaticRouteAccessGrantRequest{
|
||||
VINSID: vinsId,
|
||||
RouteId: staticRouteData.ID,
|
||||
ComputeIds: addedIds,
|
||||
}
|
||||
|
||||
if _, err := c.CloudBroker().VINS().StaticRouteAccessGrant(ctx, req); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func isContainsIds(els []interface{}, el interface{}) bool {
|
||||
convEl := el.(int)
|
||||
for _, elOld := range els {
|
||||
|
||||
@@ -341,6 +341,10 @@ func dataSourceVinsSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Description: "type",
|
||||
},
|
||||
"vnc_password": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vins": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
@@ -2509,6 +2513,10 @@ func resourceVinsSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Description: "type",
|
||||
},
|
||||
"vnc_password": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"vins": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
@@ -3389,7 +3397,6 @@ func resourceStaticRouteSchemaMake() map[string]*schema.Schema {
|
||||
"compute_ids": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
- extnet_computes_list
|
||||
- extnet_default
|
||||
- extnet_list
|
||||
- extnet_reserved_ip_list
|
||||
- flipgroup
|
||||
- flipgroup_list
|
||||
- image
|
||||
@@ -157,6 +158,7 @@
|
||||
- cb_extnet
|
||||
- cb_extnet_default
|
||||
- cb_extnet_list
|
||||
- cb_extnet_reserved_ip_list
|
||||
- cb_extnet_static_route
|
||||
- cb_extnet_static_route_list
|
||||
- cb_flipgroup
|
||||
@@ -169,7 +171,6 @@
|
||||
- cb_grid_list
|
||||
- cb_grid_list_consumption
|
||||
- cb_grid_list_emails
|
||||
- cb_grid_post_diagnosis
|
||||
- cb_grid_post_status
|
||||
- cb_image
|
||||
- cb_image_list
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Пример использования
|
||||
Получение снимка платформы с дополнительной диагностической информацией, такой как журналы и т.д.
|
||||
Получение информации о зарезервированных IP адресах или пуле адресов
|
||||
*/
|
||||
|
||||
#Расскомментируйте этот код,
|
||||
@@ -26,14 +26,18 @@ provider "decort" {
|
||||
allow_unverified_ssl = true
|
||||
}
|
||||
|
||||
data "decort_cb_grid_post_diagnosis" "grid" {
|
||||
#id grid для получения информации
|
||||
#обязательный параметр
|
||||
data "decort_extnet_reserved_ip_list" "ex_reserved_ip" {
|
||||
#идентификатор аккаунта, для которого зарезервированны ресурсы
|
||||
#обязательный параметр
|
||||
#тип - целое число
|
||||
gid = 215
|
||||
account_id = 1111
|
||||
|
||||
#идентификатор сети
|
||||
#опциональный параметр
|
||||
#тип - целое число
|
||||
#extnet_id = 1111
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = data.decort_cb_grid_post_diagnosis.grid
|
||||
value = data.decort_extnet_reserved_ip_list.ex_reserved_ip
|
||||
}
|
||||
@@ -396,6 +396,11 @@ resource "decort_kvmvm" "comp" {
|
||||
#тип - булев
|
||||
pin_to_stack = true
|
||||
|
||||
#флаг для старта компьюта при рестарте ноды
|
||||
#опциональный параметр
|
||||
#тип - булев
|
||||
auto_start_w_node = true
|
||||
|
||||
#флаг доступности компьюта для проведения с ним операций
|
||||
#опциональный параметр
|
||||
#тип - булев
|
||||
|
||||
@@ -52,12 +52,6 @@ resource "decort_vins_static_route" "sr" {
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
gateway = "192.168.201.40"
|
||||
|
||||
#список виртуальных машин, которым будет предоставлен доступ к роуту
|
||||
#опциональный параметр
|
||||
#тип - массив целых чисел
|
||||
compute_ids = [111, 222]
|
||||
|
||||
}
|
||||
|
||||
output "sr" {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Пример использования
|
||||
Получение информации о зарезервированных IP адресах или пуле адресов
|
||||
*/
|
||||
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
source = "basis/decort/decort"
|
||||
version = "<VERSION>"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
provider "decort" {
|
||||
authenticator = "decs3o"
|
||||
#controller_url = <DECORT_CONTROLLER_URL>
|
||||
controller_url = "https://ds1.digitalenergy.online"
|
||||
#oauth2_url = <DECORT_SSO_URL>
|
||||
oauth2_url = "https://sso.digitalenergy.online"
|
||||
allow_unverified_ssl = true
|
||||
}
|
||||
|
||||
data "decort_cb_extnet_reserved_ip_list" "ex_reserved_ip" {
|
||||
#идентификатор аккаунта, для которого зарезервированны ресурсы
|
||||
#обязательный параметр
|
||||
#тип - целое число
|
||||
account_id = 1111
|
||||
|
||||
#идентификатор сети
|
||||
#опциональный параметр
|
||||
#тип - целое число
|
||||
#extnet_id = 1111
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = data.decort_cb_extnet_reserved_ip_list.ex_reserved_ip
|
||||
}
|
||||
@@ -168,6 +168,26 @@ resource "decort_cb_extnet" "new_extnet" {
|
||||
#e_rate = 0
|
||||
}
|
||||
|
||||
#список зарезервированных IP или пула адресов
|
||||
#опциональный параметр
|
||||
#тип - блок
|
||||
reserved_ip {
|
||||
#идентификатор аккаунта, для которого резервируются ресурсы
|
||||
#обязательный параметр
|
||||
#тип - целое число
|
||||
account_id = 11111
|
||||
|
||||
#количество резервируемых IP
|
||||
#опциональный параметр
|
||||
#тип - целое число
|
||||
ip_count = 15
|
||||
|
||||
#список резервируемых IP
|
||||
#опциональный параметр
|
||||
#тип - массив строк
|
||||
ips = ["192.168.10.10", "192.168.10.20"]
|
||||
}
|
||||
|
||||
#ID stack на который происходит миграция
|
||||
#опциональный параметр
|
||||
#тип - целое число
|
||||
|
||||
@@ -32,6 +32,10 @@ data "decort_cb_grid_get_diagnosis" "grid" {
|
||||
#тип - целое число
|
||||
gid = 215
|
||||
|
||||
#путь, где будет создан архив, если не указан, создается в директории с main.tf с именем "diagnosis.tar.gz"
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
file_path = "abcdefg.tar.gz"
|
||||
}
|
||||
|
||||
output "test" {
|
||||
|
||||
@@ -66,6 +66,21 @@ data "decort_cb_kvmvm_list" "compute_list" {
|
||||
#тип - строка
|
||||
#ip_address = "test"
|
||||
|
||||
#фильтр по stack id
|
||||
#опциональный параметр
|
||||
#тип - целое число
|
||||
#stack_id = 123
|
||||
|
||||
#фильтр по image id
|
||||
#опциональный параметр
|
||||
#тип - целое число
|
||||
#image_id = 123
|
||||
|
||||
#фильтр по cd image id
|
||||
#опциональный параметр
|
||||
#тип - целое число
|
||||
#cd_image_id = 123
|
||||
|
||||
#фильтр по имени extnet
|
||||
#опциональный параметр
|
||||
#тип - строка
|
||||
|
||||
@@ -409,6 +409,11 @@ resource "decort_cb_kvmvm" "comp" {
|
||||
#тип - булев
|
||||
#pin_to_stack = true
|
||||
|
||||
#флаг для старта компьюта при рестарте ноды
|
||||
#опциональный параметр
|
||||
#тип - булев
|
||||
#auto_start_w_node = true
|
||||
|
||||
#id stack для добавления компьюта на этот стэк
|
||||
#опциональный параметр
|
||||
#тип - целое число
|
||||
|
||||
@@ -51,12 +51,6 @@ resource "decort_cb_vins_static_route" "sr" {
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
gateway = "192.168.201.40"
|
||||
|
||||
#список виртуальных машин, которым будет предоставлен доступ к роуту
|
||||
#опциональный параметр
|
||||
#тип - массив целых чисел
|
||||
#compute_ids = [111,222]
|
||||
|
||||
}
|
||||
|
||||
output "sr" {
|
||||
|
||||
7
wiki/4.8.0/01.-Введение.md
Normal file
7
wiki/4.8.0/01.-Введение.md
Normal file
@@ -0,0 +1,7 @@
|
||||
DECORT Terraform Provider версии 4.8.x позволяет управлять облачными ресурсами на платформе Digital Energy Cloud Orchestration Technology (DECORT) версии 4.2.x и выше посредством Terraform.
|
||||
|
||||
С помощью данного провайдера можно организовать программное управление вычислительными ресурсами (_compute_), ресурсными группами, сетевыми и дисковыми ресурсами, образами дисков, кластером, а также другими параметрами облачной платформы DECORT.
|
||||
|
||||
Если вы хорошо знакомы с инструментом Terraform и хотите максимально быстро начать использовать платформу DECORT в своих Terraform-проектах, то можете сразу перейти к разделу [Пример работы](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/02.-Пример-работы.md), где приведён подробно откомментированный пример работы с основными видами ресурсов платформы. Если у вас всё же возникнут вопросы по облачной платформе DECORT и порядку авторизации в ней, то обратитесь к главе [«Обзор облачной платформы DECORT»](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/03.-Обзор-облачной-платформы-DECORT.md). Также может оказаться полезной глава [«Инициализация Terraform провайдера DECORT»](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/04.02-Инициализация-Terraform-провайдера-DECORT.md).
|
||||
|
||||
Если вы только начинаете использовать инструмент Terraform и облачную платформу DECORT, то рекомендуем вам начать с главы [«Обзор облачной платформы DECORT»](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/03.-Обзор-облачной-платформы-DECORT.md), после чего изучить главы [«_Data source_ функции Terraform провайдера DECORT»](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/06.-Data-source-функции-Terraform-провайдера-DECORT.md) и [«_Resource_ функции Terraform провайдера DECORT»](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/07.-Resource-функции-Terraform-провайдера-DECORT.md). Примеры, приведенные в этих разделах, помогут вам быстро освоить базовые приёмы работы с инструментом Terraform и провайдером DECORT.
|
||||
92
wiki/4.8.0/02.-Пример-работы.md
Normal file
92
wiki/4.8.0/02.-Пример-работы.md
Normal file
@@ -0,0 +1,92 @@
|
||||
Данный раздел предназначен для тех, кто хорошо знаком с инструментом Terraform, а также имеет представление об основных понятиях и способах авторизации в облачной платформе DECORT.
|
||||
|
||||
Ниже приведён подробно откомментированный пример, показывающий, как создать виртуальный сервер (aka _compute_ на базе системы виртуализации KVM x86) в облачной платформе DECORT с помощью соответствующего Terraform провайдера. Сервер будет создан в новой ресурсной группе, к нему будет подключён один предварительно созданный диск, у сервера будет прямое сетевое подключение во внешнюю сеть.
|
||||
|
||||
Идентификатор образа операционной системы, на базе которого должен быть создан виртуальный сервер, считывается из облачной платформы с помощью _data source_ функции `decort_image`.
|
||||
|
||||
Далее мы с помощью _resource_ функции `decort_resgroup` создаём новую ресурсную группу, в которую будет помещён этот виртуальный сервер. В качестве альтернативы, для получения информации об уже имеющейся ресурсной группе можно использовать _data source_ функцию с таким же названием.
|
||||
|
||||
Затем с помощью _resource_ функции `decort_disk` создаётся диск, который будет подключён к виртуальному серверу в качестве дополнительного. Помимо этого дополнительного диска у сервера будет также и загрузочный диск, на который в процессе создания сервера клонируется выбранный образ операционной системы.
|
||||
|
||||
Виртуальный сервер - в данном примере на базе системы виртуализации KVM x86 - создаётся посредством _resource_ функции `decort_kvmvm`.
|
||||
|
||||
Только авторизованные в контроллере облачной платформы пользователи могут управлять облачными ресурсами. Подробнее о способах авторизации см. [Обзор облачной платформы DECORT](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/03.-Обзор-облачной-платформы-DECORT.md).
|
||||
|
||||
```terraform
|
||||
# 1. Initialize DECORT plugin and connection to DECORT cloud controller
|
||||
# NOTE: in this example credentials are expected to come from
|
||||
# DECORT_APP_ID and DECORT_APP_SECRET environmental variables - set them
|
||||
# in the shell before calling terraform.
|
||||
# Alternatively you may define plugin parameters app_id and app_secret in
|
||||
# the TF file, however, this may not be secure if you plan to share this TF
|
||||
# file with others.
|
||||
|
||||
provider "decort" {
|
||||
authenticator = "decs3o"
|
||||
controller_url = "<<DECORT_CONTROLLER_URL>>" # specify correct DECORT controller URL, e.g. "https://ds1.digitalenergy.online"
|
||||
oauth2_url = "<<DECORT_OAUTH2_URL>>" # specify corresponding DECORT OAUTH2 URL, e.g. "https://sso.digitalenergy.online"
|
||||
app_id = "<<DECORT_APP_ID>>" # application secret to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode, e.g. "ewqfrvea7s890avw804389qwguf234h0otfi3w4eiu"
|
||||
app_secret = "<<DECORT_APP_SECRET>>" # application ID to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode, e.g. "ewqfrvea7s890avw804389qwguf234h0otfi3w4eiu"
|
||||
# allow_unverified_ssl = true
|
||||
}
|
||||
|
||||
# 2. Load account to use - new VM will belong to this account
|
||||
data "decort_account" "my_account" {
|
||||
account_id = <ACCOUNT_ID> # Specify account ID
|
||||
}
|
||||
|
||||
# 3. Load OS image to use for VM deployment
|
||||
data "decort_image" "os_image" {
|
||||
image_id = <OS_IMAGE_ID> # Specify OS image id, e.g. 1234. You can get accessible image id from data source "decort_image_list"
|
||||
}
|
||||
|
||||
# 4. Create new Resource Group in the selected account, new VM will be created in this RG
|
||||
resource "decort_resgroup" "my_rg" {
|
||||
name = "NewRgByTF"
|
||||
account_id = data.decort_account.my_account.account_id
|
||||
gid = <GRID_ID> # Grid (platform) ID
|
||||
# if you want to set resource quota on this Resource Group, uncomment
|
||||
# the following code fragment
|
||||
# quota {
|
||||
# cpu = 8 # CPU limit
|
||||
# ram = 8912 # RAM limit in MB
|
||||
# disk = 96 # disk volume limit in GB
|
||||
#}
|
||||
}
|
||||
|
||||
# 5. Create extra disk, which will be attached to the new VM.
|
||||
# This step is optional - if you do not want extra disks on your VM, skip it
|
||||
# and comment out extra_disks parameter when creating VM below.
|
||||
resource "decort_disk" "extra_disk" {
|
||||
disk_name = "extra-disk-for-vm"
|
||||
account_id = data.decort_account.my_account.account_id
|
||||
gid = <GRID_ID> # Grid (platform) ID
|
||||
size_max = 5 # disk size in GB
|
||||
type = "D" # disk type, always use "D" for extra disks
|
||||
sep_id = data.decort_image.os_image.sep_id # use the same SEP ID as the OS image
|
||||
pool = "<<DATA_POOL_NAME>>" # consult your DECORT platform admin for configured storage pool names
|
||||
}
|
||||
|
||||
# 6. Create virtual machine (a compute of type KVM VM x86 in this example)
|
||||
# Now that we have all necessary components at hand, we may create a virtual machine.
|
||||
# This VM will be based on the previsouly obtained OS image, located in the specified
|
||||
# Resource Group, directly connected to an external network, have a boot disk of
|
||||
# specified size and one extra disk attached.
|
||||
resource "decort_kvmvm" "my_new_vm" {
|
||||
name = "tf-managed-vm"
|
||||
driver = "KVM_X86" # Compute virtualization driver
|
||||
rg_id = decort_resgroup.my_rg.id
|
||||
cpu = 1 # CPU count
|
||||
ram = 1024 # RAM size in MB, must be even number, ideally a power of 2
|
||||
boot_disk_size = 10 # Boot disk size in GB
|
||||
image_id = data.decort_image.os_image.image_id
|
||||
description = "Test KVM VM Compute managed by Terraform"
|
||||
extra_disks = [ decort_disk.extra_disk.id ]
|
||||
|
||||
network {
|
||||
net_type = "EXTNET"
|
||||
net_id = <<EXT_NET_ID>> # specify external network ID to use, consult your DECORT platform admin for correct IDs
|
||||
# ip_address = "<<SOME VALID AND FREE IP ADDRESS>>" # you may optionally request a specific IP address
|
||||
}
|
||||
}
|
||||
```
|
||||
31
wiki/4.8.0/03.-Обзор-облачной-платформы-DECORT.md
Normal file
31
wiki/4.8.0/03.-Обзор-облачной-платформы-DECORT.md
Normal file
@@ -0,0 +1,31 @@
|
||||
## Основные понятия
|
||||
Ниже перечислены основные понятия с указанием соответствующих им аргументов в Terraform провайдере DECORT.
|
||||
1. **Контроллер облачной платформы DECORT** – управляющее приложение, которое обеспечивает авторизацию пользователей и оркестрацию облачных ресурсов.
|
||||
- Адрес контроллера задается в обязательном аргументе `controller_url` на стадии инициализации Terraform провайдера DECORT. Например, `controller_url= "https://ds1.digitalenergy.online"`
|
||||
2. **Авторизационный провайдер** – приложение, работающее по протоколу Oauth2, предназначенное для выпуска и валидации токенов доступа к контроллеру облачной платформы в соответствующих режимах авторизации. Все действия в платформе должны выполняться авторизованными пользователями, и авторизационное приложение позволяет получить токен доступа, действующий некоторое ограниченное время, наличие которого подтверждает успешную авторизацию.
|
||||
- Адрес авторизационного провайдера задается в аргументе`oauth2_url` на стадии инициализации Terraform провайдера DECORT. Например `oauth2_url= "https://sso.digitalenergy.online"`
|
||||
3. **Подписчик** (_account_) – сущность, которая используется для группирования облачных ресурсов по принадлежности к определенному клиенту для целей учета потребления и биллинга.
|
||||
- Имя подписчика задается аргументом `account_name` при вызове _resource_ или _data_ функций провайдера. Альтернативной является задание численного идентификатора подписчика в аргументе `account_id`.
|
||||
4. **Пользователь** (_user_) – пользователь облачной инфраструктуры, представленный учетной записью. Чтобы получить возможность управлять облачными ресурсами (например, создавать виртуальные серверы или дискт) пользователь должен быть ассоциирован с одним или несколькими подписчиками и иметь соответствующие права, определяемые ролевой моделью, принятой в облачной платформе DECORT. Для доступа к платформе пользователь должен авторизоваться одним из способов, описанных ниже в разделе «Способы авторизации».
|
||||
5. **Ресурсная группа** (_resource group_) – способ группирования вычислительных ресурсов (например, виртуальных серверов по функциональному признаку или принадлежности к одному и тому же проекту). Ресурсную группу можно рассматривать как небольшой персональный дата-центр, в котором размещаются один или несколько серверов и виртуальных сетевых сегментов. Ресурсная группа идентифицируется по комбинации параметров `account` и `name`. Обратите внимание, что имя имя ресурсной группы уникально только в рамках одного и того же `account`.
|
||||
6. **Вычислительный ресурс** (_compute_) - универсальная абстракция пользовательского сервера в платформе DECORT. Благодаря использованию такой абстракции можно, например, создать одну виртуальную машину на базе KVM Intel x86, а другую - на базе KVM IBM Power, а потом управлять ими - изменять количество CPU/RAM, подключать/отключать диски и т.п. - одинаковым образом, не задумываясь об их архитектурных различиях. В то же время, так как типизация ресурсов в Terraform не поддерживает наследование, различные типы вычислительных ресурсов, доступных на платформе DECORT и абстрагируемых через понятие унифицированный _compute_, в Terraform представлены разными типами (напр., свой тип для виртуальных серверов на базе KVM и свой тип для перспективных x86-совместимых bare metal серверов).
|
||||
7. **Ресурс хранения** (_disk_) - универсальная абстракция дискового ресурса в платформе DECORT. Платформа поддерживает различные типы систем хранения данных, но при этом управление созданными на разных системах хранения дисками осуществляется посредством унифицированного набора действий, например, "подключить диск к _compute_", "увеличить размер диска", "сделать мгновенный снимок диска", "настроить параметры быстродействия диска".
|
||||
8. **Виртуальный сервер** – экземпляр _compute_, в основе технической реализации которого лежит виртуальная машина, работающая в облаке DECORT и доступна по сети. Виртуальный сервер характеризуется количеством выделенных ему CPU (аргумент`cpu`), объемом ОЗУ (`ram`), размером загрузочного диска (`boot_disk size`). При создании виртуального сервера на загрузочный диск устанавливается образ операционной системы, заданный в аргументе `image_id`. Помимо загрузочного диска к виртуальному серверу можно подключить несколько дисков для хранения прикладных данных, список которых задается аргументами `extra_disks`. Виртуальный сервер идентифицируется по комбинации аргументов `name` (имя сервера) и `rgid` (идентификатор ресурсной группы). Обратите внимание, что имя виртуального сервера `name` уникально только в рамках одной и той же ресурсной группы.
|
||||
9. **Виртуальный сетевой сегмент** (_Virtual Network Segment_ или _ViNS_) - сетевой сегмент и обеспечивающая его функционирование виртуальная инфраструктура, которые пользователь может создавать для своих нужд на уровне ресурсной группы или подписчика (_account_). ViNS можно создать полностью изолированным от внешних сетей (см. ниже _External Network_) или с подключением во внешнюю сеть. Внутри ViNS работает DHCP-сервис, обеспечивающий управление IP адресами экземпляров _compute_, подключённых в этот ViNS.
|
||||
10. **Внешняя сеть** (_External Network_) - сетевой сегмент, через который платформа DECORT взаимодействует с внешними по отношению к ней сетевыми ресурсами. Например, в случае с публичным облаком на базе DECORT в качестве внешней сети выступает сеть Интернет. В отличие от ViNS платформа не управляет внешней сетью, а лишь пользуется её ресурсами. В платформе может быть настроено несколько внешних сетей с различными диапазонами IP адресов, и существует механизм управления доступом пользователей к внешним сетям.
|
||||
11. Сетевой доступ к экземпляру _compute_ (виртуальному серверу) реализуется через его подключение к ViNS и/или прямое подключение во внешнюю сеть (External Network). Один и тот же экземпляр _compute_ может одновременно иметь несколько подключений в разные ViNS и/или различные внешние сети.
|
||||
|
||||
## Способы авторизации
|
||||
Облачная платформа DECORT поддерживает три базовых типа авторизации:
|
||||
1. С использованием авторизационного провайдера, работающего по протоколу _Oauth2_. Данный способ является предпочтительным, так как обеспечивает бОльшую гибкость и безопасность. Для авторизации в этом режиме при инициализации Terrafrom провайдера DECORT необходимо указать параметры `oauth2_url` и `controller_url`, а также предоставить одно из нижеперечисленного:
|
||||
- Комбинация Application ID & Application secret, соответствующих пользователю, от имени которого будет осуществляться управление облачными ресурсами в текущей сессии. В процессе проверки предоставленных Application ID & Application secret модуль получает от авторизационного провайдера токен (JSON Web Token, JWT), который затем используется для доступа к указанному контроллеру DECORT. Для авторизации по данному варианту, при инициализации Terraform провайдера DECORT следует установить аргумент `authenticator=decs3o` и задать аргументы `app_id` и `app_secret` (или определить соответствующие переменные окружения `DECORT_APP_ID` и `DECORT_APP_SECRET`).
|
||||
- JSON Web Token – заранее полученный от авторизационного провайдера токен доступа, ассоциированный с определенным пользователем, от имени которого будет осуществляться управление облачными ресурсами в текущей сессии. Для авторизации по данному варианту, при инициализации Terraform провайдера DECORT следует установить аргумент `authenticator=jwt` и задать аргумент `jwt` (или определить переменную окружения `DECORT_JWT`).
|
||||
2. С использованием комбинации _имя пользователя : пароль_. Данный режим не использует внешних авторизационных провайдеров и подразумевает, что пользователь с такой комбинацией зарегистрирован непосредственно на указанном в параметре `controller_url` контроллере облачной платформы DECORT.
|
||||
- Чтобы провайдер авторизовался по данному варианту, при его инициализации следует установить аргумент `authenticator=legacy` и задать аргументы `user` и `password` (или определить соответствующие переменные окружения `DECORT_USER` и `DECORT_PASSWORD`).
|
||||
3. С использованием авторизационного провайдера, работающего по протоколу _Oauth2_oidc_. Для авторизации в этом режиме при инициализации Terrafrom провайдера DECORT необходимо указать параметры `oauth2_url` и `controller_url`, а также Application ID & Application secret, _имя пользователя и пароль_, соответствующих пользователю, от имени которого будет осуществляться управление облачными ресурсами в текущей сессии, и _имя домена_. В процессе проверки предоставленных Application ID & Application secret и пары _имя пользователя-пароль_ модуль получает от авторизационного провайдера токен (JSON Web Token, JWT), который затем используется для доступа к указанному контроллеру DECORT. Для авторизации по данному варианту, при инициализации Terraform провайдера DECORT следует установить аргумент `authenticator=bvs`, задать аргументы `app_id` и `app_secret` (или определить соответствующие переменные окружения `DECORT_APP_ID` и `DECORT_APP_SECRET`), `bvs_user` и `bvs_password` (или определить соответствующие переменные окружения `DECORT_BVS_USER` и `DECORT_BVS_PASSWORD`), а также указать `domain` (или определить соответствующие переменные окружения `DECORT_DOMAIN`).
|
||||
|
||||
После успешной авторизации пользователь (или приложение-клиент) получает доступ к ресурсам, находящимся под управлением соответствующего DECORT контроллера. Доступ предоставляется в рамках подписчиков (_account_), с которыми ассоциирован данный пользователь (_user_), и в соответствии с присвоенными ему ролями.
|
||||
|
||||
## Пользовательская и административная группы API
|
||||
Пользовательская группа API - группа API платформы DECORT, которая позволяет выполнять операции с платформой с правами обычного пользователя. Покрывает большую часть задач.
|
||||
Административная группа API - группа API платформы DECORT, которая позволяет выполнять операции с платформой с расширенными правами. Данные права подразумевают расширенный перечень операций над ресурсами, расширенный перечень ресурсов, расширенную информацию. Требуются права администратора для взаимодействия с этой группой API.
|
||||
@@ -0,0 +1,6 @@
|
||||
Данный раздел описывает:
|
||||
- Системные требования
|
||||
- Установку провайдера
|
||||
- Инициализацию провайдера
|
||||
- Переключение режима работы между разными группами API
|
||||
- Получение gid/grid_id площадки
|
||||
150
wiki/4.8.0/04.01-Установка-Terraform-провайдера-DECORT.md
Normal file
150
wiki/4.8.0/04.01-Установка-Terraform-провайдера-DECORT.md
Normal file
@@ -0,0 +1,150 @@
|
||||
## Системные требования
|
||||
|
||||
Для запуска провайдера вам потребуется машина, на которой установлен Terraform.
|
||||
|
||||
Кроме того, в связи с тем, что начиная с версии 0.12 Terraform изменил алгоритм поиска и инициализации локальных провайдеров, настройка данного провайдера для работы с Terraform 0.12 или более новыми версиями потребует выполнения ряда дополнительных действий. Подробнее см. [8.3 Настройка локального провайдера для работы с новыми версиями Terraform](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/08.-Полезные-советы#user-content-8-3-настройка-локального-провайдера-для-работы-с-новыми-версиями-terraform.md).
|
||||
|
||||
## Установка
|
||||
Начиная с версии провайдера `4.3.0` в релизном архиве находятся скрипты-инсталляторы.
|
||||
Чтобы выполнить установку, необходимо:
|
||||
1. Перейти по адресу: https://repository.basistech.ru/BASIS/terraform-provider-decort/releases
|
||||
2. Выбрать необходимую версию провайдера подходящую под операционную систему.
|
||||
3. Скачать архив.
|
||||
4. Распаковать архив.
|
||||
5. Выполнить скрипт установщика, `install.sh` или `install.bat` для Windows.<br/>
|
||||
*Для запуска `install.sh` не забудьте изменить права доступа к файлу*
|
||||
```bash
|
||||
chmod u+x install.sh
|
||||
```
|
||||
6. Дождаться сообщения об успешной установке. Установщик выведет актуальный блок конфигурации провайдера, скопируйте его
|
||||
```bash
|
||||
DECORT provider version 4.3.0 has been successfully installed
|
||||
|
||||
Copy this provider configuration to main.tf file:
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "4.3.0"
|
||||
source = "basis/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
7. После этого, создайте файл `main.tf` в рабочей директории, которая может находится в любом удобном для пользователя месте.
|
||||
В данном примере, рабочая директория с файлом main.tf находится по пути:
|
||||
```bash
|
||||
~/work/tfdir/main.tf
|
||||
```
|
||||
8. Вставьте в `main.tf` блок конфигурации провайдера, который был выведен на экран установщиком:
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "4.3.0"
|
||||
source = "basis/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
9. Добавьте в файл блок с инициализацией провайдера.
|
||||
```terraform
|
||||
provider "decort" {
|
||||
authenticator = "decs3o"
|
||||
controller_url = "https://mr4.digitalenergy.online"
|
||||
oauth2_url = "https://sso.digitalenergy.online"
|
||||
allow_unverified_ssl = true
|
||||
}
|
||||
```
|
||||
|
||||
10. В консоли выполните команду
|
||||
```bash
|
||||
terraform init
|
||||
```
|
||||
|
||||
11. В случае успешной установки, Terraform инициализирует провайдер и будет готов к дальнейшей работе.
|
||||
|
||||
## Установка из релизов
|
||||
Terraform провайдер DECORT имеет скомпилированные релизные версии, которые расположены по адресу: [Релизы](https://repository.basistech.ru/BASIS/terraform-provider-decort/releases).
|
||||
Чтобы выполнить установку из релиза, необходимо:
|
||||
1. Перейти по адресу: https://repository.basistech.ru/BASIS/terraform-provider-decort/releases
|
||||
2. Выбрать необходимую версию провайдера подходящую под операционную систему.
|
||||
3. Скачать архив.
|
||||
4. Распаковать архив.
|
||||
5. Полученный файл (в директории `bin/`) необходимо поместить:
|
||||
Linux:
|
||||
```bash
|
||||
~/.terraform.d/plugins/${host_name}/${namespace}/${type}/${version}/${target}
|
||||
```
|
||||
Windows:
|
||||
```powershell
|
||||
%APPDATA%\terraform.d\plugins\${host_name}\${namespace}\${type}\${version}\${target}
|
||||
```
|
||||
Где:
|
||||
- host_name - имя хоста, держателя провайдера, например, basis
|
||||
- namespace - пространство имен хоста, например decort
|
||||
- type - тип провайдера, может совпадать с пространством имен, например, decort
|
||||
- version - версия провайдера, например 4.3.0
|
||||
- target - архитектура операционной системы, например windows_amd64
|
||||
|
||||
В примере ниже используется путь до провайдера на машине с ОС Linux:
|
||||
|
||||
```bash
|
||||
~/.terraform.d/plugins/basis/decort/decort/4.3.0/linux_amd64/tf-provider
|
||||
^ ^ ^ ^ ^ ^
|
||||
host_name | | | | | |
|
||||
| | | | |
|
||||
namespace | | | | |
|
||||
| | | |
|
||||
type | | | |
|
||||
| | |
|
||||
version | | |
|
||||
| |
|
||||
target | |
|
||||
|
|
||||
исполняемый файл |
|
||||
```
|
||||
|
||||
6. После этого, создайте файл `main.tf` в рабочей директории, которая может находится в любом удобном для пользователя месте.
|
||||
В данном примере, рабочая директория с файлом main.tf находится по пути:
|
||||
```bash
|
||||
~/work/tfdir/main.tf
|
||||
```
|
||||
7. Добавьте в `main.tf` следующий блок
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "4.3.0"
|
||||
source = "basis/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
В поле `version` указывается версия провайдера.
|
||||
<br/>
|
||||
**ВНИМАНИЕ: Версии в блоке и в пути к исполняемому файлу провайдера должны совпадать!**
|
||||
|
||||
В поле `source` помещается путь до репозитория с версией вида:
|
||||
|
||||
```bash
|
||||
${host_name}/${namespace}/${type}
|
||||
```
|
||||
|
||||
**ВНИМАНИЕ: Версии в блоке и в пути к исполняемому файлу провайдера должны совпадать!**
|
||||
|
||||
8. Добавьте в файл блок с инициализацией провайдера.
|
||||
```terraform
|
||||
provider "decort" {
|
||||
authenticator = "decs3o"
|
||||
controller_url = "https://mr4.digitalenergy.online"
|
||||
oauth2_url = "https://sso.digitalenergy.online"
|
||||
allow_unverified_ssl = true
|
||||
}
|
||||
```
|
||||
|
||||
9. В консоли выполните команду
|
||||
```bash
|
||||
terraform init
|
||||
```
|
||||
|
||||
10. В случае успешной установки, Terraform инициализирует провайдер и будет готов к дальнейшей работе.
|
||||
@@ -0,0 +1,64 @@
|
||||
## Список аргументов для инициализации
|
||||
Перед началом использования любой Terraform провайдер должен быть инициализирован.
|
||||
|
||||
В процессе инициализации Terraform провайдера DECORT проверяется корректность переданных аргументов и выполняется авторизация в указанном контроллере облачной инфраструктуры. Подробнее о способах авторизации в платформе DECORT смотри соответствующий [раздел](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/03.-Обзор-облачной-платформы-DECORT#user-content-способы-авторизации.md).
|
||||
|
||||
При инициализации Terraform провайдера DECORT используются следующие аргументы:
|
||||
|
||||
| Аргумент | Переменная окружения | Описание |
|
||||
| --- | --- | --- |
|
||||
| allow_unverified_ssl | - | Если данный аргумент явно установлен в `true`, то провайдер **не будет** проверять SSL сертификаты при взаимодействии с авторизационным сервисом OAuth2 и контроллером облачной платформы.<br>Отключение проверок может быть полезным при работе в доверенной среде, использующей самоподписанные SSL сертификаты. Однако, так как отключение проверок несёт потенциальные риски безопасности, данную настройку следует использовать с осторожностью.<br/>Разрешённые значения: `false` (значение по умолчанию) и `true`. |
|
||||
| app_id | DECORT_APP_ID | Идентификатор приложения (клиента) для авторизации в контроллере облачной платформы в режиме `decs3o` или `bvs`.<br> Аргументы `app_id` и `app_secret` являются обязательными для режимов авторизации `authenticator=decs3o` и `authenticator=bvs`.<br>Если `app_id` не задан в tf-файле, то провайдер будет использовать значение из переменной окружения `DECORT_APP_ID`. |
|
||||
| app_secret | DECORT_APP_SECRET | Секретный код приложения (клиента) для авторизации в контроллере облачной платформы в режиме `decs3o` или `bvs`.<br> Аргументы `app_id` и `app_secret` являются обязательными для режимов авторизации `authenticator=decs3o` и `authenticator=bvs`.<br>Если `app_secret` не задан в tf-файле, то провайдер будет использовать значение из переменной окружения `DECORT_APP_SECRET`. |
|
||||
| authenticator | - | Режим авторизации при подключении к контроллеру облачной платформы.<br/>Доступные режимы: `decs3o`, `legacy`, `jwt` или `bvs`.<br>Данный аргумент является обязательным. |
|
||||
| bvs_user | DECORT_BVS_USER | Имя пользователя для авторизации в контроллере облачной платформы в режиме `bvs`.<br>Аргументы `bvs_password` и `bvs_user` являются обязательными для режима авторизации `authenticator=bvs`.<br>Если `bvs_user` не задан в tf-файле, то провайдер будет использовать значение из переменной окружения `DECORT_BVS_USER`. |
|
||||
| bvs_password | DECORT_BVS_PASSWORD | Пароль пользователя для авторизации в контроллере облачной платформы в режиме `bvs`.<br>Аргументы `bvs_user` и `bvs_password` являются обязательными для режима авторизации `authenticator=bvs`.<br>Если `bvs_password` не задан в tf-файле, то провайдер будет использовать значение из переменной окружения `DECORT_BVS_PASSWORD`. |
|
||||
| domain | DECORT_DOMAIN | Имя домена в контроллере облачной платформы в режиме `bvs`.<br>Данный аргумент является обязательным.<br>Если `domain` не задан в tf-файле, то провайдер будет использовать значение из переменной окружения `DECORT_DOMAIN`. |
|
||||
| controller_url | DECORT_CONTROLLER_URL | URL контроллера облачной платформы, через который будет осуществляться управление облачными ресурсами.<br>Данный аргумент является обязательным. |
|
||||
| jwt | DECORT_JWT | JSON Web Token (JWT), который используется для авторизации в контроллере облачной платформы в режиме `jwt`.<br>Данный аргумент является обязательным для режима авторизации `authenticator=jwt`.<br>Если `jwt` не задан в tf-файле, то провайдер будет использовать значение из переменной окружения `DECORT_JWT` |
|
||||
| oauth2_url | DECORT_OAUTH2_URL | URL авторизационного сервиса OAuth2, который используется для управления доступом пользователей (или программных клиентов) к контроллеру облачной платформы.<br>Данный аргумент является обязательным для режимов авторизации `authenticator=decs3o`, `authenticator=bvs` и `authenticator=jwt`.<br>Если `oauth2_url` не задан в tf-файле, то провайдер будет использовать значение из переменной окружения `DECORT_OAUTH2_URL` |
|
||||
| password | DECORT_PASSWORD | Пароль для авторизации в контроллере облачной платформы в режиме `legacy`.<br> Аргументы `password` и `user` являются обязательными для режима авторизации `authenticator=legacy`.<br>Если `password` не задан в tf-файле, то провайдер будет использовать значение из переменной окружения `DECORT_PASSWORD`. |
|
||||
| user | DECORT_USER | Имя пользователя для авторизации в контроллере облачной платформы в режиме `legacy`.<br> Аргументы `user` и `password` являются обязательными для режима авторизации `authenticator=legacy`.<br>Если `user` не задан в tf-файле, то провайдер будет использовать значение из переменной окружения `DECORT_USER`. |
|
||||
|
||||
## Пример инициализации в режиме авторизации `decs3o`
|
||||
Пример инициализации Terraform провайдера DECORT:
|
||||
```terraform
|
||||
provider "decort" {
|
||||
authenticator = "decs3o"
|
||||
controller_url = "https://ctrl.decort.online"
|
||||
oauth2_url = "https://oauth2.decort.online:7777"
|
||||
}
|
||||
```
|
||||
|
||||
В данном примере используется режим авторизации `decs3o`.
|
||||
|
||||
Как отмечено выше, в данном режиме требуется указать аргументы `app_id` и `app_secret`, идентифицирующие пользователя (или приложение-клиент), от лица которого будут выполняться дальнейшие действия. Однако, так как данная информация является конфиденциальной (по сути, она эквивалентна паре _имя пользователя : пароль_), то в общем случае заносить такого рода данные в tf-файл не следует. Рекомендуется определять в среде запуска Terraform переменные окружения `DECORT_APP_ID` и `DECORT_APP_SECRET`, из которых провайдер извлечёт нужные данные. Приведенный пример подразумевает, что нужная информация будет получена из этих переменных окружения.
|
||||
|
||||
Пользователь, от лица которого Terrafrom будет выполнять действия в облачной платформе, должен заранее создать пару _Application ID_ и _Application Secret_ в авторизационном приложении OAuth2. Именно эти значения, а также URL авторизационного приложения Oauth2, должны присваиваться аргументам `app_id`, `app_secret` и `oauth2_url` соответственно для успешной инициализации провайдера.
|
||||
|
||||
Также обратите внимание на формат задания аргументов `controller_url` и `oauth2_url`. В общем случае они должны содержать идентификатор протокола (_https://_) и сетевой порт, если он отличается от порта по умолчанию (в примере для авторизационного сервиса OAuth2 указан порт _7777_). Эту информацию вы можете узнать у администратора вашей облачной инфраструктуры DECORT.
|
||||
|
||||
## Пример инициализации в режиме авторизации `bvs`
|
||||
Пример инициализации Terraform провайдера DECORT:
|
||||
```terraform
|
||||
provider "decort" {
|
||||
authenticator = "bvs"
|
||||
controller_url = "https://delta.qa.loc"
|
||||
oauth2_url = "https://bvs-delta.qa.loc:8443"
|
||||
app_id = "delta"
|
||||
app_secret = ""
|
||||
bvs_password = ""
|
||||
bvs_user = ""
|
||||
domain = "dynamix"
|
||||
}
|
||||
```
|
||||
|
||||
В данном примере используется режим авторизации `bvs`.
|
||||
|
||||
Как отмечено выше, в данном режиме требуется указать аргументы `app_id` - идентификатор площадки - delta, alpha, poc, etc. Можно найти на странице администратора по следующему пути: вкладка безопасность - клиентские сервисы - наименование площадки. `app_secret` - пароль площадки. Можно найти на странице администратора по следующему пути: вкладка безопасность - клиентские сервисы - наименование площадки (символ i) - поле "Пароль". Однако, так как данная информация является конфиденциальной, то в общем случае заносить такого рода данные в tf-файл не следует. Рекомендуется определять в среде запуска Terraform переменные окружения `DECORT_APP_ID` и `DECORT_APP_SECRET`, из которых провайдер извлечёт нужные данные. Приведенный пример подразумевает, что нужная информация будет получена из этих переменных окружения.
|
||||
Также обязательными аргументами являются: `bvs_user` - имя пользователя, `bvs_password` - пароль пользователя. Рекомендуется не заносить их в tf-файл, а определять в среде запуска Terraform переменные окружения `DECORT_BVS_USER` и `DECORT_BVS_PASSWORD`, из которых провайдер извлечёт нужные данные. Приведенный пример подразумевает, что нужная информация будет получена из этих переменных окружения.
|
||||
Домен для подключения `domain` - указывается наименование площадки. Данный аргумент является обязательным. Рекомендуется не заносить его в tf-файл, а определять в среде запуска Terraform переменную окружения `DECORT_DOMAIN`, из которой провайдер извлечёт нужные данные. Приведенный пример подразумевает, что нужная информация будет получена из этих переменных окружения.
|
||||
|
||||
Пользователь, от лица которого Terrafrom будет выполнять действия в облачной платформе, должен заранее получить от администратора _Application ID_ и _Application Secret_, _bvs user_ и _bvs password_, а также _domain_. А также осуществить первичный вход на платформу посредством браузера.
|
||||
|
||||
Также обратите внимание на формат задания аргументов `controller_url` и `oauth2_url`. В общем случае они должны содержать идентификатор протокола (_https://_) и сетевой порт, если он отличается от порта по умолчанию (в примере для авторизационного сервиса OAuth2 указан порт _8443_). Эту информацию вы можете узнать у администратора вашей облачной инфраструктуры DECORT.
|
||||
38
wiki/4.8.0/04.03-Переключение-между-группами-API.md
Normal file
38
wiki/4.8.0/04.03-Переключение-между-группами-API.md
Normal file
@@ -0,0 +1,38 @@
|
||||
Так как платформа DECORT предоставляет для работы две группы API, то terraform провайдер позволяет свободно переключать режимы работы между этими группами.
|
||||
По умолчанию стоит пользовательская группа API. Ее можно сменить на административную группу.
|
||||
Если прав у пользователя будет достаточно, то запрос будет выполнен, если нет, то будет ошибка:
|
||||
```bash
|
||||
Permission denied
|
||||
```
|
||||
Которая говорит о том, что прав недостаточно. Тогда для выполнения операции обратитесь к администратору платформы.
|
||||
Установка режима взаимодействия с группами API осуществляется через установку переменной окружения _DECORT_ADMIN_MODE_.
|
||||
Для более подробного описания возможностей каждой группы API см. соответствующий раздел.
|
||||
|
||||
## Переключение режима работы в Windows
|
||||
Используйте сл. команду:
|
||||
```Powershell
|
||||
$Env:DECORT_ADMIN_MODE=1
|
||||
```
|
||||
Для отключения:
|
||||
```Powershell
|
||||
$Env:DECORT_ADMIN_MODE=0
|
||||
```
|
||||
## Переключение режима работы в Linux
|
||||
Используйте сл. команду:
|
||||
```bash
|
||||
DECORT_ADMIN_MODE=1
|
||||
```
|
||||
или
|
||||
```bash
|
||||
export DECORT_ADMIN_MODE=1
|
||||
```
|
||||
Для отключения:
|
||||
```bash
|
||||
DECORT_ADMIN_MODE=0
|
||||
```
|
||||
или
|
||||
```bash
|
||||
export DECORT_ADMIN_MODE=0
|
||||
```
|
||||
**ОБРАТИТЕ ВНИМАНИЕ**
|
||||
Переменные окружения создаются для терминальной сессии. В сл. раз их придется задавать еще раз, если требуется режим, отличный от пользовательского.
|
||||
31
wiki/4.8.0/04.04-Получение-gid-или-grid_id.md
Normal file
31
wiki/4.8.0/04.04-Получение-gid-или-grid_id.md
Normal file
@@ -0,0 +1,31 @@
|
||||
Платформа может располагаться на нескольких площадках(grid).
|
||||
Такие площадки имеют свой id.
|
||||
Для создания некоторых ресурсов требуется ввести grid_id или gid площадки.
|
||||
Получение gid различается для пользовательского и административного API.
|
||||
|
||||
## Получение gid для пользовательского API
|
||||
Для получения gid с помощью пользовательского API, необходимо получить информацию из _data_source_ функции _decort_locations_list_, как указано ниже:
|
||||
```terraform
|
||||
data "decort_locations_list" "ll" {
|
||||
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = data.decort_locations_list.ll
|
||||
}
|
||||
```
|
||||
В файл состояния будет сохранен результат, где можно посмотреть доступные для работы площадки.
|
||||
|
||||
## Получение gid для административного API
|
||||
Для получения gid с помощью административного API, необходимо получить информацию из _data_source_ функции _decort_grid_list_, как указано ниже:
|
||||
```terraform
|
||||
data "decort_grid_list" "gl" {
|
||||
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = data.decort_grid_list.gl
|
||||
}
|
||||
|
||||
```
|
||||
В файл состояния будет сохранен результат, где можно посмотреть доступные для работы площадки.
|
||||
43
wiki/4.8.0/04.05-Сборка-terraform-провайдера-в-образ.md
Normal file
43
wiki/4.8.0/04.05-Сборка-terraform-провайдера-в-образ.md
Normal file
@@ -0,0 +1,43 @@
|
||||
Образ приложения - современный способ запуска приложений. Образ приложения представляет собой контейнер, в который входит ОС и необходимые для работы приложения пакеты.
|
||||
Способов создать образ приложения довольно много, для этого существуют программы контейнеризации:
|
||||
- Docker
|
||||
- Podman
|
||||
- и другие
|
||||
Образ представляет собой "зафиксированную" версию приложения, что означает, что никакие изменения в приложения внесены быть не могут. Так же означает то, что приложение не может создавать побочные файлы при работе.
|
||||
Контейнер - это запущенный экземпляр образа. То есть, один образ может порождать множество контейнеров, каждый из которых будет включать в себя отдельный экземпляр приложения.
|
||||
Одно из преимуществ работы приложения в контейнере - кроссплатформенность. Это преимущество обуславливается тем, что образ приложения уже включает в себя все необходимое для успешной работы приложения, в том числе операционную систему. Поэтому, пользователю достаточно установить на вычислительной машине программу, которая обеспечивает работу с образами приложений.
|
||||
|
||||
## Docker
|
||||
Docker является одной из самых популярных программ для работы с образами.
|
||||
Docker позволяет:
|
||||
- Создавать образы
|
||||
- Запускать контейнеры
|
||||
- Управлять контейнерами
|
||||
- Управлять образами
|
||||
Скачать и установить Docker можно по ссылке https://docs.docker.com/get-docker/
|
||||
|
||||
## Сборка terraform провайдера
|
||||
### Требования:
|
||||
- Docker
|
||||
- git
|
||||
- Компилятор языка GO
|
||||
= make
|
||||
### Установка необходимых программ
|
||||
1. Компилятор языка GO можно скачать и установить по ссылке: https://go.dev/dl/
|
||||
2. Docker можно скачать и установить по ссылке выше.
|
||||
3. Git можно скачать и установить по ссылке: https://git-scm.com/
|
||||
4. Программа make входит в пакет установленных программ для ОС Linux. Для Windows можно воспользоваться инструкцией со stack overflow: https://stackoverflow.com/questions/32127524/how-to-install-and-use-make-in-windows
|
||||
### Порядок действий
|
||||
1. Склонировать репозиторий с провайдером:
|
||||
```bash
|
||||
git clone https://github.com/rudecs/terraform-provider-decort.git
|
||||
```
|
||||
2. Перейти в директорию со скачанным кодом:
|
||||
```bash
|
||||
cd terraform-provider-decort
|
||||
```
|
||||
3. Выполнить команду:
|
||||
```bash
|
||||
make image
|
||||
```
|
||||
В результате выполнения данной последовательности, будет создан docker образ, который содержит в себе приложение terraform, terraform провайдер.
|
||||
4
wiki/4.8.0/05.-Работа-с-terraform.md
Normal file
4
wiki/4.8.0/05.-Работа-с-terraform.md
Normal file
@@ -0,0 +1,4 @@
|
||||
Раздел описывает некоторые практики работы с terraform, которые могут быть полезны пользователю.
|
||||
Раздел включает в себя следующие статьи:
|
||||
- Импортирование ресурсов
|
||||
- Работа с таймаутами
|
||||
75
wiki/4.8.0/05.01-Импортирование-ресурсов.md
Normal file
75
wiki/4.8.0/05.01-Импортирование-ресурсов.md
Normal file
@@ -0,0 +1,75 @@
|
||||
Импортирование ресурсов в terraform позволяет привести в соответствие состояние terraform (.tfstate) к состоянию ресурса в платформе.
|
||||
Необходимость такого приведения возникает в нескольких случаях:
|
||||
- Ресурс был создан через портал платформы, работа продолжается через terraform провайдер,
|
||||
- Ресурс был создан через terraform провайдер, однако был изменен через портал платформы,
|
||||
- Ресурс был создан через terraform провайдер, однако был изменен другим пользователем через terraform провайдер,
|
||||
- И так далее
|
||||
|
||||
Такие расхождения в состоянии ресурсов нередки, путей их решения несколько:
|
||||
- Использовать импортирование ресурсов,
|
||||
- Использовать общие файлы состояний ресурсов, к которым будут иметь доступ все участники, занятые в работе с платформой.
|
||||
В текущем разделе рассматривается первый вариант.
|
||||
|
||||
## Импортирование ресурсов
|
||||
Импортирование ресурсов позволяет совершить запрос к платформе, чтобы сформировать файл состояния.
|
||||
Чтобы совершить импортирование ресурсов необходимо ввести сл. команду:
|
||||
```bash
|
||||
terraform import <resource-name>.<resource-variable> <resource-id>
|
||||
```
|
||||
## Пример
|
||||
Предположим, что у нас ресурс, описывающий диск:
|
||||
```terraform
|
||||
resource "decort_disk" "disk" {
|
||||
account_id = 121212
|
||||
gid = 3333
|
||||
disk_name = "mySuperDisk"
|
||||
size_max = 100500
|
||||
}
|
||||
```
|
||||
Если запустить команду:
|
||||
```bash
|
||||
terraform apply
|
||||
```
|
||||
То у нас будет создан новый диск.
|
||||
Но, такой диск уже есть на площадке и мы хотели бы сформировать .tfstate для этого ресурса.
|
||||
Поэтому, для начала, необходимо получить список дисков:
|
||||
```terraform
|
||||
data "decort_disk_list" "dl"{
|
||||
|
||||
}
|
||||
output "test" {
|
||||
value = data.decort_disk_list.dl
|
||||
}
|
||||
```
|
||||
В полученных данных необходимо найти требуемый диск, получить его id - параметр disk_id. Пусть это будет - 777777
|
||||
Теперь можно выполнить импортирование:
|
||||
```bash
|
||||
terraform import decort_disk.disk 777777
|
||||
```
|
||||
Команда должна успешно завершиться, появиться файл состояний, который позволит манипулировать ресурсом.
|
||||
|
||||
## Ошибки при импортировании
|
||||
При импортировании ресурса может возникнуть сл. ошибка:
|
||||
```bash
|
||||
Error: <field-name>: required field is not set
|
||||
```
|
||||
Где <field-name> - наименование поля.
|
||||
Ошибка возникает в том случае, если в описании ресурса отсутствует обязательное поле.
|
||||
Например:
|
||||
```terraform
|
||||
resource "decort_disk" "disk" {
|
||||
account_id = 121212
|
||||
gid = 3333
|
||||
size_max = 100500
|
||||
}
|
||||
```
|
||||
В приведенном выше описании отсутствует поле disk_name, поэтому, при попытке импортирования возникнет ошибка.
|
||||
Для ее устранения, необходимо выполнить запрос на получение списка дисков, найти недостающее поле, после чего добавить его в описание ресурса.
|
||||
После этого повторить попытку импортирования.
|
||||
|
||||
## Общий алгоритм устранения ошибок
|
||||
1. Выполнить запрос импортирования
|
||||
2. В случае ошибки - внести недостающие поля.
|
||||
3. Повторить п.1.
|
||||
|
||||
|
||||
100
wiki/4.8.0/05.02-Работа-с-таймаутами.md
Normal file
100
wiki/4.8.0/05.02-Работа-с-таймаутами.md
Normal file
@@ -0,0 +1,100 @@
|
||||
Terraform провайдер DECORT поддерживает тонкую настройку таймаутов выполнения запросов к платформе. Таймауты необходимы для определения максимального времени выполнения запроса. При превышении этого времени соединение рвется и запрос считается невыполненным.
|
||||
Таймауты применяются при работе с _resource_ функциями провайдера. _Data source_ функции по-умолчанию имеют таймаут в 20 минут и изменяться не может.
|
||||
|
||||
## Стандартные таймауты terraform
|
||||
| Операция | Время | Описание |
|
||||
| --- | --- | --- |
|
||||
| create | 20 минут | Создание ресурса |
|
||||
| read | 20 минут | Чтение ресурса |
|
||||
| update | 20 минут | Обновление ресурса |
|
||||
| delete | 20 минут | Удаление ресурса |
|
||||
| default | 20 минут | Значение по умолчанию. Устанавливает значение для всех операций |
|
||||
|
||||
## Стандартные таймауты провайдера DECORT
|
||||
В провайдере DECORT таймауты переопределены для того, чтобы уменьшить нагрузку на платформу.
|
||||
| Операция | Время | Описание |
|
||||
| --- | --- | --- |
|
||||
| create | 10 минут | Создание ресурса |
|
||||
| read | 5 минут | Чтение ресурса |
|
||||
| update | 5 минут | Обновление ресурса |
|
||||
| delete | 5 минут | Удаление ресурса |
|
||||
| default | 5 минут | Значение по умолчанию. Устанавливает значение для всех операций |
|
||||
|
||||
## Установка таймаутов
|
||||
Все таймауты можно установить самостоятельно для каждого ресурса.
|
||||
Для этого используется блок _timeouts_, который имеется в каждом ресурсе провайдера.
|
||||
Пример:
|
||||
```terraform
|
||||
resource "decort_res" "res_name" {
|
||||
timeouts {
|
||||
create = "10m"
|
||||
update = "1m"
|
||||
delete = "2m"
|
||||
read = "7m"
|
||||
#default = "15m"
|
||||
}
|
||||
}
|
||||
```
|
||||
Где:
|
||||
- create - операция создания ресурса
|
||||
- read - операция чтения ресурса
|
||||
- update - операция обновления ресурса
|
||||
- delete - операция удаления ресурса
|
||||
- default - установит заданное время для всех операций
|
||||
## Формат установления времени
|
||||
Как видно из примера выше, провайдер принимает на вход строку вида:
|
||||
```
|
||||
"<time-num><time-val>"
|
||||
```
|
||||
Где:
|
||||
- time-num - число
|
||||
- time-val - сокращенная запись значения временного отрезка.
|
||||
|
||||
Таблица с временными отрезками:
|
||||
|
||||
| Отрезок | Значение |
|
||||
| --- | --- |
|
||||
| n | наносекунда |
|
||||
| ms | миллисекунда |
|
||||
| s | секунда |
|
||||
| m | минута |
|
||||
| h | час |
|
||||
|
||||
Примеры:
|
||||
```
|
||||
"10m"
|
||||
"1s"
|
||||
"1h10m"
|
||||
```
|
||||
И так далее
|
||||
|
||||
## Работа с таймером через .tf-файл
|
||||
В .tf-файле, в блоке ресурса можно задавать таймауты для операций над ресурсом, однако, при работе с таймаутом, следует помнить о правиле:
|
||||
__В случае изменения таймаутов в .tf-файле, операции с новыми таймаутами будут производиться только после apply/plan/destroy__
|
||||
То есть, если изменить таймауты и выполнить операцию, то она выполнится со старыми таймаутами, а сл. операция уже будет выполнена с новыми таймаутами.
|
||||
Это объясняется тем, что значения таймаутов считываются из файла состояний .tfstate при выполнении операции, и новые значения таймаутов попадут туда только при успешно выполненной операции.
|
||||
|
||||
## Ошибки при работе с таймаутом
|
||||
### context deadline exceeded
|
||||
Если время таймаута слишком короткое, то можно получить сл. ошибку:
|
||||
```
|
||||
context deadline exceeded
|
||||
```
|
||||
Которая говорит, что было выполнено прерывание работы программы из-за истечения времени на операцию.
|
||||
Для исправления можно увеличить размер окна таймаута и выполнить успешный запрос (например, с помощью терминала), чтобы новое значения таймаутов было добавлено в .tfstate. В противном случае, файл состояния придется править в ручную, либо удалить его и импортировать ресурс для формирования .tfstate.
|
||||
|
||||
### 504 ошибка
|
||||
Данная ошибка говорит о том, что сервер принудительно разорвал соединения из-за истечения времени на ответ.
|
||||
В случае получения данной ошибки, обратитесь в службу технической поддержки.
|
||||
|
||||
## Работа с таймаутами через терминал
|
||||
Сл. команда выполнит операцию terraform с заданным таймаутом:
|
||||
```bash
|
||||
timeout <time> terraform <cmd>
|
||||
```
|
||||
Где:
|
||||
- time - время таймаута, например, 1h, 10m, и так далее
|
||||
- cmd - команда terraform, например, apply, plan и так далее
|
||||
## Заключение
|
||||
Таймауты - мощный механизм terraform провайдера, который позволяет более тонко настраивать время выполнения операций.
|
||||
Как и любой подобный механизм тонкой настройки, он требует внимательного и аккуратного использования.
|
||||
29
wiki/4.8.0/05.03-Восстановление-ресурсов.md
Normal file
29
wiki/4.8.0/05.03-Восстановление-ресурсов.md
Normal file
@@ -0,0 +1,29 @@
|
||||
Ресурсы в платформе можно удалять в корзину (с возможностью восстановления), удалять сразу без возможности восстановления.
|
||||
|
||||
## Удаление ресурса
|
||||
Для удаления ресурса применяется команда:
|
||||
```bash
|
||||
terraform destroy
|
||||
```
|
||||
После выполнения данной команды произойдет следующее:
|
||||
- Будет удален файл состояния ресурса .tfstate
|
||||
- Ресурс не удалится с платформы, а будет помещен в корзину, с возможностью восстановления
|
||||
|
||||
|
||||
## Восстановление ресурсов
|
||||
__Ресурс можно восстановить, если у него есть поле `restore`__, в противном случае, необходимо воспользоваться порталом для восстановления.
|
||||
После удаления ресурса, он помечается как "Deleted" и его можно восстановить.
|
||||
Для восстановления ресурса необходимо выполнить следующие действия:
|
||||
- Создать файл .tf и описать в нем восстанавливаемый ресурс
|
||||
- Импортировать ресурс
|
||||
- Добавить поле restore со значением `true`
|
||||
- Выполнить `terraform apply`
|
||||
|
||||
## Удаление ресурсов без возможности восстановления
|
||||
Ресурсы можно удалять с платформы сразу, минуя корзину. Однако, такое удаление возможно только для ресурсов, имеющих поле `permanently`.
|
||||
Для этого необходимо выполнить сл. шаги:
|
||||
- В файле .tf добавить поле `permanently = true`
|
||||
- Применить изменения `terraform apply`
|
||||
- Выполнить удаление `terraform destroy`
|
||||
|
||||
**Проводя мгновенное удаление, ресурс восстановить будет невозможно!**
|
||||
448
wiki/4.8.0/05.04-Массовое-создание-ресурсов.-Мета-аргументы.md
Normal file
448
wiki/4.8.0/05.04-Массовое-создание-ресурсов.-Мета-аргументы.md
Normal file
@@ -0,0 +1,448 @@
|
||||
Иногда требуется создать несколько ресурсов, которые будут отличаться незначительными изменениями (например, имя).
|
||||
В terraform имеются специальные мета-аргументы, которые позволяют описать данную инфраструктуру максимально быстро, избегая повторений блоков.
|
||||
Однако, при таком подходе стоит учитывать то, что созданная при помощи такого подхода инфраструктура является неким "монолитом" и любые изменения будут применятся для всех ресурсов, которые были созданы с помощью мета аргументов.
|
||||
|
||||
__ВНИМАНИЕ: СОЗДАННЫЕ ТАКИМ ОБРАЗОМ РЕСУРСЫ, УПРАВЛЯЮТСЯ КАК ОДИН РЕСУРС__
|
||||
|
||||
## Создание дисков. Обычный вариант
|
||||
Предположим, что необходимо создать несколько дисков, которые будут иметь одинаковые поля, а отличаться только именем.
|
||||
Тогда, будут использованы несколько блоков resource с описанием данных ресурсов:
|
||||
```terraform
|
||||
resource "decort_disk" "disk1" {
|
||||
account_id = 777
|
||||
disk_name = "disk-1"
|
||||
size_max = 10
|
||||
gid = 212
|
||||
}
|
||||
|
||||
resource "decort_disk" "disk2" {
|
||||
account_id = 777
|
||||
disk_name = "disk-2"
|
||||
size_max = 10
|
||||
gid = 212
|
||||
}
|
||||
```
|
||||
Все блоки повторяются и отличаются только именем. Если не планируется изменение каждого ресурса по-отдельности, то можно вынести имена дисков в отдельную переменную, и считывать их из нее.
|
||||
## Рефакторинг
|
||||
Вынесем значения имен дисков в блок locals:
|
||||
```terraform
|
||||
locals {
|
||||
disk_names = [
|
||||
"disk-1",
|
||||
"disk-2",
|
||||
]
|
||||
}
|
||||
|
||||
resource "decort_disk" "disk1" {
|
||||
account_id = 777
|
||||
disk_name = "disk-1"
|
||||
size_max = 10
|
||||
gid = 212
|
||||
}
|
||||
|
||||
resource "decort_disk" "disk2" {
|
||||
account_id = 777
|
||||
disk_name = "disk-2"
|
||||
size_max = 10
|
||||
gid = 212
|
||||
}
|
||||
```
|
||||
Оставшиеся блоки resource идентичны друг другу, за исключением наименования ресурса, поэтому, их создание и работу с ними можно объединить.
|
||||
## Мета аргумент for_each
|
||||
Мета аргумент for_each служит для итерации по набору (set) строки, либо по мапе (map, object). Результатом работы этого мета аргумента станет так же объект, ключами которого будут либо строки, входящие в набор, либо параметры, указанные при итерировании объекта.
|
||||
Мета аргумент for_each предоставляет переменную each, в которую, при каждой итерации будут ключи (если итерация идет по набору строк), либо ключи и соответствующие им значения, если итерация идет по объекту.
|
||||
Обратиться к ним можно через символ ".", например:
|
||||
```terraform
|
||||
each.key
|
||||
each.value
|
||||
```
|
||||
Таким образом, конфигурирование одинаковых ресурсов сократится до одного.
|
||||
При добавлении в код выше, получится:
|
||||
```terraform
|
||||
locals {
|
||||
disk_names = [
|
||||
"disk-1",
|
||||
"disk-2",
|
||||
]
|
||||
}
|
||||
|
||||
#обратите внимание, что ресурс был переименован
|
||||
resource "decort_disk" "disks" {
|
||||
#преобразование массива к набору строк для успешной работы for_each
|
||||
for_each = toset(local.disk_names)
|
||||
account_id = 777
|
||||
#получение имени диска из переменной each
|
||||
disk_name = each.key
|
||||
size_max = 10
|
||||
gid = 212
|
||||
}
|
||||
|
||||
#блок output демонстрирует вывод работы на экран
|
||||
output "test" {
|
||||
value = decort_disk.disks
|
||||
}
|
||||
```
|
||||
При выполнении данной конфигурации в terraform output будет следующее:
|
||||
```
|
||||
Changes to Outputs:
|
||||
+ test = {
|
||||
+ disk-1 = {
|
||||
+ account_id = 777
|
||||
+ account_name = (known after apply)
|
||||
+ acl = (known after apply)
|
||||
+ boot_partition = (known after apply)
|
||||
+ compute_id = (known after apply)
|
||||
+ compute_name = (known after apply)
|
||||
+ created_time = (known after apply)
|
||||
+ deleted_time = (known after apply)
|
||||
+ desc = (known after apply)
|
||||
+ destruction_time = (known after apply)
|
||||
+ detach = false
|
||||
+ devicename = (known after apply)
|
||||
+ disk_id = (known after apply)
|
||||
+ disk_name = "disk-1"
|
||||
+ disk_path = (known after apply)
|
||||
+ gid = 212
|
||||
+ guid = (known after apply)
|
||||
+ id = (known after apply)
|
||||
+ image_id = (known after apply)
|
||||
+ images = (known after apply)
|
||||
+ iotune = (known after apply)
|
||||
+ iqn = (known after apply)
|
||||
+ login = (known after apply)
|
||||
+ milestones = (known after apply)
|
||||
+ order = (known after apply)
|
||||
+ params = (known after apply)
|
||||
+ parent_id = (known after apply)
|
||||
+ passwd = (known after apply)
|
||||
+ pci_slot = (known after apply)
|
||||
+ permanently = false
|
||||
+ pool = (known after apply)
|
||||
+ purge_attempts = (known after apply)
|
||||
+ purge_time = (known after apply)
|
||||
+ reality_device_number = (known after apply)
|
||||
+ reference_id = (known after apply)
|
||||
+ res_id = (known after apply)
|
||||
+ res_name = (known after apply)
|
||||
+ restore = false
|
||||
+ role = (known after apply)
|
||||
+ sep_id = (known after apply)
|
||||
+ sep_type = (known after apply)
|
||||
+ size_max = 10
|
||||
+ size_used = (known after apply)
|
||||
+ snapshots = (known after apply)
|
||||
+ status = (known after apply)
|
||||
+ tech_status = (known after apply)
|
||||
+ timeouts = null
|
||||
+ type = (known after apply)
|
||||
+ vmid = (known after apply)
|
||||
}
|
||||
+ disk-2 = {
|
||||
+ account_id = 777
|
||||
+ account_name = (known after apply)
|
||||
+ acl = (known after apply)
|
||||
+ boot_partition = (known after apply)
|
||||
+ compute_id = (known after apply)
|
||||
+ compute_name = (known after apply)
|
||||
+ created_time = (known after apply)
|
||||
+ deleted_time = (known after apply)
|
||||
+ desc = (known after apply)
|
||||
+ destruction_time = (known after apply)
|
||||
+ detach = false
|
||||
+ devicename = (known after apply)
|
||||
+ disk_id = (known after apply)
|
||||
+ disk_name = "disk-2"
|
||||
+ disk_path = (known after apply)
|
||||
+ gid = 212
|
||||
+ guid = (known after apply)
|
||||
+ id = (known after apply)
|
||||
+ image_id = (known after apply)
|
||||
+ images = (known after apply)
|
||||
+ iotune = (known after apply)
|
||||
+ iqn = (known after apply)
|
||||
+ login = (known after apply)
|
||||
+ milestones = (known after apply)
|
||||
+ order = (known after apply)
|
||||
+ params = (known after apply)
|
||||
+ parent_id = (known after apply)
|
||||
+ passwd = (known after apply)
|
||||
+ pci_slot = (known after apply)
|
||||
+ permanently = false
|
||||
+ pool = (known after apply)
|
||||
+ purge_attempts = (known after apply)
|
||||
+ purge_time = (known after apply)
|
||||
+ reality_device_number = (known after apply)
|
||||
+ reference_id = (known after apply)
|
||||
+ res_id = (known after apply)
|
||||
+ res_name = (known after apply)
|
||||
+ restore = false
|
||||
+ role = (known after apply)
|
||||
+ sep_id = (known after apply)
|
||||
+ sep_type = (known after apply)
|
||||
+ size_max = 10
|
||||
+ size_used = (known after apply)
|
||||
+ snapshots = (known after apply)
|
||||
+ status = (known after apply)
|
||||
+ tech_status = (known after apply)
|
||||
+ timeouts = null
|
||||
+ type = (known after apply)
|
||||
+ vmid = (known after apply)
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
После подтверждения команды, будет создан файл состояния инфраструктуры, в который запишутся данные.
|
||||
### Обращение к конфигурации, созданной с помощью for_each
|
||||
Получить доступ к ресурсам, созданным с помощью for_each можно по сл. схеме:
|
||||
```
|
||||
<resource_type>.<resource_name>["<key>"]
|
||||
```
|
||||
Пример получения доступа к ресурсу disk-2:
|
||||
```
|
||||
decort_disk.disks["disk-2"]
|
||||
```
|
||||
Чтобы получить доступ к полям, которые содержит ресурс:
|
||||
```
|
||||
<resource_type>.<resource_name>["<key>"].<field_name>
|
||||
```
|
||||
Например, для получения account_id для disk-2:
|
||||
```
|
||||
decort_disk.disks["disk-2"].account_id
|
||||
```
|
||||
### Использование for_each для более сложной конфигурации
|
||||
Иногда, необходимо объединить несколько ресурсов с разной конфигурацией в один ресурс, с помощью for_each. Для того, чтобы это сделать, необходимо воспользоваться функцией for для перебора информации о каждом ресурсе, в котором так же необходимо указать какое из полей будет указывать на определенный ресурс.
|
||||
Рассмотрим более сложный пример создания нескольких дисков:
|
||||
```terraform
|
||||
#создание массива из объектов, описывающих инфраструктуру
|
||||
locals {
|
||||
disks = [
|
||||
{
|
||||
account_id = 777
|
||||
diskname = "test-disk"
|
||||
disk2_gb = 100
|
||||
gid = 212
|
||||
},
|
||||
{
|
||||
account_id = 778
|
||||
diskname = "test-disk-1"
|
||||
disk2_gb = 200
|
||||
gid = 213
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
resource "decort_disk" "disks" {
|
||||
#цикл for проходит по каждому элементы списка, превращая его в объект, где
|
||||
#ключом будет - имя диска
|
||||
#знаяением - сам диск
|
||||
for_each = { for disk in local.disks : disk.diskname => disk }
|
||||
#получение account_id каждого диска
|
||||
account_id = each.value.account_id
|
||||
#шаблон задания имени диска
|
||||
#так же, если не надо вносить изменения, можно использовать:
|
||||
#disk_name = each.value.diskname
|
||||
disk_name = "${each.value.diskname}-data"
|
||||
#получение размера диска
|
||||
size_max = each.value.disk2_gb
|
||||
#получение gid диска
|
||||
gid = each.value.gid
|
||||
}
|
||||
```
|
||||
Таким образом, будут созданы ресурсы с разной конфигурацией.
|
||||
## Мета аргумент count
|
||||
Мета аргумент count так же служит для множественного создания ресурсов, объединяя их в один, с тем лишь исключением, что это будет массив, а не объект.
|
||||
Аргумент count принимает на вход либо число, либо выражение, которое возвращает число.
|
||||
Число - количество итерацией, которые предстоит произвести.
|
||||
Например:
|
||||
```terraform
|
||||
count = 3
|
||||
count = length(some_data)
|
||||
```
|
||||
Рассмотрим пример:
|
||||
```terraform
|
||||
#без изменений
|
||||
locals {
|
||||
disk_names = [
|
||||
"disk-1",
|
||||
"disk-2",
|
||||
]
|
||||
}
|
||||
|
||||
#без изменений, ресурс так же называется - "disks"
|
||||
resource "decort_disk" "disks" {
|
||||
#Используется функция length для подсчета длины списка имен дисков
|
||||
count = length(local.disk_names)
|
||||
account_id = 777
|
||||
#аргумент count имеет поле index, которое возвращает индекс(счетчик) текущей итерации
|
||||
disk_name = local.disk_names[count.index]
|
||||
size_max = 10
|
||||
gid = 212
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = decort_disk.disks
|
||||
}
|
||||
```
|
||||
|
||||
При выполнении данной конфигурации в terraform output будет следующее:
|
||||
```
|
||||
Changes to Outputs:
|
||||
+ test = [
|
||||
+ {
|
||||
+ account_id = 777
|
||||
+ account_name = (known after apply)
|
||||
+ acl = (known after apply)
|
||||
+ boot_partition = (known after apply)
|
||||
+ compute_id = (known after apply)
|
||||
+ compute_name = (known after apply)
|
||||
+ created_time = (known after apply)
|
||||
+ deleted_time = (known after apply)
|
||||
+ desc = (known after apply)
|
||||
+ destruction_time = (known after apply)
|
||||
+ detach = false
|
||||
+ devicename = (known after apply)
|
||||
+ disk_id = (known after apply)
|
||||
+ disk_name = "disk-1"
|
||||
+ disk_path = (known after apply)
|
||||
+ gid = 212
|
||||
+ guid = (known after apply)
|
||||
+ id = (known after apply)
|
||||
+ image_id = (known after apply)
|
||||
+ images = (known after apply)
|
||||
+ iotune = (known after apply)
|
||||
+ iqn = (known after apply)
|
||||
+ login = (known after apply)
|
||||
+ milestones = (known after apply)
|
||||
+ order = (known after apply)
|
||||
+ params = (known after apply)
|
||||
+ parent_id = (known after apply)
|
||||
+ passwd = (known after apply)
|
||||
+ pci_slot = (known after apply)
|
||||
+ permanently = false
|
||||
+ pool = (known after apply)
|
||||
+ purge_attempts = (known after apply)
|
||||
+ purge_time = (known after apply)
|
||||
+ reality_device_number = (known after apply)
|
||||
+ reference_id = (known after apply)
|
||||
+ res_id = (known after apply)
|
||||
+ res_name = (known after apply)
|
||||
+ restore = false
|
||||
+ role = (known after apply)
|
||||
+ sep_id = (known after apply)
|
||||
+ sep_type = (known after apply)
|
||||
+ size_max = 10
|
||||
+ size_used = (known after apply)
|
||||
+ snapshots = (known after apply)
|
||||
+ status = (known after apply)
|
||||
+ tech_status = (known after apply)
|
||||
+ timeouts = null
|
||||
+ type = (known after apply)
|
||||
+ vmid = (known after apply)
|
||||
},
|
||||
+ {
|
||||
+ account_id = 777
|
||||
+ account_name = (known after apply)
|
||||
+ acl = (known after apply)
|
||||
+ boot_partition = (known after apply)
|
||||
+ compute_id = (known after apply)
|
||||
+ compute_name = (known after apply)
|
||||
+ created_time = (known after apply)
|
||||
+ deleted_time = (known after apply)
|
||||
+ desc = (known after apply)
|
||||
+ destruction_time = (known after apply)
|
||||
+ detach = false
|
||||
+ devicename = (known after apply)
|
||||
+ disk_id = (known after apply)
|
||||
+ disk_name = "disk-2"
|
||||
+ disk_path = (known after apply)
|
||||
+ gid = 212
|
||||
+ guid = (known after apply)
|
||||
+ id = (known after apply)
|
||||
+ image_id = (known after apply)
|
||||
+ images = (known after apply)
|
||||
+ iotune = (known after apply)
|
||||
+ iqn = (known after apply)
|
||||
+ login = (known after apply)
|
||||
+ milestones = (known after apply)
|
||||
+ order = (known after apply)
|
||||
+ params = (known after apply)
|
||||
+ parent_id = (known after apply)
|
||||
+ passwd = (known after apply)
|
||||
+ pci_slot = (known after apply)
|
||||
+ permanently = false
|
||||
+ pool = (known after apply)
|
||||
+ purge_attempts = (known after apply)
|
||||
+ purge_time = (known after apply)
|
||||
+ reality_device_number = (known after apply)
|
||||
+ reference_id = (known after apply)
|
||||
+ res_id = (known after apply)
|
||||
+ res_name = (known after apply)
|
||||
+ restore = false
|
||||
+ role = (known after apply)
|
||||
+ sep_id = (known after apply)
|
||||
+ sep_type = (known after apply)
|
||||
+ size_max = 10
|
||||
+ size_used = (known after apply)
|
||||
+ snapshots = (known after apply)
|
||||
+ status = (known after apply)
|
||||
+ tech_status = (known after apply)
|
||||
+ timeouts = null
|
||||
+ type = (known after apply)
|
||||
+ vmid = (known after apply)
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
### Обращение к конфигурации, созданной с помощью сount
|
||||
Получить доступ к ресурсам, созданным с помощью count можно по сл. схеме:
|
||||
```
|
||||
<resource_type>.<resource_name>[<index>]
|
||||
```
|
||||
Пример получения доступа к ресурсу disk-2:
|
||||
```
|
||||
decort_disk.disks[1]
|
||||
```
|
||||
Чтобы получить доступ к полям, которые содержит ресурс:
|
||||
```
|
||||
<resource_type>.<resource_name>[<index>].<field_name>
|
||||
```
|
||||
Например, для получения account_id для disk-2:
|
||||
```
|
||||
decort_disk.disks[1].account_id
|
||||
```
|
||||
### Использование count для более сложной конфигурации
|
||||
Иногда, необходимо объединить несколько ресурсов с разной конфигурацией в один ресурс, с помощью count. Для того, чтобы это сделать, необходимо воспользоваться функцией length для установления длины входящих параметров. После чего, обращаться к ним, получая значения, используя индекс.
|
||||
Рассмотрим более сложный пример создания нескольких дисков:
|
||||
```terraform
|
||||
#создание массива из объектов, описывающих инфраструктуру
|
||||
locals {
|
||||
disks = [
|
||||
{
|
||||
account_id = 777
|
||||
diskname = "test-disk"
|
||||
disk2_gb = 100
|
||||
gid = 212
|
||||
},
|
||||
{
|
||||
account_id = 778
|
||||
diskname = "test-disk-1"
|
||||
disk2_gb = 200
|
||||
gid = 213
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
resource "decort_disk" "disks" {
|
||||
#получение значения длины входящих параметров
|
||||
count = length(local.disks)
|
||||
#получение идентификатора аккаунта
|
||||
account_id = local.disks[count.index].account_id
|
||||
#получение имени диска
|
||||
disk_name = "${local.disks[count.index].diskname}-data"
|
||||
#получение размера диска
|
||||
size_max = local.disks[count.index].disk2_gb
|
||||
#получение gid
|
||||
gid = local.disks[count.index].gid
|
||||
}
|
||||
```
|
||||
Таким образом, будут созданы ресурсы, с разной конфигурацией.
|
||||
262
wiki/4.8.0/05.05-Удаление-ресурсов.md
Normal file
262
wiki/4.8.0/05.05-Удаление-ресурсов.md
Normal file
@@ -0,0 +1,262 @@
|
||||
Ресурсы в terraform можно как создавать, редактировать, так и удалять. При удалении ресурса, terraform провайдер производит необходимые действия на платформе, после чего очищает эти ресурсы из своего .tfstate - файла, в котором хранится состояние инфраструктуры.
|
||||
В данном разделе рассмотрены различные способы удаления ресурсов, проблемы, которые могут возникнуть, их причины, а так же способы их решить.
|
||||
|
||||
## Команда destroy
|
||||
|
||||
Для удаления ресурса, в terraform имеется команда
|
||||
|
||||
```bash
|
||||
terraform destroy
|
||||
```
|
||||
|
||||
По умолчанию, эта команда производит удаление всей инфраструктуры, описанной и сохраненной в .tfstate-файле.
|
||||
|
||||
### Влияние конфигурационного параметра permanently
|
||||
|
||||
В некоторых ресурсах terraform провайдера имеется параметр permanently, который регулирует удаление ресурса:
|
||||
|
||||
- Если флаг имеет значение - `true`, то ресурс будет мгновенно удален с платформы и восстановить его будет невозможно.
|
||||
- Если флаг имеет значение - `false` (используется по умолчанию), то ресурс будет помещен в корзину, с возможностью дальнейшего восстановления. Ресурс будет удален автоматически из корзины через 7 дней (зависит от настроек платформы).
|
||||
|
||||
#### Возможные проблемы
|
||||
|
||||
Так как terraform, при удалении ресурса, производит удаление .tfstate-файла, то при использовании фдага permanently = false, ресурс невозможно будет восстановить из конфигурационного файла инфраструктуры - при использовании `terraform apply` - будет создана новая инфраструктура. Поэтому, старую инфраструктуру необходимо импортировать, чтобы сформировать .tfstate - файл, а потом применить `terraform apply` - тогда ресурс будет восстановлен из корзины (_фича находится в разработке - доступно в ресурсе disks_, в провайдере версии 3.2.0+)
|
||||
|
||||
## Команда destroy с флагом target
|
||||
|
||||
Как и было сказано выше, команда `terraform destroy` производит удаление всей инфраструктуры. Для того, чтобы произвести удаление определенных ресурсов, используется флаг `-target`. Флаг, в качестве параметра, принимает название ресурса для удаления, вида
|
||||
|
||||
```
|
||||
<тип-ресурса>.<имя-ресурса>
|
||||
```
|
||||
|
||||
либо
|
||||
|
||||
```
|
||||
<модуль>.<имя-ресурса>
|
||||
```
|
||||
|
||||
для ресурсов, содержащихся в модулях.
|
||||
Таким образом, общая команда выглядит так:
|
||||
|
||||
```
|
||||
terraform destroy -target <тип-ресурса>.<имя-ресурса>
|
||||
```
|
||||
|
||||
или
|
||||
|
||||
```
|
||||
terraform destroy -target <модуль>.<имя-ресурса>
|
||||
```
|
||||
|
||||
В примерах не используется модуль, поэтому, далее, в качестве примера, будет взята команда `terraform destroy -target <тип-ресурса>.<имя-ресурса>`
|
||||
|
||||
### Способы передачи параметра
|
||||
|
||||
1. `terraform destroy -target <тип-ресурса>.<имя-ресурса>`
|
||||
2. `terraform destroy -target="<тип-ресурса>.<имя-ресурса>"`
|
||||
|
||||
### Пример использования target
|
||||
|
||||
В качестве примера возьмем пример конфигурации из [прошлой статьи](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/05.04-Массовое-создание-ресурсов.-Мета-аргументы.md):
|
||||
|
||||
```terraform
|
||||
resource "decort_disk" "disk1" {
|
||||
account_id = 777
|
||||
disk_name = "disk-1"
|
||||
size_max = 10
|
||||
gid = 212
|
||||
}
|
||||
|
||||
resource "decort_disk" "disk2" {
|
||||
account_id = 777
|
||||
disk_name = "disk-2"
|
||||
size_max = 10
|
||||
gid = 212
|
||||
}
|
||||
```
|
||||
|
||||
- Чтобы удалить всю инфраструктуру, необходимо просто выполнить в терминале команду
|
||||
|
||||
```bash
|
||||
terraform destroy
|
||||
```
|
||||
|
||||
- Чтобы удалить "disk2", можно воспользоваться командой:
|
||||
|
||||
```
|
||||
terraform destroy -target decort_disk.disk2
|
||||
```
|
||||
|
||||
- Чтобы удалить "disk1", можно воспользоваться другим способом удаления:
|
||||
|
||||
```
|
||||
terraform destroy -target="decort_disk.disk1"
|
||||
```
|
||||
|
||||
Таким образом, определенный ресурс можно удалить с помощью флага target.
|
||||
|
||||
### Использование флага target при работе с ресурсами, созданными с помощью мета аргументов.
|
||||
|
||||
При создании ресурсов с помощью мета аргументов, первые получают дополнительные символы в именах ресурсов, что может привести к некоторым проблемам при работе с такими ресурсами.
|
||||
|
||||
#### Работа с for_each
|
||||
|
||||
При работе с for_each, ресурс получается имя вида: `<тип-ресурса>.<общее-имя-ресурса>["<название>"]`
|
||||
Таким образом, обращение к такому ресурсу будет выглядит следующим образом:
|
||||
|
||||
```
|
||||
terraform destroy -target='<тип-ресурса>.<общее-имя-ресурса>[\"<название>\"]'
|
||||
```
|
||||
|
||||
или
|
||||
|
||||
```
|
||||
terraform destroy -target '<тип-ресурса>.<общее-имя-ресурса>[\"<название>\"]'
|
||||
```
|
||||
|
||||
Пример:
|
||||
Для примера рассмотрим создание ресурса с помощью мета аргумента for_each из предыдущей статьи:
|
||||
|
||||
```terraform
|
||||
locals {
|
||||
disk_names = [
|
||||
"disk-1",
|
||||
"disk-2",
|
||||
]
|
||||
}
|
||||
|
||||
resource "decort_disk" "disks" {
|
||||
for_each = toset(local.disk_names)
|
||||
account_id = 777
|
||||
disk_name = each.key
|
||||
size_max = 10
|
||||
gid = 212
|
||||
}
|
||||
```
|
||||
|
||||
В результате применения команды `terrafrom apply`, будут созданы ресурсы с именами:
|
||||
|
||||
- decort_disk.disks["disk-1"]
|
||||
- decort_disk.disks["disk-2"]
|
||||
Чтобы удалить определенный ресурс, можно воспользоваться одной из команд:
|
||||
|
||||
```
|
||||
#для удаления disk-1
|
||||
terraform destroy -target='decort_disk.disks[\"disk-1\"]'
|
||||
```
|
||||
|
||||
```
|
||||
#для удаления disk-2
|
||||
terraform destroy -target 'decort_disk.disks[\"disk-2\"]'
|
||||
```
|
||||
|
||||
Либо:
|
||||
|
||||
```
|
||||
#для удаления всей инфраструктуры
|
||||
terraform destroy
|
||||
```
|
||||
|
||||
Такая запись с экранирование кавычек обуславливается работой терминальной оболочки, через которую будет производится вызов данной команды, а так же то, что terraform в качестве параметра флага ожидает строку. Так же, есть еще одно правило - в terraform в квадратных скобках указывается либо строка в двойных кавычках (в качестве имени ключа для объекта, используется для for_each), либо число - в качестве индекса для массива (используется для count)
|
||||
|
||||
#### Работа с count
|
||||
|
||||
При работе с count, ресурс получается имя вида: `<тип-ресурса>.<общее-имя-ресурса>[<индекс>]`
|
||||
Таким образом, обращение к такому ресурсу будет выглядит следующим образом:
|
||||
|
||||
```
|
||||
terraform destroy -target="<тип-ресурса>.<общее-имя-ресурса>[<индекс>]"
|
||||
```
|
||||
|
||||
или
|
||||
|
||||
```
|
||||
terraform destroy -target <тип-ресурса>.<общее-имя-ресурса>[<индекс>]
|
||||
```
|
||||
|
||||
Пример:
|
||||
Для примера рассмотрим создание ресурса с помощью мета аргумента for_each из предыдущей статьи:
|
||||
|
||||
```terraform
|
||||
locals {
|
||||
disk_names = [
|
||||
"disk-1",
|
||||
"disk-2",
|
||||
]
|
||||
}
|
||||
|
||||
resource "decort_disk" "disks" {
|
||||
count = length(local.disk_names)
|
||||
account_id = 777
|
||||
disk_name = local.disk_names[count.index]
|
||||
size_max = 10
|
||||
gid = 212
|
||||
}
|
||||
```
|
||||
|
||||
В результате применения команды `terrafrom apply`, будут созданы ресурсы с именами:
|
||||
|
||||
- decort_disk.disks[0]
|
||||
- decort_disk.disks[1]
|
||||
Чтобы удалить определенный ресурс, можно воспользоваться одной из команд:
|
||||
|
||||
```
|
||||
#для удаления disk-1
|
||||
terraform destroy -target="decort_disk.disks[0]"
|
||||
```
|
||||
|
||||
```
|
||||
#для удаления disk-2
|
||||
terraform destroy -target decort_disk.disks[1]
|
||||
```
|
||||
|
||||
Либо:
|
||||
|
||||
```
|
||||
#для удаления всей инфраструктуры
|
||||
terraform destroy
|
||||
```
|
||||
|
||||
### Удаление ресурса из состояния
|
||||
|
||||
В ходе работы, могут возникать случаи, когда состояние (state, стейт) terraform имеет ресурсы, которые были удалены с платформы. В таком случае, можно, при выполнении команд `terraform plan/apply` получить ошибку:
|
||||
|
||||
```bash
|
||||
Planning failed. Terraform encountered an error while generating this plan.
|
||||
|
||||
╷
|
||||
│ Error: The resource cannot be updated because it has been destroyed
|
||||
│
|
||||
│ with decort_kvmvm.instances["pgsmonsietc03"],
|
||||
│ on main.tf line 33, in resource "decort_kvmvm" "instances":
|
||||
│ 33: resource "decort_kvmvm" "instances" {
|
||||
```
|
||||
|
||||
Либо, в ходе неверного выполнения может возникнуть подобная ошибка:
|
||||
|
||||
```bash
|
||||
╷
|
||||
│ Error: Failed to read the given file as a state or plan file
|
||||
│
|
||||
│ State read error: Error loading statefile: open data.decort_cb_vins.vins: no such file or directory
|
||||
│
|
||||
│ Plan read error: open data.decort_cb_vins.vins: no such file or directory
|
||||
```
|
||||
|
||||
Для того, чтобы этого избежать, необходимо удалить отсутствующий ресурс из стейта, выполнив команду `terraform state rm <res>.<name>`
|
||||
Например, `terraform state rm decort_kvmvm.vm1`
|
||||
|
||||
В случае, если ресурс был создан путен работы генераторов count/for_each, работают те же правила, что и для команды `terraform destroy`.
|
||||
|
||||
## Возможные проблемы
|
||||
|
||||
Были обнаружены проблемы при использовании _oh my zsh_, которые заключались в том, что не считывались данные, переданные, при экранировании строки.
|
||||
Рекомендация: использовать _bash_.
|
||||
|
||||
## Заключение
|
||||
|
||||
Таким образом, terraform позволяет выполнять удаление:
|
||||
|
||||
- всей инфраструктуры, хранящейся в файле .tfstate с помощью `terraform destroy`
|
||||
- части инфраструктуры, используя флаг target. ОБщий вид команды такой: `terraform destroy -target <тип-ресурса>.<имя-ресурса>`
|
||||
46
wiki/4.8.0/05.06-Установка-Terraform.md
Normal file
46
wiki/4.8.0/05.06-Установка-Terraform.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Установка Terraform
|
||||
На момент написания инструкции, приложение Terraform по прямой ссылке с сайта-разработчика программного обеспечения невозможно скачать, по этой же причине, невозможно произвести установку с помощью разных пакетных менеджеров.
|
||||
Существует два способа произвести установку приложения:
|
||||
- Скачать скомпилированное приложение с зеркала компании Digital Energy.
|
||||
- Из исходных кодов.
|
||||
## Скачивание и установка скомпилированного приложения с зеркала компании Digital Energy
|
||||
1. Перейти по ссылке https://colba.decs.online/index.php/s/JfkXWbwTqww64Tz , выбрать версию terraform для подходящей ОС.
|
||||
2. Скачать архив.
|
||||
3. Разархивировать приложение и переместить:
|
||||
- Для Linux или MacOS: `/usr/local/bin`
|
||||
- Для Windows: в любую папку, после чего добавить в $PATH в переменных окружения путь до приложения
|
||||
4. Ввести в терминале `terraform -help`, в случае успеха, на экран будет информация о программе.
|
||||
### Указание переменных среды окружения в Windows
|
||||
Меню -> Панель управления -> Система -> Настройки -> Переменные окружения
|
||||
Или
|
||||
Поиск -> Изменение системных переменных среды
|
||||
В открывшемся окне -> Переменные среды
|
||||
Далее, необходимо выбрать переменную Path -> Изменить
|
||||
Создать -> ввести путь до файла -> ОК
|
||||
## Из исходных кодов
|
||||
Для компилирования приложения потребуется:
|
||||
- Компилятор языка программирования GO
|
||||
- Система контроля версий git
|
||||
- Исходные файлы приложения.
|
||||
Сначала необходимо скачать и установить компилятор языка программирования GO. Для этого, необходимо перейти по ссылке https://go.dev/doc/install . На странице сайта будет автоматически представлена последняя версия компилятора подходящая операционной системе.
|
||||
Далее, необходимо скачать и установить систему контроля версий git (https://git-scm.com/), на сайте будет так же автоматически предложена самая последняя и подходящая версия.
|
||||
После установки компилятора и системы контроля версий, необходимо произвести клонирование исходных кодов приложения. Выполнить это можно, введя в терминале следующую команду:
|
||||
```bash
|
||||
git clone https://github.com/hashicorp/terraform.git
|
||||
```
|
||||
Обратите внимание, что клонирование будет происходить в директорию, из которой происходил вызов команды.
|
||||
После клонирования, можно приступить к сборке приложения.
|
||||
Для этого необходимо перейти в каталог, в который произошло клонирование исходных кодов и выполнить команду в терминале:
|
||||
```bash
|
||||
go install
|
||||
```
|
||||
Или
|
||||
```bash
|
||||
go build
|
||||
```
|
||||
Результатом выполнения данной программы станет бинарный файл terraform.
|
||||
Полученный файл необходимо поместить в каталог `/usr/local/bin` для MacOS или Linux, либо в любой каталог и указать его путь в переменных окружения для ОС Windows.
|
||||
После всех действий, команда `terraform -help` должна выводить информацию в терминал.
|
||||
Полезные ссылки:
|
||||
- https://learn.hashicorp.com/tutorials/terraform/install-cli
|
||||
- https://stackoverflow.com/questions/1618280/where-can-i-set-path-to-make-exe-on-windows
|
||||
179
wiki/4.8.0/05.07-Миграция-k8s-кластеров-на-версию-4.2.0.md
Normal file
179
wiki/4.8.0/05.07-Миграция-k8s-кластеров-на-версию-4.2.0.md
Normal file
@@ -0,0 +1,179 @@
|
||||
Начиная с версии `4.2.0` провайдера была добавлена новая логика работы с k8s кластерами. Заключается она в разделении ответственности между двумя ресурсами:
|
||||
- `decort_k8s_cp` - используется для первичного создания и управления control plane кластера
|
||||
- `decort_k8s_wg` - используется для управления worker-группами
|
||||
|
||||
### `decort_k8s_cp` - мастер-узел кластера
|
||||
В отличии от ресурса `decort_k8s` не имеет возможности управления worker-группами и может быть создан без указания названия дефолтной группы. При успешном создании ресурса, кластер будет создан без рабочих узлов.
|
||||
|
||||
### `decort_k8s_wg` - worker-группы кластера
|
||||
Ресурс используется для создания, удаления или изменения рабочих узлов, которых у одного кластера может быть как ни одного, так и множество.
|
||||
|
||||
**При использовании `decort_k8s_cp` не рекомендуется параллельное использование `decort_k8s` для управления одним и тем же кластером во избежание проблем с идемпотентностью** <br/>
|
||||
|
||||
## Инструкция по миграции созданных кластеров
|
||||
|
||||
Ниже приведен пример ресурса, миграция которого будет проведена:
|
||||
```terraform
|
||||
resource "decort_k8s" "cluster" {
|
||||
name = "tf-wiki"
|
||||
rg_id = 1649
|
||||
k8sci_id = 55
|
||||
extnet_id = 13
|
||||
wg_name = "wiki-wg"
|
||||
network_plugin = "flannel"
|
||||
|
||||
# Описание мастер-узла
|
||||
masters {
|
||||
cpu = 2
|
||||
ram = 2048
|
||||
num = 3
|
||||
disk = 15
|
||||
}
|
||||
|
||||
# Описание дефолтной воркер-группы
|
||||
workers {
|
||||
name = "wiki-wg"
|
||||
cpu = 1
|
||||
num = 1
|
||||
ram = 1024
|
||||
disk = 15
|
||||
}
|
||||
|
||||
# Описание дополнительной воркер-группы
|
||||
workers {
|
||||
name = "additional-wg"
|
||||
cpu = 1
|
||||
num = 1
|
||||
ram = 1024
|
||||
disk = 15
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Для начала, создадим в файле конфигурации ресурс `decort_k8s_cp`:
|
||||
```terraform
|
||||
resource "decort_k8s_cp" "control_plane" {}
|
||||
```
|
||||
|
||||
2. Выполним команду импортирования с указанием ID кластера:
|
||||
```
|
||||
terraform import decort_k8s_cp.<CP_NAME> <K8s_ID>
|
||||
```
|
||||
Для кластера выше:
|
||||
```
|
||||
terraform import decort_k8s_cp.control_plane 556
|
||||
```
|
||||
|
||||
2.1: В случае, если в кластере присутствуют worker группы, провайдер напомнит об этом:
|
||||
```
|
||||
Warning: Found worker-group with ID 1353. Make sure to import it to decort_k8s_wg resource if you wish to manage it
|
||||
|
||||
Warning: Found worker-group with ID 1354. Make sure to import it to decort_k8s_wg resource if you wish to manage it
|
||||
```
|
||||
|
||||
3. После этого, заполним поля ресурса данными из `decort_k8s`:
|
||||
```terraform
|
||||
resource "decort_k8s_cp" "control_plane" {
|
||||
name = "tf-wiki"
|
||||
rg_id = 1649
|
||||
k8sci_id = 55
|
||||
extnet_id = 13
|
||||
network_plugin = "flannel"
|
||||
|
||||
# Описание мастер-узла вынесено в корень ресурса
|
||||
cpu = 2
|
||||
num = 2048
|
||||
num = 3
|
||||
disk = 15
|
||||
|
||||
# Данных о рабочих узлов в ресурсе нет - они описываются в decort_k8s_wg
|
||||
}
|
||||
```
|
||||
|
||||
4. В случае, если есть уже созданные рабочие узлы, стоит добавить ресурсы `decort_k8s_wg` для каждого в конфигурационный файл:
|
||||
```terraform
|
||||
resource "decort_k8s_wg" "<WG1_NAME> {
|
||||
# Для удобства можно сразу указать k8s_id из ранее созданного ресурса decort_k8s_cp
|
||||
k8s_id = decort_k8s_cp.<CP_NAME>.k8s_id
|
||||
}
|
||||
```
|
||||
4.1 Для кластера в примере:
|
||||
```terraform
|
||||
resource "decort_k8s_wg" "wg1" {
|
||||
k8s_id = decort_k8s_cp.control_plane.k8s_id
|
||||
name = "wiki-wg"
|
||||
cpu = 1
|
||||
num = 1
|
||||
ram = 1024
|
||||
disk = 15
|
||||
}
|
||||
|
||||
resource "decort_k8s_wg" "wg2" {
|
||||
k8s_id = decort_k8s_cp.control_plane.k8s_id
|
||||
name = "additional-wg"
|
||||
cpu = 1
|
||||
num = 1
|
||||
ram = 1024
|
||||
disk = 15
|
||||
}
|
||||
```
|
||||
|
||||
5. Выполним команду `terraform import` (отдельно для каждого ресурса):
|
||||
```
|
||||
terraform import decort_k8s_wg.<WG1_NAME> <WG_ID>#<K8s_ID>
|
||||
```
|
||||
```
|
||||
terraform import decort_k8s_wg.wg1 1353#556
|
||||
|
||||
terraform import decort_k8s_wg.wg2 1354#556
|
||||
```
|
||||
6. В случае успеха, команда `terraform plan` успешно завершится со статусом*:
|
||||
```
|
||||
No changes. Your infrastructure matches the configuration.
|
||||
```
|
||||
**кроме случаев, когда терраформ пытается записать автоматически генерируемые (дефолтные) значения параметров в стейт (например, start меняется с null на true) или ресурс был изменен вне терраформа*<br/>
|
||||
|
||||
7. После успешной миграции стоит удалить описание ресурса `decort_k8s`.
|
||||
|
||||
8. Теперь k8s кластер находится под полным управлением terraform.
|
||||
|
||||
### Конф. файл после всех изменений:
|
||||
```terraform
|
||||
resource "decort_k8s_cp" "control_plane" {
|
||||
name = "tf-wiki"
|
||||
rg_id = 1649
|
||||
k8sci_id = 55
|
||||
extnet_id = 13
|
||||
network_plugin = "flannel"
|
||||
|
||||
# Описание мастер-узла вынесено в корень ресурса
|
||||
cpu = 2
|
||||
num = 2048
|
||||
num = 3
|
||||
disk = 15
|
||||
|
||||
# Данных о рабочих узлов в ресурсе нет - они описываются в decort_k8s_wg
|
||||
}
|
||||
|
||||
resource "decort_k8s_wg" "wg1" {
|
||||
k8s_id = decort_k8s_cp.control_plane.k8s_id
|
||||
name = "wiki-wg"
|
||||
cpu = 1
|
||||
num = 1
|
||||
ram = 1024
|
||||
disk = 15
|
||||
}
|
||||
|
||||
resource "decort_k8s_wg" "wg2" {
|
||||
k8s_id = decort_k8s_cp.control_plane.k8s_id
|
||||
name = "additional-wg"
|
||||
cpu = 1
|
||||
num = 1
|
||||
ram = 1024
|
||||
disk = 15
|
||||
}
|
||||
```
|
||||
|
||||
## P. S
|
||||
1. После успешной миграции **не рекомендуется** использовать `decort_k8s` параллельно с `decort_k8s_cp` - это может привести к нежелательным проблемам идемпотентности
|
||||
2. При удалении `decort_k8s_cp` удалится как сам кластер, так и все зависимые воркер-группы, а соответственно и `decort_k8s_wg`
|
||||
@@ -0,0 +1,4 @@
|
||||
В данном разделе представлены _data_source_ функции провайдера.
|
||||
Все функции разделены на две группы:
|
||||
- Пользовательская группа
|
||||
- Административная группа
|
||||
1
wiki/4.8.0/06.01-Пользовательская-группа-API.md
Normal file
1
wiki/4.8.0/06.01-Пользовательская-группа-API.md
Normal file
@@ -0,0 +1 @@
|
||||
В данном разделе представлены функции для взаимодействия с пользовательской группой API.
|
||||
289
wiki/4.8.0/06.01.01-Data_decort_kvmvm.md
Normal file
289
wiki/4.8.0/06.01.01-Data_decort_kvmvm.md
Normal file
@@ -0,0 +1,289 @@
|
||||
_Data source_ функция **decort_kvmvm** служит для получения информации об уже существующей в облачной платформе виртуальной машине (Virtual Machine, VM), созданной на базе системы виртуализации KVM.
|
||||
|
||||
## Аргументы
|
||||
_Data source_ функция **decort_kvmvm** принимает следующие аргументы:
|
||||
|
||||
| Аргумент | Тип | Обязательный | Описание |
|
||||
| --- | --- | --- | --- |
|
||||
| compute_id | int | :heavy_check_mark: | Идентификатор экземпляра _compute_, соответствующего данной виртуальной машине (подробнее о понятии _compute_ см. в разделе [Обзор облачной платформы DECORT](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/03.-Обзор-облачной-платформы-DECORT.md)). |
|
||||
|
||||
Пользователь облачной платформы, от лица которого происходит обращение к данной функции, должен иметь доступ к указанному виртуальному серверу и ресурсной группе. В противном случае возникнет ошибка доступа.
|
||||
|
||||
Пользователь облачной платформы задается на стадии инициализации Terraform провайдера DECORT (см. [подробности](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/04.02-Инициализация-Terraform-провайдера-DECORT.md)).
|
||||
|
||||
## Возвращаемые значения
|
||||
В случае успешного выполнения _data source_ функция **decort_kvmvm** возвращает в указанную при вызове переменную следующие значения:
|
||||
|
||||
| Параметр | Тип | Описание
|
||||
| --- | --- | --- |
|
||||
| acl | []Struct [см. ниже](#описание-структуры-acl) | Cписок Acces Control |
|
||||
| account_id | int | Уникальный идентификатор подписчика-владельца ("account") данной виртуальной машины |
|
||||
| account_name | string | Имя подписчика, которому принадлежит данная виртуальная машина |
|
||||
| affinity_label | string | Лейбл аффинити |
|
||||
| affinity_rules | []Struct [см. ниже](#описание-структуры-affinity-rules) | Правила аффинити для компьютов |
|
||||
| affinity_weight | int | weight аффинити |
|
||||
| arch | string | Архитектура |
|
||||
| auto_start_w_node | bool | Автостарт при рестарте ноды |
|
||||
| boot_order | []string | Boot order |
|
||||
| boot_disk_id | int | Идентификатор загрузочного диска виртуальной машины |
|
||||
| boot_disk_size | int | Размер загрузочного диска в ГБ |
|
||||
| chipset | string | Тип эмулируемой системы |
|
||||
| cd_image_id | int | ID cd image id |
|
||||
| clone_reference | int | кол-во клонов |
|
||||
| clones | []int | id клонов |
|
||||
| computeci_id | int | Id computeci |
|
||||
| cpu_pin | bool | Необходимость запускать ВМ на выделенных CPU ядрах |
|
||||
| cpus | int | Количество виртуальных CPU, выделенных данному серверу |
|
||||
| created_by | string | Кем создан ресурс |
|
||||
| created_time | int | Время создания ресурса |
|
||||
| custom_fields | []Struct [см. ниже](#описание-структуры-custom-fields) | Кастомные поля |
|
||||
| deleted_by | string | Кем удален ресурс |
|
||||
| deleted_time | int | Время удаления ресурса |
|
||||
| desc | string | Текстовое описание виртуальной машины |
|
||||
| devices | string | Девайсы |
|
||||
| disks | []Struct [см. ниже](#описание-структуры-disks) | информация о дисках компьюта |
|
||||
| driver | string | Аппаратная архитектура данной виртуальной машины |
|
||||
| gid | int | GID |
|
||||
| guid | int | GUID |
|
||||
| hp_backed | bool | Необходимость использовать для выделения RAM виртуальной машины Huge Pages ядрах |
|
||||
| image_id | int | Идентификатор образа ОС, на базе которого создан загрузочный диск этой виртуальной машины |
|
||||
| image_name | string | Имя образа ОС, на базе которого создан загрузочный диск этой виртуальной машины |
|
||||
| interfaces | []Struct [см. ниже](#описание-структуры-interfaces) | Информация о интерфейсах компьюта |
|
||||
| lock_status | string | Статус доступности |
|
||||
| manager_id | int | Manager id |
|
||||
| manager_type | string | Type manager |
|
||||
| migrationjob | int | Migrationjob |
|
||||
| milestones | int | Вехи |
|
||||
| name | string | Имя виртуального сервера |
|
||||
| natable_vins_id | int | NAT vins id |
|
||||
| natable_vins_ip | string | NAT vins ip |
|
||||
| natable_vins_name | string | NAT vins name |
|
||||
| natable_vins_network | string | NAT vins network |
|
||||
| natable_vins_network_name | string | NAT vins network name |
|
||||
| need_reboot | bool | флаг, указывающий, что требуется перезагрузка |
|
||||
| numa_affinity | string | Необходимость выравнивать ВМ по NUMA |
|
||||
| numa_node_id | int | ID узла NUMA |
|
||||
| os_users | []Struct [см. ниже](#описание-структуры-os-users) | Имена и пароли пользователей гостевой ОС, установленные платформой при создании виртуального сервера. Формат структуры:<br/>* (string) `login` - учётная запись в гостевой ОС.<br/>* (string) `password` - пароль к этой учётной записи. |
|
||||
| pinned | bool | добавлен ли компьют на стек |
|
||||
| ram | int | Объём оперативной памяти в МБ, выделенной этой виртуальной машине |
|
||||
| reference_id | string | ID reference |
|
||||
| registered | bool | Компьют зарегестрирован |
|
||||
| res_name | string | Res name |
|
||||
| reserved_node_cpus | []int | Количество зарезервированных CPU в узле |
|
||||
| rg_id | int | Идентификатор ресурсной группы, к которой принадлежит виртуальная машина |
|
||||
| rg_name | string | Имя ресурсной группы, к которой принадлежит виртуальная машина |
|
||||
| snap_sets | []Struct [см. ниже](#описание-структуры-snap-sets) | Snap sets |
|
||||
| status | string | Cтатус |
|
||||
| tags | map[string]string | Тэги |
|
||||
| tech_status | string | Технический статус |
|
||||
| updated_by | string | Кем обновлен ресурс |
|
||||
| updated_time | int | Время обновления ресурса |
|
||||
| user_managed | bool | User managed |
|
||||
| pci_devices | []int | Список PCI девайсов |
|
||||
| userdata | string | Параметры cloud_init |
|
||||
| vnc_password | string | vnc пароль |
|
||||
| vgpus | []int | Список vgpu |
|
||||
| virtual_image_id | int | ID виртуального образа |
|
||||
| virtual_image_name | string | Имя образа ОС, на базе которого создан загрузочный диск этой виртуальной машины |
|
||||
|
||||
### Описание структуры acl
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| account_acl | []Struct [см. ниже](#описание-структуры-List-acl) | Информация о списке пользователей аккаунтов |
|
||||
| compute_acl | []Struct [см. ниже](#описание-структуры-List-acl) | Информация о списке пользователей компьютов |
|
||||
| rg_acl | []Struct [см. ниже](#описание-структуры-List-acl) | Информация о списке пользователей ресурной группы |
|
||||
|
||||
### Описание структуры affinity rules
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| guid | string | guid |
|
||||
| key | string | Ключ |
|
||||
| mode | string | Режим сравнения |
|
||||
| policy | string | Степень "строгости" этого правила |
|
||||
| topology | string | Топология |
|
||||
| value | string | Значение |
|
||||
|
||||
### Описание структуры List acl
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| explicit | bool | Явно ли указан доступ |
|
||||
| guid | string | guid Ресурса |
|
||||
| right | string | Права на ресурс |
|
||||
| status | string | Статус ресурса |
|
||||
| type | string | Тип ресурса |
|
||||
| user_group_id | string | ID user group |
|
||||
|
||||
### Описание структуры custom fields
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| key | string | Ключ |
|
||||
| val | string | Значение |
|
||||
|
||||
### Описание структуры os users
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| guid | string | GUID |
|
||||
| login | string | Логин |
|
||||
| password | string | Пароль |
|
||||
| public_key | string | Публичный ssh ключ |
|
||||
|
||||
### Описание структуры disks
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| _ckey | string | ckey |
|
||||
| acl | string | Acces Control List |
|
||||
| account_id | int | ID аккаунта |
|
||||
| bus_number | int | Номер шины |
|
||||
| boot_partition | int | Загрузочный раздел |
|
||||
| created_time | int | Время создания диска |
|
||||
| deleted_time | int | Время удаления диска |
|
||||
| description | string | Описание |
|
||||
| destruction_time | int | Время удаления |
|
||||
| disk_path | string | Путь диска |
|
||||
| gid | int | GID |
|
||||
| guid | int | GUID |
|
||||
| disk_id | int | ID диска |
|
||||
| image_id | int | ID образа |
|
||||
| images | []int | Список образов |
|
||||
| iotune | []Struct [см. ниже](#описание-структуры-iotune) | Ограничения диска |
|
||||
| iqn | string | iqn диска |
|
||||
| login | string | Логин для доступа к диску |
|
||||
| milestones | int | Вехи |
|
||||
| name | string | Наименование диска |
|
||||
| order | int | Номер диска |
|
||||
| params | string | Параметры диска |
|
||||
| parent_id | int | id родительского диска |
|
||||
| passwd | string | Пароль для доступа к диску |
|
||||
| pci_slot | int | id pci слота, к которому подключен диск |
|
||||
| pool | string | Имя пула в системе хранения, на ресурсах которой размещён данный диск |
|
||||
| present_to | []int | Список ID ресурсов, которым предоставлен диск |
|
||||
| purge_time | int | Время последней попытки |
|
||||
| replication | Struct{} [см. ниже](#описание-структуры-replication) | Информация о реплике диска |
|
||||
| reality_device_number | int | Реальный номер устройства |
|
||||
| res_id | int | id ресурса |
|
||||
| role | string | Роль диска |
|
||||
| sep_id | int | Идентификатор Storage Endpoint Provider (SEP). SEP это способ идентифицировать конкретную систему хранения, на ресурсах которой размещён данный диск |
|
||||
| shareable | bool | Флаг, отвечающий за доступность диска дургим ресурсам |
|
||||
| size_max | int | Размер диска в ГБ |
|
||||
| size_used | float | Кол-во используемого места, в ГБ |
|
||||
| snapshots | []Struct{}[см. ниже](#описание-структуры-snapshots) | Снимки состояния диска |
|
||||
| status | string | Статус диска |
|
||||
| tech_status | string | Технический статус диска |
|
||||
| type | string | Тип диска с точки зрения его роли в составе _compute_. Может принимать одно из фиксированных значений:<br/>"B" - признак загрузочного диска ("boot").<br/>"D" - признак дополнительного диска ("data") |
|
||||
| vmid | int | Идентификатор виртуальной машины (устаревшее) |
|
||||
|
||||
### Описание структуры iotune
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| read_bytes_sec | int | Кол-во байт для чтения в секунду |
|
||||
| read_bytes_sec_max | int | Максимальное кол-во байт для чтения |
|
||||
| read_iops_sec | int | Кол-во операций чтения io в секунду | |
|
||||
| read_iops_sec_max | int | Максимальное число io операций чтения |
|
||||
| size_iops_sec | int | Размер io операций |
|
||||
| total_bytes_sec | int | Общий размер байт в секунду |
|
||||
| total_bytes_sec_max | int | Максимальный общий размер байт в секунду |
|
||||
| total_iops_sec | int | Общее кол-во io операций в секунду |
|
||||
| total_iops_sec_max | int | Максимальное общее кол-во io операций в секунду |
|
||||
| write_bytes_sec | int | Кол-во байт для записи в секунду |
|
||||
| write_bytes_sec_max | int | Максимальное кол-во байт для записи в секунду |
|
||||
| write_iops_sec | int | Кол-во операций записи в секунду |
|
||||
| write_iops_sec_max | int | Максимальное число операций записей |
|
||||
|
||||
### Описание структуры replication
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| disk_id | int | id диска |
|
||||
| pool_id | string | id пула |
|
||||
| role | string | Роль диска (главный или реплика) |
|
||||
| self_volume_id | string | id раздела |
|
||||
| storage_id | int | id хранилища |
|
||||
| volume_id | int | id раздела |
|
||||
|
||||
### Описание структуры snapshots
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| guid | string | id снимка |
|
||||
| label | string | Наименование снимка |
|
||||
| res_id | string | Ссылка на снимок |
|
||||
| snap_set_guid | string | Установленный id снимка |
|
||||
| reference_id | int | Reference ID |
|
||||
| snap_set_time | int | Установленное время снимка |
|
||||
| timestamp | int | Время снимка |
|
||||
|
||||
### Описание структуры interfaces
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| bus_number | int | Номер шины |
|
||||
| conn_id | int | ID connect |
|
||||
| conn_type | string | Тип connect |
|
||||
| enabled | bool | Доступность подключения |
|
||||
| def_gw | string | Шлюз по умолчанию |
|
||||
| flip_group_id | int | id flip group |
|
||||
| guid | string | GUID |
|
||||
| ip_address | string | IP адрес |
|
||||
| listen_ssh | bool | открыт ли ssh connect |
|
||||
| mac | string | MAC адрес устройства |
|
||||
| mtu | string | Максимальный объём данных, который может быть передан за одну итерацию |
|
||||
| name | string | Имя |
|
||||
| net_id | int | ID сети |
|
||||
| netmask | int | Маска сети |
|
||||
| net_type | string | Тип сети |
|
||||
| node_id | int | ID узла |
|
||||
| pci_slot | int | Pci Slot |
|
||||
| qos | []Struct{}[см. ниже](#описание-структуры-qos) | QOS |
|
||||
| target | string | Цель сети |
|
||||
| type | string | Тип |
|
||||
| vnfs | []int | VNFS |
|
||||
| libvirt_settings | []Struct{}[см. ниже](#описание-структуры-libvirt_settings) | Параметры libvirt virtio интерфейса |
|
||||
|
||||
### Описание структуры libvirt_settings
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| guid | string | GUID |
|
||||
| txmode | string | TX mode |
|
||||
| ioeventfd | string | IO event |
|
||||
| event_idx | string | Event ID |
|
||||
| queues | int | Количество очередей |
|
||||
| rx_queue_size | int | Длина очереди RX |
|
||||
| tx_queue_size | int | Длина очереди TX |
|
||||
|
||||
### Описание структуры qos
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| e_rate | int | E rate |
|
||||
| guid | string | ID ресурса |
|
||||
| in_brust | int | In brust |
|
||||
| in_rate | int | In rate |
|
||||
|
||||
### Описание структуры snap sets
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| disks | []int | Список id дисков |
|
||||
| guid | string | GUID |
|
||||
| label | string | Лейбл |
|
||||
| timestamp | int | Время |
|
||||
|
||||
## Пример использования
|
||||
В нижеприведённом примере посредством вызова _data source_ функции **decort_kvmvm** извлекается информация об уже существующем в платформе виртуальном сервере со следующими характеристиками:
|
||||
* Имя сервера _MyOldVM_;
|
||||
* Идентификатор ресурсной группы, в которой находится данный сервер - 123.
|
||||
|
||||
```terraform
|
||||
data "decort_kvmvm" "comp" {
|
||||
#получение информации по идентификатору машины - compute_id
|
||||
#id виртуальной машины
|
||||
#обязательный параметр
|
||||
#тип - целое число
|
||||
compute_id = 11346
|
||||
}
|
||||
```
|
||||
|
||||
Данный пример подразумевает, что ранее по тексту tf-файла выполнена корректная инициализация провайдера (подробнее об инициализации Terraform провайдера DECORT см. соответствующий [раздел](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/04.02-Инициализация-Terraform-провайдера-DECORT.md)).
|
||||
|
||||
Чтобы получить идентификатор ресурсной группы (аргумент `rg_id`), можно воспользоваться _data source_ функцией [decort_resgroup](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/06.01.12-Data_decort_rg_list.md).
|
||||
|
||||
После успешного завершения такого вызова **decort_kvmvm** в переменной `data.decort_kvmvm.comp` будут сохранены возвращаемые значения. Так, например:
|
||||
* пароль для доступа в гостевую ОС, назначенный по умолчанию при создании VM - `"data.decort_kvmvm.comp.os_users.0.password`
|
||||
* идентификатор образа ОС, на базе которого была создана данная VM - `data.decort_kvmvm.comp.image_id`
|
||||
* текущий объём ОЗУ - `data.decort_kvmvm.comp.ram`
|
||||
128
wiki/4.8.0/06.01.02-Data_decort_resgroup.md
Normal file
128
wiki/4.8.0/06.01.02-Data_decort_resgroup.md
Normal file
@@ -0,0 +1,128 @@
|
||||
_Data source_ функция **decort_resgroup** служит для получения информации об уже существующей ресурсной группе.
|
||||
|
||||
Ресурсная группа в облачной платформе DECORT это способ группирования _compute_-ов (например, по функциональному признаку или принадлежности к одному и тому же проекту). Ресурсную группу можно рассматривать как небольшой персональный дата-центр, в котором размещаются один или несколько серверов и виртуальных сетевых сегментов (ViNS).
|
||||
|
||||
Экземпляры _compute_ (виртуальные серверы) всегда создаются в принадлежности к какой-либо ресурсной группе. Как следствие, для создания экземпляра _compute_ помимо других параметров требуется указать идентификатор целевой ресурсной группы. Для получения такого идентификатора можно воспользоваться рассматриваемой здесь _data source_ функцией **decort_resgroup**.
|
||||
|
||||
## Изменения в 3.5.0
|
||||
- Убраны опциональные поля account_id и name
|
||||
- Опциональное поле rg_id стало обязательным
|
||||
- Возвращаемые значения приведены в соответвие с версией платформы 3.8.5
|
||||
|
||||
## Изменения в 3.4.0
|
||||
- В возвращаемые значения добавлено новое поле gid
|
||||
- В возвращаемые значения добавлено новое поле resources
|
||||
- В возвращаемые значения добавлено новое поле status
|
||||
- В возвращаемые значения добавлено новое поле vins
|
||||
- В возвращаемые значения добавлено новое поле vms
|
||||
- Обязательное поле account_id изменено на опциональное
|
||||
|
||||
## Аргументы
|
||||
_Data source_ функция **decort_resgroup** принимает следующие аргументы:
|
||||
|
||||
| Аргумент | Тип | Обязательный | Описание |
|
||||
| --- | --- | --- | --- |
|
||||
| rg_id | int | :heavy_check_mark: | Идентификатор ресурсной группы, по которой требуется получить информацию. Идентификатор не может быть нулевым.<br/>Вы можете задать или `rg_id`, или `name`. Если задан параметр `rg_id`, то параметр `name` игнорируeтся. |
|
||||
|
||||
Пользователь облачной платформы, от лица которого происходит обращение к данной функции, должен иметь доступ к указанному `account` и ресурсной группе. В противном случае возникнет ошибка доступа.
|
||||
|
||||
Пользователь облачной платформы задается на стадии инициализации Terraform провайдера DECORT (см. [подробности](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/04.02-Инициализация-Terraform-провайдера-DECORT.md)).
|
||||
|
||||
## Возвращаемые значения
|
||||
В случае успешного выполнения _data source_ функция **decort_resgroup** возвращает в указанную при вызове переменную следующие значения:
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| resources | Struct{} [см. ниже](#описание-структуры-resources) | Информация о занимаемых ресурсах |
|
||||
| account_id | int | Уникальный идентификатор подписчика-владельца данной ресурсной группы. |
|
||||
| account_name | string | Имя подписчика ("account"), которому принадлежит данная ресурсная группа. |
|
||||
| compute_features | []string | Доступ к дополнительным функциям управления ВМ |
|
||||
| acl | []Struct [см. ниже](#описание-структуры-acl) | Cписок Acces Control |
|
||||
| created_by | string | Кем создан ресурс |
|
||||
| created_time | int | Время создания ресурса |
|
||||
| def_net_id | int | Уникальный идентификатор сети, установленной по умолчанию для данной ресурсной группы. Экземпляры _compute_, создаваемые в данной ресурсной группе, по умолчанию будут иметь подключение к данной сети, если при их создании явно не указано иное.<br/>Для `def_net_type = "EXTNET" в этом параметре указан идентификатор внешней сети. Для `def_net_type = "PRIVATE" - идентификатор ViNS. |
|
||||
| def_net_type | string | Тип сети, установленной по умолчанию для данной ресурсной группы. Может принимать одно из следующих значений:<br> * EXTNET - подключение во внешнюю сеть с идентификатором `def_net_id`<br> * PRIVATE - подключение в виртуальный сетевой сегмент (ViNS ) с идентификатором `def_net_id`<br> * NONE - сеть по умолчанию не задана, экземпляры _compute_ в данной ресурсной группе будут создаваться без сетевых подключений, если при их создании явно не указано иное. |
|
||||
| deleted_by | string | Кем удален ресурс |
|
||||
| deleted_time | int | Время удаления ресурса |
|
||||
| desc | string | Текстовое описание данной ресурсной группы. |
|
||||
| dirty | bool | Dirty |
|
||||
| gid | int | Идентификатор grid, которому будет принадлежать создаваемая ресурсная группа. |
|
||||
| guid | int | GUID |
|
||||
| lock_status | string | Lock статус |
|
||||
| milestones | int | Milestones |
|
||||
| name | string | Имя данной ресурсной группы. Обратите внимание, что имя ресурсной группы является уникальным только в рамках одного и того же подписчика ("account"). |
|
||||
| register_computes | bool | Флаг отвечающий за то зарегестрированы ли компьюты |
|
||||
| resource_limits | [см. ниже](#описание-структуры-resource-limits) | Лимиты ресурсов |
|
||||
| secret | string | Секрет |
|
||||
| status | string | Статус resgroup |
|
||||
| updated_by | string | Кем был сделан апдейт |
|
||||
| updated_time | int | Время апдейта |
|
||||
| vins | []int | Список id виртуальных сетей |
|
||||
| computes | []int | Список id компьютов |
|
||||
| cpu_allocation_parameter | string | Параметр выделения CPU |
|
||||
| cpu_allocation_ratio | float | Отношение выделения CPU |
|
||||
| res_types | []string | Res types |
|
||||
| uniq_pools | []string | Uniq pools |
|
||||
| id | int | Идентификатор данной ресурсной группы. |
|
||||
|
||||
### Описание структуры acl
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| explicit | bool | Явно ли указан доступ |
|
||||
| guid | string | guid Ресурса |
|
||||
| right | string | Права на ресурс |
|
||||
| status | string | Статус ресурса |
|
||||
| type | string | Тип ресурса |
|
||||
| user_group_id | string | ID user group |
|
||||
|
||||
### Описание структуры resources
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| current | Struct{} [см. ниже](#описание-структуры-current-и-reserved) | Информация о текуших ресурсах |
|
||||
| reserved | Struct{} [см. ниже](#описание-структуры-current-и-reserved) | Информация о зарезверированных аккаунтом ресурсах |
|
||||
|
||||
### Описание структуры current и reserved
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| cpu | int | Количество CPU |
|
||||
| disk_size | int | Размер диска |
|
||||
| disk_size_max | int | Максимальный размер диск |
|
||||
| extips | int | Внешние IPs |
|
||||
| exttraffic | int | Внешний Traffic |
|
||||
| gpu | int | Количество GPU |
|
||||
| ram | int | Количество RAM |
|
||||
| seps | []Struct{} [см . ниже](#описание-структуры-seps) | Информация о seps |
|
||||
|
||||
### Описание структуры seps
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| sep_id | int | ID SEP |
|
||||
| data_name | string | Имя пула информации внутри SEP'а |
|
||||
| disk_size | int | Количество занятого места |
|
||||
| disk_size_max | int | Размер диска |
|
||||
|
||||
### Описание структуры resources limits
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| cu_c | float | Количество ядер CPU |
|
||||
| cu_d | float | Размер диска |
|
||||
| cu_i | float | Количество публичных IP адресов |
|
||||
| cu_m | float | размер RAM |
|
||||
| cu_np | float | Хранилище траффика |
|
||||
| gpu_units | float | количество GPU ядер |
|
||||
|
||||
## Пример использования
|
||||
Пример вызова _data source_ функции **decort_resgroup**:
|
||||
|
||||
```terraform
|
||||
data "decort_resgroup" "rg" {
|
||||
#id ресурсной группы
|
||||
#обязательный параметр
|
||||
#тип - целое число
|
||||
rg_id = 1535
|
||||
}
|
||||
```
|
||||
|
||||
Данный пример подразумевает, что ранее по тексту tf-файла выполнена корректная инициализация провайдера (подробнее об инициализации Terraform провайдера DECORT см. соответствующий [раздел](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/04.02-Инициализация-Terraform-провайдера-DECORT.md) и [пример](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/02.-Пример-работы.md)).
|
||||
|
||||
После успешного завершения такого вызова **decort_resgroup** в переменной `data.decort_resgroup.rg` будут сохранены возвращаемые значения. В частности, для получения идентификатора ресурсной группы следует использовать конструкцию `data.decort_resgroup.rg.id`
|
||||
115
wiki/4.8.0/06.01.03-Data_decort_disk.md
Normal file
115
wiki/4.8.0/06.01.03-Data_decort_disk.md
Normal file
@@ -0,0 +1,115 @@
|
||||
_Data source_ функция **decort_disk** служит для получения информации об уже существующем диске.
|
||||
|
||||
## Изменения в версии 3.4.0
|
||||
- В возвращаемые значения добавлено новое поле shareable
|
||||
- В возвращаемые значения добавлено новое поле present_to
|
||||
- Убраны поля compute_id и compute_name и заменены на поле computes, которое представляет из себя список структур [см. ниже](#описание-структуры-computes)
|
||||
|
||||
## Аргументы
|
||||
_Data source_ функция **decort_disk** принимает следующие аргументы:
|
||||
|
||||
| Аргумент | Тип | Обязательный | Описание |
|
||||
| --- | --- | --- | --- |
|
||||
| disk_id | int | :heavy_check_mark: | Идентификатор диска |
|
||||
|
||||
## Возвращаемые значения
|
||||
В случае успешного выполнения _data source_ функция **decort_disk** возвращает в указанную при вызове переменную следующие значения:
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| account_id | int | Уникальный идентификатор подписчика-владельца диска |
|
||||
| account_name | string | Имя подписчика ("account"), которому принадлежит данный диск |
|
||||
| computes | Struct{} [см. ниже](#описание-структуры-computes) | Информация о компьютах (виртуальных машинах) |
|
||||
| created_time | int | Время создания |
|
||||
| deleted_time | int | Время удаления |
|
||||
| desc | string | Текстовое описание диска |
|
||||
| destruction_time | int | Время окончательного удаления |
|
||||
| devicename | string | Наименование устройства |
|
||||
| disk_id | int | Идентификатор диска. Дублирует значение параметра `id`. |
|
||||
| disk_path | string | Адрес диска |
|
||||
| gid | int | Идентификатор площадки (grid id) |
|
||||
| id | int | Идентификатор диска |
|
||||
| image_id | int | Идентификатор образа, содержимое которого было склонировано/скопировано в данный диск при его создании. 0 означает, что данный диск не создавался как клон/копия какого-либо образа |
|
||||
| images | []int | Идентификаторы образов, использующих диск |
|
||||
| iotune | Struct{}[см. ниже](#описание-структуры-iotune) | Информация об ограничениях IO диска |
|
||||
| disk_name | string | Наименование диска |
|
||||
| order | int | Номер диска |
|
||||
| params | string | Параметры диска |
|
||||
| parent_id | int | id родительского диска |
|
||||
| pci_slot | int | id pci слота, к которому подключен диск |
|
||||
| pool | string | Имя пула в системе хранения, на ресурсах которой размещён данный диск |
|
||||
| present_to | []int | Список ID ресурсов, которым предоставлен диск |
|
||||
| purge_time | int | Время последней попытки |
|
||||
| replication | Struct{} [см. ниже](#описание-структуры-replication) | Информация о реплике диска |
|
||||
| res_id | int | id ресурса |
|
||||
| res_name | string | Наименование ресурса |
|
||||
| role | string | Роль диска |
|
||||
| sep_id | int | Идентификатор Storage Endpoint Provider (SEP). SEP это способ идентифицировать конкретную систему хранения, на ресурсах которой размещён данный диск |
|
||||
| sep_type | string | Тип SEP. Определяет тип системы хранения и содержит одно из заданных в облачной платформе значений |
|
||||
| shareable | bool | Флаг, отвечающий за доступность диска дургим ресурсам |
|
||||
| size_max | int | Размер диска в ГБ |
|
||||
| size_used | float | Кол-во используемого места, в ГБ |
|
||||
| snapshots | []Struct{}[см. ниже](#описание-структуры-snapshots) | Снимки состояния диска |
|
||||
| status | string | Статус диска |
|
||||
| tech_status | string | Технический статус диска |
|
||||
| type | string | Тип диска с точки зрения его роли в составе _compute_. Может принимать одно из фиксированных значений:<br/>"B" - признак загрузочного диска ("boot").<br/>"D" - признак дополнительного диска ("data") |
|
||||
| vmid | int | Идентификатор виртуальной машины (устаревшее) |
|
||||
|
||||
### Описание структуры computes
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| compute_id | int | Идентификатор компьюта |
|
||||
| compute_name | string | Имя компьюта |
|
||||
|
||||
### Описание структуры iotune
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| read_bytes_sec | int | Кол-во байт для чтения в секунду |
|
||||
| read_bytes_sec_max | int | Максимальное кол-во байт для чтения |
|
||||
| read_iops_sec | int | Кол-во операций чтения io в секунду |
|
||||
| read_iops_sec_max | int | Максимальное число io операций чтения |
|
||||
| size_iops_sec | int | Размер io операций |
|
||||
| total_bytes_sec | int | Общий размер байт в секунду |
|
||||
| total_bytes_sec_max | int | Максимальный общий размер байт в секунду |
|
||||
| total_iops_sec | int | Общее кол-во io операций в секунду |
|
||||
| total_iops_sec_max | int | Максимальное общее кол-во io операций в секунду |
|
||||
| write_bytes_sec | int | Кол-во байт для записи в секунду |
|
||||
| write_bytes_sec_max | int | Максимальное кол-во байт для записи в секунду |
|
||||
| write_iops_sec | int | Кол-во операций записи в секунду |
|
||||
| write_iops_sec_max | int | Максимальное число операций записей |
|
||||
|
||||
### Описание структуры replication
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| disk_id | int | id диска |
|
||||
| pool_id | string | id пула |
|
||||
| role | string | Роль диска (главный или реплика) |
|
||||
| self_volume_id | string | id раздела |
|
||||
| storage_id | int | id хранилища |
|
||||
| volume_id | int | id раздела |
|
||||
|
||||
### Описание структуры snapshots
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| guid | string | id снимка |
|
||||
| label | string | Наименование снимка |
|
||||
| res_id | string | Ссылка на снимок |
|
||||
| snap_set_guid | string | Установленный id снимка |
|
||||
| snap_set_time | int | Установленное время снимка |
|
||||
| timestamp | int | Время снимка |
|
||||
|
||||
## Пример использования
|
||||
Пример вызова _data source_ функции **decort_disk**:
|
||||
|
||||
```terraform
|
||||
data "decort_disk" "acl" {
|
||||
#фильтр по id диска
|
||||
#обязательный параметр
|
||||
#тип - целое число
|
||||
disk_id = 49304
|
||||
}
|
||||
```
|
||||
|
||||
Данный пример подразумевает, что ранее по тексту tf-файла выполнена корректная инициализация провайдера (подробнее об инициализации Terraform провайдера DECORT см. соответствующий [раздел](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/04.02-Инициализация-Terraform-провайдера-DECORT.md) и [пример](https://repository.basistech.ru/BASIS/terraform-provider-decort/src/branch/main/wiki/4.8.0/02.-Пример-работы.md)).
|
||||
|
||||
После успешного завершения такого вызова **decort_disk** в переменной `data.decort_disk.my_data_disk` будут сохранены возвращаемые значения. В частности, для получения наименования диска следует использовать конструкцию `data.decort_disk.my_data_disk.acl`
|
||||
292
wiki/4.8.0/06.01.04-Data_decort_vins.md
Normal file
292
wiki/4.8.0/06.01.04-Data_decort_vins.md
Normal file
@@ -0,0 +1,292 @@
|
||||
_Data source_ функция **decort_vins** служит для получения информации об уже существующем виртуальном сетевом сегменте (Virtual Network Segment, ViNS).
|
||||
|
||||
## Аргументы
|
||||
_Data source_ функция **decort_vins** принимает следующие аргументы:
|
||||
|
||||
| Аргумент | Тип | Обязательный | Описание |
|
||||
| --- | --- | --- | --- |
|
||||
| vins_id | int | :heavy_check_mark: | ID виртуальной сети |
|
||||
|
||||
## Возвращаемые значения
|
||||
В случае успешного выполнения _data source_ функция **decort_vins** возвращает в указанную при вызове переменную следующие значения:
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| vnf_dev | []Struct{} [см. ниже](#описание-структуры-vnf_dev) | VNFDEV |
|
||||
| \_ckey | string | CKey |
|
||||
| account_id | int | Уникальный идентификатор подписчика-владельца ViNS. |
|
||||
| account_name | string | Имя подписчика ("account"), которому принадлежит ViNS. |
|
||||
| computes | []Struct{} [см. ниже](#описание-структуры-computes) | Информация о компьютах |
|
||||
| default_gw | string | Шлюз по умолчанию |
|
||||
| default_qos | []Struct{} [см. ниже](#описание-структуры-qos) | qos виртуальной сети |
|
||||
| desc | string | Текстовое описание ViNS. |
|
||||
| gid | int | Grid ID |
|
||||
| guid | int | ID ресурса |
|
||||
| lock_status | string | Статус доступа виртуальной сети |
|
||||
| manager_id | int | ID manager |
|
||||
| manager_type | string | Type of manager |
|
||||
| milestones | int | Milestones |
|
||||
| name | string | Имя ViNS. |
|
||||
| net_mask | int | Маска подсети |
|
||||
| network | string | Сеть Vins |
|
||||
| pre_reservations_num | int | Кол-во зарезервированных ip адресов |
|
||||
| redundant | bool | Redudant |
|
||||
| rg_id | int | Идентификатор ресурсной группы, на уровне которой создан ViNS. Для ViNS, существующих на уровне "account", данный параметр будет равен 0. |
|
||||
| rg_name | string | Имя ресурсной группы |
|
||||
| sec_vnf_dev_id | int | ID sec vnf |
|
||||
| status | string | Статус |
|
||||
| user_managed | bool | Флаг user managed |
|
||||
| vnfs | []Struct{} [см. ниже](#описание-структуры-vnfs) | VNFS |
|
||||
| vxlan_id | int | ID vxlan |
|
||||
|
||||
### Описание структуры vnf_dev
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| \_ckey | string | Ckey |
|
||||
| account_id | int | ID аккаунта |
|
||||
| capabilities | []string | Возможности vnf_dev |
|
||||
| config | Struct{} [см. ниже](#описание-структуры-config) | Конфиг VNF |
|
||||
| config_saved | bool | Флаг, отвечающий за то сохранен ли конфиг |
|
||||
| custom_pre_cfg | bool | Custom |
|
||||
| desc | string | Описание |
|
||||
| gid | int | Grid ID |
|
||||
| guid | int | ID ресурса |
|
||||
| vnf_id | int | ID vnf |
|
||||
| interfaces | []Struct{} [см. ниже](#описание-структуры-interfaces) | Информация о интерфейсах |
|
||||
| lock_status | string | Статус доступа vnf_dev |
|
||||
| milestones | int | Этапы |
|
||||
| vnf_name | string | Имя VNF |
|
||||
| status | string | Статус |
|
||||
| tech_status | string | Технический статус |
|
||||
| type | string | Тип vnf |
|
||||
| vnc_password | string | vnc пароль |
|
||||
| vins | []int | Список виртуальных сетей |
|
||||
|
||||
### Описание структуры config
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| mgmt | Struct{} [см. ниже](#описание-структуры-mgmt) | Config Mgmt |
|
||||
| resources | []Struct{} [см. ниже](#описание-структуры-resources) | Config resources |
|
||||
|
||||
### Описание структуры mgmt
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| ip_addr | string | IP адрес mgmt |
|
||||
| password | string | Пароль юзера |
|
||||
| ssh_key | string | Публичный SSH ключ |
|
||||
| user | string | Имя юзера |
|
||||
|
||||
### Описание структуры resources
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| cpu | int | Кол-во cpu ресурса |
|
||||
| ram | int | Кол-во ram ресурса |
|
||||
| stack_id | int | ID stack ресурса |
|
||||
| uuid | string | UUID ресурса |
|
||||
|
||||
### Описание структуры interfaces
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| conn_id | int | ID коннекта |
|
||||
| conn_type | string | Тип коннекта |
|
||||
| def_gw | string | Шлюз по умолчанию |
|
||||
| flipgroup_id | int | ID flipgroup |
|
||||
| guid | string | ID ресурса |
|
||||
| ip_address | string | IP адрес интерфейса |
|
||||
| listen_ssh | bool | Флаг, говорящий о том, слушается ли ssh |
|
||||
| mac | string | MAC адрес интерфейса |
|
||||
| mtu | string | Максимальный объём данных, который может быть передан за одну итерацию |
|
||||
| name | string | Имя интерфейса |
|
||||
| net_id | int | ID сети |
|
||||
| net_mask | int | Маска |
|
||||
| net_type | string | Тип сети |
|
||||
| node_id | int | ID узла |
|
||||
| pci_slot | int | Слот pci |
|
||||
| bus_number | int | Номер шины |
|
||||
| qos | Struct{} [см. ниже](#описание-структуры-qos) | QOS |
|
||||
| target | string | Таргет интерфейса |
|
||||
| type | string | Тип интерфейса |
|
||||
| vnfs | []int | Список ID vnf |
|
||||
| libvirt_settings | []Struct{}[см. ниже](#описание-структуры-libvirt_settings) | Параметры libvirt virtio интерфейса |
|
||||
|
||||
### Описание структуры libvirt_settings
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| guid | string | GUID |
|
||||
| txmode | string | TX mode |
|
||||
| ioeventfd | string | IO event |
|
||||
| event_idx | string | Event ID |
|
||||
| queues | int | Количество очередей |
|
||||
| rx_queue_size | int | Длина очереди RX |
|
||||
| tx_queue_size | int | Длина очереди TX |
|
||||
|
||||
### Описание структуры computes
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| compute_id | int | ID компьюта |
|
||||
| compute_name | string | Имя компьюта |
|
||||
|
||||
### Описание структуры qos
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| e_rate | int | E rate |
|
||||
| guid | string | ID ресурса |
|
||||
| in_brust | int | In brust |
|
||||
| in_rate | int | In rate |
|
||||
|
||||
### Описание структуры vnfs
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| dhcp | []Struct{} [см. ниже](#описание-структуры-dhcp) | информаиця о DHCP |
|
||||
| gw | []Struct{} [см. ниже](#описание-структуры-gw) | GW |
|
||||
| nat | []Struct{} [см. ниже](#описание-структуры-nat) | NAT |
|
||||
|
||||
### Описание структуры dhcp
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| \_ckey | string | CKey |
|
||||
| account_id | int | Уникальный идентификатор подписчика-владельца ViNS. |
|
||||
| config | Struct{} [см. ниже](#описание-структуры-dhcp-config) | Информация о DHCP конфиге |
|
||||
| created_time | int | Время создания |
|
||||
| devices | []Struct{} [см. ниже](#описание-структуры-devices) | Информация о девайсах |
|
||||
| gid | int | GRID ID |
|
||||
| guid | int | ID ресурса |
|
||||
| dhcp_id | int | ID dhcp |
|
||||
| lock_status | string | Статус доступа виртуальной сети |
|
||||
| milestones | int | Milestones |
|
||||
| owner_id | int | ID владельца |
|
||||
| owner_type | string | Тип владельца |
|
||||
| pure_virtual | bool | Флаг, показывающий является ли ресурс чисто виртуальным |
|
||||
| status | string | Статус |
|
||||
| tech_status | string | Технический статус |
|
||||
| type | string | Тип ресурса |
|
||||
|
||||
### Описание структуры dhcp config
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| default_gw | string | Шлюз по умолчанию |
|
||||
| dns | []string | Список dns |
|
||||
| ip_end | string | Конец диапазона IP адресов |
|
||||
| ip_start | string | Старт диапазона IP адресов |
|
||||
| lease | int | срок |
|
||||
| netmask | int | Маска сети |
|
||||
| network | string | Сеть |
|
||||
| reservations | []Struct{} [см. ниже](#описание-структуры-reservations) | Информация о резервациях |
|
||||
|
||||
### Описание структуры reservations
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| account_id | int | ID аккаунта |
|
||||
| ip | string | IP адрес |
|
||||
| mac | string | MAC адрес |
|
||||
| type | string | Тип |
|
||||
| vm_id | int | ID виртуальной машины |
|
||||
|
||||
|
||||
### Описание структуры devices
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| primary | Struct{} [см. ниже](#описание-структуры-primary) | Первичная информация |
|
||||
|
||||
### Описание структуры primary
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| dev_id | int | ID dev |
|
||||
| iface01 | string | Интерфейс 1 |
|
||||
| iface02 | string | Интерфейс 2 |
|
||||
|
||||
### Описание структуры gw
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| \_ckey | string | CKey |
|
||||
| account_id | int | Уникальный идентификатор подписчика-владельца ViNS. |
|
||||
| config | Struct{} [см. ниже](#описание-структуры-gw-config) | Информация о конфиге |
|
||||
| created_time | int | Время создания |
|
||||
| devices | []Struct{} [см. ниже](#описание-структуры-devices) | Информация о девайсах |
|
||||
| gid | int | GRID ID |
|
||||
| guid | int | ID ресурса |
|
||||
| gw_id | int | ID GW |
|
||||
| lock_status | string | Статус доступа виртуальной сети |
|
||||
| milestones | int | Milestones |
|
||||
| owner_id | int | ID владельца |
|
||||
| owner_type | string | Тип владельца |
|
||||
| pure_virtual | bool | Флаг, показывающий является ли ресурс чисто виртуальным |
|
||||
| status | string | Статус |
|
||||
| tech_status | string | Технический статус |
|
||||
| type | string | Тип ресурса |
|
||||
|
||||
### Описание структуры gw config
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| default_gw | string | Шлюз по умолчанию |
|
||||
| ext_net_id | int | ID внешней сети |
|
||||
| ext_net_ip | string | IP внешней сети |
|
||||
| ext_netmask | int | Маска внешней сети |
|
||||
| qos | Struct{} [см. ниже](#описание-структуры-qos) | QOS |
|
||||
|
||||
### Описание структуры nat
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| \_ckey | string | CKey |
|
||||
| account_id | int | Уникальный идентификатор подписчика-владельца ViNS. |
|
||||
| created_time | int | Время создания |
|
||||
| config | Struct{} [см. ниже](#описание-структуры-nat-config) | Информация о конфиге |
|
||||
| devices | []Struct{} [см. ниже](#описание-структуры-devices) | Информация о девайсах |
|
||||
| gid | int | GRID ID |
|
||||
| guid | int | ID ресурса |
|
||||
| nat_id | int | ID NAT |
|
||||
| lock_status | string | Статус доступа виртуальной сети |
|
||||
| milestones | int | Milestones |
|
||||
| owner_id | int | ID владельца |
|
||||
| owner_type | string | Тип владельца |
|
||||
| pure_virtual | bool | Флаг, показывающий является ли ресурс чисто виртуальным |
|
||||
| status | string | Статус |
|
||||
| tech_status | string | Технический статус |
|
||||
| type | string | Тип ресурса |
|
||||
|
||||
### Описание структуры nat config
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| net_mask | int | Маска сети |
|
||||
| network | string | Сеть |
|
||||
| rules | []Struct{} [см. ниже](#описание-структуры-rules) | Правила NAT |
|
||||
|
||||
### Описание структуры rules
|
||||
| Параметр | Тип | Описание |
|
||||
| --- | --- | --- |
|
||||
| rule_id | int | ID правила |
|
||||
| local_ip | string | Локальный IP адрес |
|
||||
| local_port | int | Локальный порт |
|
||||
| protocol | string | Протокол |
|
||||
| public_port_end | int | Конец диапазона портов |
|
||||
| public_port_start | int | Начало диапазона портов |
|
||||
| vm_id | int | ID виртуальной машины |
|
||||
| vm_name | string | Имя виртуальной машины |
|
||||
|
||||
## Пример использования
|
||||
Пример вызова _data source_ функции **decort_vins**:
|
||||
|
||||
```terraform
|
||||
data "decort_vins" "vins" {
|
||||
#обязательный параметр
|
||||
#id желаемого vins
|
||||
#тип - целое число
|
||||
vins_id = 10101
|
||||
|
||||
}
|
||||
```
|
||||
После успешного завершения такого вызова **decort_vins** в переменной `data.decort_vins.vins` будут сохранены возвращаемые значения. В частности, для получения идентификатора ViNS следует использовать конструкцию `data.decort_vins.vins.id`
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user