This commit is contained in:
asteam
2025-04-17 12:31:12 +03:00
parent b8f118097e
commit 5382579a5f
166 changed files with 16413 additions and 221 deletions

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"strconv"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
@@ -131,7 +132,7 @@ func BServiceResourceCreate(ctx context.Context, plan *models.RecordBasicService
plan.ID = types.StringValue(strconv.Itoa(int(serviceId)))
enable := plan.Enable.ValueBool()
if enable && (plan.Status.ValueString() == status.Disabled || plan.Status.ValueString() == status.Created) {
if enable {
tflog.Info(ctx, "resourceBasicServiceCreate: before calling CloudAPI().BService().Enable", map[string]any{"service_id": serviceId})
res, err := c.CloudAPI().BService().Enable(ctx, bservice.EnableRequest{ServiceID: serviceId})
if err != nil {
@@ -142,7 +143,6 @@ func BServiceResourceCreate(ctx context.Context, plan *models.RecordBasicService
return &serviceId, diags
}
tflog.Info(ctx, "resourceBasicServiceCreate: response from CloudAPI().BService().Enable", map[string]any{"service_id": serviceId, "response": res})
return &serviceId, diags
}
if plan.Start.ValueBool() {
@@ -153,6 +153,7 @@ func BServiceResourceCreate(ctx context.Context, plan *models.RecordBasicService
)
return &serviceId, diags
}
tflog.Info(ctx, "resourceBasicServiceCreate: before calling CloudAPI().BService().Start", map[string]any{"service_id": serviceId})
_, err := c.CloudAPI().BService().Start(ctx, bservice.StartRequest{
ServiceID: serviceId,
})
@@ -250,115 +251,124 @@ func StartStopBService(ctx context.Context, plan *models.RecordBasicServiceResou
return nil
}
func SnapshotsBService(ctx context.Context, oldSnapshots basetypes.ListValue, newSnapshots basetypes.ListValue, serviceID uint64, c *client.Client) diag.Diagnostics {
func SnapshotsBService(ctx context.Context, oldSnapshots basetypes.SetValue, newSnapshots basetypes.SetValue, serviceID uint64, c *client.Client) diag.Diagnostics {
diags := diag.Diagnostics{}
// Handle snapshot changes in the plan
tflog.Info(ctx, "Start SnapshotsBService", map[string]any{"service_id": serviceID})
deletedSnapshots := make([]models.ItemSnapshotResourceModel, 0)
addedSnapshots := make([]models.ItemSnapshotResourceModel, 0)
updatedSnapshots := make([]models.ItemSnapshotResourceModel, 0)
addMap, rollbackMap, deleteMap := differenceSnapshots(oldSnapshots, newSnapshots)
oldSnapshotsList := make([]models.ItemSnapshotResourceModel, 0, len(oldSnapshots.Elements()))
newSnapshotsList := make([]models.ItemSnapshotResourceModel, 0, len(newSnapshots.Elements()))
tflog.Debug(ctx, "SnapshotsBService: Snapshots to be deleted", map[string]any{"deleted_snapshots": deleteMap})
tflog.Debug(ctx, "SnapshotsBService: Snapshots to be added", map[string]any{"added_snapshots": addMap})
tflog.Debug(ctx, "SnapshotsBService: Snapshots to be updated", map[string]any{"updated_snapshots": rollbackMap})
diags.Append(oldSnapshots.ElementsAs(ctx, &oldSnapshotsList, true)...)
if diags.HasError() {
tflog.Error(ctx, "SnapshotsBService: cannot populate SnapshotsBService with plan.Snapshots object element")
return diags
}
diags.Append(newSnapshots.ElementsAs(ctx, &newSnapshotsList, true)...)
if diags.HasError() {
tflog.Error(ctx, "SnapshotsBService: cannot populate SnapshotsBService with plan.Snapshots object element")
return diags
}
for _, el := range oldSnapshotsList {
if !isContainsSnapshot(newSnapshotsList, el) {
deletedSnapshots = append(deletedSnapshots, el)
}
}
for _, el := range newSnapshotsList {
if !isContainsSnapshot(oldSnapshotsList, el) {
addedSnapshots = append(addedSnapshots, el)
} else if isRollback(oldSnapshotsList, el) {
updatedSnapshots = append(updatedSnapshots, el)
}
}
tflog.Debug(ctx, "SnapshotsBService: Snapshots to be deleted", map[string]any{"deleted_snapshots": deletedSnapshots})
tflog.Debug(ctx, "SnapshotsBService: Snapshots to be added", map[string]any{"added_snapshots": addedSnapshots})
tflog.Debug(ctx, "SnapshotsBService: Snapshots to be updated", map[string]any{"updated_snapshots": updatedSnapshots})
if len(deletedSnapshots) > 0 {
for _, snapshot := range deletedSnapshots {
if len(deleteMap) > 0 {
for _, snapshot := range deleteMap {
req := bservice.SnapshotDeleteRequest{
ServiceID: serviceID,
Label: snapshot.Label.ValueString(),
Label: snapshot["label"].(types.String).ValueString(),
}
tflog.Info(ctx, "SnapshotsBService: before calling CloudAPI().BService().SnapshotDelete", map[string]any{"service_id": serviceID, "req": req})
_, err := c.CloudAPI().BService().SnapshotDelete(ctx, req)
if err != nil {
tflog.Error(ctx, "SnapshotsBService: Failed to delete snapshot")
diags.AddError(fmt.Sprintf("SnapshotsBService: failed to delete snapshot %d from service %d",
snapshot["label"].(types.String).ValueString(), serviceID), err.Error())
return diags
}
tflog.Info(ctx, "Deleted snapshot", map[string]any{"service_id": serviceID, "label": snapshot.Label})
tflog.Info(ctx, "Deleted snapshot", map[string]any{"service_id": serviceID, "label": req.Label})
}
}
if len(addedSnapshots) > 0 {
for _, snapshot := range addedSnapshots {
if len(addMap) > 0 {
for _, snapshot := range addMap {
req := bservice.SnapshotCreateRequest{
ServiceID: serviceID,
Label: snapshot.Label.ValueString(),
Label: snapshot["label"].(types.String).ValueString(),
}
tflog.Info(ctx, "SnapshotsBService: before calling CloudAPI().BService().SnapshotCreate", map[string]any{"service_id": serviceID, "req": req})
_, err := c.CloudAPI().BService().SnapshotCreate(ctx, req)
if err != nil {
tflog.Error(ctx, "SnapshotsBService: Failed to create snapshot")
diags.AddError(fmt.Sprintf("SnapshotsBService: failed to create snapshot %d for service %d",
snapshot["label"].(types.String).ValueString(), serviceID), err.Error())
return diags
}
tflog.Info(ctx, "Created snapshot", map[string]any{"service_id": serviceID, "label": snapshot.Label})
tflog.Info(ctx, "Created snapshot", map[string]any{"service_id": serviceID, "label": req.Label})
}
}
if len(updatedSnapshots) > 0 {
for _, snapshot := range updatedSnapshots {
req := bservice.SnapshotRollbackRequest{
ServiceID: serviceID,
Label: snapshot.Label.ValueString(),
if len(rollbackMap) > 0 {
for _, snapshot := range rollbackMap {
if snapshot["rollback"].(types.Bool).ValueBool() {
req := bservice.SnapshotRollbackRequest{
ServiceID: serviceID,
Label: snapshot["label"].(types.String).ValueString(),
}
tflog.Info(ctx, "SnapshotsBService: before calling CloudAPI().BService().SnapshotRollback", map[string]any{"service_id": serviceID, "req": req})
_, err := c.CloudAPI().BService().SnapshotRollback(ctx, req)
if err != nil {
tflog.Error(ctx, "SnapshotsBService: Failed to rollback snapshot")
diags.AddError(fmt.Sprintf("SnapshotsBService: failed to rollback snapshot %d from service %d",
snapshot["label"].(types.String).ValueString(), serviceID), err.Error())
return diags
}
tflog.Info(ctx, "Rolled back snapshot", map[string]any{"service_id": serviceID, "label": req.Label})
}
_, err := c.CloudAPI().BService().SnapshotRollback(ctx, req)
if err != nil {
tflog.Error(ctx, "SnapshotsBService: Failed to rollback snapshot")
return diags
}
tflog.Info(ctx, "Rolled back snapshot", map[string]any{"service_id": serviceID, "label": snapshot.Label})
}
}
return nil
}
func isContainsSnapshot(els []models.ItemSnapshotResourceModel, el models.ItemSnapshotResourceModel) bool {
for _, elOld := range els {
if elOld.GUID == el.GUID {
return true
}
}
return false
}
func differenceSnapshots(oldSet, newSet types.Set) (added, rollback, removed []map[string]attr.Value) {
oldSlice := oldSet.Elements()
newSlice := newSet.Elements()
func isRollback(els []models.ItemSnapshotResourceModel, el models.ItemSnapshotResourceModel) bool {
for _, elOld := range els {
if elOld.GUID == el.GUID && elOld.Rollback != el.Rollback && el.Rollback.ValueBool() {
return true
added = make([]map[string]attr.Value, 0)
rollback = make([]map[string]attr.Value, 0)
removed = make([]map[string]attr.Value, 0)
for _, oldSnapshot := range oldSlice {
oldMap := oldSnapshot.(types.Object).Attributes()
found := false
for _, newSnapshot := range newSlice {
newMap := newSnapshot.(types.Object).Attributes()
if newMap["label"] == oldMap["label"] {
if newMap["rollback"] != oldMap["rollback"] {
rollback = append(rollback, newMap)
}
found = true
break
}
}
if found {
continue
}
removed = append(removed, oldMap)
}
return false
for _, newSnapshot := range newSlice {
newMap := newSnapshot.(types.Object).Attributes()
found := false
for _, oldSnapshot := range oldSlice {
oldMap := oldSnapshot.(types.Object).Attributes()
if newMap["label"] == oldMap["label"] {
if newMap["rollback"] != oldMap["rollback"] {
rollback = append(rollback, newMap)
}
found = true
break
}
}
if found {
continue
}
added = append(added, newMap)
}
return
}
// restoreBservice performs BService Restore request.