This commit is contained in:
2024-11-12 13:41:38 +03:00
parent 040af43607
commit 36879efd58
517 changed files with 37877 additions and 1900 deletions

View File

@@ -260,6 +260,10 @@ func computeListDisksSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt,
Computed: true,
},
"bus_number": {
Type: schema.TypeInt,
Computed: true,
},
"created_time": {
Type: schema.TypeInt,
Computed: true,
@@ -475,6 +479,10 @@ func computeQOSSchemaMake() map[string]*schema.Schema {
func computeInterfacesSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"bus_number": {
Type: schema.TypeInt,
Computed: true,
},
"conn_id": {
Type: schema.TypeInt,
Computed: true,
@@ -511,6 +519,10 @@ func computeInterfacesSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString,
Computed: true,
},
"mtu": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
@@ -542,6 +554,13 @@ func computeInterfacesSchemaMake() map[string]*schema.Schema {
Schema: computeQOSSchemaMake(),
},
},
"libvirt_settings": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: computeLibvirtSettingsSchemaMake(),
},
},
"target": {
Type: schema.TypeString,
Computed: true,
@@ -559,6 +578,40 @@ func computeInterfacesSchemaMake() map[string]*schema.Schema {
},
}
}
func computeLibvirtSettingsSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"guid": {
Type: schema.TypeString,
Computed: true,
},
"txmode": {
Type: schema.TypeString,
Computed: true,
},
"ioeventfd": {
Type: schema.TypeString,
Computed: true,
},
"event_idx": {
Type: schema.TypeString,
Computed: true,
},
"queues": {
Type: schema.TypeInt,
Computed: true,
},
"rx_queue_size": {
Type: schema.TypeInt,
Computed: true,
},
"tx_queue_size": {
Type: schema.TypeInt,
Computed: true,
},
}
}
func computeOsUsersSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"guid": {
@@ -650,6 +703,10 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString,
Computed: true,
},
"chipset": {
Type: schema.TypeString,
Computed: true,
},
"boot_order": {
Type: schema.TypeList,
Computed: true,

View File

@@ -64,6 +64,10 @@ func dataSourceComputeListRead(ctx context.Context, d *schema.ResourceData, m in
func computeDisksSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"bus_number": {
Type: schema.TypeInt,
Computed: true,
},
"disk_id": {
Type: schema.TypeInt,
Computed: true,
@@ -136,6 +140,10 @@ func itemComputeSchemaMake() map[string]*schema.Schema {
Type: schema.TypeInt,
Computed: true,
},
"chipset": {
Type: schema.TypeString,
Computed: true,
},
"clones": {
Type: schema.TypeList,
Computed: true,

View File

@@ -47,8 +47,9 @@ func flattenDisks(disks []compute.InfoDisk) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, disk := range disks {
temp := map[string]interface{}{
"disk_id": disk.ID,
"pci_slot": disk.PCISlot,
"bus_number": disk.BusNumber,
"disk_id": disk.ID,
"pci_slot": disk.PCISlot,
}
res = append(res, temp)
}
@@ -69,30 +70,49 @@ func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface
res := make([]map[string]interface{}, 0, len(interfaces))
for _, interfaceItem := range interfaces {
temp := map[string]interface{}{
"conn_id": interfaceItem.ConnID,
"conn_type": interfaceItem.ConnType,
"def_gw": interfaceItem.DefGW,
"enabled": interfaceItem.Enabled,
"flip_group_id": interfaceItem.FLIPGroupID,
"guid": interfaceItem.GUID,
"ip_address": interfaceItem.IPAddress,
"listen_ssh": interfaceItem.ListenSSH,
"mac": interfaceItem.MAC,
"name": interfaceItem.Name,
"net_id": interfaceItem.NetID,
"netmask": interfaceItem.NetMask,
"net_type": interfaceItem.NetType,
"node_id": interfaceItem.NodeID,
"pci_slot": interfaceItem.PCISlot,
"qos": flattenQOS(interfaceItem.QOS),
"target": interfaceItem.Target,
"type": interfaceItem.Type,
"vnfs": interfaceItem.VNFs,
"bus_number": interfaceItem.BusNumber,
"conn_id": interfaceItem.ConnID,
"conn_type": interfaceItem.ConnType,
"def_gw": interfaceItem.DefGW,
"enabled": interfaceItem.Enabled,
"flip_group_id": interfaceItem.FLIPGroupID,
"guid": interfaceItem.GUID,
"ip_address": interfaceItem.IPAddress,
"listen_ssh": interfaceItem.ListenSSH,
"mac": interfaceItem.MAC,
"mtu": interfaceItem.MTU,
"name": interfaceItem.Name,
"net_id": interfaceItem.NetID,
"netmask": interfaceItem.NetMask,
"net_type": interfaceItem.NetType,
"node_id": interfaceItem.NodeID,
"pci_slot": interfaceItem.PCISlot,
"qos": flattenQOS(interfaceItem.QOS),
"target": interfaceItem.Target,
"type": interfaceItem.Type,
"vnfs": interfaceItem.VNFs,
"libvirt_settings": flattenLibvirtSettings(interfaceItem.LibvirtSettings),
}
res = append(res, temp)
}
return res
}
func flattenLibvirtSettings(libvirtSettings compute.LibvirtSettings) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"guid": libvirtSettings.GUID,
"txmode": libvirtSettings.TXMode,
"ioeventfd": libvirtSettings.IOEventFD,
"event_idx": libvirtSettings.EventIDx,
"queues": libvirtSettings.Queues,
"rx_queue_size": libvirtSettings.RXQueueSize,
"tx_queue_size": libvirtSettings.TXQueueSize,
}
res = append(res, temp)
return res
}
func flattenSnapSets(snapSets compute.ListSnapSets) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(snapSets))
for _, snapSet := range snapSets {
@@ -165,6 +185,7 @@ func flattenComputeList(computes *compute.ListComputes) []map[string]interface{}
"arch": compute.Architecture,
"boot_order": compute.BootOrder,
"bootdisk_size": compute.BootDiskSize,
"chipset": compute.Chipset,
"cd_image_id": compute.CdImageId,
"clone_reference": compute.CloneReference,
"clones": compute.Clones,
@@ -348,6 +369,7 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute, pc
d.Set("cd_image_id", computeRec.CdImageId)
d.Set("sep_id", bootDisk.SepID)
d.Set("pool", bootDisk.Pool)
d.Set("chipset", computeRec.Chipset)
d.Set("clone_reference", computeRec.CloneReference)
d.Set("clones", computeRec.Clones)
d.Set("computeci_id", computeRec.ComputeCIID)
@@ -503,6 +525,7 @@ func flattenListComputeDisks(disks compute.ListComputeDisks) []map[string]interf
"acl": string(acl),
"account_id": disk.AccountID,
"boot_partition": disk.BootPartition,
"bus_number": disk.BusNumber,
"created_time": disk.CreatedTime,
"deleted_time": disk.DeletedTime,
"description": disk.Description,
@@ -590,6 +613,7 @@ func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute
d.Set("affinity_weight", computeRec.AffinityWeight)
d.Set("anti_affinity_rules", flattenListRules(computeRec.AntiAffinityRules))
d.Set("arch", computeRec.Architecture)
d.Set("chipset", computeRec.Chipset)
d.Set("boot_order", computeRec.BootOrder)
d.Set("bootdisk_size", computeRec.BootDiskSize)
d.Set("cd_image_id", computeRec.CdImageId)

View File

@@ -128,7 +128,7 @@ func networkSubresourceSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString,
Required: true,
StateFunc: statefuncs.StateFuncToUpper,
ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS", "VFNIC"}, false), // observe case while validating
ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS", "VFNIC", "DPDK"}, false), // observe case while validating
Description: "Type of the network for this connection, either EXTNET or VINS.",
},

