1.0.0
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputeCheckPresence(ctx context.Context, state *models.RecordComputeModel, c *decort.DecortClient) (*compute.RecordCompute, error) {
|
||||
tflog.Info(ctx, "Get compute info")
|
||||
|
||||
req := compute.GetRequest{
|
||||
ComputeID: uint64(state.ComputeId.ValueInt64()),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
computeRecord, err := c.CloudAPI().Compute().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute info, successfully")
|
||||
return computeRecord, nil
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputeGetAuditsCheckPresence(ctx context.Context, state *models.GetAuditsModel, c *decort.DecortClient) (*compute.ListShortAudits, error) {
|
||||
tflog.Info(ctx, "Get compute short audits info")
|
||||
|
||||
req := compute.GetAuditsRequest{
|
||||
ComputeID: uint64(state.ComputeID.ValueInt64()),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
auditsShortList, err := c.CloudAPI().Compute().GetAudits(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute short audits, successfully")
|
||||
return &auditsShortList, nil
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputeAuditsCheckPresence(ctx context.Context, state *models.ListAuditsModel, c *decort.DecortClient) (*compute.ListAudits, error) {
|
||||
tflog.Info(ctx, "Get compute audits list info")
|
||||
|
||||
req := compute.AuditsRequest{
|
||||
ComputeID: uint64(state.ComputeID.ValueInt64()),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
auditsList, err := c.CloudAPI().Compute().Audits(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute audits list, successfully")
|
||||
return &auditsList, nil
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputeGetConsoleUrlCheckPresence(ctx context.Context, state *models.GetConsoleUrlModel, c *decort.DecortClient) (string, error) {
|
||||
tflog.Info(ctx, "Get compute console url")
|
||||
|
||||
req := compute.GetConsoleURLRequest{
|
||||
ComputeID: uint64(state.ComputeID.ValueInt64()),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
consoleUrl, err := c.CloudAPI().Compute().GetConsoleURL(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
result := strings.ReplaceAll(consoleUrl, "\"", "")
|
||||
result = strings.ReplaceAll(result, "\\", "")
|
||||
|
||||
tflog.Info(ctx, "Getting compute console url, successfully")
|
||||
return result, nil
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputeGetLogCheckPresence(ctx context.Context, state *models.GetLogModel, c *decort.DecortClient) (string, error) {
|
||||
tflog.Info(ctx, "Get compute log")
|
||||
|
||||
req := compute.GetLogRequest{
|
||||
ComputeID: uint64(state.ComputeID.ValueInt64()),
|
||||
Path: state.Path.ValueString(),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
log, err := c.CloudAPI().Compute().GetLog(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute log, successfully")
|
||||
return log, nil
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputeListCheckPresence(ctx context.Context, state *models.ListComputesModel, c *decort.DecortClient) (*compute.ListComputes, error) {
|
||||
tflog.Info(ctx, "Get compute list info")
|
||||
|
||||
req := compute.ListRequest{}
|
||||
if !state.ByID.IsNull() {
|
||||
req.ByID = uint64(state.ByID.ValueInt64())
|
||||
}
|
||||
if !state.Name.IsNull() {
|
||||
req.Name = state.Name.ValueString()
|
||||
}
|
||||
if !state.AccountID.IsNull() {
|
||||
req.AccountID = uint64(state.AccountID.ValueInt64())
|
||||
}
|
||||
if !state.RGName.IsNull() {
|
||||
req.RGName = state.RGName.ValueString()
|
||||
}
|
||||
if !state.RGID.IsNull() {
|
||||
req.RGID = uint64(state.RGID.ValueInt64())
|
||||
}
|
||||
if !state.TechStatus.IsNull() {
|
||||
req.TechStatus = state.TechStatus.ValueString()
|
||||
}
|
||||
if !state.Status.IsNull() {
|
||||
req.Status = state.Status.ValueString()
|
||||
}
|
||||
if !state.IPAddress.IsNull() {
|
||||
req.IPAddress = state.IPAddress.ValueString()
|
||||
}
|
||||
if !state.ExtNetName.IsNull() {
|
||||
req.ExtNetName = state.ExtNetName.ValueString()
|
||||
}
|
||||
if !state.ExtNetID.IsNull() {
|
||||
req.ExtNetID = uint64(state.ExtNetID.ValueInt64())
|
||||
}
|
||||
if !state.IncludeDeleted.IsNull() {
|
||||
req.IncludeDeleted = state.IncludeDeleted.ValueBool()
|
||||
}
|
||||
if !state.SortBy.IsNull() {
|
||||
req.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
req.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
req.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
list, err := c.CloudAPI().Compute().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !state.IgnoreK8s.IsNull() && state.IgnoreK8s.ValueBool() {
|
||||
list = matchComputes(list)
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute list info, successfully")
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func matchComputes(computeList *compute.ListComputes) *compute.ListComputes {
|
||||
matched, _ := regexp.Compile(`[a-zA-Z]+\\d+-[a-zA-Z]+\\d+-[a-zA-Z]+\\d+`)
|
||||
result := computeList.FilterFunc(func(ic compute.ItemCompute) bool {
|
||||
res := matched.Match([]byte(ic.Name))
|
||||
return !res
|
||||
})
|
||||
|
||||
return &result
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputeListDeletedCheckPresence(ctx context.Context, state *models.ListDeletedComputesModel, c *decort.DecortClient) (*compute.ListComputes, error) {
|
||||
tflog.Info(ctx, "Get compute list deleted info")
|
||||
|
||||
req := compute.ListDeletedRequest{}
|
||||
if !state.ByID.IsNull() {
|
||||
req.ByID = uint64(state.ByID.ValueInt64())
|
||||
}
|
||||
if !state.Name.IsNull() {
|
||||
req.Name = state.Name.ValueString()
|
||||
}
|
||||
if !state.AccountID.IsNull() {
|
||||
req.AccountID = uint64(state.AccountID.ValueInt64())
|
||||
}
|
||||
if !state.RGName.IsNull() {
|
||||
req.RGName = state.RGName.ValueString()
|
||||
}
|
||||
if !state.RGID.IsNull() {
|
||||
req.RGID = uint64(state.RGID.ValueInt64())
|
||||
}
|
||||
if !state.TechStatus.IsNull() {
|
||||
req.TechStatus = state.TechStatus.ValueString()
|
||||
}
|
||||
if !state.IPAddress.IsNull() {
|
||||
req.IPAddress = state.IPAddress.ValueString()
|
||||
}
|
||||
if !state.ExtNetName.IsNull() {
|
||||
req.ExtNetName = state.ExtNetName.ValueString()
|
||||
}
|
||||
if !state.ExtNetID.IsNull() {
|
||||
req.ExtNetID = uint64(state.ExtNetID.ValueInt64())
|
||||
}
|
||||
if !state.SortBy.IsNull() {
|
||||
req.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
req.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
req.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
list, err := c.CloudAPI().Compute().ListDeleted(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !state.IgnoreK8s.IsNull() && state.IgnoreK8s.ValueBool() {
|
||||
list = matchComputes(list)
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute list deleted info, successfully")
|
||||
return list, nil
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputePciDeviceListCheckPresence(ctx context.Context, state *models.ListPCIDevicesModel, c *decort.DecortClient) (*compute.ListPCIDevices, error) {
|
||||
tflog.Info(ctx, "Get compute pci device list info")
|
||||
|
||||
req := compute.ListPCIDeviceRequest{
|
||||
ComputeID: uint64(state.ComputeID.ValueInt64()),
|
||||
}
|
||||
|
||||
if !state.RGID.IsNull() {
|
||||
req.RGID = uint64(state.RGID.ValueInt64())
|
||||
}
|
||||
if !state.DevID.IsNull() {
|
||||
req.DevID = uint64(state.DevID.ValueInt64())
|
||||
}
|
||||
if !state.Name.IsNull() {
|
||||
req.Name = state.Name.ValueString()
|
||||
}
|
||||
if !state.Status.IsNull() {
|
||||
req.Status = state.Status.ValueString()
|
||||
}
|
||||
if !state.SortBy.IsNull() {
|
||||
req.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
req.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
req.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
log, err := c.CloudAPI().Compute().ListPCIDevice(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute pci device list info, successfully")
|
||||
return log, nil
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputePFWListCheckPresence(ctx context.Context, state *models.ListPFWsModel, c *decort.DecortClient) (*compute.ListPFWs, error) {
|
||||
tflog.Info(ctx, "Get compute pfw list info")
|
||||
|
||||
req := compute.PFWListRequest{
|
||||
ComputeID: uint64(state.ComputeID.ValueInt64()),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
pfwList, err := c.CloudAPI().Compute().PFWList(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute pfw list info, successfully")
|
||||
return pfwList, nil
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputeSnapshotUsageCheckPresence(ctx context.Context, state *models.ListSnapShotsModel, c *decort.DecortClient) (*compute.ListUsageSnapshots, error) {
|
||||
tflog.Info(ctx, "Get compute snapshot usage info")
|
||||
|
||||
req := compute.SnapshotUsageRequest{
|
||||
ComputeID: uint64(state.ComputeID.ValueInt64()),
|
||||
}
|
||||
if !state.Label.IsNull() {
|
||||
req.Label = state.Label.ValueString()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
snapshotUsage, err := c.CloudAPI().Compute().SnapshotUsage(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute snapshot usage info, successfully")
|
||||
return &snapshotUsage, nil
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputeUserListCheckPresence(ctx context.Context, state *models.ListUsersModel, c *decort.DecortClient) (*compute.ListUsers, error) {
|
||||
tflog.Info(ctx, "Get compute user list info")
|
||||
|
||||
req := compute.UserListRequest{
|
||||
ComputeID: uint64(state.ComputeID.ValueInt64()),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
userList, err := c.CloudAPI().Compute().UserList(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute user list info, successfully")
|
||||
return userList, nil
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/service/cloudapi/kvmvm/models"
|
||||
)
|
||||
|
||||
func ComputeVGPUListCheckPresence(ctx context.Context, state *models.ListVGPUsModel, c *decort.DecortClient) (*compute.ListVGPUs, error) {
|
||||
tflog.Info(ctx, "Get compute vgpu list info")
|
||||
|
||||
req := compute.ListVGPURequest{
|
||||
ComputeID: uint64(state.ComputeID.ValueInt64()),
|
||||
}
|
||||
|
||||
if !state.GPUID.IsNull() {
|
||||
req.GPUID = uint64(state.GPUID.ValueInt64())
|
||||
}
|
||||
if !state.Type.IsNull() {
|
||||
req.Type = state.Type.ValueString()
|
||||
}
|
||||
if !state.Status.IsNull() {
|
||||
req.Status = state.Status.ValueString()
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
req.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
if !state.SortBy.IsNull() {
|
||||
req.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
req.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
if !state.IncludeDeleted.IsNull() {
|
||||
req.IncludeDeleted = state.IncludeDeleted.ValueBool()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Check req", map[string]any{"req": req})
|
||||
|
||||
log, err := c.CloudAPI().Compute().ListVGPU(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting compute vgpu list info, successfully")
|
||||
return log, nil
|
||||
}
|
||||
@@ -0,0 +1,807 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"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"
|
||||
)
|
||||
|
||||
func ComputeResourceCheckPresence(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) (*compute.RecordCompute, diag.Diagnostics) {
|
||||
tflog.Info(ctx, fmt.Sprintf("ComputeResourceCheckPresence: Get info about compute with ID - %v", plan.ID.ValueString()))
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
computeId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("ComputeResourceCheckPresence: Cannot parsed ID lb from state", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
computeItem, err := c.CloudAPI().Compute().Get(ctx, compute.GetRequest{ComputeID: computeId})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("ComputeResourceCheckPresence: Cannot get info about compute with ID %v", computeId), err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
return computeItem, nil
|
||||
}
|
||||
|
||||
func ComputeResourceCheckDetachDisks(state *models.ResourceComputeModel, recordCompute *compute.RecordCompute) bool {
|
||||
bootDiskId := uint64(state.BootDiskId.ValueInt64())
|
||||
extraDiskList := state.ExtraDisks.Elements()
|
||||
for _, disk := range recordCompute.Disks {
|
||||
if disk.ID == bootDiskId {
|
||||
continue
|
||||
}
|
||||
for _, extraDisk := range extraDiskList {
|
||||
if uint64(extraDisk.(types.Int64).ValueInt64()) == disk.ID {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ComputeResourceBootDiskCheckPresence(ctx context.Context, state *models.ResourceComputeModel, c *decort.DecortClient) (*compute.ItemComputeDisk, diag.Diagnostics) {
|
||||
tflog.Info(ctx, "ComputeResourceBootDiskCheckPresence: Get info about boot disk")
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
recordItemCompute, diags := ComputeResourceCheckPresence(ctx, state, c)
|
||||
if diags.HasError() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
bootDisk := &compute.ItemComputeDisk{}
|
||||
for _, disk := range recordItemCompute.Disks {
|
||||
if disk.Name == "bootdisk" {
|
||||
*bootDisk = disk
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return bootDisk, nil
|
||||
}
|
||||
|
||||
func CreateResourceCompute(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) (uint64, diag.Diagnostics) {
|
||||
tflog.Info(ctx, fmt.Sprintf("CreateResourceCompute: Start create ResourceCompute: name %s", plan.Name.ValueString()))
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
createReqX86.Interfaces = make([]kvmx86.Interface, 0)
|
||||
|
||||
if !plan.Network.IsNull() {
|
||||
networkList := plan.Network.Elements()
|
||||
interfaces := make([]kvmx86.Interface, 0)
|
||||
for _, elem := range networkList {
|
||||
objVal := elem.(types.Object)
|
||||
elemMap := objVal.Attributes()
|
||||
reqInterface := kvmx86.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)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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) {
|
||||
tflog.Info(ctx, fmt.Sprintf("CleanupResourceCompute: Start delete ResourceCompute: id %d", computeId))
|
||||
req := compute.DeleteRequest{
|
||||
ComputeID: computeId,
|
||||
Permanently: true,
|
||||
DetachDisks: true,
|
||||
}
|
||||
|
||||
if _, err := c.CloudAPI().Compute().Delete(ctx, req); err != nil {
|
||||
tflog.Error(ctx, fmt.Sprintf("CleanupResourceCompute: could not delete compute after failed creation: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func ComputeResourceExtraDiskCreate(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeExtraDiskCreate: Start added extra disk(s) from 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("Cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
extraDiskList := plan.ExtraDisks.Elements()
|
||||
for _, disk := range extraDiskList {
|
||||
diskId := disk.(types.Int64).ValueInt64()
|
||||
req := compute.DiskAttachRequest{
|
||||
ComputeID: computeId,
|
||||
DiskID: uint64(diskId),
|
||||
}
|
||||
tflog.Info(ctx, "ComputeExtraDiskCreate: Start attach disk to compute with ID", map[string]any{"compute_id": plan.ID.ValueString(), "disk_id": diskId})
|
||||
_, err = c.CloudAPI().Compute().DiskAttach(ctx, req)
|
||||
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot attach disk with ID - %d", diskId), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
func ComputeResourceEnableDisable(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeEnableDisable: Start enabled/disabled 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("ComputeEnableDisable: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
var enable bool
|
||||
if plan.Enabled.IsNull() {
|
||||
enable = true // default value
|
||||
} else {
|
||||
enable = plan.Enabled.ValueBool()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeEnableDisable: compute to be enabled/disabled", map[string]any{
|
||||
"compute_id": computeId,
|
||||
"enable": enable})
|
||||
|
||||
if enable {
|
||||
_, err = c.CloudAPI().Compute().Enable(ctx, compute.EnableRequest{ComputeID: computeId})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeEnableDisable: cannot enable compute", err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
}
|
||||
|
||||
if !enable {
|
||||
_, err = c.CloudAPI().Compute().Disable(ctx, compute.DisableRequest{ComputeID: computeId})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeEnableDisable: cannot disable compute", err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeEnableDisable: compute is successfully enabled/disabled", map[string]any{"compute_id": computeId, "enable": enable})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComputeResourceStartStop(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeStartStop: Start started/stopped 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("ComputeStartStop: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
var started bool
|
||||
if plan.Started.IsNull() {
|
||||
started = true // default value
|
||||
} else {
|
||||
started = plan.Started.ValueBool()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeStartStop: compute to be started/stopped", map[string]any{
|
||||
"compute_id": computeId,
|
||||
"started": started})
|
||||
|
||||
if started {
|
||||
_, err = c.CloudAPI().Compute().Start(ctx, compute.StartRequest{ComputeID: computeId})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeStartStop: cannot start compute", err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
}
|
||||
|
||||
if !started {
|
||||
_, err = c.CloudAPI().Compute().Stop(ctx, compute.StopRequest{ComputeID: computeId})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeStartStop: cannot stop compute", err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeStartStop: compute is successfully started/stopped", map[string]any{"compute_id": computeId, "started": started})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComputeResourceAffinityLabel(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeAffinityLabel: Start added affinity label 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("ComputeAffinityLabel: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
req := compute.AffinityLabelSetRequest{
|
||||
ComputeID: computeId,
|
||||
AffinityLabel: plan.AffinityLabel.ValueString(),
|
||||
}
|
||||
|
||||
_, err = c.CloudAPI().Compute().AffinityLabelSet(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeAffinityLabel: Unable to AffinityLabelAdd for Compute",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeAffinityLabel: affinity label is successfully added", map[string]any{"compute_id": computeId})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComputeResourceAffinityRules(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeAffinityRules: Start added affinity rules 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("ComputeAffinityRules: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
itemsAffinityRules := make([]models.ItemResourceRulesModel, 0, len(plan.AffinityRules.Elements()))
|
||||
diags = plan.AffinityRules.ElementsAs(ctx, &itemsAffinityRules, false)
|
||||
if diags.HasError() {
|
||||
diags.AddWarning(
|
||||
fmt.Sprintf("ComputeAffinityRules: Unable to set affinity rules for compute %d", computeId),
|
||||
"cannot populate itemsAffinityRules with plan.AffinityRules List elements",
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
for _, itemAffinityRules := range itemsAffinityRules {
|
||||
req := compute.AffinityRuleAddRequest{
|
||||
ComputeID: computeId,
|
||||
Topology: strings.ToLower(itemAffinityRules.Topology.ValueString()),
|
||||
Policy: strings.ToUpper(itemAffinityRules.Policy.ValueString()),
|
||||
Mode: strings.ToUpper(itemAffinityRules.Mode.ValueString()),
|
||||
Key: itemAffinityRules.Key.ValueString(),
|
||||
Value: itemAffinityRules.Value.ValueString(),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeAffinityRules: before calling CloudAPI().Compute().AffinityRuleAdd", map[string]any{"compute_id": computeId, "req": req})
|
||||
res, err := c.CloudAPI().Compute().AffinityRuleAdd(ctx, req)
|
||||
tflog.Info(ctx, "ComputeAffinityRules: response from CloudAPI().Compute().AffinityRuleAdd", map[string]any{"compute_id": computeId, "response": res})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeAffinityRules: Unable to AffinityRuleAdd for Compute",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
}
|
||||
|
||||
if diags.WarningsCount() != 0 {
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeAffinityRules: affinity rules is successfully added", map[string]any{"compute_id": computeId})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComputeResourceAntiAffinityRules(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeAntiAffinityRules: Start added anti affinity rules 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("ComputeAntiAffinityRules: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
itemsAntiAffinityRules := make([]models.ItemResourceRulesModel, 0, len(plan.AntiAffinityRules.Elements()))
|
||||
diags = plan.AntiAffinityRules.ElementsAs(ctx, &itemsAntiAffinityRules, false)
|
||||
if diags.HasError() {
|
||||
diags.AddWarning(
|
||||
fmt.Sprintf("ComputeAntiAffinityRules: Unable to set anti affinity rules for compute %d", computeId),
|
||||
"cannot populate itemsAntiAffinityRules with plan.AntiAffinityRules List elements",
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
for _, itemAntiAffinityRules := range itemsAntiAffinityRules {
|
||||
req := compute.AntiAffinityRuleAddRequest{
|
||||
ComputeID: computeId,
|
||||
Topology: strings.ToLower(itemAntiAffinityRules.Topology.ValueString()),
|
||||
Policy: strings.ToUpper(itemAntiAffinityRules.Policy.ValueString()),
|
||||
Mode: strings.ToUpper(itemAntiAffinityRules.Mode.ValueString()),
|
||||
Key: itemAntiAffinityRules.Key.ValueString(),
|
||||
Value: itemAntiAffinityRules.Value.ValueString(),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeAntiAffinityRules: before calling CloudAPI().Compute().AntiAffinityRuleAdd", map[string]any{"compute_id": computeId, "req": req})
|
||||
res, err := c.CloudAPI().Compute().AntiAffinityRuleAdd(ctx, req)
|
||||
tflog.Info(ctx, "ComputeAntiAffinityRules: response from CloudAPI().Compute().AntiAffinityRuleAdd", map[string]any{"compute_id": computeId, "response": res})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeAntiAffinityRules: Unable to AntiAffinityRuleAdd for Compute",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
}
|
||||
|
||||
if diags.WarningsCount() != 0 {
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeAntiAffinityRules: anti affinity rules is successfully added", map[string]any{"compute_id": computeId})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComputeResourceTags(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeResourceTags: Start added tags 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("ComputeResourceTags: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
for _, tags := range plan.Tags.Elements() {
|
||||
req := compute.TagAddRequest{ComputeID: computeId}
|
||||
objTag := tags.(types.Object)
|
||||
tagMap := objTag.Attributes()
|
||||
req.Key = tagMap["key"].(types.String).ValueString()
|
||||
req.Value = tagMap["value"].(types.String).ValueString()
|
||||
tflog.Info(ctx, "ComputeResourceTags: before calling CloudAPI().Compute().TagAdd", map[string]any{"compute_id": computeId, "req": req})
|
||||
res, err := c.CloudAPI().Compute().TagAdd(ctx, req)
|
||||
tflog.Info(ctx, "ComputeResourceTags: response from CloudAPI().Compute().TagAdd", map[string]any{"compute_id": computeId, "response": res})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeResourceTags: Unable to add tags for Compute",
|
||||
err.Error(),
|
||||
)
|
||||
}
|
||||
}
|
||||
if diags.WarningsCount() != 0 {
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeResourceTags: tags is successfully added", map[string]any{"compute_id": computeId})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComputeResourcePortForwarding(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeResourcePortForwarding: Start added port forwarding 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("ComputeResourcePortForwarding: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
itemsPortForwarding := make([]models.ItemPortForfardingModel, 0, len(plan.PortForwarding.Elements()))
|
||||
diags = plan.PortForwarding.ElementsAs(ctx, &itemsPortForwarding, false)
|
||||
if diags.HasError() {
|
||||
diags.AddWarning(
|
||||
fmt.Sprintf("ComputeResourcePortForwarding: Unable to set port forwading rules for compute %d", computeId),
|
||||
"cannot populate itemsPortForwarding with plan.PortForwarding List elements",
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
for _, itemPortForwarding := range itemsPortForwarding {
|
||||
req := compute.PFWAddRequest{
|
||||
ComputeID: computeId,
|
||||
PublicPortStart: uint64(itemPortForwarding.PublicPortStart.ValueInt64()),
|
||||
Proto: strings.ToLower(itemPortForwarding.Proto.ValueString()),
|
||||
}
|
||||
if itemPortForwarding.PublicPortStart.ValueInt64() != 0 {
|
||||
req.PublicPortStart = uint64(itemPortForwarding.PublicPortStart.ValueInt64())
|
||||
}
|
||||
if itemPortForwarding.LocalPort.ValueInt64() != 0 {
|
||||
req.LocalBasePort = uint64(itemPortForwarding.LocalPort.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeResourcePortForwarding: before calling CloudAPI().Compute().PFWAdd", map[string]any{"compute_id": computeId, "req": req})
|
||||
res, err := c.CloudAPI().Compute().PFWAdd(ctx, req)
|
||||
tflog.Info(ctx, "ComputeResourcePortForwarding: response from CloudAPI().Compute().PFWAdd", map[string]any{"compute_id": computeId, "response": res})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeResourcePortForwarding: Unable to add pfw for Compute",
|
||||
err.Error(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if diags.WarningsCount() != 0 {
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeResourcePortForwarding: port forwarding rules is successfully added", map[string]any{"compute_id": computeId})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComputeResourceUserAccess(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeResourceUserAccess: Start added user(s) access 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("ComputeResourceUserAccess: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
for _, userAccess := range plan.UserAccess.Elements() {
|
||||
req := compute.UserGrantRequest{ComputeID: computeId}
|
||||
usersTag := userAccess.(types.Object)
|
||||
usersMap := usersTag.Attributes()
|
||||
req.Username = usersMap["username"].(types.String).ValueString()
|
||||
req.AccessType = usersMap["access_type"].(types.String).ValueString()
|
||||
tflog.Info(ctx, "ComputeResourceUserAccess: before calling CloudAPI().Compute().UserGrant", map[string]any{"compute_id": computeId, "req": req})
|
||||
res, err := c.CloudAPI().Compute().UserGrant(ctx, req)
|
||||
tflog.Info(ctx, "ComputeResourceUserAccess: response from CloudAPI().Compute().UserGrant", map[string]any{"compute_id": computeId, "response": res})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeResourceUserAccess: Unable to add user access for Compute",
|
||||
err.Error(),
|
||||
)
|
||||
}
|
||||
}
|
||||
if diags.WarningsCount() != 0 {
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeResourceUserAccess: user(s) access is successfully added", map[string]any{"compute_id": computeId})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComputeResourceSnapshot(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeResourceSnapshot: Start added snapshot 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("ComputeResourceSnapshot: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
for _, snapshots := range plan.Snapshot.Elements() {
|
||||
req := compute.SnapshotCreateRequest{ComputeID: computeId}
|
||||
snapshotTag := snapshots.(types.Object)
|
||||
snapshotMap := snapshotTag.Attributes()
|
||||
req.Label = snapshotMap["label"].(types.String).ValueString()
|
||||
tflog.Info(ctx, "ComputeResourceSnapshot: before calling CloudAPI().Compute().SnapshotCreate", map[string]any{"compute_id": computeId, "req": req})
|
||||
res, err := c.CloudAPI().Compute().SnapshotCreate(ctx, req)
|
||||
tflog.Info(ctx, "ComputeResourceSnapshot: response from CloudAPI().Compute().SnapshotCreate", map[string]any{"compute_id": computeId, "response": res})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeResourceSnapshot: Unable to add snapshot for Compute",
|
||||
err.Error(),
|
||||
)
|
||||
}
|
||||
}
|
||||
if diags.WarningsCount() != 0 {
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeResourceSnapshot: snapshot(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{}
|
||||
|
||||
computeId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("ComputeResourceSnapshot: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
req := compute.CDInsertRequest{ComputeID: computeId}
|
||||
req.CDROMID = uint64(plan.CD.Attributes()["cdrom_id"].(types.Int64).ValueInt64())
|
||||
tflog.Info(ctx, "ComputeResourceCDInsert: before calling CloudAPI().Compute().CDInsert", map[string]any{"compute_id": computeId, "req": req})
|
||||
res, err := c.CloudAPI().Compute().CDInsert(ctx, req)
|
||||
tflog.Info(ctx, "ComputeResourceCDInsert: response from CloudAPI().Compute().CDInsert", map[string]any{"compute_id": computeId, "response": res})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeResourceCDInsert: Unable to add cd for Compute",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeResourceCDInsert: cd(s) is successfully added", map[string]any{"compute_id": computeId})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComputeResourcePinToStack(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeResourcePinToStack: Start pin to stack 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("ComputeResourcePinToStack: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
_, err = c.CloudAPI().Compute().PinToStack(ctx, compute.PinToStackRequest{ComputeID: computeId})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeResourcePinToStack: cannot pin to stack compute", err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeResourcePinToStack: compute is successfully pin to stack", map[string]any{"compute_id": computeId})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComputeResourcePause(ctx context.Context, plan *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeResourcePause: Start pause 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("ComputeResourcePause: cannot parsed ID compute from plan", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
_, err = c.CloudAPI().Compute().Pause(ctx, compute.PauseRequest{ComputeID: computeId})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"ComputeResourcePause: cannot pause compute", err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeResourcePause: compute is successfully pause", map[string]any{"compute_id": computeId})
|
||||
return nil
|
||||
}
|
||||
func ComputeReadStatus(ctx context.Context, state *models.ResourceComputeModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ComputeReadStatus: Read status compute with ID", map[string]any{"rg_id": state.ID.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
computeId, err := strconv.ParseUint(state.ID.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("ComputeReadStatus: Cannot parse resource group ID from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
recordCompute, diags := ComputeResourceCheckPresence(ctx, state, c)
|
||||
if diags.HasError() {
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ComputeReadStatus: compute values before status check", map[string]any{
|
||||
"compute_id": computeId,
|
||||
"recordCompute": recordCompute})
|
||||
|
||||
// check resource status
|
||||
switch recordCompute.Status {
|
||||
case status.Modeled:
|
||||
diags.AddError(
|
||||
"Compute is in status Modeled",
|
||||
"please, contact support for more information",
|
||||
)
|
||||
return diags
|
||||
case status.Deleted:
|
||||
tflog.Info(ctx, "ComputeReadStatus: compute with status.Deleted is being checked", map[string]any{
|
||||
"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
|
||||
diags.Append(RestoreCompute(ctx, computeId, c)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "ComputeReadStatus: cannot restore compute")
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "ComputeReadStatus: compute restored successfully", map[string]any{"compute_id": computeId})
|
||||
if !state.ExtraDisks.IsNull() && ComputeResourceCheckDetachDisks(state, recordCompute) {
|
||||
diags.Append(ComputeResourceExtraDiskCreate(ctx, state, c)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "ComputeReadStatus: error when attaching extra disk(s) to a Compute ")
|
||||
return diags
|
||||
}
|
||||
}
|
||||
if state.Enabled.IsNull() || 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() {
|
||||
diags.Append(ComputeResourceStartStop(ctx, state, c)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "ComputeReadStatus: Unable to start compute")
|
||||
return diags
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case status.Destroyed:
|
||||
diags.AddError(
|
||||
"ComputeReadStatus: compute is in status Destroyed",
|
||||
fmt.Sprintf("the resource with id %d cannot be read because it has been destroyed", computeId),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func RestoreCompute(ctx context.Context, computeId uint64, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
restoreReq := compute.RestoreRequest{ComputeID: computeId}
|
||||
|
||||
tflog.Info(ctx, "RestoreCompute: before calling CloudAPI().Compute().Restore", map[string]any{"compute_id": computeId, "req": restoreReq})
|
||||
|
||||
res, err := c.CloudAPI().Compute().Restore(ctx, restoreReq)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"RestoreCompute: cannot restore compute",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "RestoreCompute: response from CloudAPI().Compute().Restore", map[string]any{"compute_id": computeId, "response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
package utilities
|
||||
|
||||
import "github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
// differenceSimpleType returns lists added and removed values
|
||||
func differenceSimpleType(oldSet, newSet types.Set) (added, removed []any) {
|
||||
oldMap := make(map[interface{}]struct{})
|
||||
newMap := make(map[interface{}]struct{})
|
||||
|
||||
for _, elem := range oldSet.Elements() {
|
||||
oldMap[elem] = struct{}{}
|
||||
}
|
||||
|
||||
for _, elem := range newSet.Elements() {
|
||||
newMap[elem] = struct{}{}
|
||||
}
|
||||
|
||||
for elem := range newMap {
|
||||
if _, found := oldMap[elem]; !found {
|
||||
added = append(added, elem)
|
||||
}
|
||||
}
|
||||
|
||||
for elem := range oldMap {
|
||||
if _, found := newMap[elem]; !found {
|
||||
removed = append(removed, elem)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func differenceNetwork(oldSet, newSet types.Set) (added, removed []any) {
|
||||
oldSlice := oldSet.Elements()
|
||||
newSlice := newSet.Elements()
|
||||
foundIdx := make([]bool, len(oldSlice))
|
||||
|
||||
for _, newElem := range newSlice {
|
||||
newObj := newElem.(types.Object)
|
||||
newElemMap := newObj.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"] {
|
||||
found = true
|
||||
foundIdx[i] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
added = append(added, newElem)
|
||||
}
|
||||
}
|
||||
|
||||
for i, found := range foundIdx {
|
||||
if !found {
|
||||
removed = append(removed, oldSlice[i])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func differenceAffinityRules(oldSet, newSet types.Set) (added, removed []any) {
|
||||
oldSlice := oldSet.Elements()
|
||||
newSlice := newSet.Elements()
|
||||
foundIdx := make([]bool, len(oldSlice))
|
||||
|
||||
for _, newElem := range newSlice {
|
||||
newObj := newElem.(types.Object)
|
||||
newElemMap := newObj.Attributes()
|
||||
found := false
|
||||
for i, oldElem := range oldSlice {
|
||||
oldObj := oldElem.(types.Object)
|
||||
oldElemMap := oldObj.Attributes()
|
||||
if oldElemMap["topology"] == newElemMap["topology"] && oldElemMap["policy"] == newElemMap["policy"] &&
|
||||
oldElemMap["mode"] == newElemMap["mode"] && oldElemMap["key"] == newElemMap["key"] {
|
||||
valueOld, okOld := oldElemMap["value"]
|
||||
valueNew, okNew := newElemMap["value"]
|
||||
if !okNew && !okOld || valueOld == valueNew {
|
||||
found = true
|
||||
foundIdx[i] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
added = append(added, newElem)
|
||||
}
|
||||
}
|
||||
|
||||
for i, found := range foundIdx {
|
||||
if !found {
|
||||
removed = append(removed, oldSlice[i])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func differenceTags(oldSet, newSet types.Set) (added, removed []any) {
|
||||
oldSlice := oldSet.Elements()
|
||||
newSlice := newSet.Elements()
|
||||
foundIdx := make([]bool, len(oldSlice))
|
||||
|
||||
for _, newElem := range newSlice {
|
||||
newObj := newElem.(types.Object)
|
||||
newElemMap := newObj.Attributes()
|
||||
found := false
|
||||
for i, oldElem := range oldSlice {
|
||||
oldObj := oldElem.(types.Object)
|
||||
oldElemMap := oldObj.Attributes()
|
||||
if oldElemMap["key"] == newElemMap["key"] && oldElemMap["value"] == newElemMap["value"] {
|
||||
found = true
|
||||
foundIdx[i] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
added = append(added, newElem)
|
||||
}
|
||||
}
|
||||
|
||||
for i, found := range foundIdx {
|
||||
if !found {
|
||||
removed = append(removed, oldSlice[i])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func differencePortForwarding(oldSet, newSet types.Set) (added, removed []any) {
|
||||
oldSlice := oldSet.Elements()
|
||||
newSlice := newSet.Elements()
|
||||
foundIdx := make([]bool, len(oldSlice))
|
||||
|
||||
for _, newElem := range newSlice {
|
||||
newObj := newElem.(types.Object)
|
||||
newElemMap := newObj.Attributes()
|
||||
found := false
|
||||
for i, oldElem := range oldSlice {
|
||||
oldObj := oldElem.(types.Object)
|
||||
oldElemMap := oldObj.Attributes()
|
||||
if oldElemMap["public_port_start"] == newElemMap["public_port_start"] && oldElemMap["public_port_end"] == newElemMap["public_port_end"] &&
|
||||
oldElemMap["local_port"] == newElemMap["local_port"] && oldElemMap["proto"] == newElemMap["proto"] {
|
||||
found = true
|
||||
foundIdx[i] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
added = append(added, newElem)
|
||||
}
|
||||
}
|
||||
|
||||
for i, found := range foundIdx {
|
||||
if !found {
|
||||
removed = append(removed, oldSlice[i])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func differenceUserAccess(oldSet, newSet types.Set) (added, removed []any) {
|
||||
oldSlice := oldSet.Elements()
|
||||
newSlice := newSet.Elements()
|
||||
foundIdx := make([]bool, len(oldSlice))
|
||||
|
||||
for _, newElem := range newSlice {
|
||||
newObj := newElem.(types.Object)
|
||||
newElemMap := newObj.Attributes()
|
||||
found := false
|
||||
for i, oldElem := range oldSlice {
|
||||
oldObj := oldElem.(types.Object)
|
||||
oldElemMap := oldObj.Attributes()
|
||||
if oldElemMap["username"] == newElemMap["username"] && oldElemMap["access_type"] == newElemMap["access_type"] {
|
||||
found = true
|
||||
foundIdx[i] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
added = append(added, newElem)
|
||||
}
|
||||
}
|
||||
|
||||
for i, found := range foundIdx {
|
||||
if !found {
|
||||
removed = append(removed, oldSlice[i])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func differenceSnapshot(oldSet, newSet types.Set) (added, removed []any) {
|
||||
oldSlice := oldSet.Elements()
|
||||
newSlice := newSet.Elements()
|
||||
foundIdx := make([]bool, len(oldSlice))
|
||||
|
||||
for _, newElem := range newSlice {
|
||||
newObj := newElem.(types.Object)
|
||||
newElemMap := newObj.Attributes()
|
||||
found := false
|
||||
for i, oldElem := range oldSlice {
|
||||
oldObj := oldElem.(types.Object)
|
||||
oldElemMap := oldObj.Attributes()
|
||||
if oldElemMap["label"] == newElemMap["label"] {
|
||||
found = true
|
||||
foundIdx[i] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
added = append(added, newElem)
|
||||
}
|
||||
}
|
||||
|
||||
for i, found := range foundIdx {
|
||||
if !found {
|
||||
removed = append(removed, oldSlice[i])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user