This commit is contained in:
stSolo
2022-12-09 13:48:03 +03:00
parent 9402d6f291
commit 0adf28daf6
28 changed files with 2297 additions and 167 deletions

View File

@@ -49,4 +49,7 @@ const (
ComputeUpdateAPI = "/restmachine/cloudapi/compute/update"
ComputeDiskAddAPI = "/restmachine/cloudapi/compute/diskAdd"
ComputeDiskDeleteAPI = "/restmachine/cloudapi/compute/diskDel"
ComputeRestoreAPI = "/restmachine/cloudapi/compute/restore"
ComputeEnableAPI = "/restmachine/cloudapi/compute/enable"
ComputeDisableAPI = "/restmachine/cloudapi/compute/disable"
)

View File

@@ -40,10 +40,12 @@ import (
// "net/url"
"github.com/rudecs/terraform-provider-decort/internal/constants"
"github.com/rudecs/terraform-provider-decort/internal/status"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)
@@ -176,14 +178,17 @@ func flattenCompute(d *schema.ResourceData, compFacts string) error {
d.Set("image_id", model.ImageID)
}
d.Set("description", model.Desc)
d.Set("enabled", false)
if model.Status == status.Enabled {
d.Set("enabled", true)
}
d.Set("cloud_init", "applied") // NOTE: for existing compute we hard-code this value as an indicator for DiffSuppress fucntion
// d.Set("status", model.Status)
// d.Set("tech_status", model.TechStatus)
d.Set("started", false)
if model.TechStatus == "STARTED" {
d.Set("started", true)
} else {
d.Set("started", false)
}
bootDisk := findBootDisk(model.Disks)
@@ -270,6 +275,12 @@ func DataSourceCompute() *schema.Resource {
Description: "ID of the resource group where this compute instance is located.",
},
"enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "If true - enable the compute, else - disable",
},
"rg_name": {
Type: schema.TypeString,
Computed: true,
@@ -339,16 +350,67 @@ func DataSourceCompute() *schema.Resource {
Description: "IDs of the extra disk(s) attached to this compute.",
},
/*
"disks": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: dataSourceDiskSchemaMake(), // ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
"disks": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"disk_name": {
Type: schema.TypeString,
Required: true,
Description: "Name for disk",
},
"size": {
Type: schema.TypeInt,
Required: true,
Description: "Disk size in GiB",
},
"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'",
},
"sep_id": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
Description: "Storage endpoint provider ID; by default the same with boot disk",
},
"pool": {
Type: schema.TypeString,
Computed: true,
Optional: true,
Description: "Pool name; by default will be chosen automatically",
},
"desc": {
Type: schema.TypeString,
Computed: true,
Optional: true,
Description: "Optional description",
},
"image_id": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
Description: "Specify image id for create disk from template",
},
"disk_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Disk ID",
},
"permanently": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Disk deletion status",
},
},
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
},
*/
},
"network": {
Type: schema.TypeSet,
@@ -384,7 +446,7 @@ func DataSourceCompute() *schema.Resource {
"started": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Computed: true,
Description: "Is compute started.",
},
},

View File