View File

@@ -27,7 +27,7 @@ func resourceComputeResourceV1() *schema.Resource {
Required: true,
ForceNew: true,
StateFunc: statefuncs.StateFuncToUpper,
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86", "KVM_PPC"}, false), // observe case while validating
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86"}, false), // observe case while validating
Description: "Hardware architecture of this compute instance.",
},
"cpu": {
@@ -569,7 +569,7 @@ func resourceComputeResourceV2() *schema.Resource {
Required: true,
ForceNew: true,
StateFunc: statefuncs.StateFuncToUpper,
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86", "KVM_PPC"}, false), // observe case while validating
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86"}, false), // observe case while validating
Description: "Hardware architecture of this compute instance.",
},
"cpu": {

View File

@@ -38,6 +38,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/dpdknet"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg"
@@ -147,6 +148,23 @@ func existVFPoolId(ctx context.Context, m interface{}, id int) (int, bool) {
return id, false
}
func existDPDKNetId(ctx context.Context, m interface{}, id int) (int, bool) {
c := m.(*controller.ControllerCfg)
req := dpdknet.ListRequest{ByID: uint64(id)}
dpdkList, err := c.CloudAPI().DPDKNet().List(ctx, req)
if err != nil {
log.Debugf("Unable to retrieve vfpool list, %s", err)
return id, false
}
if len(dpdkList.Data) == 1 {
return 0, true
}
return id, false
}
func isMoreThanOneDisksTypeB(ctx context.Context, disks interface{}) bool {
count := 0

View File

@@ -42,7 +42,6 @@ import (
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmppc"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmx86"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
@@ -60,7 +59,6 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int))
c := m.(*controller.ControllerCfg)
createReqX86 := kvmx86.CreateRequest{}
createReqPPC := kvmppc.CreateRequest{}
hasRG, err := existRgID(ctx, d, m)
if err != nil {
@@ -101,12 +99,13 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
return diag.Errorf("resourceComputeCreate: can't create compute because extnet ID %d is not allowed or does not exist", extNetId)
}
case "VFNIC":
if d.Get("driver").(string) == "KVM_PPC" {
return diag.Errorf("resourceComputeCreate: can't create compute because 'VFNIC' net_type is not allowed for driver 'KVM_PPC'")
}
if vfpoolId, ok := existVFPoolId(ctx, m, networkData["net_id"].(int)); !ok {
return diag.Errorf("resourceComputeCreate: can't create compute because vfpool ID %d is not allowed or does not exist", vfpoolId)
}
case "DPDK":
if dpdkId, ok := existDPDKNetId(ctx, m, networkData["net_id"].(int)); !ok {
return diag.Errorf("resourceComputeCreate: can't create compute because DPDK ID %d is not allowed or does not exist", dpdkId)
}
default:
continue
}
@@ -115,32 +114,26 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
argVal, ok := d.GetOk("description")
if ok {
createReqPPC.Description = argVal.(string)
createReqX86.Description = argVal.(string)
}
if sepID, ok := d.GetOk("sep_id"); ok {
createReqPPC.SEPID = uint64(sepID.(int))
createReqX86.SepID = uint64(sepID.(int))
}
if pool, ok := d.GetOk("pool"); ok {
createReqPPC.Pool = pool.(string)
createReqX86.Pool = pool.(string)
}
if ipaType, ok := d.GetOk("ipa_type"); ok {
createReqPPC.IPAType = ipaType.(string)
createReqX86.IPAType = ipaType.(string)
}
if bootSize, ok := d.GetOk("boot_disk_size"); ok {
createReqPPC.BootDisk = uint64(bootSize.(int))
createReqX86.BootDisk = uint64(bootSize.(int))
}
if IS, ok := d.GetOk("is"); ok {
createReqPPC.IS = IS.(string)
createReqX86.IS = IS.(string)
}
@@ -181,45 +174,8 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
}
createReqPPC.Interfaces = make([]kvmppc.Interface, 0)
if networks, ok := d.GetOk("network"); ok {
if networks.(*schema.Set).Len() > 0 {
ns := networks.(*schema.Set).List()
sort.Slice(ns, func(i, j int) bool {
weightI := ns[i].(map[string]interface{})["weight"].(int)
weightJ := ns[j].(map[string]interface{})["weight"].(int)
if weightI == 0 {
return false
}
if weightJ == 0 {
return true
}
return weightI < weightJ
})
interfaces := make([]kvmppc.Interface, 0)
for _, elem := range ns {
netInterfaceVal := elem.(map[string]interface{})
reqInterface := kvmppc.Interface{
NetType: netInterfaceVal["net_type"].(string),
NetID: uint64(netInterfaceVal["net_id"].(int)),
}
ipaddr, ipSet := netInterfaceVal["ip_address"]
if ipSet {
reqInterface.IPAddr = ipaddr.(string)
}
interfaces = append(interfaces, reqInterface)
}
createReqPPC.Interfaces = interfaces
}
}
if disks, ok := d.GetOk("disks"); ok {
disksX86 := make([]kvmx86.DataDisk, 0)
disksPPC := make([]kvmppc.DataDisk, 0)
for _, elem := range disks.([]interface{}) {
diskVal := elem.(map[string]interface{})
@@ -244,96 +200,58 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
createReqX86.DataDisks = disksX86
for _, elem := range disks.([]interface{}) {
diskVal := elem.(map[string]interface{})
reqDataDisk := kvmppc.DataDisk{
DiskName: diskVal["disk_name"].(string),
Size: uint64(diskVal["size"].(int)),
}
if sepId, ok := diskVal["sep_id"]; ok {
reqDataDisk.SepID = uint64(sepId.(int))
}
if pool, ok := diskVal["pool"]; ok {
reqDataDisk.Pool = pool.(string)
}
if desc, ok := diskVal["desc"]; ok {
reqDataDisk.Description = desc.(string)
}
if imageID, ok := diskVal["image_id"]; ok {
reqDataDisk.ImageID = uint64(imageID.(int))
}
disksPPC = append(disksPPC, reqDataDisk)
}
createReqPPC.DataDisks = disksPPC
}
argVal, ok = d.GetOk("cloud_init")
if ok {
userdata := argVal.(string)
if userdata != "" && userdata != "applied" {
createReqPPC.Userdata = strings.TrimSpace(userdata)
createReqX86.Userdata = strings.TrimSpace(userdata)
}
}
var computeId uint64
driver := d.Get("driver").(string)
if driver == "KVM_PPC" {
createReqPPC.RGID = uint64(d.Get("rg_id").(int))
createReqPPC.Name = d.Get("name").(string)
createReqPPC.CPU = uint64(d.Get("cpu").(int))
createReqPPC.RAM = uint64(d.Get("ram").(int))
createReqPPC.ImageID = uint64(d.Get("image_id").(int))
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM PowerPC")
apiResp, err := c.CloudAPI().KVMPPC().Create(ctx, createReqPPC)
if err != nil {
return diag.FromErr(err)
}
createReqX86.RGID = uint64(d.Get("rg_id").(int))
createReqX86.Name = d.Get("name").(string)
createReqX86.CPU = uint64(d.Get("cpu").(int))
createReqX86.RAM = uint64(d.Get("ram").(int))
d.SetId(strconv.FormatUint(apiResp, 10))
computeId = apiResp
} else {
createReqX86.RGID = uint64(d.Get("rg_id").(int))
createReqX86.Name = d.Get("name").(string)
createReqX86.CPU = uint64(d.Get("cpu").(int))
createReqX86.RAM = uint64(d.Get("ram").(int))
createReqX86.Driver = driver
createReqX86.Driver = driver
if image, ok := d.GetOk("image_id"); ok {
createReqX86.ImageID = uint64(image.(int))
}
if withoutBootDisk, ok := d.GetOk("without_boot_disk"); ok {
createReqX86.WithoutBootDisk = withoutBootDisk.(bool)
}
if custom_fields, ok := d.GetOk("custom_fields"); ok {
val := custom_fields.(string)
val = strings.ReplaceAll(val, "\\", "")
val = strings.ReplaceAll(val, "\n", "")
val = strings.ReplaceAll(val, "\t", "")
val = strings.TrimSpace(val)
createReqX86.CustomFields = val
}
if numaAffinity, ok := d.GetOk("numa_affinity"); ok {
createReqX86.NumaAffinity = numaAffinity.(string)
}
createReqX86.CPUPin = d.Get("cpu_pin").(bool)
createReqX86.HPBacked = d.Get("hp_backed").(bool)
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
apiResp, err := c.CloudAPI().KVMX86().Create(ctx, createReqX86)
if err != nil {
return diag.FromErr(err)
}
d.SetId(strconv.FormatUint(apiResp, 10))
computeId = apiResp
if image, ok := d.GetOk("image_id"); ok {
createReqX86.ImageID = uint64(image.(int))
}
if withoutBootDisk, ok := d.GetOk("without_boot_disk"); ok {
createReqX86.WithoutBootDisk = withoutBootDisk.(bool)
}
if custom_fields, ok := d.GetOk("custom_fields"); ok {
val := custom_fields.(string)
val = strings.ReplaceAll(val, "\\", "")
val = strings.ReplaceAll(val, "\n", "")
val = strings.ReplaceAll(val, "\t", "")
val = strings.TrimSpace(val)
createReqX86.CustomFields = val
}
if numaAffinity, ok := d.GetOk("numa_affinity"); ok {
createReqX86.NumaAffinity = numaAffinity.(string)
}
createReqX86.CPUPin = d.Get("cpu_pin").(bool)
createReqX86.HPBacked = d.Get("hp_backed").(bool)
createReqX86.Chipset = d.Get("chipset").(string)
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
apiResp, err := c.CloudAPI().KVMX86().Create(ctx, createReqX86)
if err != nil {
return diag.FromErr(err)
}
d.SetId(strconv.FormatUint(apiResp, 10))
computeId = apiResp
warnings := dc.Warnings{}
@@ -730,12 +648,13 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
return diag.Errorf("resourceComputeUpdate: can't update compute because extnet ID %d is not allowed or does not exist", extNetId)
}
case "VFNIC":
if d.Get("driver").(string) == "KVM_PPC" {
return diag.Errorf("resourceComputeUpdate: can't create compute because 'VFNIC' net_type is not allowed for driver 'KVM_PPC'")
}
if vfpoolId, ok := existVFPoolId(ctx, m, networkData["net_id"].(int)); !ok {
return diag.Errorf("resourceComputeUpdate: can't create compute because vfpool ID %d is not allowed or does not exist", vfpoolId)
}
case "DPDK":
if dpdkId, ok := existDPDKNetId(ctx, m, networkData["net_id"].(int)); !ok {
return diag.Errorf("resourceComputeCreate: can't create compute because DPDK ID %d is not allowed or does not exist", dpdkId)
}
default:
continue
}
@@ -960,6 +879,10 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
req.HPBacked = d.Get("hp_backed").(bool)
}
if d.HasChange("chipset") {
req.Chipset = d.Get("chipset").(string)
}
// 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
@@ -1449,10 +1372,19 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
Label: snapshotItem["label"].(string),
}
_, err := c.CloudAPI().Compute().SnapshotDelete(ctx, req)
if err != nil {
return diag.FromErr(err)
asyncMode, ok := d.GetOk("snapshot_delete_async")
if ok && asyncMode.(bool) {
_, err := c.CloudAPI().Compute().SnapshotDeleteAsync(ctx, req)
if err != nil {
return diag.FromErr(err)
}
} else {
_, err := c.CloudAPI().Compute().SnapshotDelete(ctx, req)
if err != nil {
return diag.FromErr(err)
}
}
}
}
@@ -1924,7 +1856,7 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Required: true,
// ForceNew: true,
StateFunc: statefuncs.StateFuncToUpper,
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86", "KVM_PPC"}, false), // observe case while validating
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86"}, false), // observe case while validating
Description: "Hardware architecture of this compute instance.",
},
"cpu": {
@@ -1948,6 +1880,12 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
//ForceNew: true, //REDEPLOY
Description: "ID of the OS image to base this compute instance on.",
},
"chipset": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "Type of the emulated system.",
},
"without_boot_disk": {
Type: schema.TypeBool,
Optional: true,
@@ -2124,6 +2062,10 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Schema: snapshotSubresourceSchemaMake(),
},
},
"snapshot_delete_async": {
Type: schema.TypeBool,
Optional: true,
},
"rollback": {
Type: schema.TypeSet,
MaxItems: 1,

View File

@@ -177,13 +177,16 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
oldSet, newSet := d.GetChange("network")
oldList := oldSet.(*schema.Set).List()
newList := newSet.(*schema.Set).List()
detachMap, changeIpMap, attachMap := differenceNetwork(oldList, newList)
apiErrCount := 0
var lastSavedError error
detachSet := oldSet.(*schema.Set).Difference(newSet.(*schema.Set))
log.Debugf("utilityComputeNetworksConfigure: detach set has %d items for Compute ID %s", detachSet.Len(), d.Id())
for _, runner := range detachSet.List() {
netData := runner.(map[string]interface{})
log.Debugf("utilityComputeNetworksConfigure: detach set has %d items for Compute ID %s", len(detachMap), d.Id())
for _, netData := range detachMap {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
req := compute.NetDetachRequest{
ComputeID: computeId,
@@ -200,22 +203,41 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
}
}
log.Debugf("utilityComputeNetworksConfigure: changeIp set has %d items for Compute ID %s", len(changeIpMap), d.Id())
for _, netData := range changeIpMap {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
req := compute.ChangeIPRequest{
ComputeID: computeId,
NetType: netData["net_type"].(string),
NetID: uint64(netData["net_id"].(int)),
IPAddr: netData["ip_address"].(string),
}
_, err := c.CloudAPI().Compute().ChangeIP(ctx, req)
if err != nil {
log.Errorf("utilityComputeNetworksConfigure: failed to change net ID %d of type %s from Compute ID %s: %s",
netData["net_id"].(int), netData["net_type"].(string), d.Id(), err)
apiErrCount++
lastSavedError = err
}
}
needStart := false
if d.Get("network").(*schema.Set).Len() == 1 || oldSet.(*schema.Set).Len() < 1 {
if oldSet.(*schema.Set).Len() == len(detachMap) || oldSet.(*schema.Set).Len() == 0 {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
if err := utilityComputeStop(ctx, computeId, m); err != nil {
apiErrCount++
lastSavedError = err
}
needStart = true
if start := d.Get("started"); start.(bool) {
needStart = true
}
}
attachSet := newSet.(*schema.Set).Difference(oldSet.(*schema.Set))
attachList := attachSet.List()
sort.Slice(attachList, func(i, j int) bool {
weightI := attachList[i].(map[string]interface{})["weight"].(int)
weightJ := attachList[j].(map[string]interface{})["weight"].(int)
sort.Slice(attachMap, func(i, j int) bool {
weightI := attachMap[i]["weight"].(int)
weightJ := attachMap[j]["weight"].(int)
if weightI == 0 {
return false
}
@@ -224,9 +246,8 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
}
return weightI < weightJ
})
log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", attachSet.Len(), d.Id())
for _, runner := range attachList {
netData := runner.(map[string]interface{})
log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", len(attachMap), d.Id())
for _, netData := range attachMap {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
req := compute.NetAttachRequest{
ComputeID: computeId,
@@ -343,3 +364,50 @@ func utilityComputeUpdatePciDevices(ctx context.Context, d *schema.ResourceData,
return nil
}
func differenceNetwork(oldList, newList []interface{}) (detachMap, changeIpMap, attachMap []map[string]interface{}) {
attachMap = make([]map[string]interface{}, 0)
changeIpMap = make([]map[string]interface{}, 0)
detachMap = make([]map[string]interface{}, 0)
for _, oldNetwork := range oldList {
oldMap := oldNetwork.(map[string]interface{})
found := false
for _, newNetwork := range newList {
newMap := newNetwork.(map[string]interface{})
if newMap["net_type"] == oldMap["net_type"] && newMap["net_id"] == oldMap["net_id"] && newMap["weight"] == oldMap["weight"] {
if (newMap["net_type"].(string) == "EXTNET" || newMap["net_type"].(string) == "VINS") && newMap["ip_address"] != oldMap["ip_address"] {
changeIpMap = append(changeIpMap, newMap)
found = true
break
} else if newMap["ip_address"] == oldMap["ip_address"] {
found = true
break
}
}
}
if found {
continue
}
detachMap = append(detachMap, oldMap)
}
for _, newNetwork := range newList {
newMap := newNetwork.(map[string]interface{})
found := false
for _, oldNetwork := range oldList {
oldMap := oldNetwork.(map[string]interface{})
if newMap["net_type"] == oldMap["net_type"] && newMap["net_id"] == oldMap["net_id"] && newMap["weight"] == oldMap["weight"] {
if newMap["ip_address"] == oldMap["ip_address"] || ((newMap["net_type"].(string) == "EXTNET" || newMap["net_type"].(string) == "VINS") && newMap["ip_address"] != oldMap["ip_address"]) {
found = true
break
}
}
}
if found {
continue
}
attachMap = append(attachMap, newMap)
}
return
}