This commit is contained in:
asteam
2024-12-04 13:18:58 +03:00
parent 003e4d656e
commit 76ea459b3d
417 changed files with 30051 additions and 975 deletions

View File

@@ -11,6 +11,7 @@ import (
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/kvmvm/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/kvmvm/utilities"
)
@@ -26,6 +27,8 @@ func DataSourceCompute(ctx context.Context, state *models.RecordComputeModel, c
return diags
}
pciDevicesList, err := utilities.ComputePCIDevicesListCheckPresence(ctx, state, c)
id := uuid.New()
customFields, _ := json.Marshal(computeRecord.CustomFields)
@@ -44,6 +47,7 @@ func DataSourceCompute(ctx context.Context, state *models.RecordComputeModel, c
AffinityWeight: types.Int64Value(int64(computeRecord.AffinityWeight)),
AntiAffinityRules: flattenAffinityRule(ctx, &computeRecord.AntiAffinityRules),
Architecture: types.StringValue(computeRecord.Architecture),
Chipset: types.StringValue(computeRecord.Chipset),
BootDiskSize: types.Int64Value(int64(computeRecord.BootDiskSize)),
CdImageId: types.Int64Value(int64(computeRecord.CdImageId)),
CloneReference: types.Int64Value(int64(computeRecord.CloneReference)),
@@ -81,6 +85,7 @@ func DataSourceCompute(ctx context.Context, state *models.RecordComputeModel, c
NumaNodeId: types.Int64Value(int64(computeRecord.NumaNodeId)),
OSUsers: flattenOSUsers(ctx, &computeRecord.OSUsers),
Pinned: types.BoolValue(computeRecord.Pinned),
PCIDevices: flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, flattenPCI(ctx, pciDevicesList)),
RAM: types.Int64Value(int64(computeRecord.RAM)),
ReferenceID: types.StringValue(computeRecord.ReferenceID),
Registered: types.BoolValue(computeRecord.Registered),
@@ -189,6 +194,7 @@ func flattenDisks(ctx context.Context, disks *compute.ListComputeDisks) []models
ACL: types.StringValue(string(acl)),
AccountID: types.Int64Value(int64(item.AccountID)),
BootPartition: types.Int64Value(int64(item.BootPartition)),
BusNumber: types.Int64Value(int64(item.BusNumber)),
CreatedTime: types.Int64Value(int64(item.CreatedTime)),
DeletedTime: types.Int64Value(int64(item.CreatedTime)),
Description: types.StringValue(item.Description),
@@ -290,6 +296,7 @@ func flattenInterfaces(ctx context.Context, interfaces *compute.ListInterfaces)
res := make([]models.ItemInterfaceModel, 0, len(*interfaces))
for _, item := range *interfaces {
temp := models.ItemInterfaceModel{
BusNumber: types.Int64Value(int64(item.BusNumber)),
ConnID: types.Int64Value(int64(item.ConnID)),
ConnType: types.StringValue(item.ConnType),
DefGW: types.StringValue(item.DefGW),
@@ -297,14 +304,24 @@ func flattenInterfaces(ctx context.Context, interfaces *compute.ListInterfaces)
FLIPGroupID: types.Int64Value(int64(item.FLIPGroupID)),
GUID: types.StringValue(item.GUID),
IPAddress: types.StringValue(item.IPAddress),
ListenSSH: types.BoolValue(item.ListenSSH),
MAC: types.StringValue(item.MAC),
Name: types.StringValue(item.Name),
NetID: types.Int64Value(int64(item.NetID)),
NetMask: types.Int64Value(int64(item.NetMask)),
NetType: types.StringValue(item.NetType),
NodeID: types.Int64Value(int64(item.NodeID)),
PCISlot: types.Int64Value(item.PCISlot),
LibvirtSettings: &models.LibvirtModel{
GUID: types.StringValue(item.LibvirtSettings.GUID),
TXMode: types.StringValue(item.LibvirtSettings.TXMode),
IOEventFD: types.StringValue(item.LibvirtSettings.IOEventFD),
EventIDx: types.StringValue(item.LibvirtSettings.EventIDx),
Queues: types.Int64Value(int64(item.LibvirtSettings.Queues)),
RXQueueSize: types.Int64Value(int64(item.LibvirtSettings.RXQueueSize)),
TXQueueSize: types.Int64Value(int64(item.LibvirtSettings.TXQueueSize)),
},
ListenSSH: types.BoolValue(item.ListenSSH),
MAC: types.StringValue(item.MAC),
MTU: types.Int64Value(int64(item.MTU)),
Name: types.StringValue(item.Name),
NetID: types.Int64Value(int64(item.NetID)),
NetMask: types.Int64Value(int64(item.NetMask)),
NetType: types.StringValue(item.NetType),
NodeID: types.Int64Value(int64(item.NodeID)),
PCISlot: types.Int64Value(item.PCISlot),
QOS: &models.QOSModel{
ERate: types.Int64Value(int64(item.QOS.ERate)),
GUID: types.StringValue(item.QOS.GUID),
@@ -365,3 +382,15 @@ func flattenOSUsers(ctx context.Context, osUsers *compute.ListOSUser) []models.I
tflog.Info(ctx, "End flattenOSUsers")
return res
}
func flattenPCI(ctx context.Context, pciList *compute.ListPCIDevices) []uint64 {
tflog.Info(ctx, "Start flattenPCI")
res := make([]uint64, 0, len(pciList.Data))
for _, v := range pciList.Data {
res = append(res, v.ID)
}
tflog.Info(ctx, "End flattenPCI")
return res
}

View File

@@ -75,6 +75,7 @@ func flattenItemsList(ctx context.Context, computes *compute.ListComputes) []mod
BootDiskSize: types.Int64Value(int64(item.BootDiskSize)),
CdImageId: types.Int64Value(int64(item.CdImageId)),
CloneReference: types.Int64Value(int64(item.CloneReference)),
Chipset: types.StringValue(item.Chipset),
ComputeCIID: types.Int64Value(int64(item.ComputeCIID)),
CPU: types.Int64Value(int64(item.CPU)),
CPUPin: types.BoolValue(item.CPUPin),
@@ -195,8 +196,9 @@ func flattenDisksInList(ctx context.Context, disks *compute.ListInfoDisks) []mod
res := make([]models.DiskInListModel, 0, len(*disks))
for _, item := range *disks {
temp := models.DiskInListModel{
DiskId: types.Int64Value(int64(item.ID)),
PCISlot: types.Int64Value(item.PCISlot),
BusNumber: types.Int64Value(int64(item.BusNumber)),
DiskId: types.Int64Value(int64(item.ID)),
PCISlot: types.Int64Value(item.PCISlot),
}
res = append(res, temp)
}
@@ -213,6 +215,7 @@ func flattenInterfaceInList(ctx context.Context, interfaces *compute.ListInterfa
res := make([]models.ItemVNFInterfaceInListModel, 0, len(*interfaces))
for _, item := range *interfaces {
temp := models.ItemVNFInterfaceInListModel{
BusNumber: types.Int64Value(int64(item.BusNumber)),
ConnID: types.Int64Value(int64(item.ConnID)),
ConnType: types.StringValue(item.ConnType),
DefGW: types.StringValue(item.DefGW),
@@ -220,14 +223,23 @@ func flattenInterfaceInList(ctx context.Context, interfaces *compute.ListInterfa
FLIPGroupID: types.Int64Value(int64(item.FLIPGroupID)),
GUID: types.StringValue(item.GUID),
IPAddress: types.StringValue(item.IPAddress),
ListenSSH: types.BoolValue(item.ListenSSH),
MAC: types.StringValue(item.MAC),
Name: types.StringValue(item.Name),
NetID: types.Int64Value(int64(item.NetID)),
NetMask: types.Int64Value(int64(item.NetMask)),
NetType: types.StringValue(item.NetType),
NodeID: types.Int64Value(int64(item.NodeID)),
PCISlot: types.Int64Value(item.PCISlot),
LibvirtSettings: &models.LibvirtModel{
GUID: types.StringValue(item.LibvirtSettings.GUID),
TXMode: types.StringValue(item.LibvirtSettings.TXMode),
IOEventFD: types.StringValue(item.LibvirtSettings.IOEventFD),
EventIDx: types.StringValue(item.LibvirtSettings.EventIDx),
Queues: types.Int64Value(int64(item.LibvirtSettings.Queues)),
RXQueueSize: types.Int64Value(int64(item.LibvirtSettings.RXQueueSize)),
TXQueueSize: types.Int64Value(int64(item.LibvirtSettings.TXQueueSize)),
},
ListenSSH: types.BoolValue(item.ListenSSH),
MAC: types.StringValue(item.MAC),
Name: types.StringValue(item.Name),
NetID: types.Int64Value(int64(item.NetID)),
NetMask: types.Int64Value(int64(item.NetMask)),
NetType: types.StringValue(item.NetType),
NodeID: types.Int64Value(int64(item.NodeID)),
PCISlot: types.Int64Value(item.PCISlot),
QOS: &models.QOSInListModel{
ERate: types.Int64Value(int64(item.QOS.ERate)),
GUID: types.StringValue(item.QOS.GUID),

View File

@@ -72,6 +72,7 @@ func flattenItemsListDeleted(ctx context.Context, computes *compute.ListComputes
Architecture: types.StringValue(item.Architecture),
BootDiskSize: types.Int64Value(int64(item.BootDiskSize)),
CdImageId: types.Int64Value(int64(item.CdImageId)),
Chipset: types.StringValue(item.Chipset),
CloneReference: types.Int64Value(int64(item.CloneReference)),
ComputeCIID: types.Int64Value(int64(item.ComputeCIID)),
CPU: types.Int64Value(int64(item.CPU)),
@@ -193,8 +194,9 @@ func flattenDisksInListDeleted(ctx context.Context, disks *compute.ListInfoDisks
res := make([]models.DiskInListDeletedModel, 0, len(*disks))
for _, item := range *disks {
temp := models.DiskInListDeletedModel{
DiskId: types.Int64Value(int64(item.ID)),
PCISlot: types.Int64Value(item.PCISlot),
BusNumber: types.Int64Value(int64(item.BusNumber)),
DiskId: types.Int64Value(int64(item.ID)),
PCISlot: types.Int64Value(item.PCISlot),
}
res = append(res, temp)
}
@@ -211,6 +213,7 @@ func flattenInterfaceInListDeleted(ctx context.Context, interfaces *compute.List
res := make([]models.ItemVNFInterfaceInListDeletedModel, 0, len(*interfaces))
for _, item := range *interfaces {
temp := models.ItemVNFInterfaceInListDeletedModel{
BusNumber: types.Int64Value(int64(item.BusNumber)),
ConnID: types.Int64Value(int64(item.ConnID)),
ConnType: types.StringValue(item.ConnType),
DefGW: types.StringValue(item.DefGW),
@@ -218,14 +221,23 @@ func flattenInterfaceInListDeleted(ctx context.Context, interfaces *compute.List
FLIPGroupID: types.Int64Value(int64(item.FLIPGroupID)),
GUID: types.StringValue(item.GUID),
IPAddress: types.StringValue(item.IPAddress),
ListenSSH: types.BoolValue(item.ListenSSH),
MAC: types.StringValue(item.MAC),
Name: types.StringValue(item.Name),
NetID: types.Int64Value(int64(item.NetID)),
NetMask: types.Int64Value(int64(item.NetMask)),
NetType: types.StringValue(item.NetType),
NodeID: types.Int64Value(int64(item.NodeID)),
PCISlot: types.Int64Value(item.PCISlot),
LibvirtSettings: &models.LibvirtModel{
GUID: types.StringValue(item.LibvirtSettings.GUID),
TXMode: types.StringValue(item.LibvirtSettings.TXMode),
IOEventFD: types.StringValue(item.LibvirtSettings.IOEventFD),
EventIDx: types.StringValue(item.LibvirtSettings.EventIDx),
Queues: types.Int64Value(int64(item.LibvirtSettings.Queues)),
RXQueueSize: types.Int64Value(int64(item.LibvirtSettings.RXQueueSize)),
TXQueueSize: types.Int64Value(int64(item.LibvirtSettings.TXQueueSize)),
},
ListenSSH: types.BoolValue(item.ListenSSH),
MAC: types.StringValue(item.MAC),
Name: types.StringValue(item.Name),
NetID: types.Int64Value(int64(item.NetID)),
NetMask: types.Int64Value(int64(item.NetMask)),
NetType: types.StringValue(item.NetType),
NodeID: types.Int64Value(int64(item.NodeID)),
PCISlot: types.Int64Value(item.PCISlot),
QOS: &models.QOSInListModel{
ERate: types.Int64Value(int64(item.QOS.ERate)),
GUID: types.StringValue(item.QOS.GUID),

View File

@@ -49,15 +49,17 @@ func ComputeResource(ctx context.Context, plan *models.ResourceComputeModel, c *
AffinityRules: plan.AffinityRules,
AntiAffinityRules: plan.AntiAffinityRules,
CustomFields: types.StringValue(string(customFields)),
Chipset: types.StringValue(recordItemCompute.Chipset),
Stateless: plan.Stateless,
SepId: types.Int64Value(int64(bootdisk.SepID)),
Pool: types.StringValue(bootdisk.Pool),
ExtraDisks: plan.ExtraDisks,
Network: flattenNetwork(ctx, &recordItemCompute.Interfaces),
Network: flattenNetwork(ctx, plan.Network, &recordItemCompute.Interfaces),
Tags: plan.Tags,
PortForwarding: plan.PortForwarding,
UserAccess: plan.UserAccess,
Snapshot: plan.Snapshot,
PCIDevices: plan.PCIDevices,
Rollback: plan.Rollback,
CD: plan.CD,
PinToStack: plan.PinToStack,
@@ -205,6 +207,7 @@ func flattenDisk(ctx context.Context, disk *compute.ItemComputeDisk) types.Objec
ACL: types.StringValue(string(acl)),
AccountID: types.Int64Value(int64(disk.AccountID)),
BootPartition: types.Int64Value(int64(disk.BootPartition)),
BusNumber: types.Int64Value(int64(disk.BusNumber)),
CreatedTime: types.Int64Value(int64(disk.CreatedTime)),
DeletedTime: types.Int64Value(int64(disk.DeletedTime)),
Description: types.StringValue(disk.Description),
@@ -385,25 +388,28 @@ func flattenResourceInterfaces(ctx context.Context, interfaces *compute.ListInte
for _, item := range *interfaces {
temp := models.ItemResourceInterfacesModel{
ConnID: types.Int64Value(int64(item.ConnID)),
ConnType: types.StringValue(item.ConnType),
GetGW: types.StringValue(item.DefGW),
Enabled: types.BoolValue(item.Enabled),
FLIPGroupID: types.Int64Value(int64(item.FLIPGroupID)),
GUID: types.StringValue(item.GUID),
IPAddress: types.StringValue(item.IPAddress),
ListenSSH: types.BoolValue(item.ListenSSH),
MAC: types.StringValue(item.MAC),
Name: types.StringValue(item.Name),
NetID: types.Int64Value(int64(item.NetID)),
NetMask: types.Int64Value(int64(item.NetMask)),
NetType: types.StringValue(item.NetType),
NodeID: types.Int64Value(int64(item.NodeID)),
PCISlot: types.Int64Value(item.PCISlot),
QOS: flattenQOS(ctx, &item.QOS),
Target: types.StringValue(item.Target),
Type: types.StringValue(item.Type),
VNFs: flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, item.VNFs),
BusNumber: types.Int64Value(int64(item.BusNumber)),
ConnID: types.Int64Value(int64(item.ConnID)),
ConnType: types.StringValue(item.ConnType),
GetGW: types.StringValue(item.DefGW),
Enabled: types.BoolValue(item.Enabled),
FLIPGroupID: types.Int64Value(int64(item.FLIPGroupID)),
GUID: types.StringValue(item.GUID),
IPAddress: types.StringValue(item.IPAddress),
ListenSSH: types.BoolValue(item.ListenSSH),
MAC: types.StringValue(item.MAC),
MTU: types.Int64Value(int64(item.MTU)),
Name: types.StringValue(item.Name),
NetID: types.Int64Value(int64(item.NetID)),
NetMask: types.Int64Value(int64(item.NetMask)),
NetType: types.StringValue(item.NetType),
NodeID: types.Int64Value(int64(item.NodeID)),
PCISlot: types.Int64Value(item.PCISlot),
QOS: flattenQOS(ctx, &item.QOS),
LibvirtSettings: flattenLibvirtSetttings(ctx, &item.LibvirtSettings),
Target: types.StringValue(item.Target),
Type: types.StringValue(item.Type),
VNFs: flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, item.VNFs),
}
obj, err := types.ObjectValueFrom(ctx, models.ItemInterfaces, temp)
if err != nil {
@@ -439,6 +445,27 @@ func flattenQOS(ctx context.Context, QOS *compute.QOS) types.Object {
return res
}
func flattenLibvirtSetttings(ctx context.Context, settings *compute.LibvirtSettings) types.Object {
tflog.Info(ctx, "Start flattenLibvirtSetttings")
temp := models.LibvirtModel{
GUID: types.StringValue(settings.GUID),
TXMode: types.StringValue(settings.TXMode),
IOEventFD: types.StringValue(settings.IOEventFD),
EventIDx: types.StringValue(settings.EventIDx),
Queues: types.Int64Value(int64(settings.Queues)),
RXQueueSize: types.Int64Value(int64(settings.RXQueueSize)),
TXQueueSize: types.Int64Value(int64(settings.TXQueueSize)),
}
res, err := types.ObjectValueFrom(ctx, models.ItemLibvirtSettings, temp)
if err != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenLibvirtSetttings struct to obj", err))
}
tflog.Info(ctx, "End flattenLibvirtSetttings")
return res
}
func flattenSnapSets(ctx context.Context, snapSets *compute.ListSnapSets) types.List {
tflog.Info(ctx, "Start flattenSnapSets")
tempSlice := make([]types.Object, 0, len(*snapSets))
@@ -465,7 +492,7 @@ func flattenSnapSets(ctx context.Context, snapSets *compute.ListSnapSets) types.
return res
}
func flattenNetwork(ctx context.Context, interfaces *compute.ListInterfaces) types.Set {
func flattenNetwork(ctx context.Context, networks types.Set, interfaces *compute.ListInterfaces) types.Set {
tflog.Info(ctx, "Start flattenNetwork")
tempSlice := make([]types.Object, 0, len(*interfaces))
@@ -476,6 +503,8 @@ func flattenNetwork(ctx context.Context, interfaces *compute.ListInterfaces) typ
NetId: types.Int64Value(int64(item.NetID)),
IpAddress: types.StringValue(item.IPAddress),
Mac: types.StringValue(item.MAC),
Weight: flattenNetworkWeight(ctx, networks, item),
MTU: types.Int64Value(int64(item.MTU)),
}
obj, err := types.ObjectValueFrom(ctx, models.ItemNetwork, temp)
if err != nil {
@@ -492,3 +521,16 @@ func flattenNetwork(ctx context.Context, interfaces *compute.ListInterfaces) typ
tflog.Info(ctx, "End flattenNetwork")
return res
}
func flattenNetworkWeight(ctx context.Context, networks types.Set, item compute.ItemVNFInterface) types.Int64 {
tflog.Info(ctx, "Start flattenNetworkWeight")
networkList := networks.Elements()
for _, network := range networkList {
networkMap := network.(types.Object).Attributes()
if uint64(networkMap["net_id"].(types.Int64).ValueInt64()) == item.NetID && networkMap["net_type"].(types.String).ValueString() == item.NetType {
return types.Int64Value(networkMap["weight"].(types.Int64).ValueInt64())
}
}
tflog.Info(ctx, "End flattenNetworkWeight")
return types.Int64Value(0)
}

View File

@@ -59,14 +59,17 @@ func resourceComputeInputChecks(ctx context.Context, plan *models.ResourceComput
diags.AddError(fmt.Sprintf("Cannot create compute because extnet ID %d is not allowed or does not exist", extNetId), err.Error())
}
case "VFNIC":
if strings.EqualFold(plan.Driver.ValueString(), "KVM_PPC") {
diags.AddError("can't create compute because 'VFNIC' net_type is not allowed for driver 'KVM_PPC'", "")
}
vfpoolId := uint64(elemMap["net_id"].(types.Int64).ValueInt64())
err = ic.ExistVFPool(ctx, vfpoolId, c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot create compute because vfpool ID %d is not allowed or does not exist", vfpoolId), err.Error())
}
case "DPDK":
dpdkId := uint64(elemMap["net_id"].(types.Int64).ValueInt64())
err = ic.ExistDPDK(ctx, dpdkId, c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot create compute because DPDK net ID %d is not allowed or does not exist", dpdkId), err.Error())
}
}
}
}

View File

@@ -19,6 +19,7 @@ type RecordComputeModel struct {
AffinityWeight types.Int64 `tfsdk:"affinity_weight"`
AntiAffinityRules []ItemRuleModel `tfsdk:"anti_affinity_rules"`
Architecture types.String `tfsdk:"arch"`
Chipset types.String `tfsdk:"chipset"`
BootOrder types.List `tfsdk:"boot_order"`
BootDiskSize types.Int64 `tfsdk:"bootdisk_size"`
CdImageId types.Int64 `tfsdk:"cd_image_id"`
@@ -57,6 +58,7 @@ type RecordComputeModel struct {
NumaAffinity types.String `tfsdk:"numa_affinity"`
NumaNodeId types.Int64 `tfsdk:"numa_node_id"`
OSUsers []ItemOSUserModel `tfsdk:"os_users"`
PCIDevices types.List `tfsdk:"pci_devices"`
Pinned types.Bool `tfsdk:"pinned"`
RAM types.Int64 `tfsdk:"ram"`
ReferenceID types.String `tfsdk:"reference_id"`
@@ -109,6 +111,7 @@ type ItemDiskModel struct {
ACL types.String `tfsdk:"acl"`
AccountID types.Int64 `tfsdk:"account_id"`
BootPartition types.Int64 `tfsdk:"boot_partition"`
BusNumber types.Int64 `tfsdk:"bus_number"`
CreatedTime types.Int64 `tfsdk:"created_time"`
DeletedTime types.Int64 `tfsdk:"deleted_time"`
Description types.String `tfsdk:"desc"`
@@ -149,25 +152,28 @@ type ItemDiskModel struct {
}
type ItemInterfaceModel struct {
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
DefGW types.String `tfsdk:"def_gw"`
Enabled types.Bool `tfsdk:"enabled"`
FLIPGroupID types.Int64 `tfsdk:"flip_group_id"`
GUID types.String `tfsdk:"guid"`
IPAddress types.String `tfsdk:"ip_address"`
ListenSSH types.Bool `tfsdk:"listen_ssh"`
MAC types.String `tfsdk:"mac"`
Name types.String `tfsdk:"name"`
NetID types.Int64 `tfsdk:"net_id"`
NetMask types.Int64 `tfsdk:"netmask"`
NetType types.String `tfsdk:"net_type"`
NodeID types.Int64 `tfsdk:"node_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
QOS *QOSModel `tfsdk:"qos"`
Target types.String `tfsdk:"target"`
Type types.String `tfsdk:"type"`
VNFs types.List `tfsdk:"vnfs"`
BusNumber types.Int64 `tfsdk:"bus_number"`
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
DefGW types.String `tfsdk:"def_gw"`
Enabled types.Bool `tfsdk:"enabled"`
FLIPGroupID types.Int64 `tfsdk:"flip_group_id"`
GUID types.String `tfsdk:"guid"`
IPAddress types.String `tfsdk:"ip_address"`
LibvirtSettings *LibvirtModel `tfsdk:"libvirt_settings"`
ListenSSH types.Bool `tfsdk:"listen_ssh"`
MAC types.String `tfsdk:"mac"`
MTU types.Int64 `tfsdk:"mtu"`
Name types.String `tfsdk:"name"`
NetID types.Int64 `tfsdk:"net_id"`
NetMask types.Int64 `tfsdk:"netmask"`
NetType types.String `tfsdk:"net_type"`
NodeID types.Int64 `tfsdk:"node_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
QOS *QOSModel `tfsdk:"qos"`
Target types.String `tfsdk:"target"`
Type types.String `tfsdk:"type"`
VNFs types.List `tfsdk:"vnfs"`
}
type QOSModel struct {
@@ -177,6 +183,16 @@ type QOSModel struct {
InRate types.Int64 `tfsdk:"in_rate"`
}
type LibvirtModel struct {
GUID types.String `tfsdk:"guid"`
TXMode types.String `tfsdk:"txmode"`
IOEventFD types.String `tfsdk:"ioeventfd"`
EventIDx types.String `tfsdk:"event_idx"`
Queues types.Int64 `tfsdk:"queues"`
RXQueueSize types.Int64 `tfsdk:"rx_queue_size"`
TXQueueSize types.Int64 `tfsdk:"tx_queue_size"`
}
type ItemSnapSetModel struct {
Disks types.List `tfsdk:"disks"`
GUID types.String `tfsdk:"guid"`

View File

@@ -43,6 +43,7 @@ type ItemComputeModel struct {
CdImageId types.Int64 `tfsdk:"cd_image_id"`
CloneReference types.Int64 `tfsdk:"clone_reference"`
Clones types.List `tfsdk:"clones"`
Chipset types.String `tfsdk:"chipset"`
ComputeCIID types.Int64 `tfsdk:"computeci_id"`
CPU types.Int64 `tfsdk:"cpus"`
CPUPin types.Bool `tfsdk:"cpu_pin"`
@@ -112,30 +113,33 @@ type ItemRuleInListModel struct {
}
type DiskInListModel struct {
DiskId types.Int64 `tfsdk:"disk_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
BusNumber types.Int64 `tfsdk:"bus_number"`
DiskId types.Int64 `tfsdk:"disk_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
}
type ItemVNFInterfaceInListModel struct {
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
DefGW types.String `tfsdk:"def_gw"`
Enabled types.Bool `tfsdk:"enabled"`
FLIPGroupID types.Int64 `tfsdk:"flip_group_id"`
GUID types.String `tfsdk:"guid"`
IPAddress types.String `tfsdk:"ip_address"`
ListenSSH types.Bool `tfsdk:"listen_ssh"`
MAC types.String `tfsdk:"mac"`
Name types.String `tfsdk:"name"`
NetID types.Int64 `tfsdk:"net_id"`
NetMask types.Int64 `tfsdk:"netmask"`
NetType types.String `tfsdk:"net_type"`
NodeID types.Int64 `tfsdk:"node_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
QOS *QOSInListModel `tfsdk:"qos"`
Target types.String `tfsdk:"target"`
Type types.String `tfsdk:"type"`
VNFs types.List `tfsdk:"vnfs"`
BusNumber types.Int64 `tfsdk:"bus_number"`
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
DefGW types.String `tfsdk:"def_gw"`
Enabled types.Bool `tfsdk:"enabled"`
FLIPGroupID types.Int64 `tfsdk:"flip_group_id"`
GUID types.String `tfsdk:"guid"`
IPAddress types.String `tfsdk:"ip_address"`
LibvirtSettings *LibvirtModel `tfsdk:"libvirt_settings"`
ListenSSH types.Bool `tfsdk:"listen_ssh"`
MAC types.String `tfsdk:"mac"`
Name types.String `tfsdk:"name"`
NetID types.Int64 `tfsdk:"net_id"`
NetMask types.Int64 `tfsdk:"netmask"`
NetType types.String `tfsdk:"net_type"`
NodeID types.Int64 `tfsdk:"node_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
QOS *QOSInListModel `tfsdk:"qos"`
Target types.String `tfsdk:"target"`
Type types.String `tfsdk:"type"`
VNFs types.List `tfsdk:"vnfs"`
}
type QOSInListModel struct {

View File

@@ -39,6 +39,7 @@ type ItemListDeletedComputeModel struct {
BootOrder types.List `tfsdk:"boot_order"`
BootDiskSize types.Int64 `tfsdk:"bootdisk_size"`
CdImageId types.Int64 `tfsdk:"cd_image_id"`
Chipset types.String `tfsdk:"chipset"`
CloneReference types.Int64 `tfsdk:"clone_reference"`
Clones types.List `tfsdk:"clones"`
ComputeCIID types.Int64 `tfsdk:"computeci_id"`
@@ -110,30 +111,33 @@ type ItemRuleInListDeletedModel struct {
}
type DiskInListDeletedModel struct {
DiskId types.Int64 `tfsdk:"disk_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
BusNumber types.Int64 `tfsdk:"bus_number"`
DiskId types.Int64 `tfsdk:"disk_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
}
type ItemVNFInterfaceInListDeletedModel struct {
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
DefGW types.String `tfsdk:"def_gw"`
Enabled types.Bool `tfsdk:"enabled"`
FLIPGroupID types.Int64 `tfsdk:"flip_group_id"`
GUID types.String `tfsdk:"guid"`
IPAddress types.String `tfsdk:"ip_address"`
ListenSSH types.Bool `tfsdk:"listen_ssh"`
MAC types.String `tfsdk:"mac"`
Name types.String `tfsdk:"name"`
NetID types.Int64 `tfsdk:"net_id"`
NetMask types.Int64 `tfsdk:"netmask"`
NetType types.String `tfsdk:"net_type"`
NodeID types.Int64 `tfsdk:"node_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
QOS *QOSInListModel `tfsdk:"qos"`
Target types.String `tfsdk:"target"`
Type types.String `tfsdk:"type"`
VNFs types.List `tfsdk:"vnfs"`
BusNumber types.Int64 `tfsdk:"bus_number"`
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
DefGW types.String `tfsdk:"def_gw"`
Enabled types.Bool `tfsdk:"enabled"`
FLIPGroupID types.Int64 `tfsdk:"flip_group_id"`
GUID types.String `tfsdk:"guid"`
IPAddress types.String `tfsdk:"ip_address"`
LibvirtSettings *LibvirtModel `tfsdk:"libvirt_settings"`
ListenSSH types.Bool `tfsdk:"listen_ssh"`
MAC types.String `tfsdk:"mac"`
Name types.String `tfsdk:"name"`
NetID types.Int64 `tfsdk:"net_id"`
NetMask types.Int64 `tfsdk:"netmask"`
NetType types.String `tfsdk:"net_type"`
NodeID types.Int64 `tfsdk:"node_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
QOS *QOSInListModel `tfsdk:"qos"`
Target types.String `tfsdk:"target"`
Type types.String `tfsdk:"type"`
VNFs types.List `tfsdk:"vnfs"`
}
type QOSInListDeletedModel struct {

View File

@@ -23,6 +23,7 @@ type ResourceComputeModel struct {
AffinityRules types.Set `tfsdk:"affinity_rules"`
AntiAffinityRules types.Set `tfsdk:"anti_affinity_rules"`
CustomFields types.String `tfsdk:"custom_fields"`
Chipset types.String `tfsdk:"chipset"`
Stateless types.Bool `tfsdk:"stateless"`
SepId types.Int64 `tfsdk:"sep_id"`
Pool types.String `tfsdk:"pool"`
@@ -32,6 +33,7 @@ type ResourceComputeModel struct {
PortForwarding types.Set `tfsdk:"port_forwarding"`
UserAccess types.Set `tfsdk:"user_access"`
Snapshot types.Set `tfsdk:"snapshot"`
PCIDevices types.Set `tfsdk:"pci_devices"`
Rollback types.Object `tfsdk:"rollback"`
CD types.Object `tfsdk:"cd"`
PinToStack types.Bool `tfsdk:"pin_to_stack"`
@@ -124,6 +126,7 @@ type ItemResourceDiskModel struct {
ACL types.String `tfsdk:"acl"`
AccountID types.Int64 `tfsdk:"account_id"`
BootPartition types.Int64 `tfsdk:"boot_partition"`
BusNumber types.Int64 `tfsdk:"bus_number"`
CreatedTime types.Int64 `tfsdk:"created_time"`
DeletedTime types.Int64 `tfsdk:"deleted_time"`
Description types.String `tfsdk:"desc"`
@@ -175,28 +178,33 @@ type ItemNetworkModel struct {
NetId types.Int64 `tfsdk:"net_id"`
IpAddress types.String `tfsdk:"ip_address"`
Mac types.String `tfsdk:"mac"`
Weight types.Int64 `tfsdk:"weight"`
MTU types.Int64 `tfsdk:"mtu"`
}
type ItemResourceInterfacesModel struct {
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
GetGW types.String `tfsdk:"get_gw"`
Enabled types.Bool `tfsdk:"enabled"`
FLIPGroupID types.Int64 `tfsdk:"flip_group_id"`
GUID types.String `tfsdk:"guid"`
IPAddress types.String `tfsdk:"ip_address"`
ListenSSH types.Bool `tfsdk:"listen_ssh"`
MAC types.String `tfsdk:"mac"`
Name types.String `tfsdk:"name"`
NetID types.Int64 `tfsdk:"net_id"`
NetMask types.Int64 `tfsdk:"netmask"`
NetType types.String `tfsdk:"net_type"`
NodeID types.Int64 `tfsdk:"node_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
QOS types.Object `tfsdk:"qos"`
Target types.String `tfsdk:"target"`
Type types.String `tfsdk:"type"`
VNFs types.List `tfsdk:"vnfs"`
BusNumber types.Int64 `tfsdk:"bus_number"`
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
GetGW types.String `tfsdk:"get_gw"`
Enabled types.Bool `tfsdk:"enabled"`
FLIPGroupID types.Int64 `tfsdk:"flip_group_id"`
GUID types.String `tfsdk:"guid"`
IPAddress types.String `tfsdk:"ip_address"`
ListenSSH types.Bool `tfsdk:"listen_ssh"`
MAC types.String `tfsdk:"mac"`
MTU types.Int64 `tfsdk:"mtu"`
Name types.String `tfsdk:"name"`
NetID types.Int64 `tfsdk:"net_id"`
NetMask types.Int64 `tfsdk:"netmask"`
NetType types.String `tfsdk:"net_type"`
NodeID types.Int64 `tfsdk:"node_id"`
PCISlot types.Int64 `tfsdk:"pci_slot"`
QOS types.Object `tfsdk:"qos"`
LibvirtSettings types.Object `tfsdk:"libvirt_settings"`
Target types.String `tfsdk:"target"`
Type types.String `tfsdk:"type"`
VNFs types.List `tfsdk:"vnfs"`
}
type ItemResourceRulesModel struct {
@@ -212,6 +220,8 @@ var ItemNetwork = map[string]attr.Type{
"net_id": types.Int64Type,
"ip_address": types.StringType,
"mac": types.StringType,
"weight": types.Int64Type,
"mtu": types.Int64Type,
}
var ItemDisk = map[string]attr.Type{
@@ -219,6 +229,7 @@ var ItemDisk = map[string]attr.Type{
"acl": types.StringType,
"account_id": types.Int64Type,
"boot_partition": types.Int64Type,
"bus_number": types.Int64Type,
"created_time": types.Int64Type,
"deleted_time": types.Int64Type,
"desc": types.StringType,
@@ -293,25 +304,28 @@ var ItemACL = map[string]attr.Type{
}
var ItemInterfaces = map[string]attr.Type{
"conn_id": types.Int64Type,
"conn_type": types.StringType,
"get_gw": types.StringType,
"enabled": types.BoolType,
"flip_group_id": types.Int64Type,
"guid": types.StringType,
"ip_address": types.StringType,
"listen_ssh": types.BoolType,
"mac": types.StringType,
"name": types.StringType,
"net_id": types.Int64Type,
"netmask": types.Int64Type,
"net_type": types.StringType,
"node_id": types.Int64Type,
"pci_slot": types.Int64Type,
"qos": types.ObjectType{AttrTypes: ItemQos},
"target": types.StringType,
"type": types.StringType,
"vnfs": types.ListType{ElemType: types.Int64Type},
"bus_number": types.Int64Type,
"conn_id": types.Int64Type,
"conn_type": types.StringType,
"get_gw": types.StringType,
"enabled": types.BoolType,
"flip_group_id": types.Int64Type,
"guid": types.StringType,
"ip_address": types.StringType,
"listen_ssh": types.BoolType,
"mac": types.StringType,
"mtu": types.Int64Type,
"name": types.StringType,
"net_id": types.Int64Type,
"netmask": types.Int64Type,
"net_type": types.StringType,
"node_id": types.Int64Type,
"pci_slot": types.Int64Type,
"qos": types.ObjectType{AttrTypes: ItemQos},
"libvirt_settings": types.ObjectType{AttrTypes: ItemLibvirtSettings},
"target": types.StringType,
"type": types.StringType,
"vnfs": types.ListType{ElemType: types.Int64Type},
}
var ItemQos = map[string]attr.Type{
@@ -321,6 +335,16 @@ var ItemQos = map[string]attr.Type{
"in_rate": types.Int64Type,
}
var ItemLibvirtSettings = map[string]attr.Type{
"guid": types.StringType,
"txmode": types.StringType,
"ioeventfd": types.StringType,
"event_idx": types.StringType,
"queues": types.Int64Type,
"rx_queue_size": types.Int64Type,
"tx_queue_size": types.Int64Type,
}
var ItemOSUsers = map[string]attr.Type{
"guid": types.StringType,
"login": types.StringType,

View File

@@ -142,6 +142,11 @@ func (r *resourceCompute) Create(ctx context.Context, req resource.CreateRequest
resp.Diagnostics.Append(utilities.ComputeResourceCDInsert(ctx, &plan, r.client)...)
}
// attach PCI devices to compute if needed, warnings added to resp.Diagnostics in case of failure.
if !plan.PCIDevices.IsNull() {
resp.Diagnostics.Append(utilities.ComputeResourcePCIDevice(ctx, &plan, r.client)...)
}
// pin to stack if needed, warnings added to resp.Diagnostics in case of failure.
if !plan.PinToStack.IsNull() && plan.PinToStack.ValueBool() {
resp.Diagnostics.Append(utilities.ComputeResourcePinToStack(ctx, &plan, r.client)...)
@@ -319,9 +324,18 @@ func (r *resourceCompute) Update(ctx context.Context, req resource.UpdateRequest
}
}
// PCI device(s) update if needed
if !plan.PCIDevices.Equal(state.PCIDevices) {
resp.Diagnostics.Append(utilities.ComputeResourcePCIDeviceUpdate(ctx, &state, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceCompute: Error update PCI device(s) list")
return
}
}
// Compute parameters update if needed
if (!plan.Description.IsUnknown() && !plan.Description.Equal(state.Description)) || !plan.Name.Equal(state.Name) ||
!plan.NumaAffinity.Equal(state.NumaAffinity) || !plan.CPUPin.Equal(state.CPUPin) || !plan.HPBacked.Equal(state.HPBacked) {
!plan.NumaAffinity.Equal(state.NumaAffinity) || !plan.CPUPin.Equal(state.CPUPin) || !plan.HPBacked.Equal(state.HPBacked) || (!plan.Chipset.IsUnknown() && !plan.Chipset.Equal(state.Chipset)) {
resp.Diagnostics.Append(utilities.ComputeResourceComputeUpdate(ctx, &state, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceCompute: Error update compute parameters")
@@ -494,25 +508,11 @@ func (r *resourceCompute) Delete(ctx context.Context, req resource.DeleteRequest
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
var permanently bool
if state.Permanently.IsNull() {
permanently = true
} else {
permanently = state.Permanently.ValueBool()
}
var detach bool
if state.DetachDisks.IsNull() {
detach = true
} else {
detach = state.DetachDisks.ValueBool()
}
// Delete existing Compute
delReq := compute.DeleteRequest{
ComputeID: uint64(state.ComputeId.ValueInt64()),
Permanently: permanently,
DetachDisks: detach,
Permanently: state.Permanently.ValueBool(),
DetachDisks: state.DetachDisks.ValueBool(),
}
tflog.Info(ctx, "Delete resourceCompute: calling CloudAPI().Compute().Delete", map[string]any{

View File

@@ -160,6 +160,9 @@ func MakeSchemaDataSourceCompute() map[string]schema.Attribute {
"arch": schema.StringAttribute{
Computed: true,
},
"chipset": schema.StringAttribute{
Computed: true,
},
"boot_order": schema.ListAttribute{
Computed: true,
ElementType: types.StringType,
@@ -223,6 +226,9 @@ func MakeSchemaDataSourceCompute() map[string]schema.Attribute {
"boot_partition": schema.Int64Attribute{
Computed: true,
},
"bus_number": schema.Int64Attribute{
Computed: true,
},
"created_time": schema.Int64Attribute{
Computed: true,
},
@@ -447,6 +453,9 @@ func MakeSchemaDataSourceCompute() map[string]schema.Attribute {
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"bus_number": schema.Int64Attribute{
Computed: true,
},
"conn_id": schema.Int64Attribute{
Computed: true,
},
@@ -468,12 +477,41 @@ func MakeSchemaDataSourceCompute() map[string]schema.Attribute {
"ip_address": schema.StringAttribute{
Computed: true,
},
"libvirt_settings": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"guid": schema.StringAttribute{
Computed: true,
},
"txmode": schema.StringAttribute{
Computed: true,
},
"ioeventfd": schema.StringAttribute{
Computed: true,
},
"event_idx": schema.StringAttribute{
Computed: true,
},
"queues": schema.Int64Attribute{
Computed: true,
},
"rx_queue_size": schema.Int64Attribute{
Computed: true,
},
"tx_queue_size": schema.Int64Attribute{
Computed: true,
},
},
},
"listen_ssh": schema.BoolAttribute{
Computed: true,
},
"mac": schema.StringAttribute{
Computed: true,
},
"mtu": schema.Int64Attribute{
Computed: true,
},
"name": schema.StringAttribute{
Computed: true,
},
@@ -583,6 +621,10 @@ func MakeSchemaDataSourceCompute() map[string]schema.Attribute {
},
},
},
"pci_devices": schema.ListAttribute{
Computed: true,
ElementType: types.Int64Type,
},
"pinned": schema.BoolAttribute{
Computed: true,
},

View File

@@ -166,6 +166,9 @@ func MakeSchemaDataSourceComputeList() map[string]schema.Attribute {
"arch": schema.StringAttribute{
Computed: true,
},
"chipset": schema.StringAttribute{
Computed: true,
},
"boot_order": schema.ListAttribute{
Computed: true,
ElementType: types.StringType,
@@ -217,6 +220,9 @@ func MakeSchemaDataSourceComputeList() map[string]schema.Attribute {
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"bus_number": schema.Int64Attribute{
Computed: true,
},
"disk_id": schema.Int64Attribute{
Computed: true,
},
@@ -248,6 +254,9 @@ func MakeSchemaDataSourceComputeList() map[string]schema.Attribute {
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"bus_number": schema.Int64Attribute{
Computed: true,
},
"conn_id": schema.Int64Attribute{
Computed: true,
},
@@ -310,6 +319,32 @@ func MakeSchemaDataSourceComputeList() map[string]schema.Attribute {
},
},
},
"libvirt_settings": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"guid": schema.StringAttribute{
Computed: true,
},
"txmode": schema.StringAttribute{
Computed: true,
},
"ioeventfd": schema.StringAttribute{
Computed: true,
},
"event_idx": schema.StringAttribute{
Computed: true,
},
"queues": schema.Int64Attribute{
Computed: true,
},
"rx_queue_size": schema.Int64Attribute{
Computed: true,
},
"tx_queue_size": schema.Int64Attribute{
Computed: true,
},
},
},
"target": schema.StringAttribute{
Computed: true,
},

View File

@@ -158,6 +158,9 @@ func MakeSchemaDataSourceComputeListDeleted() map[string]schema.Attribute {
"arch": schema.StringAttribute{
Computed: true,
},
"chipset": schema.StringAttribute{
Computed: true,
},
"boot_order": schema.ListAttribute{
Computed: true,
ElementType: types.StringType,
@@ -209,6 +212,9 @@ func MakeSchemaDataSourceComputeListDeleted() map[string]schema.Attribute {
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"bus_number": schema.Int64Attribute{
Computed: true,
},
"disk_id": schema.Int64Attribute{
Computed: true,
},
@@ -240,6 +246,9 @@ func MakeSchemaDataSourceComputeListDeleted() map[string]schema.Attribute {
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"bus_number": schema.Int64Attribute{
Computed: true,
},
"conn_id": schema.Int64Attribute{
Computed: true,
},
@@ -261,6 +270,32 @@ func MakeSchemaDataSourceComputeListDeleted() map[string]schema.Attribute {
"ip_address": schema.StringAttribute{
Computed: true,
},
"libvirt_settings": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"guid": schema.StringAttribute{
Computed: true,
},
"txmode": schema.StringAttribute{
Computed: true,
},
"ioeventfd": schema.StringAttribute{
Computed: true,
},
"event_idx": schema.StringAttribute{
Computed: true,
},
"queues": schema.Int64Attribute{
Computed: true,
},
"rx_queue_size": schema.Int64Attribute{
Computed: true,
},
"tx_queue_size": schema.Int64Attribute{
Computed: true,
},
},
},
"listen_ssh": schema.BoolAttribute{
Computed: true,
},

View File

@@ -5,6 +5,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
@@ -30,7 +31,7 @@ func MakeSchemaResourceCompute() map[string]schema.Attribute {
"driver": schema.StringAttribute{
Required: true,
Validators: []validator.String{
stringvalidator.OneOf("SVA_KVM_X86", "KVM_X86", "KVM_PPC"),
stringvalidator.OneOf("SVA_KVM_X86", "KVM_X86"),
},
Description: "Hardware architecture of this compute instance.",
},
@@ -180,7 +181,7 @@ func MakeSchemaResourceCompute() map[string]schema.Attribute {
"net_type": schema.StringAttribute{
Required: true,
Validators: []validator.String{
stringvalidator.OneOf("EXTNET", "VINS", "VFNIC"),
stringvalidator.OneOf("EXTNET", "VINS", "VFNIC", "DPDK"),
},
Description: "Type of the network for this connection, either EXTNET or VINS.",
},
@@ -197,6 +198,19 @@ func MakeSchemaResourceCompute() map[string]schema.Attribute {
Computed: true,
Description: "MAC address associated with this connection. MAC address is assigned automatically.",
},
"weight": schema.Int64Attribute{
Optional: true,
Computed: true,
Description: "Weight the network if you need to sort network list, the smallest attach first. zero or null weight attach last",
},
"mtu": schema.Int64Attribute{
Optional: true,
Computed: true,
Validators: []validator.Int64{
int64validator.Between(1, 9216),
},
Description: "Maximum transmission unit, used only for DPDK type, must be 1-9216",
},
},
},
},
@@ -289,6 +303,8 @@ func MakeSchemaResourceCompute() map[string]schema.Attribute {
},
"enabled": schema.BoolAttribute{
Optional: true,
Computed: true,
Default: booldefault.StaticBool(true),
Description: "If true - enable compute, else - disable",
},
"pause": schema.BoolAttribute{
@@ -301,6 +317,8 @@ func MakeSchemaResourceCompute() map[string]schema.Attribute {
},
"restore": schema.BoolAttribute{
Optional: true,
Computed: true,
Default: booldefault.StaticBool(true),
//Default: true,
},
"auto_start": schema.BoolAttribute{
@@ -328,15 +346,21 @@ func MakeSchemaResourceCompute() map[string]schema.Attribute {
},
"started": schema.BoolAttribute{
Optional: true,
Computed: true,
Default: booldefault.StaticBool(true),
//Default: true,
Description: "Is compute started.",
},
"detach_disks": schema.BoolAttribute{
Optional: true,
Computed: true,
Default: booldefault.StaticBool(true),
//Default: true,
},
"permanently": schema.BoolAttribute{
Optional: true,
Computed: true,
Default: booldefault.StaticBool(true),
//Default: true,
},
"is": schema.StringAttribute{
@@ -365,6 +389,19 @@ func MakeSchemaResourceCompute() map[string]schema.Attribute {
//Default: false,
Description: "Use Huge Pages to allocate RAM of the virtual machine. The system must be pre-configured by allocating Huge Pages on the physical node.",
},
"pci_devices": schema.SetAttribute{
Optional: true,
ElementType: types.Int64Type,
Description: "ID of the connected pci devices",
},
"chipset": schema.StringAttribute{
Optional: true,
Computed: true,
Validators: []validator.String{
stringvalidator.OneOf("i440fx", "Q35"),
},
Description: "Type of the emulated system, Q35 or i440fx",
},
// computed attributes
"compute_id": schema.Int64Attribute{
@@ -528,6 +565,9 @@ func MakeSchemaResourceCompute() map[string]schema.Attribute {
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"bus_number": schema.Int64Attribute{
Computed: true,
},
"conn_id": schema.Int64Attribute{
Computed: true,
},
@@ -555,6 +595,9 @@ func MakeSchemaResourceCompute() map[string]schema.Attribute {
"mac": schema.StringAttribute{
Computed: true,
},
"mtu": schema.Int64Attribute{
Computed: true,
},
"name": schema.StringAttribute{
Computed: true,
},
@@ -590,6 +633,32 @@ func MakeSchemaResourceCompute() map[string]schema.Attribute {
},
},
},
"libvirt_settings": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"guid": schema.StringAttribute{
Computed: true,
},
"txmode": schema.StringAttribute{
Computed: true,
},
"ioeventfd": schema.StringAttribute{
Computed: true,
},
"event_idx": schema.StringAttribute{
Computed: true,
},
"queues": schema.Int64Attribute{
Computed: true,
},
"rx_queue_size": schema.Int64Attribute{
Computed: true,
},
"tx_queue_size": schema.Int64Attribute{
Computed: true,
},
},
},
"target": schema.StringAttribute{
Computed: true,
},
@@ -749,6 +818,9 @@ func MakeSchemaResourceComputeDisks() map[string]schema.Attribute {
"boot_partition": schema.Int64Attribute{
Computed: true,
},
"bus_number": schema.Int64Attribute{
Computed: true,
},
"created_time": schema.Int64Attribute{
Computed: true,
},

View File

@@ -26,3 +26,21 @@ func ComputeCheckPresence(ctx context.Context, state *models.RecordComputeModel,
tflog.Info(ctx, "Getting compute info, successfully")
return computeRecord, nil
}
func ComputePCIDevicesListCheckPresence(ctx context.Context, state *models.RecordComputeModel, c *decort.DecortClient) (*compute.ListPCIDevices, error) {
tflog.Info(ctx, "Get PCI devices info")
req := compute.ListPCIDeviceRequest{
ComputeID: uint64(state.ComputeId.ValueInt64()),
}
tflog.Info(ctx, "Check req", map[string]any{"req": req})
pciDevicesList, err := c.CloudAPI().Compute().ListPCIDevice(ctx, req)
if err != nil {
return nil, err
}
tflog.Info(ctx, "Getting PCI devices info, successfully")
return pciDevicesList, nil
}

View File

@@ -3,6 +3,7 @@ package utilities
import (
"context"
"fmt"
"sort"
"strconv"
"strings"
@@ -11,7 +12,6 @@ import (
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute"
"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-dynamix/internal/service/cloudapi/kvmvm/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/status"
@@ -81,42 +81,50 @@ func CreateResourceCompute(ctx context.Context, plan *models.ResourceComputeMode
diags := diag.Diagnostics{}
createReqX86 := kvmx86.CreateRequest{Start: false}
createReqPPC := kvmppc.CreateRequest{Start: false}
if !plan.Description.IsUnknown() {
createReqPPC.Description = plan.Description.ValueString()
createReqX86.Description = plan.Description.ValueString()
}
if !plan.SepId.IsUnknown() {
createReqPPC.SEPID = uint64(plan.SepId.ValueInt64())
createReqX86.SepID = uint64(plan.SepId.ValueInt64())
}
if !plan.Pool.IsUnknown() {
createReqPPC.Pool = plan.Pool.ValueString()
createReqX86.Pool = plan.Pool.ValueString()
}
if !plan.IpaType.IsNull() {
createReqPPC.IPAType = plan.IpaType.ValueString()
createReqX86.IPAType = plan.IpaType.ValueString()
}
if !plan.BootDiskSize.IsNull() {
createReqPPC.BootDisk = uint64(plan.BootDiskSize.ValueInt64())
createReqX86.BootDisk = uint64(plan.BootDiskSize.ValueInt64())
}
if !plan.IS.IsNull() {
createReqPPC.IS = plan.IS.ValueString()
createReqX86.IS = plan.IS.ValueString()
}
if !plan.Chipset.IsUnknown() {
createReqX86.Chipset = plan.Chipset.ValueString()
}
createReqX86.Interfaces = make([]kvmx86.Interface, 0)
if !plan.Network.IsNull() {
networkList := plan.Network.Elements()
sort.Slice(networkList, func(i, j int) bool {
weightI := networkList[i].(types.Object).Attributes()["weight"].(types.Int64).ValueInt64()
weightJ := networkList[j].(types.Object).Attributes()["weight"].(types.Int64).ValueInt64()
if weightI == 0 {
return false
}
if weightJ == 0 {
return true
}
return weightI < weightJ
})
interfaces := make([]kvmx86.Interface, 0)
for _, elem := range networkList {
objVal := elem.(types.Object)
@@ -125,108 +133,72 @@ func CreateResourceCompute(ctx context.Context, plan *models.ResourceComputeMode
NetType: strings.ToUpper(elemMap["net_type"].(types.String).ValueString()),
NetID: uint64(elemMap["net_id"].(types.Int64).ValueInt64()),
}
if reqInterface.NetType == "DPDK" {
reqInterface.MTU = uint64(elemMap["mtu"].(types.Int64).ValueInt64())
}
ipaddr, ipSet := elemMap["ip_address"]
if ipSet {
reqInterface.IPAddr = ipaddr.(types.String).ValueString()
}
interfaces = append(interfaces, reqInterface)
}
createReqX86.Interfaces = interfaces
}
createReqPPC.Interfaces = make([]kvmppc.Interface, 0)
if !plan.Network.IsNull() {
networkList := plan.Network.Elements()
interfaces := make([]kvmppc.Interface, 0)
for _, elem := range networkList {
objVal := elem.(types.Object)
elemMap := objVal.Attributes()
reqInterface := kvmppc.Interface{
NetType: strings.ToUpper(elemMap["net_type"].(types.String).ValueString()),
NetID: uint64(elemMap["net_id"].(types.Int64).ValueInt64()),
}
ipaddr, ipSet := elemMap["ip_address"]
if ipSet {
reqInterface.IPAddr = ipaddr.(types.String).ValueString()
}
interfaces = append(interfaces, reqInterface)
}
createReqPPC.Interfaces = interfaces
}
if !plan.CloudInit.IsNull() {
userData := plan.CloudInit.ValueString()
if userData != "" && userData != "applied" {
createReqPPC.Userdata = strings.TrimSpace(userData)
createReqX86.Userdata = strings.TrimSpace(userData)
}
}
driver := strings.ToUpper(plan.Driver.ValueString())
if driver == "KVM_PPC" {
createReqPPC.RGID = uint64(plan.RGID.ValueInt64())
createReqPPC.Name = plan.Name.ValueString()
createReqPPC.CPU = uint64(plan.CPU.ValueInt64())
createReqPPC.RAM = uint64(plan.RAM.ValueInt64())
createReqPPC.ImageID = uint64(plan.ImageID.ValueInt64())
tflog.Info(ctx, fmt.Sprintf("CreateResourceCompute: creating Compute of type KVM VM PowerPC"))
id, err := c.CloudAPI().KVMPPC().Create(ctx, createReqPPC)
if err != nil {
diags.AddError("CreateResourceCompute: unable to create KVM VP PowerPC", err.Error())
return 0, diags
}
return id, diags
} else {
createReqX86.RGID = uint64(plan.RGID.ValueInt64())
createReqX86.Name = plan.Name.ValueString()
createReqX86.CPU = uint64(plan.CPU.ValueInt64())
createReqX86.RAM = uint64(plan.RAM.ValueInt64())
createReqX86.Driver = driver
createReqX86.RGID = uint64(plan.RGID.ValueInt64())
createReqX86.Name = plan.Name.ValueString()
createReqX86.CPU = uint64(plan.CPU.ValueInt64())
createReqX86.RAM = uint64(plan.RAM.ValueInt64())
createReqX86.Driver = driver
if !plan.ImageID.IsNull() {
createReqX86.ImageID = uint64(plan.ImageID.ValueInt64())
}
if !plan.WithoutBootDisk.IsNull() {
createReqX86.WithoutBootDisk = plan.WithoutBootDisk.ValueBool()
}
if !plan.CustomFields.IsUnknown() { //CustomFields optional && computed
val := plan.CustomFields.ValueString()
val = strings.ReplaceAll(val, "\\", "")
val = strings.ReplaceAll(val, "\n", "")
val = strings.ReplaceAll(val, "\t", "")
val = strings.TrimSpace(val)
createReqX86.CustomFields = val
}
if !plan.NumaAffinity.IsNull() {
createReqX86.NumaAffinity = strings.ToLower(plan.NumaAffinity.ValueString())
}
if !plan.CPUPin.IsNull() && plan.CPUPin.ValueBool() {
createReqX86.CPUPin = true
}
if !plan.HPBacked.IsNull() && plan.HPBacked.ValueBool() {
createReqX86.HPBacked = true
}
tflog.Info(ctx, fmt.Sprintf("CreateResourceCompute: creating Compute of type KVM VM x86"))
id, err := c.CloudAPI().KVMX86().Create(ctx, createReqX86)
if err != nil {
diags.AddError("CreateResourceCompute: unable to create KVM VP x86", err.Error())
return 0, diags
}
return id, diags
if !plan.ImageID.IsNull() {
createReqX86.ImageID = uint64(plan.ImageID.ValueInt64())
}
if !plan.WithoutBootDisk.IsNull() {
createReqX86.WithoutBootDisk = plan.WithoutBootDisk.ValueBool()
}
if !plan.CustomFields.IsUnknown() { //CustomFields optional && computed
val := plan.CustomFields.ValueString()
val = strings.ReplaceAll(val, "\\", "")
val = strings.ReplaceAll(val, "\n", "")
val = strings.ReplaceAll(val, "\t", "")
val = strings.TrimSpace(val)
createReqX86.CustomFields = val
}
if !plan.NumaAffinity.IsNull() {
createReqX86.NumaAffinity = strings.ToLower(plan.NumaAffinity.ValueString())
}
if !plan.CPUPin.IsNull() && plan.CPUPin.ValueBool() {
createReqX86.CPUPin = true
}
if !plan.HPBacked.IsNull() && plan.HPBacked.ValueBool() {
createReqX86.HPBacked = true
}
tflog.Info(ctx, fmt.Sprintf("CreateResourceCompute: creating Compute of type KVM VM x86"))
id, err := c.CloudAPI().KVMX86().Create(ctx, createReqX86)
if err != nil {
diags.AddError("CreateResourceCompute: unable to create KVM VP x86", err.Error())
return 0, diags
}
return id, diags
}
func CleanupResourceCompute(ctx context.Context, computeId uint64, c *decort.DecortClient) {
@@ -281,16 +253,11 @@ func ComputeResourceEnableDisable(ctx context.Context, plan *models.ResourceComp
return diags
}
var enable bool
if plan.Enabled.IsNull() {
enable = true // default value
} else {
enable = plan.Enabled.ValueBool()
}
enable := plan.Enabled.ValueBool()
tflog.Info(ctx, "ComputeEnableDisable: compute to be enabled/disabled", map[string]any{
"compute_id": computeId,
"enable": enable})
"enable": plan.Enabled.ValueBool()})
if enable {
_, err = c.CloudAPI().Compute().Enable(ctx, compute.EnableRequest{ComputeID: computeId})
@@ -326,12 +293,7 @@ func ComputeResourceStartStop(ctx context.Context, plan *models.ResourceComputeM
return diags
}
var started bool
if plan.Started.IsNull() {
started = true // default value
} else {
started = plan.Started.ValueBool()
}
started := plan.Started.ValueBool()
tflog.Info(ctx, "ComputeStartStop: compute to be started/stopped", map[string]any{
"compute_id": computeId,
@@ -642,6 +604,41 @@ func ComputeResourceSnapshot(ctx context.Context, plan *models.ResourceComputeMo
return nil
}
func ComputeResourcePCIDevice(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "ComputeResourcePCIDevice: Start added PCI devices(s) to compute with ID", map[string]any{"compute_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
computeId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("ComputeResourcePCIDevice: cannot parsed ID compute from plan", err.Error())
return diags
}
pciDeviceList := plan.PCIDevices.Elements()
for _, pciDevice := range pciDeviceList {
pciDeviceId := pciDevice.(types.Int64).ValueInt64()
req := compute.AttachPCIDeviceRequest{
ComputeID: computeId,
DeviceID: uint64(pciDeviceId),
}
tflog.Info(ctx, "ComputeResourcePCIDevice: Start attach PCI device to compute with ID", map[string]any{"compute_id": plan.ID.ValueString(), "pci_device_id": pciDeviceId})
res, err := c.CloudAPI().Compute().AttachPCIDevice(ctx, req)
tflog.Info(ctx, "ComputeResourceSnapshot: response from CloudAPI().Compute().AttachPCIDevice", map[string]any{"compute_id": computeId, "response": res})
if err != nil {
diags.AddWarning(
"ComputeResourceSnapshot: Unable to add PCI device for Compute",
err.Error(),
)
}
}
if diags.WarningsCount() != 0 {
return diags
}
tflog.Info(ctx, "ComputeResourcePCIDevice: PCI devices(s) is successfully added", map[string]any{"compute_id": computeId})
return nil
}
func ComputeResourceCDInsert(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "ComputeResourceCDInsert: Start added cd to compute with ID", map[string]any{"compute_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
@@ -745,7 +742,7 @@ func ComputeReadStatus(ctx context.Context, state *models.ResourceComputeModel,
"compute_id": computeId,
"status": recordCompute.Status})
// restore and enable compute in case it is required
if state.Restore.IsNull() || state.Restore.ValueBool() { // default true or user set-up true
if state.Restore.ValueBool() { // default true or user set-up true
diags.Append(RestoreCompute(ctx, computeId, c)...)
if diags.HasError() {
tflog.Error(ctx, "ComputeReadStatus: cannot restore compute")
@@ -759,14 +756,14 @@ func ComputeReadStatus(ctx context.Context, state *models.ResourceComputeModel,
return diags
}
}
if state.Enabled.IsNull() || state.Enabled.ValueBool() { // default true or user set-up true
if state.Enabled.ValueBool() { // default true or user set-up true
diags.Append(ComputeResourceEnableDisable(ctx, state, c)...)
if diags.HasError() {
tflog.Error(ctx, "ComputeReadStatus: Unable to enable compute")
return diags
}
tflog.Info(ctx, "ComputeReadStatus: compute enabled successfully", map[string]any{"compute_id": computeId})
if state.Started.IsNull() || state.Started.ValueBool() {
if state.Started.ValueBool() {
diags.Append(ComputeResourceStartStop(ctx, state, c)...)
if diags.HasError() {
tflog.Error(ctx, "ComputeReadStatus: Unable to start compute")

View File

@@ -1,6 +1,9 @@
package utilities
import "github.com/hashicorp/terraform-plugin-framework/types"
import (
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"
)
// differenceSimpleType returns lists added and removed values
func differenceSimpleType(oldSet, newSet types.Set) (added, removed []any) {
@@ -30,36 +33,52 @@ func differenceSimpleType(oldSet, newSet types.Set) (added, removed []any) {
return
}
func differenceNetwork(oldSet, newSet types.Set) (added, removed []any) {
func differenceNetwork(oldSet, newSet types.Set) (added, changeIp, removed []map[string]attr.Value) {
oldSlice := oldSet.Elements()
newSlice := newSet.Elements()
foundIdx := make([]bool, len(oldSlice))
for _, newElem := range newSlice {
newObj := newElem.(types.Object)
newElemMap := newObj.Attributes()
added = make([]map[string]attr.Value, 0)
changeIp = make([]map[string]attr.Value, 0)
removed = make([]map[string]attr.Value, 0)
for _, oldNetwork := range oldSlice {
oldMap := oldNetwork.(types.Object).Attributes()
found := false
for i, oldElem := range oldSlice {
oldObj := oldElem.(types.Object)
oldElemMap := oldObj.Attributes()
if oldElemMap["net_type"] == newElemMap["net_type"] && oldElemMap["net_id"] == newElemMap["net_id"] {
ipaddr, ipSet := newElemMap["ip_address"]
if !ipSet || ipaddr.(types.String).ValueString() == "" || ipaddr == oldElemMap["ip_address"] {
for _, newNetwork := range newSlice {
newMap := newNetwork.(types.Object).Attributes()
if newMap["net_type"] == oldMap["net_type"] && newMap["net_id"] == oldMap["net_id"] && newMap["weight"] == oldMap["weight"] && (newMap["mtu"] == oldMap["mtu"] || newMap["mtu"].(types.Int64).ValueInt64() == 0) {
if (newMap["net_type"].(types.String).ValueString() == "EXTNET" || newMap["net_type"].(types.String).ValueString() == "VINS") && (newMap["ip_address"] != oldMap["ip_address"] && newMap["ip_address"].(types.String).ValueString() != "") {
changeIp = append(changeIp, newMap)
found = true
break
} else if newMap["ip_address"] == oldMap["ip_address"] || newMap["ip_address"].(types.String).ValueString() != "" {
found = true
foundIdx[i] = true
break
}
}
}
if !found {
added = append(added, newElem)
if found {
continue
}
removed = append(removed, oldMap)
}
for i, found := range foundIdx {
if !found {
removed = append(removed, oldSlice[i])
for _, newNetwork := range newSlice {
newMap := newNetwork.(types.Object).Attributes()
found := false
for _, oldNetwork := range oldSlice {
oldMap := oldNetwork.(types.Object).Attributes()
if newMap["net_type"] == oldMap["net_type"] && newMap["net_id"] == oldMap["net_id"] && newMap["weight"] == oldMap["weight"] && (newMap["mtu"] == oldMap["mtu"] || newMap["mtu"].(types.Int64).ValueInt64() == 0) {
if newMap["ip_address"] == oldMap["ip_address"] || newMap["ip_address"].(types.String).ValueString() != "" || ((newMap["net_type"].(types.String).ValueString() == "EXTNET" || newMap["net_type"].(types.String).ValueString() == "VINS") && newMap["ip_address"] != oldMap["ip_address"]) {
found = true
break
}
}
}
if found {
continue
}
added = append(added, newMap)
}
return

View File

@@ -3,6 +3,7 @@ package utilities
import (
"context"
"fmt"
"sort"
"strconv"
"strings"
@@ -169,7 +170,7 @@ func ComputeResourceExtraDiskUpdate(ctx context.Context, state *models.ResourceC
}
}
if len(detachSet) > 0 && (plan.Started.ValueBool() || plan.Started.IsNull()) {
if len(detachSet) > 0 && plan.Started.ValueBool() {
diags = ComputeResourceStartStop(ctx, plan, c)
}
@@ -182,6 +183,55 @@ func ComputeResourceExtraDiskUpdate(ctx context.Context, state *models.ResourceC
return nil
}
func ComputeResourcePCIDeviceUpdate(ctx context.Context, state *models.ResourceComputeModel, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "ComputeResourcePCIDeviceUpdate: start update PCI device(s) list to compute with ID", map[string]any{"compute_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
computeId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("ComputeResourcePCIDeviceUpdate: cannot parsed ID compute from state", err.Error())
return diags
}
attachSet, detachSet := differenceSimpleType(state.ExtraDisks, plan.ExtraDisks)
for _, pciDevice := range detachSet {
pciDeviceId := pciDevice.(types.Int64).ValueInt64()
tflog.Info(ctx, fmt.Sprintf("ComputeResourcePCIDeviceUpdate: Start detach PCI device with ID - %d from compute with ID - %d", pciDeviceId, computeId))
req := compute.DetachPCIDeviceRequest{
ComputeID: computeId,
DeviceID: uint64(pciDeviceId),
}
res, err := c.CloudAPI().Compute().DetachPCIDevice(ctx, req)
tflog.Info(ctx, "ComputeResourcePCIDeviceUpdate: response from CloudAPI().Compute().DetachPCIDevice", map[string]any{"compute_id": plan.ID.ValueString(), "response": res})
if err != nil {
diags.AddError(fmt.Sprintf("ComputeResourcePCIDeviceUpdate: Cannot detach PCI device with ID - %d", pciDeviceId), err.Error())
}
}
for _, pciDevice := range attachSet {
pciDeviceId := pciDevice.(types.Int64).ValueInt64()
tflog.Info(ctx, fmt.Sprintf("ComputeResourcePCIDeviceUpdate: Start attach PCI device with ID - %d to compute with ID - %d", pciDeviceId, computeId))
req := compute.AttachPCIDeviceRequest{
ComputeID: computeId,
DeviceID: uint64(pciDeviceId),
}
res, err := c.CloudAPI().Compute().AttachPCIDevice(ctx, req)
tflog.Info(ctx, "ComputeResourcePCIDeviceUpdate: response from CloudAPI().Compute().AttachPCIDevice", map[string]any{"compute_id": plan.ID.ValueString(), "response": res})
if err != nil {
diags.AddError(fmt.Sprintf("ComputeResourcePCIDeviceUpdate: Cannot attach PCI device with ID - %d", pciDeviceId), err.Error())
}
}
if diags.HasError() {
tflog.Error(ctx, "ComputeResourcePCIDeviceUpdate: Errors occurred while managing PCI device(s)")
return diags
}
tflog.Info(ctx, "ComputeResourcePCIDeviceUpdate: PCI device(s) is successfully update", map[string]any{"compute_id": computeId})
return nil
}
func ComputeResourceNetworkUpdate(ctx context.Context, state *models.ResourceComputeModel, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "ComputeResourceNetworkUpdate: start update network rules to compute with ID", map[string]any{"compute_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
@@ -192,22 +242,43 @@ func ComputeResourceNetworkUpdate(ctx context.Context, state *models.ResourceCom
return diags
}
attachSet, detachSet := differenceNetwork(state.Network, plan.Network)
attachMap, changeIpMap, detachMap := differenceNetwork(state.Network, plan.Network)
for _, network := range detachSet {
objVal := network.(types.Object)
elemMap := objVal.Attributes()
tflog.Info(ctx, "ComputeResourceNetworkUpdate: start detach network(s) rules to compute with ID", map[string]any{"compute_id": plan.ID.ValueString()})
for _, network := range detachMap {
req := compute.NetDetachRequest{
ComputeID: computeId,
IPAddr: elemMap["ip_address"].(types.String).ValueString(),
MAC: elemMap["mac"].(types.String).ValueString(),
IPAddr: network["ip_address"].(types.String).ValueString(),
MAC: network["mac"].(types.String).ValueString(),
}
tflog.Info(ctx, "ComputeResourceNetworkUpdate: before calling CloudAPI().Compute().NetDetach", map[string]any{"compute_id": computeId, "req": req})
res, err := c.CloudAPI().Compute().NetDetach(ctx, req)
tflog.Info(ctx, "ComputeResourceNetworkUpdate: response from CloudAPI().Compute().NetDetach", map[string]any{"compute_id": plan.ID.ValueString(), "response": res})
if err != nil {
diags.AddError(fmt.Sprintf("ComputeResourceNetworkUpdate: failed to detach net ID %d from Compute ID %d",
elemMap["net_id"].(types.Int64).ValueInt64(), computeId), err.Error())
network["net_id"].(types.Int64).ValueInt64(), computeId), err.Error())
}
}
if diags.HasError() {
return diags
}
tflog.Info(ctx, "ComputeResourceNetworkUpdate: start change IP network(s) rules to compute with ID", map[string]any{"compute_id": plan.ID.ValueString()})
for _, network := range changeIpMap {
req := compute.ChangeIPRequest{
ComputeID: computeId,
NetType: network["net_type"].(types.String).ValueString(),
NetID: uint64(network["net_id"].(types.Int64).ValueInt64()),
IPAddr: network["ip_address"].(types.String).ValueString(),
}
tflog.Info(ctx, "ComputeResourceNetworkUpdate: before calling CloudAPI().Compute().ChangeIP", map[string]any{"compute_id": computeId, "req": req})
res, err := c.CloudAPI().Compute().ChangeIP(ctx, req)
tflog.Info(ctx, "ComputeResourceNetworkUpdate: response from CloudAPI().Compute().ChangeIP", map[string]any{"compute_id": plan.ID.ValueString(), "response": res})
if err != nil {
diags.AddError(fmt.Sprintf("ComputeResourceNetworkUpdate: failed to change IP net ID %d from Compute ID %d",
network["net_id"].(types.Int64).ValueInt64(), computeId), err.Error())
}
}
@@ -217,7 +288,7 @@ func ComputeResourceNetworkUpdate(ctx context.Context, state *models.ResourceCom
needStart := false
// need stop to attach first network
if (len(detachSet) == len(state.Network.Elements()) || len(state.Network.Elements()) < 1) && len(attachSet) > 0 {
if len(detachMap) == len(state.Network.Elements()) || (len(state.Network.Elements()) < 1) && len(attachMap) > 0 || hasDPDKnetwork(attachMap) {
tflog.Info(ctx, "ComputeResourceNetworkUpdate: stop compute", map[string]any{"compute_id": computeId})
_, err = c.CloudAPI().Compute().Stop(ctx, compute.StopRequest{ComputeID: computeId})
if err != nil {
@@ -226,18 +297,33 @@ func ComputeResourceNetworkUpdate(ctx context.Context, state *models.ResourceCom
)
return diags
}
needStart = true
if plan.Started.ValueBool() {
needStart = true
}
}
for _, network := range attachSet {
objVal := network.(types.Object)
elemMap := objVal.Attributes()
sort.Slice(attachMap, func(i, j int) bool {
weightI := attachMap[i]["weight"].(types.Int64).ValueInt64()
weightJ := attachMap[j]["weight"].(types.Int64).ValueInt64()
if weightI == 0 {
return false
}
if weightJ == 0 {
return true
}
return weightI < weightJ
})
for _, network := range attachMap {
req := compute.NetAttachRequest{
ComputeID: computeId,
NetType: strings.ToUpper(elemMap["net_type"].(types.String).ValueString()),
NetID: uint64(elemMap["net_id"].(types.Int64).ValueInt64()),
NetType: strings.ToUpper(network["net_type"].(types.String).ValueString()),
NetID: uint64(network["net_id"].(types.Int64).ValueInt64()),
}
ipaddr, ipSet := elemMap["ip_address"]
if req.NetType == "DPDK" {
req.MTU = uint64(network["mtu"].(types.Int64).ValueInt64())
}
ipaddr, ipSet := network["ip_address"]
if ipSet {
req.IPAddr = ipaddr.(types.String).ValueString()
}
@@ -246,11 +332,11 @@ func ComputeResourceNetworkUpdate(ctx context.Context, state *models.ResourceCom
tflog.Info(ctx, "ComputeResourceNetworkUpdate: response from CloudAPI().Compute().NetAttach", map[string]any{"compute_id": plan.ID.ValueString(), "response": res})
if err != nil {
diags.AddError(fmt.Sprintf("ComputeResourceNetworkUpdate: failed to attach net ID %d from Compute ID %d",
elemMap["net_id"].(types.Int64).ValueInt64(), computeId), err.Error())
network["net_id"].(types.Int64).ValueInt64(), computeId), err.Error())
}
}
if needStart && (plan.Started.ValueBool() || plan.Started.IsNull()) {
if needStart {
diags = ComputeResourceStartStop(ctx, plan, c)
}
@@ -263,6 +349,15 @@ func ComputeResourceNetworkUpdate(ctx context.Context, state *models.ResourceCom
return nil
}
func hasDPDKnetwork(networkAttachMap []map[string]attr.Value) bool {
for _, elem := range networkAttachMap {
if elem["net_type"].(types.String).ValueString() == "DPDK" {
return true
}
}
return false
}
func ComputeResourceComputeUpdate(ctx context.Context, state *models.ResourceComputeModel, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "ComputeResourceComputeUpdate: start update compute parameters", map[string]any{"compute_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
@@ -301,6 +396,10 @@ func ComputeResourceComputeUpdate(ctx context.Context, state *models.ResourceCom
req.HPBacked = state.HPBacked.ValueBool()
}
if !plan.Chipset.IsUnknown() && !plan.Chipset.Equal(state.Chipset) {
req.Chipset = plan.Chipset.ValueString()
}
// 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
@@ -328,7 +427,7 @@ func ComputeResourceComputeUpdate(ctx context.Context, state *models.ResourceCom
return diags
}
if isStopRequred && (plan.Started.ValueBool() || plan.Started.IsNull()) {
if isStopRequred && plan.Started.ValueBool() {
diags = ComputeResourceStartStop(ctx, plan, c)
}
@@ -889,7 +988,7 @@ func ComputeResourceRollback(ctx context.Context, plan *models.ResourceComputeMo
return diags
}
if plan.Started.ValueBool() || plan.Started.IsNull() {
if plan.Started.ValueBool() {
diags = ComputeResourceStartStop(ctx, plan, c)
if diags.HasError() {
tflog.Error(ctx, "ComputeResourceRollback: cannot start compute")
@@ -1092,7 +1191,7 @@ func ComputeResourceRedeploy(ctx context.Context, plan *models.ResourceComputeMo
return diags
}
if plan.Started.ValueBool() || plan.Started.IsNull() {
if plan.Started.ValueBool() {
diags = ComputeResourceStartStop(ctx, plan, c)
if diags.HasError() {
tflog.Error(ctx, "ComputeResourceRedeploy: cannot start compute")