1.0.0
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
)
|
||||
|
||||
func DataSourceDiskCheckPresence(ctx context.Context, diskId uint64, c *decort.DecortClient) (*disks.RecordDisk, error) {
|
||||
tflog.Info(ctx, fmt.Sprintf("DataSourceDiskCheckPresence: Get info about disk with ID - %v", diskId))
|
||||
|
||||
recordDisk, err := c.CloudAPI().Disks().Get(ctx, disks.GetRequest{DiskID: diskId})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get info about disk with error: %w", err)
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskCheckPresence: response from CloudAPI().Disks().Get", map[string]any{
|
||||
"disk_id": diskId,
|
||||
"response": recordDisk})
|
||||
|
||||
return recordDisk, err
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks/models"
|
||||
)
|
||||
|
||||
func DataSourceDiskListCheckPresence(ctx context.Context, state *models.DataSourceDiskListModel, c *decort.DecortClient) (*disks.ListDisks, diag.Diagnostics) {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
listReq := disks.ListRequest{}
|
||||
|
||||
if !state.ByID.IsNull() {
|
||||
listReq.ByID = uint64(state.ByID.ValueInt64())
|
||||
}
|
||||
if !state.Name.IsNull() {
|
||||
listReq.Name = state.Name.ValueString()
|
||||
}
|
||||
if !state.AccountName.IsNull() {
|
||||
listReq.AccountName = state.AccountName.ValueString()
|
||||
}
|
||||
if !state.DiskMaxSize.IsNull() {
|
||||
listReq.DiskMaxSize = state.DiskMaxSize.ValueInt64()
|
||||
}
|
||||
if !state.Status.IsNull() {
|
||||
listReq.Status = state.Status.ValueString()
|
||||
}
|
||||
if !state.Shared.IsNull() {
|
||||
listReq.Shared = state.Shared.ValueBool()
|
||||
}
|
||||
if !state.AccountID.IsNull() {
|
||||
listReq.AccountID = uint64(state.AccountID.ValueInt64())
|
||||
}
|
||||
if !state.Type.IsNull() {
|
||||
listReq.Type = state.Type.ValueString()
|
||||
}
|
||||
if !state.SEPID.IsNull() {
|
||||
listReq.SEPID = uint64(state.SEPID.ValueInt64())
|
||||
}
|
||||
if !state.PoolName.IsNull() {
|
||||
listReq.Pool = state.PoolName.ValueString()
|
||||
}
|
||||
if !state.SortBy.IsNull() {
|
||||
listReq.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
listReq.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
listReq.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskListCheckPresence: before call CloudAPI().Disks().List", map[string]any{
|
||||
"req": listReq,
|
||||
})
|
||||
|
||||
diskList, err := c.CloudAPI().Disks().List(ctx, listReq)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about disk list", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskListCheckPresence: got list successfully", map[string]any{
|
||||
"entry_count": diskList.EntryCount,
|
||||
})
|
||||
return diskList, nil
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks/models"
|
||||
)
|
||||
|
||||
func DataSourceDiskListDeletedCheckPresence(ctx context.Context, state *models.DataSourceDiskListDeletedModel, c *decort.DecortClient) (*disks.ListDisks, diag.Diagnostics) {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
listReq := disks.ListDeletedRequest{}
|
||||
|
||||
if !state.ByID.IsNull() {
|
||||
listReq.ByID = uint64(state.ByID.ValueInt64())
|
||||
}
|
||||
if !state.Name.IsNull() {
|
||||
listReq.Name = state.Name.ValueString()
|
||||
}
|
||||
if !state.AccountName.IsNull() {
|
||||
listReq.AccountName = state.AccountName.ValueString()
|
||||
}
|
||||
if !state.DiskMaxSize.IsNull() {
|
||||
listReq.DiskMaxSize = state.DiskMaxSize.ValueInt64()
|
||||
}
|
||||
if !state.Shared.IsNull() {
|
||||
listReq.Shared = state.Shared.ValueBool()
|
||||
}
|
||||
if !state.AccountID.IsNull() {
|
||||
listReq.AccountID = uint64(state.AccountID.ValueInt64())
|
||||
}
|
||||
if !state.Type.IsNull() {
|
||||
listReq.Type = state.Type.ValueString()
|
||||
}
|
||||
if !state.SortBy.IsNull() {
|
||||
listReq.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
listReq.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
listReq.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskListDeletedCheckPresence: before call CloudAPI().Disks().ListDeleted", map[string]any{
|
||||
"req": listReq,
|
||||
})
|
||||
|
||||
diskList, err := c.CloudAPI().Disks().ListDeleted(ctx, listReq)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about disk list", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskListDeletedCheckPresence: got list successfully", map[string]any{
|
||||
"entry_count": diskList.EntryCount,
|
||||
})
|
||||
return diskList, nil
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks/models"
|
||||
)
|
||||
|
||||
func DataSourceDiskListTypesCheckPresence(ctx context.Context, state *models.DataSourceDiskListTypesModel, c *decort.DecortClient) (*disks.ListTypes, diag.Diagnostics) {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
listTypesReq := disks.ListTypesRequest{Detailed: false}
|
||||
|
||||
if !state.SortBy.IsNull() {
|
||||
listTypesReq.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
listTypesReq.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
listTypesReq.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskListTypesCheckPresence: before call CloudAPI().Disks().ListTypes", map[string]any{
|
||||
"req": listTypesReq,
|
||||
})
|
||||
|
||||
listTypes, err := c.CloudAPI().Disks().ListTypes(ctx, listTypesReq)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about disk list types", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskListTypesCheckPresence: got list successfully", map[string]any{
|
||||
"entry_count": listTypes.EntryCount,
|
||||
})
|
||||
return listTypes, nil
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks/models"
|
||||
)
|
||||
|
||||
func DataSourceDiskListTypesDetailedCheckPresence(ctx context.Context, state *models.DataSourceDiskListTypesDetailedModel, c *decort.DecortClient) (*disks.ListTypes, diag.Diagnostics) {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
listTypesReq := disks.ListTypesRequest{Detailed: true}
|
||||
|
||||
if !state.SortBy.IsNull() {
|
||||
listTypesReq.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
listTypesReq.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
listTypesReq.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskListTypesDetailedCheckPresence: before call CloudAPI().Disks().ListTypes", map[string]any{
|
||||
"req": listTypesReq,
|
||||
})
|
||||
|
||||
listTypes, err := c.CloudAPI().Disks().ListTypes(ctx, listTypesReq)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about disk list types", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskListTypesDetailedCheckPresence: got list successfully", map[string]any{
|
||||
"entry_count": listTypes.EntryCount,
|
||||
})
|
||||
return listTypes, nil
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks/models"
|
||||
)
|
||||
|
||||
func DataSourceDiskListUnattachedCheckPresence(ctx context.Context, state *models.DataSourceDiskListUnattachedModel, c *decort.DecortClient) (*disks.ListDisksUnattached, diag.Diagnostics) {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
listReq := disks.ListUnattachedRequest{}
|
||||
|
||||
if !state.ByID.IsNull() {
|
||||
listReq.ByID = uint64(state.ByID.ValueInt64())
|
||||
}
|
||||
if !state.AccountName.IsNull() {
|
||||
listReq.AccountName = state.AccountName.ValueString()
|
||||
}
|
||||
if !state.DiskMaxSize.IsNull() {
|
||||
listReq.DiskMaxSize = state.DiskMaxSize.ValueInt64()
|
||||
}
|
||||
if !state.Status.IsNull() {
|
||||
listReq.Status = state.Status.ValueString()
|
||||
}
|
||||
if !state.AccountID.IsNull() {
|
||||
listReq.AccountID = uint64(state.AccountID.ValueInt64())
|
||||
}
|
||||
if !state.SepID.IsNull() {
|
||||
listReq.SEPID = uint64(state.SepID.ValueInt64())
|
||||
}
|
||||
if !state.PoolName.IsNull() {
|
||||
listReq.Pool = state.PoolName.ValueString()
|
||||
}
|
||||
if !state.Type.IsNull() {
|
||||
listReq.Type = state.Type.ValueString()
|
||||
}
|
||||
if !state.SortBy.IsNull() {
|
||||
listReq.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
listReq.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
listReq.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskListUnattachedCheckPresence: before call CloudAPI().Disks().ListUnattached", map[string]any{
|
||||
"req": listReq,
|
||||
})
|
||||
|
||||
diskList, err := c.CloudAPI().Disks().ListUnattached(ctx, listReq)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about disk list", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskListUnattachedCheckPresence: got list successfully", map[string]any{
|
||||
"entry_count": diskList.EntryCount,
|
||||
})
|
||||
return diskList, nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
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/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks/models"
|
||||
)
|
||||
|
||||
func DataSourceDiskReplicationCheckPresence(ctx context.Context, state *models.RecordDiskModel, c *decort.DecortClient) (*disks.RecordDisk, *string, error) {
|
||||
|
||||
status, err := c.CloudAPI().Disks().ReplicationStatus(ctx, disks.ReplicationStatusRequest{DiskID: uint64(state.DiskId.ValueInt64())})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req := disks.GetRequest{}
|
||||
|
||||
if !state.DiskId.IsNull() && !state.DiskId.IsUnknown() {
|
||||
req.DiskID = uint64(state.DiskId.ValueInt64())
|
||||
} else {
|
||||
req.DiskID = uint64(state.ID.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskReplicationCheckPresence: load disk")
|
||||
disk, err := c.CloudAPI().Disks().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return disk, &status, nil
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks/models"
|
||||
)
|
||||
|
||||
func DataSourceDiskSnapshotCheckPresence(ctx context.Context, plan *models.DataSourceDiskSnapshotModel, c *decort.DecortClient) (*disks.ItemSnapshot, diag.Diagnostics) {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
diskId := uint64(plan.DiskID.ValueInt64())
|
||||
label := plan.Label.ValueString()
|
||||
tflog.Info(ctx, "Start DataSourceDiskSnapshotCheckPresence", map[string]any{"disk_id": diskId, "label": label})
|
||||
|
||||
tflog.Info(ctx, "DataSourceDiskSnapshotCheckPresence: before call CloudAPI().Disks().Get", map[string]any{"disk_id": diskId})
|
||||
disk, err := c.CloudAPI().Disks().Get(ctx, disks.GetRequest{DiskID: diskId})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
fmt.Sprintf("Cannot get info about disk with disk_id %d", diskId),
|
||||
err.Error(),
|
||||
)
|
||||
return nil, diags
|
||||
}
|
||||
tflog.Info(ctx, "DataSourceDiskSnapshotCheckPresence: response from CloudAPI().Disks().Get", map[string]any{"response": disk})
|
||||
|
||||
for _, sn := range disk.Snapshots {
|
||||
if label == sn.Label {
|
||||
return &sn, nil
|
||||
}
|
||||
}
|
||||
|
||||
diags.AddError(
|
||||
"Snapshot not found",
|
||||
fmt.Sprintf("Snapshot with label %s for disk with disk_id %d not found", label, diskId),
|
||||
)
|
||||
return nil, diags
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
)
|
||||
|
||||
func DiskSnapshotListCheckPresence(ctx context.Context, diskId uint64, c *decort.DecortClient) (*disks.ListSnapshots, error) {
|
||||
tflog.Info(ctx, fmt.Sprintf("DiskSnapshotListCheckPresence: Get info about disk snapshot list with disk ID - %v", diskId))
|
||||
|
||||
recordDisk, err := c.CloudAPI().Disks().Get(ctx, disks.GetRequest{DiskID: diskId})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get info about disk with error: %w", err)
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DiskSnapshotListCheckPresence: response from CloudAPI().Disks().Get", map[string]any{
|
||||
"disk_id": diskId,
|
||||
"response": recordDisk})
|
||||
|
||||
return &recordDisk.Snapshots, err
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/status"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks/models"
|
||||
)
|
||||
|
||||
// DiskCheckPresence checks if disk with diskId exists
|
||||
func DiskCheckPresence(ctx context.Context, diskId uint64, c *decort.DecortClient) (*disks.RecordDisk, error) {
|
||||
tflog.Info(ctx, fmt.Sprintf("Get info about disk with ID - %v", diskId))
|
||||
|
||||
diskRecord, err := c.CloudAPI().Disks().Get(ctx, disks.GetRequest{DiskID: diskId})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get info about disk with error: %w", err)
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "DiskCheckPresence resourceDisk: response from CloudAPI().Disks().Get", map[string]any{"disk_id": diskId, "response": diskRecord})
|
||||
|
||||
return diskRecord, err
|
||||
}
|
||||
|
||||
// CreateRequestResourceDisk generates disk create request from plan
|
||||
func CreateRequestResourceDisk(ctx context.Context, plan *models.ResourceDiskModel) disks.CreateRequest {
|
||||
tflog.Info(ctx, "Start CreateRequestResourceDisk", map[string]any{
|
||||
"account_id": plan.AccountID.ValueInt64(),
|
||||
"disk_name": plan.DiskName.ValueString(),
|
||||
"size_max": plan.SizeMax.ValueInt64(),
|
||||
"gid": plan.GID.ValueInt64(),
|
||||
})
|
||||
|
||||
// set up required parameters in disk create request
|
||||
createReq := disks.CreateRequest{
|
||||
AccountID: uint64(plan.AccountID.ValueInt64()),
|
||||
Name: plan.DiskName.ValueString(),
|
||||
Size: uint64(plan.SizeMax.ValueInt64()),
|
||||
GID: uint64(plan.GID.ValueInt64()),
|
||||
}
|
||||
|
||||
if plan.Type.IsUnknown() {
|
||||
createReq.Type = "D" // default value
|
||||
} else {
|
||||
createReq.Type = plan.Type.ValueString()
|
||||
}
|
||||
if !plan.SEPID.IsUnknown() {
|
||||
createReq.SEPID = uint64(plan.SEPID.ValueInt64())
|
||||
}
|
||||
if !plan.Pool.IsUnknown() {
|
||||
createReq.Pool = plan.Pool.ValueString()
|
||||
}
|
||||
if !plan.Description.IsUnknown() {
|
||||
createReq.Description = plan.Description.ValueString()
|
||||
}
|
||||
|
||||
return createReq
|
||||
}
|
||||
|
||||
// LimitIOCreateDisk sets IO limits that user specified in iotune field for created resource.
|
||||
// In case of failure returns warnings.
|
||||
func LimitIOCreateDisk(ctx context.Context, diskId uint64, plan *models.ResourceDiskModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
limitIOReq := disks.LimitIORequest{
|
||||
DiskID: diskId,
|
||||
}
|
||||
|
||||
var iotunePlan models.IOTuneModel
|
||||
// plan.IOTune is not null as it was checked before call
|
||||
tflog.Info(ctx, "LimitIOCreateDisk: new iotune specified", map[string]any{"disk_id": diskId})
|
||||
diags.Append(plan.IOTune.As(ctx, &iotunePlan, basetypes.ObjectAsOptions{})...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "LimitIOCreateDisk: cannot populate iotune with plan.IOTune object element")
|
||||
return diags
|
||||
}
|
||||
|
||||
limitIOReq.IOPS = uint64(iotunePlan.TotalIOPSSec.ValueInt64())
|
||||
|
||||
limitIOReq.ReadBytesSec = uint64(iotunePlan.ReadBytesSec.ValueInt64())
|
||||
limitIOReq.ReadBytesSecMax = uint64(iotunePlan.ReadBytesSecMax.ValueInt64())
|
||||
limitIOReq.ReadIOPSSec = uint64(iotunePlan.ReadIOPSSec.ValueInt64())
|
||||
limitIOReq.ReadIOPSSecMax = uint64(iotunePlan.ReadIOPSSecMax.ValueInt64())
|
||||
|
||||
limitIOReq.SizeIOPSSec = uint64(iotunePlan.SizeIOPSSec.ValueInt64())
|
||||
limitIOReq.TotalBytesSec = uint64(iotunePlan.TotalBytesSec.ValueInt64())
|
||||
limitIOReq.TotalBytesSecMax = uint64(iotunePlan.TotalBytesSecMax.ValueInt64())
|
||||
limitIOReq.TotalIOPSSecMax = uint64(iotunePlan.TotalIOPSSecMax.ValueInt64())
|
||||
limitIOReq.TotalIOPSSec = uint64(iotunePlan.TotalIOPSSec.ValueInt64())
|
||||
|
||||
limitIOReq.WriteBytesSec = uint64(iotunePlan.WriteBytesSec.ValueInt64())
|
||||
limitIOReq.WriteBytesSecMax = uint64(iotunePlan.WriteBytesSecMax.ValueInt64())
|
||||
limitIOReq.WriteIOPSSec = uint64(iotunePlan.WriteIOPSSec.ValueInt64())
|
||||
limitIOReq.WriteIOPSSecMax = uint64(iotunePlan.WriteIOPSSecMax.ValueInt64())
|
||||
|
||||
tflog.Info(ctx, "LimitIOCreateDisk: before calling CloudAPI().Disks().LimitIO", map[string]any{
|
||||
"disk_id": diskId,
|
||||
"limitIOReq": limitIOReq})
|
||||
res, err := c.CloudAPI().Disks().LimitIO(ctx, limitIOReq)
|
||||
if err != nil {
|
||||
diags.AddWarning("LimitIOCreateDisk: Unable to limit io for Disk",
|
||||
err.Error())
|
||||
}
|
||||
tflog.Info(ctx, "LimitIOCreateDisk: response from CloudAPI().Disks().LimitIO", map[string]any{
|
||||
"disk_id": diskId,
|
||||
"response": res})
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// ShareableCreateDisk shares disk.
|
||||
// In case of failure returns warnings.
|
||||
func ShareableCreateDisk(ctx context.Context, diskId uint64, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
tflog.Info(ctx, "ShareableCreateDisk: before calling CloudAPI().Disks().Share", map[string]any{"disk_id": diskId})
|
||||
res, err := c.CloudAPI().Disks().Share(ctx, disks.ShareRequest{DiskID: diskId})
|
||||
if err != nil {
|
||||
diags.AddWarning("ShareableCreateDisk: Unable to share Disk",
|
||||
err.Error())
|
||||
}
|
||||
tflog.Info(ctx, "ShareableCreateDisk: response from CloudAPI().Disks().Share", map[string]any{
|
||||
"disk_id": diskId,
|
||||
"response": res})
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// DiskReadStatus loads disk resource by ids id, gets it current status. Performs restore and enable if needed for
|
||||
// Deleted status.
|
||||
// In case of failure returns errors.
|
||||
func DiskReadStatus(ctx context.Context, state *models.ResourceDiskModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "DiskReadStatus: Read status disk with ID", map[string]any{"disk_id": state.Id.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
diskId, err := strconv.ParseUint(state.Id.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("DiskReadStatus: Cannot parse disk ID from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
recordDisk, err := DiskCheckPresence(ctx, diskId, c)
|
||||
if err != nil {
|
||||
diags.AddError("DiskReadStatus: Unable to Read Disk before status check", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
// check resource status
|
||||
switch recordDisk.Status {
|
||||
case status.Modeled:
|
||||
diags.AddError(
|
||||
"Disk is in status Modeled",
|
||||
"please, contact support for more information",
|
||||
)
|
||||
return diags
|
||||
case status.Deleted:
|
||||
// attempt to restore disk
|
||||
tflog.Info(ctx, "DiskReadStatus: disk with status.Deleted is being read, attempt to restore it", map[string]any{
|
||||
"disk_id": recordDisk.ID,
|
||||
"status": recordDisk.Status})
|
||||
diags.Append(RestoreDisk(ctx, diskId, c)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "DiskReadStatus: cannot restore disk")
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "DiskReadStatus: disk restored successfully", map[string]any{"disk_id": diskId})
|
||||
state.LastUpdated = types.StringValue(time.Now().Format(time.RFC850))
|
||||
case status.Destroyed, status.Purged:
|
||||
diags.AddError(
|
||||
"DiskReadStatus: Disk is in status Destroyed or Purged",
|
||||
fmt.Sprintf("the resource with disk_id %d cannot be read because it has been destroyed or purged", diskId),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RestoreDisk performs disk Restore request.
|
||||
// Returns error in case of failures.
|
||||
func RestoreDisk(ctx context.Context, diskId uint64, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
restoreReq := disks.RestoreRequest{
|
||||
DiskID: diskId,
|
||||
Reason: "Terraform automatic restore",
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "RestoreDisk: before calling CloudAPI().Disks().Restore", map[string]any{"diskId": diskId, "req": restoreReq})
|
||||
|
||||
res, err := c.CloudAPI().Disks().Restore(ctx, restoreReq)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"RestoreDisk: cannot restore disk",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "RestoreDisk: response from CloudAPI().Disks().Restore", map[string]any{"disk_id": diskId, "response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SizeMaxUpdateDisk resizes disk.
|
||||
// Returns error in case of failures.
|
||||
func SizeMaxUpdateDisk(ctx context.Context, diskId uint64, plan, state *models.ResourceDiskModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
var diags diag.Diagnostics
|
||||
|
||||
resizeReq := disks.ResizeRequest{
|
||||
DiskID: diskId,
|
||||
}
|
||||
|
||||
// check if resize request is valid
|
||||
if plan.SizeMax.ValueInt64() < state.SizeMax.ValueInt64() {
|
||||
diags.AddError(
|
||||
"SizeMaxUpdateDisk: reducing disk size is not allowed",
|
||||
fmt.Sprintf("disk with id %s has state size %d, plan size %d",
|
||||
plan.Id.ValueString(),
|
||||
state.SizeMax.ValueInt64(),
|
||||
plan.SizeMax.ValueInt64()))
|
||||
return diags
|
||||
}
|
||||
|
||||
resizeReq.Size = uint64(plan.SizeMax.ValueInt64())
|
||||
|
||||
tflog.Info(ctx, "SizeMaxUpdateDisk: before calling CloudAPI().Disks().Resize2", map[string]any{
|
||||
"disk_id": plan.Id.ValueString(),
|
||||
"size_max_state": state.SizeMax.ValueInt64(),
|
||||
"size_max_plan": plan.SizeMax.ValueInt64(),
|
||||
"req": resizeReq,
|
||||
})
|
||||
|
||||
res, err := c.CloudAPI().Disks().Resize2(ctx, resizeReq)
|
||||
|
||||
if err != nil {
|
||||
diags.AddError("can not resize disk", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "SizeMaxUpdateDisk: response from CloudAPI().Disks().Resize2", map[string]any{
|
||||
"disk_id": plan.Id.ValueString(),
|
||||
"response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NameUpdateDisk renames disk.
|
||||
// Returns error in case of failures.
|
||||
func NameUpdateDisk(ctx context.Context, diskId uint64, plan *models.ResourceDiskModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
var diags diag.Diagnostics
|
||||
|
||||
renameReq := disks.RenameRequest{
|
||||
DiskID: diskId,
|
||||
Name: plan.DiskName.ValueString(),
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "NameUpdateDisk: before calling CloudAPI().Disks().Rename", map[string]any{
|
||||
"disk_id": plan.Id.ValueString(),
|
||||
"disk_name_plan": plan.DiskName.ValueString(),
|
||||
"req": renameReq,
|
||||
})
|
||||
|
||||
res, err := c.CloudAPI().Disks().Rename(ctx, renameReq)
|
||||
|
||||
if err != nil {
|
||||
diags.AddError("NameUpdateDisk: can not rename disk", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "NameUpdateDisk: response from CloudAPI().Disks().Rename", map[string]any{
|
||||
"disk_id": plan.Id.ValueString(),
|
||||
"response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LimitIOUpdateDisk changes IO limits that user specified in iotune field for updated resource.
|
||||
// In case of failure returns errors.
|
||||
func LimitIOUpdateDisk(ctx context.Context, diskId uint64, plan *models.ResourceDiskModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
limitIOReq := disks.LimitIORequest{
|
||||
DiskID: diskId,
|
||||
}
|
||||
|
||||
var iotunePlan models.IOTuneModel
|
||||
// plan.IOTune is not null as it was checked before call
|
||||
tflog.Info(ctx, "LimitIOUpdateDisk: new iotune specified", map[string]any{"disk_id": diskId})
|
||||
diags.Append(plan.IOTune.As(ctx, &iotunePlan, basetypes.ObjectAsOptions{})...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "LimitIOUpdateDisk: cannot populate iotune with plan.IOTune object element")
|
||||
return diags
|
||||
}
|
||||
|
||||
limitIOReq.IOPS = uint64(iotunePlan.TotalIOPSSec.ValueInt64())
|
||||
|
||||
limitIOReq.ReadBytesSec = uint64(iotunePlan.ReadBytesSec.ValueInt64())
|
||||
limitIOReq.ReadBytesSecMax = uint64(iotunePlan.ReadBytesSecMax.ValueInt64())
|
||||
limitIOReq.ReadIOPSSec = uint64(iotunePlan.ReadIOPSSec.ValueInt64())
|
||||
limitIOReq.ReadIOPSSecMax = uint64(iotunePlan.ReadIOPSSecMax.ValueInt64())
|
||||
|
||||
limitIOReq.SizeIOPSSec = uint64(iotunePlan.SizeIOPSSec.ValueInt64())
|
||||
limitIOReq.TotalBytesSec = uint64(iotunePlan.TotalBytesSec.ValueInt64())
|
||||
limitIOReq.TotalBytesSecMax = uint64(iotunePlan.TotalBytesSecMax.ValueInt64())
|
||||
limitIOReq.TotalIOPSSecMax = uint64(iotunePlan.TotalIOPSSecMax.ValueInt64())
|
||||
limitIOReq.TotalIOPSSec = uint64(iotunePlan.TotalIOPSSec.ValueInt64())
|
||||
|
||||
limitIOReq.WriteBytesSec = uint64(iotunePlan.WriteBytesSec.ValueInt64())
|
||||
limitIOReq.WriteBytesSecMax = uint64(iotunePlan.WriteBytesSecMax.ValueInt64())
|
||||
limitIOReq.WriteIOPSSec = uint64(iotunePlan.WriteIOPSSec.ValueInt64())
|
||||
limitIOReq.WriteIOPSSecMax = uint64(iotunePlan.WriteIOPSSecMax.ValueInt64())
|
||||
|
||||
tflog.Info(ctx, "LimitIOUpdateDisk: before calling CloudAPI().Disks().LimitIO", map[string]any{
|
||||
"disk_id": diskId,
|
||||
"limitIOReq": limitIOReq})
|
||||
res, err := c.CloudAPI().Disks().LimitIO(ctx, limitIOReq)
|
||||
if err != nil {
|
||||
diags.AddError("LimitIOUpdateDisk: Unable to limit io for Disk",
|
||||
err.Error())
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "LimitIOUpdateDisk: response from CloudAPI().Disks().LimitIO", map[string]any{
|
||||
"disk_id": diskId,
|
||||
"response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShareableUpdateDisk shares or unshares disk.
|
||||
// In case of failure returns errors.
|
||||
func ShareableUpdateDisk(ctx context.Context, diskId uint64, share bool, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
// share
|
||||
if share {
|
||||
tflog.Info(ctx, "ShareableUpdateDisk: before calling CloudAPI().Disks().Share", map[string]any{"disk_id": diskId})
|
||||
res, err := c.CloudAPI().Disks().Share(ctx, disks.ShareRequest{DiskID: diskId})
|
||||
if err != nil {
|
||||
diags.AddError("ShareableUpdateDisk: Unable to share Disk",
|
||||
err.Error())
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "ShareableUpdateDisk: response from CloudAPI().Disks().Share", map[string]any{
|
||||
"disk_id": diskId,
|
||||
"response": res})
|
||||
}
|
||||
|
||||
// unshare
|
||||
if !share {
|
||||
tflog.Info(ctx, "ShareableUpdateDisk: before calling CloudAPI().Disks().Unshare", map[string]any{"disk_id": diskId})
|
||||
res, err := c.CloudAPI().Disks().Unshare(ctx, disks.UnshareRequest{DiskID: diskId})
|
||||
if err != nil {
|
||||
diags.AddError("ShareableUpdateDisk: Unable to unshare Disk",
|
||||
err.Error())
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "ShareableUpdateDisk: response from CloudAPI().Disks().Unshare", map[string]any{
|
||||
"disk_id": diskId,
|
||||
"response": res})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks/models"
|
||||
)
|
||||
|
||||
func UtilityDiskReplicationUpdateStartStop(ctx context.Context, state *models.ResourceRecordDiskReplicationModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
diskId := uint64(state.DiskId.ValueInt64())
|
||||
targetDiskId := uint64(state.ReplicationId.ValueInt64())
|
||||
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdateStartStop: start update for disk replica with ID: %d", diskId))
|
||||
|
||||
ok := !(state.Start.IsNull() || state.Start.IsUnknown())
|
||||
start := state.Start.ValueBool()
|
||||
|
||||
if ok && start {
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdateStartStop: start disk replication from Disk with ID: %d to Disk with ID: %d", diskId, targetDiskId))
|
||||
req := disks.ReplicationStartRequest{
|
||||
DiskID: diskId,
|
||||
TargetDiskID: targetDiskId,
|
||||
}
|
||||
_, err := c.CloudAPI().Disks().ReplicationStart(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError("UtilityDiskReplicationUpdateStartStop: Unable to start replicate disk", err.Error())
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdateStartStop: start disk replication from Disk with ID: %d to Disk with ID: %d, complete", diskId, targetDiskId))
|
||||
|
||||
}
|
||||
|
||||
if ok && !start {
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdateStartStop: stop disk replication from Disk with ID: %d to Disk with ID: %d", targetDiskId, diskId))
|
||||
req := disks.ReplicationStopRequest{
|
||||
DiskID: targetDiskId,
|
||||
}
|
||||
_, err := c.CloudAPI().Disks().ReplicationStop(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError("UtilityDiskReplicationUpdateStartStop: Unable to stop replicate disk", err.Error())
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdateStartStop: stop disk replication from Disk with ID: %d to Disk with ID: %d, complete", targetDiskId, diskId))
|
||||
}
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdateStartStop: complete update for disk replica with ID: %d", diskId))
|
||||
return nil
|
||||
}
|
||||
|
||||
func UtilityDiskReplicationUpdatePause(ctx context.Context, state *models.ResourceRecordDiskReplicationModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
diskId := uint64(state.DiskId.ValueInt64())
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdatePause: start update for disk replica with ID: %d", diskId))
|
||||
pause := state.Pause.ValueBool()
|
||||
ok := !(state.Pause.IsNull() || state.Pause.IsUnknown())
|
||||
|
||||
if ok && pause {
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdatePause: pause disk replication with ID: %d", diskId))
|
||||
req := disks.ReplicationSuspendRequest{
|
||||
DiskID: diskId,
|
||||
}
|
||||
_, err := c.CloudAPI().Disks().ReplicationSuspend(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError("utilityDiskReplicationUpdatePause: Unable to pause disk", err.Error())
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdatePause: pause disk replication with ID: %d, complete", diskId))
|
||||
}
|
||||
|
||||
if ok && !pause {
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdatePause: resume disk replication with ID: %d", diskId))
|
||||
req := disks.ReplicationResumeRequest{
|
||||
DiskID: diskId,
|
||||
}
|
||||
_, err := c.CloudAPI().Disks().ReplicationResume(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError("utilityDiskReplicationUpdatePause: Unable to resume disk", err.Error())
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdatePause: resume disk replication with ID: %d, complete", diskId))
|
||||
}
|
||||
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicationUpdatePause: complete update for disk replica with ID: %d", diskId))
|
||||
return nil
|
||||
}
|
||||
|
||||
func UtilityDiskReplicationUpdateReverse(ctx context.Context, state *models.ResourceRecordDiskReplicationModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
diskId := uint64(state.DiskId.ValueInt64())
|
||||
targetDiskId := uint64(state.ReplicationId.ValueInt64())
|
||||
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicaUpdateReverse: start update for disk replica with ID: %d", diskId))
|
||||
|
||||
reverse := state.Reverse.ValueBool()
|
||||
ok := !(state.Reverse.IsNull() || state.Reverse.IsUnknown())
|
||||
|
||||
if ok && reverse {
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d", diskId, targetDiskId))
|
||||
req := disks.ReplicationReverseRequest{
|
||||
DiskID: diskId,
|
||||
}
|
||||
_, err := c.CloudAPI().Disks().ReplicationReverse(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError("utilityDiskReplicationUpdateReverse: Unable to reverse disk", err.Error())
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d, complete", diskId, targetDiskId))
|
||||
}
|
||||
|
||||
if ok && !reverse {
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d", targetDiskId, diskId))
|
||||
req := disks.ReplicationReverseRequest{
|
||||
DiskID: targetDiskId,
|
||||
}
|
||||
_, err := c.CloudAPI().Disks().ReplicationReverse(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError("utilityDiskReplicationUpdateReverse: Unable to reverse disk", err.Error())
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicaUpdateReverse: reverse disk replication from Disk with ID: %d to Disk with ID: %d, complete", targetDiskId, diskId))
|
||||
}
|
||||
|
||||
tflog.Info(ctx, fmt.Sprintf("utilityDiskReplicaUpdateReverse: complete update for disk replica with ID: %d", diskId))
|
||||
return nil
|
||||
}
|
||||
|
||||
func ResourceDiskReplicationCheckPresence(ctx context.Context, state *models.ResourceRecordDiskReplicationModel, c *decort.DecortClient) (*disks.RecordDisk, *string, error) {
|
||||
|
||||
status, err := c.CloudAPI().Disks().ReplicationStatus(ctx, disks.ReplicationStatusRequest{DiskID: uint64(state.DiskId.ValueInt64())})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req := disks.GetRequest{}
|
||||
|
||||
if !state.DiskId.IsNull() && !state.DiskId.IsUnknown() {
|
||||
req.DiskID = uint64(state.DiskId.ValueInt64())
|
||||
} else {
|
||||
req.DiskID = uint64(state.ReplicationId.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "ResourceDiskReplicationCheckPresence: load disk")
|
||||
disk, err := c.CloudAPI().Disks().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return disk, &status, nil
|
||||
}
|
||||
|
||||
// DiskReadStatus loads disk resource by ids id, gets it current status.
|
||||
// In case of failure returns errors.
|
||||
func ReplicationDiskReadStatus(ctx context.Context, state *models.ResourceRecordDiskReplicationModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "ReplicationDiskReadStatus: Read status disk with ID", map[string]any{"disk_id": state.DiskId.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
_, _, err := ResourceDiskReplicationCheckPresence(ctx, state, c)
|
||||
if err != nil {
|
||||
diags.AddError("ReplicationDiskReadStatus: Unable to Read Disk before status check", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks/models"
|
||||
)
|
||||
|
||||
// DiskSnapshotCheckPresence checks if disk snapshot exists
|
||||
func DiskSnapshotCheckPresence(ctx context.Context, plan *models.ResourceDiskSnapshotModel, c *decort.DecortClient) (*disks.ItemSnapshot, diag.Diagnostics) {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
// take diskId and label from plan
|
||||
diskId := uint64(plan.DiskID.ValueInt64())
|
||||
label := plan.Label.ValueString()
|
||||
|
||||
// take diskId and label from Id for imported resource
|
||||
if strings.Contains(plan.Id.ValueString(), "#") {
|
||||
diskIdInt, err := strconv.Atoi(strings.Split(plan.Id.ValueString(), "#")[0])
|
||||
if err != nil {
|
||||
diags.AddError("Cannot parse disk ID from state", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
diskId = uint64(diskIdInt)
|
||||
label = strings.Split(plan.Id.ValueString(), "#")[1]
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Start DiskSnapshotCheckPresence", map[string]any{
|
||||
"disk_id": diskId,
|
||||
"label": label,
|
||||
"id": plan.Id.ValueString(),
|
||||
})
|
||||
|
||||
tflog.Info(ctx, "DiskSnapshotCheckPresence: before call CloudAPI().Disks().Get", map[string]any{"disk_id": diskId})
|
||||
disk, err := c.CloudAPI().Disks().Get(ctx, disks.GetRequest{DiskID: diskId})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
fmt.Sprintf("Cannot get info about disk with disk_id %d", diskId),
|
||||
err.Error(),
|
||||
)
|
||||
return nil, diags
|
||||
}
|
||||
tflog.Info(ctx, "DiskSnapshotCheckPresence: response from CloudAPI().Disks().Get", map[string]any{"response": disk})
|
||||
|
||||
for _, sn := range disk.Snapshots {
|
||||
if label == sn.Label {
|
||||
return &sn, nil
|
||||
}
|
||||
}
|
||||
|
||||
diags.AddError(
|
||||
"Snapshot not found",
|
||||
fmt.Sprintf("Snapshot with label %s for disk with disk_id %d not found", label, diskId),
|
||||
)
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
// RollbackDiskSnapshot rollbacks disk snapshot.
|
||||
// Returns error in case of failures.
|
||||
func RollbackDiskSnapshot(ctx context.Context, plan *models.ResourceDiskSnapshotModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
rollbackReq := disks.SnapshotRollbackRequest{
|
||||
DiskID: uint64(plan.DiskID.ValueInt64()),
|
||||
Label: plan.Label.ValueString(),
|
||||
}
|
||||
|
||||
if !plan.TimeStamp.IsUnknown() {
|
||||
rollbackReq.TimeStamp = uint64(plan.TimeStamp.ValueInt64())
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "RollbackDiskSnapshot: before calling CloudAPI().Disks().SnapshotRollback", map[string]any{"req": rollbackReq})
|
||||
res, err := c.CloudAPI().Disks().SnapshotRollback(ctx, rollbackReq)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"RollbackDiskSnapshot: Cannot rollback snapshot",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "RollbackDiskSnapshot: response from CloudAPI().Disks().SnapshotRollback", map[string]any{
|
||||
"disk_id": plan.DiskID.ValueInt64(),
|
||||
"label": plan.Label.ValueString(),
|
||||
"response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user