1.0.0
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
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/bservice"
|
||||
)
|
||||
|
||||
func BServiceDataSourceCheckPresence(ctx context.Context, serviceId uint64, c *decort.DecortClient) (*bservice.RecordBasicService, error) {
|
||||
tflog.Info(ctx, fmt.Sprintf("BServiceDataSourceCheckPresence: Get info about bserivce with ID - %v", serviceId))
|
||||
|
||||
record, err := c.CloudAPI().BService().Get(ctx, bservice.GetRequest{ServiceID: serviceId})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get info about bservice with error: %w", err)
|
||||
}
|
||||
|
||||
return record, err
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
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/bservice"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
|
||||
)
|
||||
|
||||
func BServiceDeletedListDataSourceCheckPresence(ctx context.Context, plan models.ListBasicServicesDelModel, c *decort.DecortClient) (*bservice.ListBasicServices, error) {
|
||||
tflog.Info(ctx, "BServiceListDataSourceCheckPresence: Get deleted list bserivce")
|
||||
|
||||
accListDelReq := bservice.ListDeletedRequest{}
|
||||
|
||||
if !plan.AccountID.IsNull() {
|
||||
accListDelReq.AccountID = uint64(plan.AccountID.ValueInt64())
|
||||
}
|
||||
if !plan.RGID.IsNull() {
|
||||
accListDelReq.RGID = uint64(plan.RGID.ValueInt64())
|
||||
}
|
||||
if !plan.SortBy.IsNull() {
|
||||
accListDelReq.SortBy = plan.SortBy.ValueString()
|
||||
}
|
||||
if !plan.Page.IsNull() {
|
||||
accListDelReq.Page = uint64(plan.Page.ValueInt64())
|
||||
}
|
||||
if !plan.Size.IsNull() {
|
||||
accListDelReq.Size = uint64(plan.Size.ValueInt64())
|
||||
}
|
||||
|
||||
record, err := c.CloudAPI().BService().ListDeleted(ctx, accListDelReq)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get bservice deleted list with error: %w", err)
|
||||
}
|
||||
|
||||
return record, err
|
||||
}
|
||||
@@ -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/bservice"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
|
||||
)
|
||||
|
||||
func BServiceGroupDataSourceCheckPresence(ctx context.Context, state models.RecordGroupModel, c *decort.DecortClient) (*bservice.RecordGroup, error) {
|
||||
tflog.Info(ctx, fmt.Sprintf("BServiceGroupDataSourceCheckPresence: Get info about bserivce with ID - %v", state.ServiceID))
|
||||
|
||||
req := bservice.GroupGetRequest{ServiceID: uint64(state.ServiceID.ValueInt64()), CompGroupID: uint64(state.ID.ValueInt64())}
|
||||
|
||||
record, err := c.CloudAPI().BService().GroupGet(ctx, req)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get info about bservice with error: %w", err)
|
||||
}
|
||||
|
||||
return record, err
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
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/bservice"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
|
||||
)
|
||||
|
||||
func BServiceListDataSourceCheckPresence(ctx context.Context, plan models.ListBasicServicesModel, c *decort.DecortClient) (*bservice.ListBasicServices, error) {
|
||||
tflog.Info(ctx, "BServiceListDataSourceCheckPresence: Get list bserivce")
|
||||
|
||||
accListReq := bservice.ListRequest{}
|
||||
|
||||
if !plan.ByID.IsNull() {
|
||||
accListReq.ByID = uint64(plan.ByID.ValueInt64())
|
||||
}
|
||||
if !plan.Name.IsNull() {
|
||||
accListReq.Name = plan.Name.ValueString()
|
||||
}
|
||||
if !plan.RGName.IsNull() {
|
||||
accListReq.RGName = plan.RGName.ValueString()
|
||||
}
|
||||
if !plan.Status.IsNull() {
|
||||
accListReq.Status = plan.Status.ValueString()
|
||||
}
|
||||
if !plan.TechStatus.IsNull() {
|
||||
accListReq.TechStatus = plan.TechStatus.ValueString()
|
||||
}
|
||||
if !plan.AccountName.IsNull() {
|
||||
accListReq.AccountName = plan.AccountName.ValueString()
|
||||
}
|
||||
if !plan.AccountID.IsNull() {
|
||||
accListReq.AccountID = uint64(plan.AccountID.ValueInt64())
|
||||
}
|
||||
if !plan.RGID.IsNull() {
|
||||
accListReq.RGID = uint64(plan.RGID.ValueInt64())
|
||||
}
|
||||
if !plan.SortBy.IsNull() {
|
||||
accListReq.SortBy = plan.SortBy.ValueString()
|
||||
}
|
||||
if !plan.Page.IsNull() {
|
||||
accListReq.Page = uint64(plan.Page.ValueInt64())
|
||||
}
|
||||
if !plan.Size.IsNull() {
|
||||
accListReq.Size = uint64(plan.Size.ValueInt64())
|
||||
}
|
||||
|
||||
record, err := c.CloudAPI().BService().List(ctx, accListReq)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get bservice list with error: %w", err)
|
||||
}
|
||||
|
||||
return record, err
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
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/bservice"
|
||||
)
|
||||
|
||||
func BServiceSnapshotListDataSourceCheckPresence(ctx context.Context, serviceID uint64, c *decort.DecortClient) (*bservice.ListInfoSnapshots, error) {
|
||||
tflog.Info(ctx, "BServiceSnapshotListDataSourceCheckPresence: Get deleted list bserivce")
|
||||
|
||||
req := bservice.SnapshotListRequest{ServiceID: serviceID}
|
||||
|
||||
record, err := c.CloudAPI().BService().SnapshotList(ctx, req)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get bservice snapshots list with error: %w", err)
|
||||
}
|
||||
|
||||
return record, err
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"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/bservice"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/ic"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/status"
|
||||
)
|
||||
|
||||
// BServiceResourceCheckPresence checks if BService with serviceID exists
|
||||
func BServiceResourceCheckPresence(ctx context.Context, serviceID uint64, c *decort.DecortClient) (*bservice.RecordBasicService, error) {
|
||||
tflog.Info(ctx, fmt.Sprintf("BServiceResourceCheckPresence: Get info about service with ID - %v", serviceID))
|
||||
|
||||
record, err := c.CloudAPI().BService().Get(ctx, bservice.GetRequest{ServiceID: serviceID})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("BServiceResourceCheckPresence: cannot get info about resource with error: %w", err)
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "BServiceResourceCheckPresence: response from CloudAPI().BService().Get", map[string]any{"service_id": serviceID, "response": record})
|
||||
|
||||
return record, err
|
||||
}
|
||||
|
||||
// BServiceReadStatus loads BService resource by its id, gets it current status. Performs restore and enable if needed for
|
||||
// Deleted status.
|
||||
// In case of failure returns errors.
|
||||
func BSerivceReadStatus(ctx context.Context, state *models.RecordBasicServiceResourceModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "BSerivceReadStatus: Read status resource with ID", map[string]any{"resource_id": state.ID.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
resourceId, err := strconv.ParseUint(state.ID.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("BSerivceReadStatus: Cannot parse resource ID from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
record, err := BServiceResourceCheckPresence(ctx, resourceId, c)
|
||||
if err != nil {
|
||||
diags.AddError("BSerivceReadStatus: Unable to Read bservice before status check", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
// check resource status
|
||||
switch record.Status {
|
||||
case status.Disabled:
|
||||
tflog.Info(ctx, "The BService is in status Disabled, troubles may occur with update. Please, enable BService first.")
|
||||
case status.Modeled:
|
||||
diags.AddError("The basic service is in status: %s, please, contact support for more information", record.Status)
|
||||
case status.Disabling:
|
||||
tflog.Info(ctx, fmt.Sprintf("The basic service is in status: %s, troubles can occur with the update.", record.Status))
|
||||
case status.Deleted:
|
||||
restore := state.Restore.ValueBool()
|
||||
if state.Restore.IsNull() {
|
||||
restore = true
|
||||
} // default true
|
||||
if restore {
|
||||
// attempt to restore bservice
|
||||
tflog.Info(ctx, "BServiceReadStatus: BService with status.Deleted is being read, attempt to restore it", map[string]any{
|
||||
"BService": state.ID.ValueString(),
|
||||
"status": record.Status})
|
||||
diags.Append(restoreBservice(ctx, resourceId, c)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "BServiceReadStatus: cannot restore BService")
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "BServiceReadStatus: BService restored successfully", map[string]any{"service_id": resourceId})
|
||||
} else {
|
||||
tflog.Info(ctx, "BServiceReadStatus: BService is i status Deleted but restore is not specified")
|
||||
}
|
||||
|
||||
case status.Destroyed:
|
||||
diags.AddError(
|
||||
"BSerivceReadStatus: BService is in status Destroyed",
|
||||
fmt.Sprintf("the resource with bservice_id %d cannot be read or updated because it has been destroyed", resourceId),
|
||||
)
|
||||
return diags
|
||||
|
||||
case status.Destroying:
|
||||
diags.AddError(
|
||||
"BSerivceReadStatus: BService is in progress with status Destroying",
|
||||
fmt.Sprintf("the resource with bservice_id %d cannot be read or updated because it is currently being destroyed", resourceId),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func BServiceResourceCreate(ctx context.Context, plan *models.RecordBasicServiceResourceModel, c *decort.DecortClient) (*uint64, diag.Diagnostics) {
|
||||
tflog.Info(ctx, "Start BServiceResourceCreate", map[string]any{"service_id": plan.ServiceId.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
err := ic.ExistRG(ctx, uint64(plan.RGID.ValueInt64()), c)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("resourceBasicServiceCreate: can't create basic service because RGID %d is not allowed or does not exist", plan.RGID.ValueInt64()), err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
req := bservice.CreateRequest{}
|
||||
|
||||
req.Name = plan.Name.ValueString()
|
||||
req.RGID = uint64(plan.RGID.ValueInt64())
|
||||
|
||||
if !plan.SSHKey.IsNull() {
|
||||
req.SSHKey = plan.SSHKey.ValueString()
|
||||
}
|
||||
|
||||
if !plan.SSHUser.IsNull() {
|
||||
req.SSHUser = plan.SSHUser.ValueString()
|
||||
}
|
||||
|
||||
// Make request and get response
|
||||
serviceId, err := c.CloudAPI().BService().Create(ctx, req)
|
||||
if err != nil {
|
||||
tflog.Error(ctx, "Error response for create bservice", map[string]any{"error": err.Error()})
|
||||
diags.AddError("Unable to Create bservice", err.Error())
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
plan.ID = types.StringValue(strconv.Itoa(int(serviceId)))
|
||||
|
||||
enable := plan.Enable.ValueBool()
|
||||
if enable && (plan.Status.ValueString() == status.Disabled || plan.Status.ValueString() == status.Created) {
|
||||
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 {
|
||||
diags.AddWarning(
|
||||
"resourceBasicServiceCreate: cannot enable BService",
|
||||
err.Error(),
|
||||
)
|
||||
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() {
|
||||
if !enable {
|
||||
diags.AddWarning(
|
||||
"can not start bservice that is not enabled. Set enable = true and start = true to enable and start bservice",
|
||||
fmt.Sprintf("service_id: %v", serviceId),
|
||||
)
|
||||
return &serviceId, diags
|
||||
}
|
||||
_, err := c.CloudAPI().BService().Start(ctx, bservice.StartRequest{
|
||||
ServiceID: serviceId,
|
||||
})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"resourceBasicServiceCreate: cannot start BService",
|
||||
err.Error(),
|
||||
)
|
||||
return &serviceId, diags
|
||||
}
|
||||
}
|
||||
tflog.Info(ctx, "End resourceBasicServiceCreate", map[string]any{"service_id": serviceId})
|
||||
return &serviceId, diags
|
||||
}
|
||||
|
||||
// EnableDisableBService performs BService Enable/Disable request.
|
||||
// Returns error in case of failures.
|
||||
func EnableDisableBService(ctx context.Context, plan *models.RecordBasicServiceResourceModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start EnableDisableBService", map[string]any{"service_id": plan.ID.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
serviceID, err := strconv.Atoi(plan.ID.ValueString())
|
||||
if err != nil {
|
||||
diags.AddError("EnableDisableBService: Cannot parse ID from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
if plan.Enable.ValueBool() {
|
||||
tflog.Info(ctx, "EnableDisableBService: before calling CloudAPI().BService().Enable", map[string]any{"service_id": serviceID})
|
||||
res, err := c.CloudAPI().BService().Enable(ctx, bservice.EnableRequest{ServiceID: uint64(serviceID)})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"EnableDisableBService: cannot enable BService",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "EnableDisableBService: response from CloudAPI().BService().Enable", map[string]any{"service_id": serviceID, "response": res})
|
||||
return nil
|
||||
} else {
|
||||
tflog.Info(ctx, "EnableDisableBService: before calling CloudAPI().BService().Disable", map[string]any{"service_id": serviceID})
|
||||
res, err := c.CloudAPI().BService().Disable(ctx, bservice.DisableRequest{ServiceID: uint64(serviceID)})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"EnableDisableBService: cannot disable BService",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "EnableDisableBService: response from CloudAPI().BService().Disable", map[string]any{"service_id": serviceID, "response": res})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartStopBService performs BService Start/Stop request.
|
||||
// Returns error in case of failures.
|
||||
func StartStopBService(ctx context.Context, plan *models.RecordBasicServiceResourceModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start StartStopBService", map[string]any{"service_id": plan.ID.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
serviceID, err := strconv.Atoi(plan.ID.ValueString())
|
||||
if err != nil {
|
||||
diags.AddError("StartStopBService: Cannot parse ID from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
if plan.Start.ValueBool() {
|
||||
tflog.Info(ctx, "StartStopBService: before calling CloudAPI().BService().Start", map[string]any{"service_id": serviceID})
|
||||
res, err := c.CloudAPI().BService().Start(ctx, bservice.StartRequest{ServiceID: uint64(serviceID)})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"StartStopBService: cannot start BService",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "StartStopBService: response from CloudAPI().BService().Start", map[string]any{"service_id": serviceID, "response": res})
|
||||
return nil
|
||||
} else {
|
||||
tflog.Info(ctx, "StartStopBService: before calling CloudAPI().BService().Stop", map[string]any{"service_id": serviceID})
|
||||
res, err := c.CloudAPI().BService().Stop(ctx, bservice.StopRequest{ServiceID: uint64(serviceID)})
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"StartStopBService: cannot stop BService",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "StartStopBService: response from CloudAPI().BService().Stop", map[string]any{"service_id": serviceID, "response": res})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SnapshotsBService(ctx context.Context, oldSnapshots basetypes.ListValue, newSnapshots basetypes.ListValue, serviceID uint64, c *decort.DecortClient) 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)
|
||||
|
||||
oldSnapshotsList := make([]models.ItemSnapshotResourceModel, 0, len(oldSnapshots.Elements()))
|
||||
newSnapshotsList := make([]models.ItemSnapshotResourceModel, 0, len(newSnapshots.Elements()))
|
||||
|
||||
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 {
|
||||
req := bservice.SnapshotDeleteRequest{
|
||||
ServiceID: serviceID,
|
||||
Label: snapshot.Label.ValueString(),
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().BService().SnapshotDelete(ctx, req)
|
||||
if err != nil {
|
||||
tflog.Error(ctx, "SnapshotsBService: Failed to delete snapshot")
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "Deleted snapshot", map[string]any{"service_id": serviceID, "label": snapshot.Label})
|
||||
}
|
||||
}
|
||||
|
||||
if len(addedSnapshots) > 0 {
|
||||
for _, snapshot := range addedSnapshots {
|
||||
req := bservice.SnapshotCreateRequest{
|
||||
ServiceID: serviceID,
|
||||
Label: snapshot.Label.ValueString(),
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().BService().SnapshotCreate(ctx, req)
|
||||
if err != nil {
|
||||
tflog.Error(ctx, "SnapshotsBService: Failed to create snapshot")
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "Created snapshot", map[string]any{"service_id": serviceID, "label": snapshot.Label})
|
||||
}
|
||||
}
|
||||
|
||||
if len(updatedSnapshots) > 0 {
|
||||
for _, snapshot := range updatedSnapshots {
|
||||
req := bservice.SnapshotRollbackRequest{
|
||||
ServiceID: serviceID,
|
||||
Label: snapshot.Label.ValueString(),
|
||||
}
|
||||
|
||||
_, 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 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
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// restoreBservice performs BService Restore request.
|
||||
// Returns error in case of failures.
|
||||
func restoreBservice(ctx context.Context, serviceID uint64, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
restoreReq := bservice.RestoreRequest{
|
||||
ServiceID: serviceID,
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "restoreBservice: before calling CloudAPI().BService().Restore", map[string]any{"service_id": serviceID, "req": restoreReq})
|
||||
|
||||
res, err := c.CloudAPI().BService().Restore(ctx, restoreReq)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"restoreBservice: cannot restore BService",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
tflog.Info(ctx, "restoreBservice: response from CloudAPI().BService().Restore", map[string]any{"service_id": serviceID, "response": res})
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,403 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"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/bservice"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/status"
|
||||
)
|
||||
|
||||
func BServiceGroupResourceCheckPresence(ctx context.Context, serviceID uint64, compGroupID uint64, c *decort.DecortClient) (*bservice.RecordGroup, error) {
|
||||
tflog.Info(ctx, fmt.Sprintf("BServiceGroupResourceCheckPresence: Get info about bserivce group with ID - %v", compGroupID))
|
||||
|
||||
req := bservice.GroupGetRequest{ServiceID: serviceID, CompGroupID: compGroupID}
|
||||
record, err := c.CloudAPI().BService().GroupGet(ctx, req)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get info about bservice with error: %w", err)
|
||||
}
|
||||
|
||||
return record, err
|
||||
}
|
||||
|
||||
func BServiceGroupResourceCreate(ctx context.Context, plan *models.ResourceRecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start BServiceGroupResourceCreate", map[string]any{"service": plan.ServiceID.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
req := bservice.GroupAddRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
Name: plan.Name.ValueString(),
|
||||
Count: uint64(plan.CompCount.ValueInt64()),
|
||||
CPU: uint64(plan.CPU.ValueInt64()),
|
||||
RAM: uint64(plan.RAM.ValueInt64()),
|
||||
Disk: uint64(plan.Disk.ValueInt64()),
|
||||
ImageID: uint64(plan.ImageID.ValueInt64()),
|
||||
Driver: plan.Driver.ValueString(),
|
||||
}
|
||||
|
||||
if !plan.SEPID.IsNull() {
|
||||
req.SEPID = uint64(plan.SEPID.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.SepPool.IsNull() {
|
||||
req.SEPPool = plan.SepPool.ValueString()
|
||||
}
|
||||
|
||||
if !plan.Role.IsNull() {
|
||||
req.Role = plan.Role.ValueString()
|
||||
}
|
||||
|
||||
if !plan.TimeoutStart.IsNull() {
|
||||
req.TimeoutStart = uint64(plan.TimeoutStart.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.VINSes.IsNull() {
|
||||
result := make([]uint64, 0, len(plan.VINSes.Elements()))
|
||||
|
||||
diags.Append(plan.VINSes.ElementsAs(ctx, &result, true)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "BServiceGroupResourceCreate: cannot populate result with plan.VINSes object element")
|
||||
return diags
|
||||
}
|
||||
|
||||
req.VINSes = result
|
||||
}
|
||||
|
||||
if !plan.ExtNets.IsNull() {
|
||||
result := make([]uint64, 0, len(plan.ExtNets.Elements()))
|
||||
|
||||
diags.Append(plan.ExtNets.ElementsAs(ctx, &result, true)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "BServiceGroupResourceCreate: cannot populate result with plan.ExtNets object element")
|
||||
return diags
|
||||
}
|
||||
|
||||
req.ExtNets = result
|
||||
}
|
||||
|
||||
// Make request and get response
|
||||
compgroupId, err := c.CloudAPI().BService().GroupAdd(ctx, req)
|
||||
if err != nil {
|
||||
tflog.Error(ctx, "Error response for group add", map[string]any{"error": err.Error()})
|
||||
diags.AddError("Unable to add group", err.Error())
|
||||
return diags
|
||||
}
|
||||
plan.ID = types.StringValue(strconv.Itoa(int(plan.CompgroupID.ValueInt64())))
|
||||
plan.SID = types.StringValue(strconv.Itoa(int(plan.ServiceID.ValueInt64())))
|
||||
|
||||
if plan.Start.ValueBool() {
|
||||
tflog.Info(ctx, "BServiceGroupResourceCreate: start group", map[string]any{"service_id": plan.ServiceID.ValueInt64()})
|
||||
_, err := c.CloudAPI().BService().GroupStart(ctx, bservice.GroupStartRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
CompGroupID: compgroupId,
|
||||
})
|
||||
if err != nil {
|
||||
diags.AddWarning(
|
||||
"resourceBasicServiceCreate: cannot start BService",
|
||||
err.Error(),
|
||||
)
|
||||
return diags
|
||||
}
|
||||
|
||||
}
|
||||
tflog.Info(ctx, "End BServiceGroupResourceCreate", map[string]any{"service_id": compgroupId})
|
||||
return diags
|
||||
}
|
||||
|
||||
func BServiceGroupResize(ctx context.Context, plan *models.ResourceRecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "BServiceGroupResize: start.", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
req := bservice.GroupResizeRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
CompGroupID: uint64(plan.CompgroupID.ValueInt64()),
|
||||
Count: plan.CompCount.ValueInt64(),
|
||||
Mode: plan.Mode.ValueString(),
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().BService().GroupResize(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot resize group with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), plan.CompCount.ValueInt64()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "BServiceGroupResize: resize group successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func BServiceGroupUpdate(ctx context.Context, plan *models.ResourceRecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "BServiceGroupUpdate: start.", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
req := bservice.GroupUpdateRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
CompGroupID: uint64(plan.CompgroupID.ValueInt64()),
|
||||
Name: plan.Name.ValueString(),
|
||||
Role: plan.Role.ValueString(),
|
||||
CPU: uint64(plan.CPU.ValueInt64()),
|
||||
RAM: uint64(plan.RAM.ValueInt64()),
|
||||
Disk: uint64(plan.Disk.ValueInt64()),
|
||||
Force: plan.ForceUpdate.ValueBool(),
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().BService().GroupUpdate(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot update group with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), plan.CompgroupID.ValueInt64()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "BServiceGroupUpdate: update group successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func BServiceGroupReadStatus(ctx context.Context, plan *models.ResourceRecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Read status BServiceGroupReadStatus with ID", map[string]any{"service_id": plan.ServiceID.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
serviceID, err := strconv.ParseUint(plan.SID.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("BServiceGroupReadStatus: Cannot parse resource ID from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
compGroupID, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("BServiceGroupReadStatus: Cannot parse resource ID from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
resource, err := BServiceGroupResourceCheckPresence(ctx, serviceID, compGroupID, c)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about bservice group ", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
switch resource.Status {
|
||||
case status.Modeled:
|
||||
diags.AddError("Error:", fmt.Sprintf("The bservice group is in status: %s, please, contact support for more information", resource.Status))
|
||||
return diags
|
||||
case status.Destroying:
|
||||
diags.AddError("Error:", fmt.Sprintf("The bservice group is in progress with status: %s", resource.Status))
|
||||
return diags
|
||||
case status.Destroyed:
|
||||
diags.AddError("Error:", "The resource cannot be updated because it has been destroyed")
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Read status bservice group successfully", map[string]any{"compgroup_id": plan.ID.ValueString()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func BServiceGroupStartStop(ctx context.Context, plan *models.ResourceRecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start/Stop bservice group", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
if plan.Start.ValueBool() {
|
||||
req := bservice.GroupStartRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
CompGroupID: uint64(plan.CompgroupID.ValueInt64()),
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().BService().GroupStart(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot start bservice group with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), plan.CompCount.ValueInt64()), err.Error())
|
||||
return diags
|
||||
}
|
||||
} else {
|
||||
req := bservice.GroupStopRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
CompGroupID: uint64(plan.CompgroupID.ValueInt64()),
|
||||
Force: plan.ForceStop.ValueBool(),
|
||||
}
|
||||
_, err := c.CloudAPI().BService().GroupStop(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot stop bservice group with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), plan.CompCount.ValueInt64()), err.Error())
|
||||
return diags
|
||||
}
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Start/Stop bservice group successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func BServiceGroupExtNet(ctx context.Context, plan *models.ResourceRecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "update ExtNets", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
extnetList := make([]uint64, 0, len(plan.ExtNets.Elements()))
|
||||
|
||||
diags.Append(plan.ExtNets.ElementsAs(ctx, &extnetList, true)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "BServiceGroupExtNet: cannot populate result with plan.ExtNets object element")
|
||||
return diags
|
||||
}
|
||||
|
||||
req := bservice.GroupUpdateExtNetRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
CompGroupID: uint64(plan.CompgroupID.ValueInt64()),
|
||||
ExtNets: extnetList,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().BService().GroupUpdateExtNet(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot update bservice group extnets with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), plan.CompCount.ValueInt64()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "BServiceGroupExtNet: update successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func BServiceGroupVinses(ctx context.Context, plan *models.ResourceRecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "update Vinses", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
vinsesList := make([]uint64, 0, len(plan.VINSes.Elements()))
|
||||
|
||||
diags.Append(plan.VINSes.ElementsAs(ctx, &vinsesList, true)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "BServiceGroupVinses: cannot populate result with plan.VINSes object element")
|
||||
return diags
|
||||
}
|
||||
|
||||
req := bservice.GroupUpdateVINSRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
CompGroupID: uint64(plan.ServiceID.ValueInt64()),
|
||||
VINSes: vinsesList,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().BService().GroupUpdateVINS(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot update bservice group vinses with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), plan.CompCount.ValueInt64()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "BServiceGroupVinses: update successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func BServiceGroupParents(ctx context.Context, newParents basetypes.ListValue, oldParents basetypes.ListValue, plan *models.ResourceRecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
tflog.Info(ctx, "Start BServiceGroupParents", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
|
||||
deletedParents := make([]uint64, 0)
|
||||
addedParents := make([]uint64, 0)
|
||||
|
||||
oldParentsList := make([]uint64, 0, len(oldParents.Elements()))
|
||||
newParentsList := make([]uint64, 0, len(newParents.Elements()))
|
||||
|
||||
diags.Append(oldParents.ElementsAs(ctx, &oldParentsList, true)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "BServiceGroupParents: cannot populate uint64 with plan.Parents object element")
|
||||
return diags
|
||||
}
|
||||
|
||||
diags.Append(newParents.ElementsAs(ctx, &newParentsList, true)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "BServiceGroupParents: cannot populate uint64 with plan.Parents object element")
|
||||
return diags
|
||||
}
|
||||
|
||||
for _, el := range oldParentsList {
|
||||
if !isContainsParent(newParentsList, el) {
|
||||
deletedParents = append(deletedParents, el)
|
||||
}
|
||||
}
|
||||
|
||||
for _, el := range newParentsList {
|
||||
if !isContainsParent(oldParentsList, el) {
|
||||
addedParents = append(addedParents, el)
|
||||
}
|
||||
}
|
||||
|
||||
if len(deletedParents) > 0 {
|
||||
for _, parent := range deletedParents {
|
||||
|
||||
req := bservice.GroupParentRemoveRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
CompGroupID: uint64(plan.CompCount.ValueInt64()),
|
||||
ParentID: parent,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().BService().GroupParentRemove(ctx, req)
|
||||
if err != nil {
|
||||
tflog.Error(ctx, "BServiceGroupParents: Failed to remove parent")
|
||||
return diags
|
||||
}
|
||||
}
|
||||
tflog.Info(ctx, "Deleted parents", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
}
|
||||
|
||||
if len(addedParents) > 0 {
|
||||
for _, parent := range addedParents {
|
||||
|
||||
req := bservice.GroupParentAddRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
CompGroupID: uint64(plan.CompCount.ValueInt64()),
|
||||
ParentID: parent,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().BService().GroupParentAdd(ctx, req)
|
||||
if err != nil {
|
||||
tflog.Error(ctx, "BServiceGroupParents: Failed to add parent")
|
||||
return diags
|
||||
}
|
||||
}
|
||||
tflog.Info(ctx, "Added parents", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
func BServiceGroupRemoveComputes(ctx context.Context, plan *models.ResourceRecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
rcs := plan.RemoveComputes
|
||||
|
||||
rcsList := make([]uint64, 0, len(rcs.Elements()))
|
||||
|
||||
diags.Append(rcs.ElementsAs(ctx, &rcsList, true)...)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "BServiceGroupRemoveComputes: cannot populate uint64 with plan.RemoveComputes object element")
|
||||
return diags
|
||||
}
|
||||
if len(rcsList) > 0 {
|
||||
for _, rc := range rcsList {
|
||||
req := bservice.GroupComputeRemoveRequest{
|
||||
ServiceID: uint64(plan.ServiceID.ValueInt64()),
|
||||
CompGroupID: uint64(plan.CompCount.ValueInt64()),
|
||||
ComputeID: rc,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().BService().GroupComputeRemove(ctx, req)
|
||||
if err != nil {
|
||||
tflog.Error(ctx, "BServiceGroupRemoveComputes: Failed to remove compute")
|
||||
return diags
|
||||
}
|
||||
}
|
||||
}
|
||||
return diags
|
||||
}
|
||||
|
||||
func isContainsParent(els []uint64, el uint64) bool {
|
||||
for _, elOld := range els {
|
||||
if elOld == el {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user