diff --git a/CHANGELOG.md b/CHANGELOG.md
index cc2f54bc..5c830c9e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,38 @@
-## Version 4.10.5
+## Version 4.10.6
+
+### Добавлено
+
+#### kvmvm
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BATF-1276 | Добавлено опциональное поле `create_blank` в resource `decort_kvmvm` в cloudapi/kvmvm и в resource `decort_cb_kvmvm` в cloudbroker/kvmvm |
+| BATF-1276 | Опциональное поле `alt_boot_id` в resource `decort_kvmvm` в cloudapi/kvmvm |
+
+### Изменено
+#### kvmvm
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BATF-1276 | Тип поля `disk_type` с опционального на вычисляемый в resource `decort_kvmvm` в cloudapi/kvmvm и в resource `decort_cb_kvmvm` в cloudbroker/kvmvm |
### Исправлено
-#### kvmvmm
+#### flipgroup
| Идентификатор
задачи | Описание |
| --- | --- |
-| BATF-1270 | Опциональное поле `iotune` в блоке `disks` в resource `decort_kvmvm` в cloudapi/kvmvm и в resource `decort_cb_kvmvm` в cloudbroker/kvmvm |
\ No newline at end of file
+| BATF-1283 | Установка поля `desc` с платформы в ресурсе `decort_cb_flipgroup` в cloudbroker/flipgroup |
+
+#### kvmvm
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BATF-1276 | Ошибка при старте ВМ с указанием поля `alt_boot_id` в resource `decort_cb_kvmvm` в cloudbroker/kvmvm |
+
+#### trunk
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BATF-1285 | Установка полей `account_ids`, `ovs_bridge`, `native_vlan_id`, `trunk_tags` с платформы в ресурсе `decort_cb_trunk ` в cloudbroker/trunk |
+
+#### vfpool
+| Идентификатор
задачи | Описание |
+| --- | --- |
+| BATF-1289 | Разрешено создавать пул виртуальных функций с блоком `config` при значении поля `enable` равным `false` в resource `decort_cb_vfpool` в cloudbroker/vfpool |
+| BATF-1289 | Разрешено обновлять поля `name`, `description`, `account_access` и `rg_access` без блока `config` в resource `decort_cb_vfpool` в cloudbroker/vfpool |
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 28d60669..ce9a573b 100644
--- a/Makefile
+++ b/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.10.5
+VERSION=4.10.6
OS_ARCH=$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH)
FILES = ${BINARY}_${VERSION}_darwin_amd64\
diff --git a/docs/resources/cb_kvmvm.md b/docs/resources/cb_kvmvm.md
index be5995a0..5d74b75e 100644
--- a/docs/resources/cb_kvmvm.md
+++ b/docs/resources/cb_kvmvm.md
@@ -36,6 +36,7 @@ description: |-
- `chipset` (String) Type of the emulated system.
- `cloud_init` (String) Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.
- `cpu_pin` (Boolean) Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node.
+- `create_blank` (Boolean) If True, the compute is created via kvmx86/createBlank endpoint (without OS image). The image_id field is not required in this case.
- `custom_fields` (String)
- `description` (String) Optional text description of this compute instance.
- `detach_disks` (Boolean)
@@ -188,7 +189,6 @@ Required:
Optional:
- `desc` (String) Optional description
-- `disk_type` (String) The type of disk in terms of its role in compute: 'B=Boot, D=Data'
- `image_id` (Number) Specify image id for create disk from template
- `iotune` (Block List, Max: 1) (see [below for nested schema](#nestedblock--disks--iotune))
- `node_ids` (Set of Number)
@@ -204,6 +204,7 @@ Read-Only:
- `delete_time` (Number)
- `devicename` (String)
- `disk_id` (Number) Disk ID
+- `disk_type` (String) The type of disk in terms of its role in compute: 'B=Boot, D=Data'
- `present_to` (Map of Number)
- `shareable` (Boolean)
- `size_max` (Number)
diff --git a/docs/resources/kvmvm.md b/docs/resources/kvmvm.md
index 220fc806..a7267354 100644
--- a/docs/resources/kvmvm.md
+++ b/docs/resources/kvmvm.md
@@ -27,6 +27,7 @@ description: |-
- `affinity_label` (String) Set affinity label for compute
- `affinity_rules` (Block List) (see [below for nested schema](#nestedblock--affinity_rules))
+- `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_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.
@@ -35,6 +36,7 @@ description: |-
- `chipset` (String) Type of the emulated system.
- `cloud_init` (String) Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.
- `cpu_pin` (Boolean) Run VM on dedicated CPUs. To use this feature, the system must be pre-configured by allocating CPUs on the physical node.
+- `create_blank` (Boolean) If True, the compute is created via kvmx86/createBlank endpoint (without OS image). The image_id field is not required in this case.
- `custom_fields` (String)
- `description` (String) Optional text description of this compute instance.
- `detach_disks` (Boolean)
@@ -182,7 +184,6 @@ Required:
Optional:
- `desc` (String) Optional description
-- `disk_type` (String) The type of disk in terms of its role in compute: 'B=Boot, D=Data'
- `image_id` (Number) Specify image id for create disk from template
- `iotune` (Block List, Max: 1) (see [below for nested schema](#nestedblock--disks--iotune))
- `permanently` (Boolean) Disk deletion status
@@ -197,6 +198,7 @@ Read-Only:
- `deleted_time` (Number)
- `devicename` (String)
- `disk_id` (Number) Disk ID
+- `disk_type` (String) The type of disk in terms of its role in compute: 'B=Boot, D=Data'
- `present_to` (Map of Number)
- `shareable` (Boolean)
- `size_max` (Number)
diff --git a/go.mod b/go.mod
index 9ad304eb..4709c87b 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,7 @@ require (
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1
github.com/sirupsen/logrus v1.9.0
golang.org/x/net v0.44.0
- repository.basistech.ru/BASIS/decort-golang-sdk v1.12.11
+ repository.basistech.ru/BASIS/decort-golang-sdk v1.12.12
)
require (
diff --git a/go.sum b/go.sum
index 69942e2e..b43fab2e 100644
--- a/go.sum
+++ b/go.sum
@@ -318,5 +318,5 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-repository.basistech.ru/BASIS/decort-golang-sdk v1.12.11 h1:Y5meH2uCSsH7QOsQqqyRxSObRIGtmXB9pKbJZDCKzsw=
-repository.basistech.ru/BASIS/decort-golang-sdk v1.12.11/go.mod h1:S/f7GxwWcE88eFpORV+I9xqEf8zDW5srQHpG2XQCLZM=
+repository.basistech.ru/BASIS/decort-golang-sdk v1.12.12 h1:dkLPikeIh9un93zDB2FMtF5E0hJnp8kEKBrC9YbSki8=
+repository.basistech.ru/BASIS/decort-golang-sdk v1.12.12/go.mod h1:S/f7GxwWcE88eFpORV+I9xqEf8zDW5srQHpG2XQCLZM=
diff --git a/internal/service/cloudapi/kvmvm/resource_compute.go b/internal/service/cloudapi/kvmvm/resource_compute.go
index cdca311c..0e8f685b 100644
--- a/internal/service/cloudapi/kvmvm/resource_compute.go
+++ b/internal/service/cloudapi/kvmvm/resource_compute.go
@@ -71,13 +71,15 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
return diag.Errorf("resourceComputeCreate: can't create Compute because rgID %d is not allowed or does not exist", d.Get("rg_id").(int))
}
- hasImage, err := existImageId(ctx, d, m)
- if err != nil {
- return diag.FromErr(err)
- }
+ if !d.Get("create_blank").(bool) {
+ hasImage, err := existImageId(ctx, d, m)
+ if err != nil {
+ return diag.FromErr(err)
+ }
- if !hasImage {
- return diag.Errorf("resourceComputeCreate: can't create Compute because imageID %d is not allowed or does not exist", d.Get("image_id").(int))
+ if !hasImage {
+ return diag.Errorf("resourceComputeCreate: can't create Compute because imageID %d is not allowed or does not exist", d.Get("image_id").(int))
+ }
}
if zoneID, ok := d.GetOk("zone_id"); ok {
@@ -288,7 +290,31 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
- apiResp, err := c.CloudAPI().KVMX86().Create(ctx, createReqX86)
+ var apiResp uint64
+ if d.Get("create_blank").(bool) {
+ log.Debugf("resourceComputeCreate: using createBlank endpoint")
+ createBlankReq := kvmx86.CreateBlankRequest{
+ RGID: createReqX86.RGID,
+ Name: createReqX86.Name,
+ CPU: createReqX86.CPU,
+ RAM: createReqX86.RAM,
+ StoragePolicyID: createReqX86.StoragePolicyID,
+ WithoutBootDisk: createReqX86.WithoutBootDisk,
+ BootDisk: createReqX86.BootDisk,
+ SEPID: createReqX86.SepID,
+ Pool: createReqX86.Pool,
+ DataDisks: createReqX86.DataDisks,
+ Interfaces: createReqX86.Interfaces,
+ Description: createReqX86.Description,
+ Chipset: createReqX86.Chipset,
+ PreferredCPU: createReqX86.PreferredCPU,
+ ZoneID: createReqX86.ZoneID,
+ OSVersion: createReqX86.OSVersion,
+ }
+ apiResp, err = c.CloudAPI().KVMX86().CreateBlank(ctx, createBlankReq)
+ } else {
+ apiResp, err = c.CloudAPI().KVMX86().Create(ctx, createReqX86)
+ }
if err != nil {
return diag.FromErr(err)
}
@@ -452,6 +478,9 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
if start, ok := d.GetOk("started"); ok {
if start.(bool) {
req := compute.StartRequest{ComputeID: computeId}
+ if altBootID, ok := d.Get("alt_boot_id").(int); ok {
+ req.AltBootID = uint64(altBootID)
+ }
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", computeId)
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
warnings.Add(err)
@@ -763,13 +792,15 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
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)
- if err != nil {
- return diag.FromErr(err)
- }
+ if !d.Get("create_blank").(bool) {
+ hasImage, err := existImageId(ctx, d, m)
+ if err != nil {
+ return diag.FromErr(err)
+ }
- if !hasImage {
- return diag.Errorf("resourceComputeUpdate: can't update Compute because imageID %d not allowed or does not exist", d.Get("image_id").(int))
+ if !hasImage {
+ return diag.Errorf("resourceComputeUpdate: can't update Compute because imageID %d not allowed or does not exist", d.Get("image_id").(int))
+ }
}
if d.HasChange("zone_id") {
@@ -857,6 +888,9 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if start, ok := d.GetOk("started"); ok {
if start.(bool) {
req := compute.StartRequest{ComputeID: computeRec.ID}
+ if altBootID, ok := d.Get("alt_boot_id").(int); ok {
+ req.AltBootID = uint64(altBootID)
+ }
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
return diag.FromErr(err)
@@ -1099,7 +1133,11 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
// If used to be STARTED, we need to start it after update
if isStopRequired {
- if _, err := c.CloudAPI().Compute().Start(ctx, compute.StartRequest{ComputeID: computeRec.ID}); err != nil {
+ req := compute.StartRequest{ComputeID: computeRec.ID}
+ if altBootID, ok := d.Get("alt_boot_id").(int); ok {
+ req.AltBootID = uint64(altBootID)
+ }
+ if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
return diag.FromErr(err)
}
}
@@ -1208,9 +1246,6 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if diskConv["sep_id"].(int) != 0 {
req.SepID = uint64(diskConv["sep_id"].(int))
}
- if diskConv["disk_type"].(string) != "" {
- req.DiskType = diskConv["disk_type"].(string)
- }
if diskConv["pool"].(string) != "" {
req.Pool = diskConv["pool"].(string)
}
@@ -1856,6 +1891,9 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
req := compute.StartRequest{
ComputeID: computeRec.ID,
}
+ if altBootID, ok := d.Get("alt_boot_id").(int); ok {
+ req.AltBootID = uint64(altBootID)
+ }
if !isStopRequired {
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
return diag.FromErr(err)
@@ -2051,11 +2089,9 @@ func disksSubresourceSchemaMake() map[string]*schema.Schema {
Description: "Storage endpoint provider ID; by default the same with boot disk",
},
"disk_type": {
- Type: schema.TypeString,
- Computed: true,
- Optional: true,
- ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false),
- Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'",
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'",
},
"pool": {
Type: schema.TypeString,
@@ -2353,6 +2389,12 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Default: false,
Description: "If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state.",
},
+ "create_blank": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Default: false,
+ Description: "If True, the compute is created via kvmx86/createBlank endpoint (without OS image). The image_id field is not required in this case.",
+ },
"boot_disk_size": {
Type: schema.TypeInt,
Optional: true,
@@ -2607,6 +2649,11 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Default: false,
Description: "Flag for resize compute",
},
+ "alt_boot_id": {
+ Type: schema.TypeInt,
+ Optional: true,
+ Description: "ID of CD-ROM live image to boot",
+ },
"started": {
Type: schema.TypeBool,
Optional: true,
diff --git a/internal/service/cloudapi/kvmvm/utility_compute.go b/internal/service/cloudapi/kvmvm/utility_compute.go
index 12789c5e..6dc71e9c 100644
--- a/internal/service/cloudapi/kvmvm/utility_compute.go
+++ b/internal/service/cloudapi/kvmvm/utility_compute.go
@@ -293,7 +293,13 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
if needStart {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
- if numErr, err := utilityComputeStart(ctx, computeId, m); err != nil {
+ var altBootID uint64
+ if altBootIDRaw, ok := d.Get("alt_boot_id").(int); ok {
+ altBootID = uint64(altBootIDRaw)
+ } else {
+ altBootID = 0
+ }
+ if numErr, err := utilityComputeStart(ctx, computeId, altBootID, m); err != nil {
apiErrCount += numErr
lastSavedError = err
}
@@ -456,10 +462,14 @@ func utilityComputeStop(ctx context.Context, computeID uint64, m interface{}) er
return nil
}
-func utilityComputeStart(ctx context.Context, computeID uint64, m interface{}) (int, error) {
+func utilityComputeStart(ctx context.Context, computeID uint64, altBootID uint64, m interface{}) (int, error) {
c := m.(*controller.ControllerCfg)
startReq := compute.StartRequest{ComputeID: computeID}
+ if altBootID > 0 {
+ startReq.AltBootID = altBootID
+ }
+
log.Debugf("utilityComputeNetworksConfigure: starting compute %d", computeID)
_, err := c.CloudAPI().Compute().Start(ctx, startReq)
if err != nil {
diff --git a/internal/service/cloudbroker/flipgroup/flattens.go b/internal/service/cloudbroker/flipgroup/flattens.go
index 4c35c5cb..131d42c0 100644
--- a/internal/service/cloudbroker/flipgroup/flattens.go
+++ b/internal/service/cloudbroker/flipgroup/flattens.go
@@ -70,6 +70,36 @@ func flattenFlipgroup(d *schema.ResourceData, flip *flipgroup.RecordFLIPGroup) {
d.Set("updated_time", flip.UpdatedTime)
}
+func flattenFlipgroupResource(d *schema.ResourceData, flip *flipgroup.RecordFLIPGroup) {
+ d.Set("flipgroup_id", flip.ID)
+ d.Set("account_id", flip.AccountID)
+ d.Set("account_name", flip.AccountName)
+ d.Set("client_ids", flip.ClientIDs)
+ d.Set("client_names", flip.ClientNames)
+ d.Set("client_type", flip.ClientType)
+ d.Set("conn_id", flip.ConnID)
+ d.Set("conn_type", flip.ConnType)
+ d.Set("created_by", flip.CreatedBy)
+ d.Set("created_time", flip.CreatedTime)
+ d.Set("default_gw", flip.DefaultGW)
+ d.Set("deleted_by", flip.DeletedBy)
+ d.Set("deleted_time", flip.DeletedTime)
+ d.Set("desc", flip.Description)
+ d.Set("gid", flip.GID)
+ d.Set("guid", flip.GUID)
+ d.Set("ip", flip.IP)
+ d.Set("milestones", flip.Milestones)
+ d.Set("name", flip.Name)
+ d.Set("net_id", flip.NetID)
+ d.Set("net_type", flip.NetType)
+ d.Set("network", flip.Network)
+ d.Set("rg_id", flip.RGID)
+ d.Set("rg_name", flip.RGName)
+ d.Set("status", flip.Status)
+ d.Set("updated_by", flip.UpdatedBy)
+ d.Set("updated_time", flip.UpdatedTime)
+}
+
func flattenFlipgroupsList(fg *flipgroup.ListFLIPGroups) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(fg.Data))
for _, flip := range fg.Data {
diff --git a/internal/service/cloudbroker/flipgroup/resource_flipgroup.go b/internal/service/cloudbroker/flipgroup/resource_flipgroup.go
index 5e5a5ac0..fdbf6335 100644
--- a/internal/service/cloudbroker/flipgroup/resource_flipgroup.go
+++ b/internal/service/cloudbroker/flipgroup/resource_flipgroup.go
@@ -110,7 +110,7 @@ func resourceFlipgroupRead(ctx context.Context, d *schema.ResourceData, m interf
return diag.Errorf("The flipgroup status is destroyed and cannot be read.")
}
- flattenFlipgroup(d, fg)
+ flattenFlipgroupResource(d, fg)
log.Debugf("resourceFlipgroupRead: after flattenFlipgroup: flipgroup_id %s, name %s",
d.Id(), d.Get("name").(string))
diff --git a/internal/service/cloudbroker/kvmvm/resource_check_input_values.go b/internal/service/cloudbroker/kvmvm/resource_check_input_values.go
index c0969933..79971b88 100644
--- a/internal/service/cloudbroker/kvmvm/resource_check_input_values.go
+++ b/internal/service/cloudbroker/kvmvm/resource_check_input_values.go
@@ -17,8 +17,10 @@ func checkParamsExistence(ctx context.Context, d *schema.ResourceData, c *contro
errs = append(errs, err)
}
- if err := ic.ExistImage(ctx, uint64(d.Get("image_id").(int)), c); err != nil {
- errs = append(errs, err)
+ if !d.Get("create_blank").(bool) {
+ if err := ic.ExistImage(ctx, uint64(d.Get("image_id").(int)), c); err != nil {
+ errs = append(errs, err)
+ }
}
if netErrs := existNetworks(ctx, d, c); errs != nil {
diff --git a/internal/service/cloudbroker/kvmvm/resource_compute.go b/internal/service/cloudbroker/kvmvm/resource_compute.go
index cad6cf52..a90299e9 100644
--- a/internal/service/cloudbroker/kvmvm/resource_compute.go
+++ b/internal/service/cloudbroker/kvmvm/resource_compute.go
@@ -231,7 +231,32 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
- apiResp, err := c.CloudBroker().KVMX86().Create(ctx, createReqX86)
+ var apiResp uint64
+ var err error
+ if d.Get("create_blank").(bool) {
+ log.Debugf("resourceComputeCreate: using createBlank endpoint")
+ createBlankReq := kvmx86.CreateBlankRequest{
+ RGID: createReqX86.RGID,
+ Name: createReqX86.Name,
+ CPU: createReqX86.CPU,
+ RAM: createReqX86.RAM,
+ StoragePolicyID: createReqX86.StoragePolicyID,
+ WithoutBootDisk: createReqX86.WithoutBootDisk,
+ BootDisk: createReqX86.BootDisk,
+ SEPID: createReqX86.SEPID,
+ Pool: createReqX86.Pool,
+ DataDisks: createReqX86.DataDisks,
+ Interfaces: createReqX86.Interfaces,
+ Description: createReqX86.Description,
+ Chipset: createReqX86.Chipset,
+ PreferredCPU: createReqX86.PreferredCPU,
+ ZoneID: createReqX86.ZoneID,
+ OSVersion: createReqX86.OSVersion,
+ }
+ apiResp, err = c.CloudBroker().KVMX86().CreateBlank(ctx, createBlankReq)
+ } else {
+ apiResp, err = c.CloudBroker().KVMX86().Create(ctx, createReqX86)
+ }
if err != nil {
return diag.FromErr(err)
}
@@ -424,6 +449,9 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
if start, ok := d.GetOk("started"); ok && start.(bool) {
req := compute.StartRequest{ComputeID: computeId}
+ if altBootID, ok := d.Get("alt_boot_id").(int); ok {
+ req.AltBootID = uint64(altBootID)
+ }
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", computeId)
if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil {
warnings.Add(err)
diff --git a/internal/service/cloudbroker/kvmvm/schema.go b/internal/service/cloudbroker/kvmvm/schema.go
index 3e341fe8..2cdc04e3 100644
--- a/internal/service/cloudbroker/kvmvm/schema.go
+++ b/internal/service/cloudbroker/kvmvm/schema.go
@@ -3406,6 +3406,12 @@ func resourceComputeSchemaMake() map[string]*schema.Schema {
Default: false,
Description: "If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state.",
},
+ "create_blank": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Default: false,
+ Description: "If True, the compute is created via kvmx86/createBlank endpoint (without OS image). The image_id field is not required in this case.",
+ },
"boot_disk_size": {
Type: schema.TypeInt,
Optional: true,
@@ -3728,11 +3734,9 @@ func resourceComputeSchemaMake() map[string]*schema.Schema {
Description: "Storage endpoint provider ID; by default the same with boot disk",
},
"disk_type": {
- Type: schema.TypeString,
- Computed: true,
- Optional: true,
- ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false),
- Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'",
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'",
},
"pool": {
Type: schema.TypeString,
diff --git a/internal/service/cloudbroker/kvmvm/utility_compute.go b/internal/service/cloudbroker/kvmvm/utility_compute.go
index 2633d3a1..3100ead4 100644
--- a/internal/service/cloudbroker/kvmvm/utility_compute.go
+++ b/internal/service/cloudbroker/kvmvm/utility_compute.go
@@ -184,7 +184,11 @@ func utilityComputeResize(ctx context.Context, d *schema.ResourceData, m interfa
}
if isStopRequired {
- if _, err := c.CloudBroker().Compute().Start(ctx, compute.StartRequest{ComputeID: computeId}); err != nil {
+ req := compute.StartRequest{ComputeID: computeId}
+ if altBootID, ok := d.Get("alt_boot_id").(int); ok {
+ req.AltBootID = uint64(altBootID)
+ }
+ if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil {
return err
}
}
@@ -324,9 +328,6 @@ func utilityComputeUpdateDisks(ctx context.Context, d *schema.ResourceData, m in
if diskConv["sep_id"].(int) != 0 {
req.SepID = uint64(diskConv["sep_id"].(int))
}
- if diskConv["disk_type"].(string) != "" {
- req.DiskType = diskConv["disk_type"].(string)
- }
if diskConv["pool"].(string) != "" {
req.Pool = diskConv["pool"].(string)
}
@@ -835,7 +836,13 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
if needStart {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
- if numErr, err := utilityComputeStart(ctx, computeId, m); err != nil {
+ var altBootID uint64
+ if altBootIDRaw, ok := d.Get("alt_boot_id").(int); ok {
+ altBootID = uint64(altBootIDRaw)
+ } else {
+ altBootID = 0
+ }
+ if numErr, err := utilityComputeStart(ctx, computeId, altBootID, m); err != nil {
apiErrCount += numErr
lastSavedError = err
}
@@ -1162,7 +1169,11 @@ func utilityComputeUpdate(ctx context.Context, d *schema.ResourceData, m interfa
// If used to be STARTED, we need to start it after update
if isStopRequired {
- if _, err := c.CloudBroker().Compute().Start(ctx, compute.StartRequest{ComputeID: computeId}); err != nil {
+ req := compute.StartRequest{ComputeID: computeId}
+ if altBootID, ok := d.Get("alt_boot_id").(int); ok {
+ req.AltBootID = uint64(altBootID)
+ }
+ if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil {
return err
}
}
@@ -1633,6 +1644,9 @@ func utilityComputeRollback(ctx context.Context, d *schema.ResourceData, m inter
}
startReq := compute.StartRequest{ComputeID: computeId}
+ if altBootID, ok := d.Get("alt_boot_id").(int); ok {
+ startReq.AltBootID = uint64(altBootID)
+ }
log.Debugf("utilityComputeRollback: starting compute %d", computeId)
@@ -1890,10 +1904,14 @@ func utilityComputeStop(ctx context.Context, d *schema.ResourceData, m interface
return nil
}
-func utilityComputeStart(ctx context.Context, computeID uint64, m interface{}) (int, error) {
+func utilityComputeStart(ctx context.Context, computeID uint64, altBootID uint64, m interface{}) (int, error) {
c := m.(*controller.ControllerCfg)
startReq := compute.StartRequest{ComputeID: computeID}
+ if altBootID > 0 {
+ startReq.AltBootID = altBootID
+ }
+
log.Debugf("utilityComputeStart: starting compute %d", computeID)
_, err := c.CloudBroker().Compute().Start(ctx, startReq)
if err != nil {
diff --git a/internal/service/cloudbroker/trunk/flattens.go b/internal/service/cloudbroker/trunk/flattens.go
index b7591780..4cb9679f 100644
--- a/internal/service/cloudbroker/trunk/flattens.go
+++ b/internal/service/cloudbroker/trunk/flattens.go
@@ -15,11 +15,11 @@ func flattenTrunkResource(d *schema.ResourceData, details *trunk.ItemTrunk) {
d.Set("name", details.Name)
d.Set("mac", details.MAC)
d.Set("description", details.Description)
- d.Set("accountIds", details.AccountIDs)
- d.Set("ovsBridge", details.OVSBridge)
- d.Set("nativeVlanId", details.NativeVLANID)
+ d.Set("account_ids", details.AccountIDs)
+ d.Set("ovs_bridge", details.OVSBridge)
+ d.Set("native_vlan_id", details.NativeVLANID)
d.Set("status", details.Status)
- d.Set("trunkTags", details.TrunkTags)
+ d.Set("trunk_tags", details.TrunkTags)
d.Set("created_at", details.CreatedAt)
d.Set("created_by", details.CreatedBy)
d.Set("updated_at", details.UpdatedAt)
diff --git a/internal/service/cloudbroker/vfpool/resource_vfpool.go b/internal/service/cloudbroker/vfpool/resource_vfpool.go
index 5ea466b5..1e10ce3b 100644
--- a/internal/service/cloudbroker/vfpool/resource_vfpool.go
+++ b/internal/service/cloudbroker/vfpool/resource_vfpool.go
@@ -33,6 +33,7 @@ package vfpool
import (
"context"
+ "fmt"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -85,6 +86,12 @@ func resourceVFPoolCreate(ctx context.Context, d *schema.ResourceData, m interfa
}
config, configOk := d.GetOk("config")
+
+ enableVal := d.Get("enable").(bool)
+ if enableVal && !configOk {
+ return diag.FromErr(fmt.Errorf("enable requires config to be set"))
+ }
+
if configOk {
configArray := config.(*schema.Set).List()
req.Config = make([]vfpool.Config, 0, len(configArray))
@@ -117,10 +124,8 @@ func resourceVFPoolCreate(ctx context.Context, d *schema.ResourceData, m interfa
warnings := dc.Warnings{}
- if enable, ok := d.GetOk("enable"); ok {
- if err := utilityVFPoolEnabled(ctx, m, enable.(bool), vfPoolID, configOk); err != nil {
- warnings.Add(err)
- }
+ if err := utilityVFPoolEnabled(ctx, m, enableVal, vfPoolID); err != nil {
+ warnings.Add(err)
}
log.Debugf("resourceVFPoolCreate: create VFPool with ID: %d, complete", vfPoolID)
@@ -147,20 +152,12 @@ func resourceVFPoolUpdate(ctx context.Context, d *schema.ResourceData, m interfa
log.Debugf("resourceVFPoolUpdate: called VFPool with id %d", vfPoolID)
- _, ok := d.GetOk("config")
-
- if d.HasChanges("name,", "description", "account_access", "rg_access,", "config") {
+ if d.HasChanges("name", "description", "account_access", "rg_access", "config", "enable") {
if err := utilityVFPoolUpdate(ctx, d, m, vfPoolID); err != nil {
return diag.FromErr(err)
}
}
- if d.HasChange("enable") {
- if err := utilityVFPoolEnabled(ctx, m, d.Get("enable").(bool), vfPoolID, ok); err != nil {
- return diag.FromErr(err)
- }
- }
-
log.Debugf("resourceVFPoolUpdate: update VFPool with id %d, complete", vfPoolID)
return resourceVFPoolRead(ctx, d, m)
diff --git a/internal/service/cloudbroker/vfpool/utility_vfpool.go b/internal/service/cloudbroker/vfpool/utility_vfpool.go
index 7fd0c985..8b3e4d55 100644
--- a/internal/service/cloudbroker/vfpool/utility_vfpool.go
+++ b/internal/service/cloudbroker/vfpool/utility_vfpool.go
@@ -64,37 +64,26 @@ func utilityVFpoolCheckPresence(ctx context.Context, d *schema.ResourceData, m i
return vfpoolData, nil
}
-func utilityVFPoolEnabled(ctx context.Context, m interface{}, enable bool, vfPoolID uint64, configOk bool) error {
+func utilityVFPoolEnabled(ctx context.Context, m interface{}, enable bool, vfPoolID uint64) error {
c := m.(*controller.ControllerCfg)
- if enable && configOk {
- req := vfpool.EnableRequest{
- VFPoolID: vfPoolID,
- }
- _, err := c.CloudBroker().VFPool().Enable(ctx, req)
- if err != nil {
- return err
- }
- }
- if enable && !configOk {
- return fmt.Errorf("you must provide configuration for this resource, after enabling it")
- }
- if !enable {
- req := vfpool.DisableRequest{
- VFPoolID: vfPoolID,
- }
- _, err := c.CloudBroker().VFPool().Disable(ctx, req)
- if err != nil {
- return err
- }
+ var err error
+
+ if enable {
+ _, err = c.CloudBroker().VFPool().Enable(ctx, vfpool.EnableRequest{VFPoolID: vfPoolID})
+ } else {
+ _, err = c.CloudBroker().VFPool().Disable(ctx, vfpool.DisableRequest{VFPoolID: vfPoolID})
}
- log.Debugf("utilityVFPoolEnabled: enable=%v vfPool ID %d after completing its resource configuration", enable, vfPoolID)
-
- return nil
+ return err
}
func utilityVFPoolUpdate(ctx context.Context, d *schema.ResourceData, m interface{}, vfPoolID uint64) error {
+ hasConfig := len(d.Get("config").(*schema.Set).List()) > 0
+ if d.Get("enable").(bool) && !hasConfig {
+ return fmt.Errorf("enable requires config to be set")
+ }
+
c := m.(*controller.ControllerCfg)
vfPool, err := utilityVFpoolCheckPresence(ctx, d, m)
@@ -190,7 +179,7 @@ func utilityVFPoolUpdate(ctx context.Context, d *schema.ResourceData, m interfac
}
log.Debugf("utilityVFPoolUpdate: update vfPool with ID: %d, complete with params=%v", vfPoolID, req)
- if len(d.Get("config").(*schema.Set).List()) > 0 && d.Get("enable").(bool) {
+ if hasConfig && d.Get("enable").(bool) {
reqEnable := vfpool.EnableRequest{
VFPoolID: vfPoolID,
}
@@ -201,8 +190,6 @@ func utilityVFPoolUpdate(ctx context.Context, d *schema.ResourceData, m interfac
return err
}
log.Debugf("utilityVFPoolUpdate: enable vfPool with ID: %d, complete", vfPoolID)
- } else {
- return (fmt.Errorf("the vfPool is not enabled after update, you must provide configuration for this resource, after enabling it"))
}
return nil
diff --git a/samples/cloudapi/kvmvm/resource_kvmvm/main.tf b/samples/cloudapi/kvmvm/resource_kvmvm/main.tf
index b8152064..6d88ed3c 100644
--- a/samples/cloudapi/kvmvm/resource_kvmvm/main.tf
+++ b/samples/cloudapi/kvmvm/resource_kvmvm/main.tf
@@ -112,6 +112,18 @@ resource "decort_kvmvm" "comp" {
#используется при создании
#without_boot_disk = true
+ #создание без образа ОС
+ #опциональный параметр
+ #тип - булев
+ #используется при создании
+ #create_blank = false
+
+ #id образа CD-ROM для загрузки
+ #опциональный параметр
+ #тип - целое число
+ #используется при создании и обновлении
+ #alt_boot_id = 1
+
#необходимость выравнивать ВМ по NUMA
#опциональный параметр
#возможные значения - "none, "strict", "loose"
@@ -160,11 +172,6 @@ resource "decort_kvmvm" "comp" {
#тип - целое число
#size = 5
- #тип диска
- #опциональный параметр
- #тип - строка
- #disk_type = "D"
-
#id сепа
#опциональный параметр
#тип - целое число
diff --git a/samples/cloudbroker/kvmvm/resource_kvmvm/main.tf b/samples/cloudbroker/kvmvm/resource_kvmvm/main.tf
index 23065e9e..161b345e 100644
--- a/samples/cloudbroker/kvmvm/resource_kvmvm/main.tf
+++ b/samples/cloudbroker/kvmvm/resource_kvmvm/main.tf
@@ -82,6 +82,12 @@ resource "decort_cb_kvmvm" "comp" {
#используется при создании
#without_boot_disk = true
+ #создание без образа ОС
+ #опциональный параметр
+ #тип - булев
+ #используется при создании
+ #create_blank = false
+
#размер загрузочного диска
#опциональный параметр
#тип - целое число
@@ -121,7 +127,7 @@ resource "decort_cb_kvmvm" "comp" {
#id образа CD-ROM для загрузки
#опциональный параметр
#тип - целое число
- #используется при обновлении, при повторном старте вм
+ #используется при создании и обновлении
#alt_boot_id = 1
#необходимость выравнивать ВМ по NUMA
@@ -166,11 +172,6 @@ resource "decort_cb_kvmvm" "comp" {
#тип - целое число
#storage_policy_id = 1
- #тип диска
- #опциональный параметр
- #тип - строка
- #disk_type = "D"
-
#опциональный параметр
#тип - целое число
#sep_id = 1