@@ -34,6 +34,7 @@ package kvmvm
import (
"context"
"encoding/json"
"fmt"
"net/url"
"strconv"
@@ -41,6 +42,7 @@ import (
"github.com/rudecs/terraform-provider-decort/internal/constants"
"github.com/rudecs/terraform-provider-decort/internal/controller"
"github.com/rudecs/terraform-provider-decort/internal/statefuncs"
"github.com/rudecs/terraform-provider-decort/internal/status"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -208,6 +210,20 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
}
if enabled, ok := d.GetOk("enabled"); ok {
api := ComputeDisableAPI
if enabled.(bool) {
api = ComputeEnableAPI
}
urlValues := &url.Values{}
urlValues.Add("computeId", fmt.Sprintf("%d", compId))
log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", compId, enabled)
if _, err := c.DecortAPICall(ctx, "POST", api, urlValues); err != nil {
return diag.FromErr(err)
}
}
if !cleanup {
if disks, ok := d.GetOk("disks"); ok {
log.Debugf("resourceComputeCreate: Create disks on ComputeID: %d", compId)
@@ -258,6 +274,8 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
log.Debugf("resourceComputeRead: called for Compute name %s, RG ID %d",
d.Get("name").(string), d.Get("rg_id").(int))
c := m.(*controller.ControllerCfg)
compFacts, err := utilityComputeCheckPresence(ctx, d, m)
if compFacts == "" {
if err != nil {
@@ -267,6 +285,49 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
return nil
}
compute := &ComputeGetResp{}
err = json.Unmarshal([]byte(compFacts), compute)
log.Debugf("resourceComputeRead: compute is: %+v", compute)
if err != nil {
return diag.FromErr(err)
}
switch compute.Status {
case status.Deleted:
urlValues := &url.Values{}
urlValues.Add("computeId", d.Id())
_, err := c.DecortAPICall(ctx, "POST", ComputeRestoreAPI, urlValues)
if err != nil {
return diag.FromErr(err)
}
_, err = c.DecortAPICall(ctx, "POST", ComputeEnableAPI, urlValues)
if err != nil {
return diag.FromErr(err)
}
case status.Destroyed:
d.SetId("")
return resourceComputeCreate(ctx, d, m)
case status.Disabled:
log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", compute.Status)
case status.Redeploying:
case status.Deleting:
case status.Destroying:
return diag.Errorf("The compute is in progress with status: %s", compute.Status)
case status.Modeled:
return diag.Errorf("The compute is in status: %s, please, contant the support for more information", compute.Status)
}
compFacts, err = utilityComputeCheckPresence(ctx, d, m)
log.Debugf("resourceComputeRead: after changes compute is: %s", compFacts)
if compFacts == "" {
if err != nil {
return diag.FromErr(err)
}
// Compute with such name and RG ID was not found
return nil
}
if err = flattenCompute(d, compFacts); err != nil {
return diag.FromErr(err)
}
@@ -283,6 +344,56 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
c := m.(*controller.ControllerCfg)
computeRaw, err := utilityComputeCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
compute := &ComputeGetResp{}
err = json.Unmarshal([]byte(computeRaw), compute)
if err != nil {
return diag.FromErr(err)
}
if d.HasChange("enabled") {
enabled := d.Get("enabled")
api := ComputeDisableAPI
if enabled.(bool) {
api = ComputeEnableAPI
}
urlValues := &url.Values{}
urlValues.Add("computeId", d.Id())
log.Debugf("resourceComputeUpdate: enable=%t Compute ID %s after completing its resource configuration", d.Id(), enabled)
if _, err := c.DecortAPICall(ctx, "POST", api, urlValues); err != nil {
return diag.FromErr(err)
}
}
// check compute statuses
switch compute.Status {
case status.Deleted:
urlValues := &url.Values{}
urlValues.Add("computeId", d.Id())
_, err := c.DecortAPICall(ctx, "POST", ComputeRestoreAPI, urlValues)
if err != nil {
return diag.FromErr(err)
}
_, err = c.DecortAPICall(ctx, "POST", ComputeEnableAPI, urlValues)
if err != nil {
return diag.FromErr(err)
}
case status.Destroyed:
d.SetId("")
return resourceComputeCreate(ctx, d, m)
case status.Disabled:
log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", compute.Status)
case status.Redeploying:
case status.Deleting:
case status.Destroying:
return diag.Errorf("The compute is in progress with status: %s", compute.Status)
case status.Modeled:
return diag.Errorf("The compute is in status: %s, please, contant the support for more information", compute.Status)
}
/*
1. Resize CPU/RAM
2. Resize (grow) boot disk
@@ -348,7 +459,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
}
// 4. Calculate and apply changes to network connections
err := utilityComputeNetworksConfigure(ctx, d, m, true, false) // pass do_delta = true to apply changes, if any
err = utilityComputeNetworksConfigure(ctx, d, m, true, false) // pass do_delta = true to apply changes, if any
if err != nil {
return diag.FromErr(err)
}
@@ -678,6 +789,13 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.",
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "If true - enable compute, else - disable",
},
// The rest are Compute properties, which are "computed" once it is created
"rg_name": {
Type: schema.TypeString,
@@ -715,7 +833,7 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
"started": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Computed: true,
Description: "Is compute started.",
},
"detach_disks": {