Moving from TypeList to TypeSet for network and extra_disks attributes of compute

rc-1.30
Sergey Shubin svs1370 3 years ago
parent d0fdf38473
commit 8da3f8d348

@ -65,6 +65,8 @@ func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
return result return result
} }
// NOTE: this is a legacy function, which is not used as of rc-1.10
// Use "parseComputeDisksToExtraDisks" instead
func parseComputeDisks(disks []DiskRecord) []interface{} { func parseComputeDisks(disks []DiskRecord) []interface{} {
// Return value was designed to d.Set("disks",) item of dataSourceCompute schema // Return value was designed to d.Set("disks",) item of dataSourceCompute schema
// However, this item was excluded from the schema as it is not directly // However, this item was excluded from the schema as it is not directly
@ -80,21 +82,20 @@ func parseComputeDisks(disks []DiskRecord) []interface{} {
} }
*/ */
result := make([]interface{}, length) result := []interface{}{}
if length == 0 { if length == 0 {
return result return result
} }
elem := make(map[string]interface{}) for _, value := range disks {
for i, value := range disks {
/* /*
if value.Type == "B" { if value.Type == "B" {
// skip boot disk when parsing the list of disks // skip boot disk when parsing the list of disks
continue continue
} }
*/ */
elem := make(map[string]interface{})
// keys in this map should correspond to the Schema definition // keys in this map should correspond to the Schema definition
// as returned by dataSourceDiskSchemaMake() // as returned by dataSourceDiskSchemaMake()
elem["name"] = value.Name elem["name"] = value.Name
@ -111,7 +112,8 @@ func parseComputeDisks(disks []DiskRecord) []interface{} {
// elem["status"] = value.Status // elem["status"] = value.Status
// elem["tech_status"] = value.TechStatus // elem["tech_status"] = value.TechStatus
elem["compute_id"] = value.ComputeID elem["compute_id"] = value.ComputeID
result[i] = elem
result = append(result, elem)
} }
return result return result
@ -149,8 +151,32 @@ func parseBootDiskId(disks []DiskRecord) uint {
// Parse the list of interfaces from compute/get response into a list of networks // Parse the list of interfaces from compute/get response into a list of networks
// attached to this compute // attached to this compute
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
// return value will be used to d.Set("network") item of dataSourceCompute schema
length := len(ifaces)
log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length)
result := []interface{}{}
for _, value := range ifaces {
elem := make(map[string]interface{})
// Keys in this map should correspond to the Schema definition
// as returned by networkSubresourceSchemaMake()
elem["net_id"] = value.NetID
elem["net_type"] = value.NetType
elem["ip_address"] = value.IPAddress
elem["mac"] = value.MAC
// log.Debugf(" element %d: net_id=%d, net_type=%s", i, value.NetID, value.NetType)
result = append(result, elem)
}
return result
}
/*
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]interface{} { func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]interface{} {
// return value will be used to d.Set("network",) item of dataSourceCompute schema // return value will be used to d.Set("network") item of dataSourceCompute schema
length := len(ifaces) length := len(ifaces)
log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length) log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length)
@ -172,7 +198,10 @@ func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]int
return result return result
} }
*/
// NOTE: this function is retained for historical purposes and actually not used as of rc-1.10
func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} { func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} {
// return value was designed to d.Set("interfaces",) item of dataSourceCompute schema // return value was designed to d.Set("interfaces",) item of dataSourceCompute schema
// However, this item was excluded from the schema as it is not directly // However, this item was excluded from the schema as it is not directly
@ -374,7 +403,7 @@ func dataSourceCompute() *schema.Resource {
}, },
"extra_disks": { "extra_disks": {
Type: schema.TypeList, Type: schema.TypeSet,
Computed: true, Computed: true,
MaxItems: MaxExtraDisksPerCompute, MaxItems: MaxExtraDisksPerCompute,
Elem: &schema.Schema { Elem: &schema.Schema {
@ -395,7 +424,7 @@ func dataSourceCompute() *schema.Resource {
*/ */
"network": { "network": {
Type: schema.TypeList, Type: schema.TypeSet,
Optional: true, Optional: true,
MaxItems: MaxNetworksPerCompute, MaxItems: MaxNetworksPerCompute,
Elem: &schema.Resource{ Elem: &schema.Resource{

@ -44,6 +44,7 @@ func diskSubresourceSchemaMake() map[string]*schema.Schema {
"account_id": { "account_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Computed: true, Computed: true,
ValidateFunc: validation.IntAtLeast(1),
Description: "ID of the account this disk belongs to.", Description: "ID of the account this disk belongs to.",
}, },

@ -21,11 +21,15 @@ import (
// "encoding/json" // "encoding/json"
// "fmt" // "fmt"
"bytes"
"hash/fnv"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
// "net/url" // "net/url"
"sort"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
// "github.com/hashicorp/terraform-plugin-sdk/v2/internal/helper/hashcode"
) )
// This is subresource of compute resource used when creating/managing compute network connections // This is subresource of compute resource used when creating/managing compute network connections
@ -39,6 +43,71 @@ func networkSubresIPAddreDiffSupperss(key, oldVal, newVal string, d *schema.Reso
return true // suppress difference return true // suppress difference
} }
// This function is based on the original Terraform SerializeResourceForHash found
// in helper/schema/serialize.go
// It skips network subresource attributes, which are irrelevant for identification
// of unique network blocks
func networkSubresourceSerialize(output *bytes.Buffer, val interface{}, resource *schema.Resource) {
if val == nil {
return
}
rs := resource.Schema
m := val.(map[string]interface{})
var keys []string
allComputed := true
for k, val := range rs {
if val.Optional || val.Required {
allComputed = false
}
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
// explicitly ignore "ip_address" when hashing
if k == "ip_address" {
continue
}
subSchema := rs[k]
// Skip attributes that are not user-provided. Computed attributes
// do not contribute to the hash since their ultimate value cannot
// be known at plan/diff time.
if !allComputed && !(subSchema.Required || subSchema.Optional) {
continue
}
output.WriteString(k)
output.WriteRune(':')
value := m[k]
schema.SerializeValueForHash(output, value, subSchema)
}
}
// HashNetworkSubresource hashes network subresource of compute resource. It uses
// specially designed networkSubresourceSerialize (see above) to make sure hashing
// does not involve attributes that we deem irrelevant to the uniqueness of network
// subresource definitions.
// It is this function that should be specified as SchemaSetFunc when creating Set
// from network subresource (e.g. in flattenCompute)
//
// This function is based on the original Terraform function HashResource from
// helper/schema/set.go
func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc {
return func(v interface{}) int {
var serialized bytes.Buffer
networkSubresourceSerialize(&serialized, v, resource)
hs := fnv.New32a()
hs.Write(serialized.Bytes())
return int(hs.Sum32())
}
}
func networkSubresourceSchemaMake() map[string]*schema.Schema { func networkSubresourceSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{ rets := map[string]*schema.Schema{
"net_type": { "net_type": {
@ -58,6 +127,7 @@ func networkSubresourceSchemaMake() map[string]*schema.Schema {
"ip_address": { "ip_address": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true,
DiffSuppressFunc: networkSubresIPAddreDiffSupperss, DiffSuppressFunc: networkSubresIPAddreDiffSupperss,
Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.", Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.",
}, },

@ -123,12 +123,12 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
// Configure data disks if any // Configure data disks if any
extraDisksOk := true extraDisksOk := true
argVal, argSet = d.GetOk("extra_disks") argVal, argSet = d.GetOk("extra_disks")
if argSet && len(argVal.([]interface{})) > 0 { if argSet && argVal.(*schema.Set).Len() > 0 {
// urlValues.Add("desc", argVal.(string)) // urlValues.Add("desc", argVal.(string))
log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", len(argVal.([]interface{}))) log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len())
err = controller.utilityComputeExtraDisksConfigure(d, false) // do_delta=false, as we are working on a new compute err = controller.utilityComputeExtraDisksConfigure(d, false) // do_delta=false, as we are working on a new compute
if err != nil { if err != nil {
log.Errorf("resourceComputeCreate: error when attaching extra disks to a new Compute ID %s: %s", compId, err) log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %s: %s", compId, err)
extraDisksOk = false extraDisksOk = false
} }
} }
@ -139,8 +139,8 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
// Configure external networks if any // Configure external networks if any
netsOk := true netsOk := true
argVal, argSet = d.GetOk("network") argVal, argSet = d.GetOk("network")
if argSet && len(argVal.([]interface{})) > 0 { if argSet && argVal.(*schema.Set).Len() > 0 {
log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", len(argVal.([]interface{}))) log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", argVal.(*schema.Set).Len())
err = controller.utilityComputeNetworksConfigure(d, false) // do_delta=false, as we are working on a new compute err = controller.utilityComputeNetworksConfigure(d, false) // do_delta=false, as we are working on a new compute
if err != nil { if err != nil {
log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", compId, err) log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", compId, err)
@ -398,12 +398,12 @@ func resourceCompute() *schema.Resource {
"boot_disk_size": { "boot_disk_size": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Required: true,
Description: "This compute instance boot disk size in GB.", Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.",
}, },
"extra_disks": { "extra_disks": {
Type: schema.TypeList, Type: schema.TypeSet,
Optional: true, Optional: true,
MaxItems: MaxExtraDisksPerCompute, MaxItems: MaxExtraDisksPerCompute,
Elem: &schema.Schema{ Elem: &schema.Schema{
@ -413,7 +413,7 @@ func resourceCompute() *schema.Resource {
}, },
"network": { "network": {
Type: schema.TypeList, Type: schema.TypeSet,
Optional: true, Optional: true,
MaxItems: MaxNetworksPerCompute, MaxItems: MaxNetworksPerCompute,
Elem: &schema.Resource{ Elem: &schema.Resource{

@ -146,7 +146,28 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceResgroupUpdate: called for RG name %s, account ID %d", log.Debugf("resourceResgroupUpdate: called for RG name %s, account ID %d",
d.Get("name").(string), d.Get("account_id").(int)) d.Get("name").(string), d.Get("account_id").(int))
do_update := false /* NOTE: we do not allow changing the following attributes of an existing RG via terraform:
- def_net_type
- ipcidr
- ext_net_id
- ext_ip
The following code fragment checks if any of these have been changed and generates error.
*/
for _, attr := range []string{"def_net_type", "ipcidr", "ext_ip"} {
attr_new, attr_old := d.GetChange("def_net_type")
if attr_new.(string) != attr_old.(string) {
return fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing %s for existing RG is not allowed", d.Id(), attr)
}
}
attr_new, attr_old := d.GetChange("ext_net_id")
if attr_new.(int) != attr_old.(int) {
return fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing ext_net_id for existing RG is not allowed", d.Id())
}
do_general_update := false // will be true if general RG update is necessary (API rg/update)
controller := m.(*ControllerCfg) controller := m.(*ControllerCfg)
url_values := &url.Values{} url_values := &url.Values{}
@ -157,7 +178,7 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceResgroupUpdate: name specified - looking for deltas from the old settings.") log.Debugf("resourceResgroupUpdate: name specified - looking for deltas from the old settings.")
name_old, _ := d.GetChange("name") name_old, _ := d.GetChange("name")
if name_old.(string) != name_new.(string) { if name_old.(string) != name_new.(string) {
do_update = true do_general_update = true
url_values.Add("name", name_new.(string)) url_values.Add("name", name_new.(string))
} }
} }
@ -170,31 +191,31 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
quotarecord_old, _ := makeQuotaRecord(quota_value_old.([]interface{})) quotarecord_old, _ := makeQuotaRecord(quota_value_old.([]interface{}))
if quotarecord_new.Cpu != quotarecord_old.Cpu { if quotarecord_new.Cpu != quotarecord_old.Cpu {
do_update = true do_general_update = true
log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotarecord_new.Cpu, quotarecord_old.Cpu) log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotarecord_new.Cpu, quotarecord_old.Cpu)
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotarecord_new.Cpu)) url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotarecord_new.Cpu))
} }
if quotarecord_new.Disk != quotarecord_old.Disk { if quotarecord_new.Disk != quotarecord_old.Disk {
do_update = true do_general_update = true
log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotarecord_new.Disk, quotarecord_old.Disk) log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotarecord_new.Disk, quotarecord_old.Disk)
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotarecord_new.Disk)) url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotarecord_new.Disk))
} }
if quotarecord_new.Ram != quotarecord_old.Ram { // NB: quota on RAM is stored as float32, in units of MB if quotarecord_new.Ram != quotarecord_old.Ram { // NB: quota on RAM is stored as float32, in units of MB
do_update = true do_general_update = true
log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecord_new.Ram, quotarecord_old.Ram) log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecord_new.Ram, quotarecord_old.Ram)
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecord_new.Ram)) url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecord_new.Ram))
} }
if quotarecord_new.ExtTraffic != quotarecord_old.ExtTraffic { if quotarecord_new.ExtTraffic != quotarecord_old.ExtTraffic {
do_update = true do_general_update = true
log.Debugf("resourceResgroupUpdate: ExtTraffic diff %d <- %d", quotarecord_new.ExtTraffic, quotarecord_old.ExtTraffic) log.Debugf("resourceResgroupUpdate: ExtTraffic diff %d <- %d", quotarecord_new.ExtTraffic, quotarecord_old.ExtTraffic)
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotarecord_new.ExtTraffic)) url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotarecord_new.ExtTraffic))
} }
if quotarecord_new.ExtIPs != quotarecord_old.ExtIPs { if quotarecord_new.ExtIPs != quotarecord_old.ExtIPs {
do_update = true do_general_update = true
log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotarecord_new.ExtIPs, quotarecord_old.ExtIPs) log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotarecord_new.ExtIPs, quotarecord_old.ExtIPs)
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotarecord_new.ExtIPs)) url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotarecord_new.ExtIPs))
} }
@ -205,12 +226,12 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceResgroupUpdate: description specified - looking for deltas from the old settings.") log.Debugf("resourceResgroupUpdate: description specified - looking for deltas from the old settings.")
desc_old, _ := d.GetChange("description") desc_old, _ := d.GetChange("description")
if desc_old.(string) != desc_new.(string) { if desc_old.(string) != desc_new.(string) {
do_update = true do_general_update = true
url_values.Add("desc", desc_new.(string)) url_values.Add("desc", desc_new.(string))
} }
} }
if do_update { if do_general_update {
log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG") log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG")
_, err := controller.decortAPICall("POST", ResgroupUpdateAPI, url_values) _, err := controller.decortAPICall("POST", ResgroupUpdateAPI, url_values)
if err != nil { if err != nil {
@ -303,7 +324,7 @@ func resourceResgroup() *schema.Resource {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Default: "PRIVATE", Default: "PRIVATE",
// ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC", "NONE"}, false), ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC", "NONE"}, false),
Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.", Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.",
}, },
@ -323,13 +344,13 @@ func resourceResgroup() *schema.Resource {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Default: 0, Default: 0,
Description: "ID of the external network, which this resource group will use as default for its computes if def_net_type=PUBLIC", Description: "ID of the external network for default ViNS. Pass 0 if def_net_type=PUBLIC or no external connection required for the defult ViNS when def_net_type=PRIVATE",
}, },
"ext_ip": { "ext_ip": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Description: "IP address on the external netowrk to request, if def_net_type=PUBLIC", Description: "IP address on the external netowrk to request when def_net_type=PRIVATE and ext_net_id is not 0",
}, },
/* commented out, as in this version of provider we use default Grid ID /* commented out, as in this version of provider we use default Grid ID

@ -33,6 +33,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation" // "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
) )
@ -223,6 +224,7 @@ func resourceVinsSchemaMake() map[string]*schema.Schema {
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ValidateFunc: validation.StringIsNotEmpty,
Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.", Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.",
}, },
@ -247,12 +249,14 @@ func resourceVinsSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ForceNew: true, ForceNew: true,
ValidateFunc: validation.IntAtLeast(1),
Description: "ID of the account, which this ViNS belongs to. For ViNS created at account level, resource group ID is 0.", Description: "ID of the account, which this ViNS belongs to. For ViNS created at account level, resource group ID is 0.",
}, },
"ext_net_id": { "ext_net_id": {
Type: schema.TypeInt, Type: schema.TypeInt,
Required: true, Required: true,
ValidateFunc: validation.IntAtLeast(0),
Description: "ID of the external network this ViNS is connected to. Pass 0 if no external connection required.", Description: "ID of the external network this ViNS is connected to. Pass 0 if no external connection required.",
}, },

@ -45,8 +45,10 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
// disks via atomic API calls. However, it will not retry failed manipulation on the same disk. // disks via atomic API calls. However, it will not retry failed manipulation on the same disk.
log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %b", d.Id(), do_delta) log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %b", d.Id(), do_delta)
// NB: as of rc-1.25 "extra_disks" are TypeSet with the elem of TypeInt
old_set, new_set := d.GetChange("extra_disks") old_set, new_set := d.GetChange("extra_disks")
/*
old_disks := make([]interface{},0,0) old_disks := make([]interface{},0,0)
if old_set != nil { if old_set != nil {
old_disks = old_set.([]interface{}) old_disks = old_set.([]interface{})
@ -56,16 +58,17 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
if new_set != nil { if new_set != nil {
new_disks = new_set.([]interface{}) new_disks = new_set.([]interface{})
} }
*/
apiErrCount := 0 apiErrCount := 0
var lastSavedError error var lastSavedError error
if !do_delta { if !do_delta {
if len(new_disks) < 1 { if new_set.(*schema.Set).Len() < 1 {
return nil return nil
} }
for _, disk := range new_disks { for _, disk := range new_set.(*schema.Set).List() {
urlValues := &url.Values{} urlValues := &url.Values{}
urlValues.Add("computeId", d.Id()) urlValues.Add("computeId", d.Id())
urlValues.Add("diskId", fmt.Sprintf("%d", disk.(int))) urlValues.Add("diskId", fmt.Sprintf("%d", disk.(int)))
@ -86,9 +89,10 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
return nil return nil
} }
detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set))
/*
var attach_list, detach_list []int var attach_list, detach_list []int
match := false match := false
for _, oDisk := range old_disks { for _, oDisk := range old_disks {
match = false match = false
for _, nDisk := range new_disks { for _, nDisk := range new_disks {
@ -101,8 +105,10 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
detach_list = append(detach_list, oDisk.(int)) detach_list = append(detach_list, oDisk.(int))
} }
} }
log.Debugf("utilityComputeExtraDisksConfigure: detach list has %d items for Compute ID %s", len(detach_list), d.Id()) */
log.Debugf("utilityComputeExtraDisksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id())
/*
for _, nDisk := range new_disks { for _, nDisk := range new_disks {
match = false match = false
for _, oDisk := range old_disks { for _, oDisk := range old_disks {
@ -115,29 +121,31 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
attach_list = append(attach_list, nDisk.(int)) attach_list = append(attach_list, nDisk.(int))
} }
} }
log.Debugf("utilityComputeExtraDisksConfigure: attach list has %d items for Compute ID %s", len(attach_list), d.Id()) */
attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set))
log.Debugf("utilityComputeExtraDisksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id())
for _, diskId := range detach_list { for _, diskId := range detach_set.List() {
urlValues := &url.Values{} urlValues := &url.Values{}
urlValues.Add("computeId", d.Id()) urlValues.Add("computeId", d.Id())
urlValues.Add("diskId", fmt.Sprintf("%d", diskId)) urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
_, err := ctrl.decortAPICall("POST", ComputeDiskDetachAPI, urlValues) _, err := ctrl.decortAPICall("POST", ComputeDiskDetachAPI, urlValues)
if err != nil { if err != nil {
// failed to detach disk - there will be partial resource update // failed to detach disk - there will be partial resource update
log.Debugf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId, d.Id(), err) log.Debugf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err)
apiErrCount++ apiErrCount++
lastSavedError = err lastSavedError = err
} }
} }
for _, diskId := range attach_list { for _, diskId := range attach_set.List() {
urlValues := &url.Values{} urlValues := &url.Values{}
urlValues.Add("computeId", d.Id()) urlValues.Add("computeId", d.Id())
urlValues.Add("diskId", fmt.Sprintf("%d", diskId)) urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
_, err := ctrl.decortAPICall("POST", ComputeDiskAttachAPI, urlValues) _, err := ctrl.decortAPICall("POST", ComputeDiskAttachAPI, urlValues)
if err != nil { if err != nil {
// failed to attach disk - there will be partial resource update // failed to attach disk - there will be partial resource update
log.Debugf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId, d.Id(), err) log.Debugf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err)
apiErrCount++ apiErrCount++
lastSavedError = err lastSavedError = err
} }
@ -152,7 +160,6 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
return nil return nil
} }
// TODO: implement do_delta logic
func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceData, do_delta bool) error { func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceData, do_delta bool) error {
// "d" is filled with data according to computeResource schema, so extra networks config is retrieved via "network" key // "d" is filled with data according to computeResource schema, so extra networks config is retrieved via "network" key
// If do_delta is true, this function will identify changes between new and existing specs for network and try to // If do_delta is true, this function will identify changes between new and existing specs for network and try to
@ -170,12 +177,12 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
oldNets := make([]interface{},0,0) oldNets := make([]interface{},0,0)
if old_set != nil { if old_set != nil {
oldNets = old_set.([]interface{}) // network is ar array of maps; for keys see func networkSubresourceSchemaMake() definition oldNets = old_set.(*schema.Set).List() // network set is ar array of maps; for keys see func networkSubresourceSchemaMake() definition
} }
newNets := make([]interface{},0,0) newNets := make([]interface{},0,0)
if new_set != nil { if new_set != nil {
newNets = new_set.([]interface{}) // network is ar array of maps; for keys see func networkSubresourceSchemaMake() definition newNets = new_set.(*schema.Set).List() // network set is ar array of maps; for keys see func networkSubresourceSchemaMake() definition
} }
apiErrCount := 0 apiErrCount := 0

Loading…
Cancel
Save