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

@@ -40,14 +40,14 @@ func BServiceResource(ctx context.Context, state *models.RecordBasicServiceResou
tflog.Info(ctx, "flattens.BServiceResource: before flatten", map[string]any{"service_id": serviceId, "recordBService": recordBService})
*state = models.RecordBasicServiceResourceModel{
Name: state.Name,
RGID: state.RGID,
Name: types.StringValue(recordBService.Name),
RGID: types.Int64Value(int64(recordBService.RGID)),
Permanently: state.Permanently,
Enable: state.Enable,
Restore: state.Restore,
Start: state.Start,
Snapshots: state.Snapshots,
Timeouts: state.Timeouts,
Snapshots: flattenSnapshot(ctx, state.Snapshots, recordBService.Snapshots),
SSHKey: types.StringValue(recordBService.SSHKey),
SSHUser: types.StringValue(recordBService.SSHUser),
ServiceId: types.Int64Value(int64(recordBService.ID)),
@@ -142,3 +142,43 @@ func flattenGroups(ctx context.Context, items bservice.ListGroups) types.List {
tflog.Info(ctx, "End flattenGroups")
return res
}
func flattenSnapshot(ctx context.Context, snapshots types.Set, items bservice.ListSnapshots) types.Set {
tflog.Info(ctx, "Start flattenSnapshot")
tempSlice := make([]types.Object, 0, len(items))
for _, v := range items {
temp := models.ItemSnapshotResourceModel{
GUID: types.StringValue(v.GUID),
Label: types.StringValue(v.Label),
Rollback: flattenSnapshotRollback(ctx, snapshots, v),
Timestamp: types.Int64Value(int64(v.Timestamp)),
Valid: types.BoolValue(v.Valid),
}
obj, diags := types.ObjectValueFrom(ctx, models.ItemSnapshotResource, temp)
if diags != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenSnapshot struct to obj", diags))
}
tempSlice = append(tempSlice, obj)
}
res, diags := types.SetValueFrom(ctx, types.ObjectType{AttrTypes: models.ItemSnapshotResource}, tempSlice)
if diags != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenSnapshot", diags))
}
tflog.Info(ctx, "End flattenSnapshot")
return res
}
func flattenSnapshotRollback(ctx context.Context, snapshots types.Set, item bservice.ItemSnapshot) types.Bool {
tflog.Info(ctx, "Start flattenSnapshotRollback")
snapshotsList := snapshots.Elements()
for _, snapshot := range snapshotsList {
snapshotMap := snapshot.(types.Object).Attributes()
if snapshotMap["label"].(types.String).ValueString() == item.Label {
return types.BoolValue(snapshotMap["rollback"].(types.Bool).ValueBool())
}
}
tflog.Info(ctx, "End flattenSnapshotRollback")
return types.BoolValue(false)
}

View File

@@ -50,14 +50,14 @@ func BServiceGroupResource(ctx context.Context, plan *models.ResourceRecordGroup
}
*plan = models.ResourceRecordGroupModel{
ServiceID: plan.ServiceID,
ServiceID: types.Int64Value(int64(recordResourceGroup.ServiceID)),
CompCount: plan.CompCount,
Name: plan.Name,
CPU: plan.CPU,
RAM: plan.RAM,
Disk: plan.Disk,
ImageID: plan.ImageID,
Driver: plan.Driver,
Name: types.StringValue(recordResourceGroup.Name),
CPU: types.Int64Value(int64(recordResourceGroup.CPU)),
RAM: types.Int64Value(int64(recordResourceGroup.RAM)),
Disk: types.Int64Value(int64(recordResourceGroup.Disk)),
ImageID: types.Int64Value(int64(recordResourceGroup.ImageID)),
Driver: types.StringValue(recordResourceGroup.Driver),
SEPID: types.Int64Value(int64(recordResourceGroup.SEPID)),
SepPool: types.StringValue(recordResourceGroup.PoolName),
CloudInit: plan.CloudInit,
@@ -71,9 +71,9 @@ func BServiceGroupResource(ctx context.Context, plan *models.ResourceRecordGroup
ForceUpdate: plan.ForceUpdate,
Parents: flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, recordResourceGroup.Parents),
RemoveComputes: plan.RemoveComputes,
CompgroupID: plan.CompgroupID,
ID: types.StringValue(strconv.Itoa(int(plan.CompgroupID.ValueInt64()))),
SID: types.StringValue(strconv.Itoa(int(plan.ServiceID.ValueInt64()))),
CompgroupID: types.Int64Value(int64(recordResourceGroup.ID)),
ID: types.StringValue(strconv.Itoa(int(recordResourceGroup.ID))),
SID: types.StringValue(strconv.Itoa(int(recordResourceGroup.ServiceID))),
Timeouts: plan.Timeouts,
AccountID: types.Int64Value(int64(recordResourceGroup.AccountID)),
AccountName: types.StringValue(recordResourceGroup.AccountName),
@@ -95,6 +95,10 @@ func BServiceGroupResource(ctx context.Context, plan *models.ResourceRecordGroup
UpdatedTime: types.Int64Value(int64(recordResourceGroup.UpdatedTime)),
}
if plan.CompCount == types.Int64Null() {
plan.CompCount = types.Int64Value(int64(len(recordResourceGroup.Computes)))
}
tflog.Info(ctx, "End BServiceGroupResource", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
return nil
}

View File

@@ -0,0 +1,69 @@
package bservice
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/ic"
)
// resourceBServiceGroupInputCheck checks if input parameters are valid.
func resourceBServiceGroupInputCheck(ctx context.Context, plan *models.ResourceRecordGroupModel, c *client.Client) diag.Diagnostics {
diags := diag.Diagnostics{}
serviceID := uint64(plan.ServiceID.ValueInt64())
serviceIDValid := true
tflog.Info(ctx, "resourceBServiceGroupInputCheck: exist resource bservice", map[string]any{"service_id": serviceID})
err := ic.ExistBservise(ctx, serviceID, c)
if err != nil {
serviceIDValid = false
diags.AddError(fmt.Sprintf("Cannot get info about bservice with ID %v", serviceID), err.Error())
}
imageID := uint64(plan.ImageID.ValueInt64())
tflog.Info(ctx, "resourceBServiceGroupInputCheck: exist resource image", map[string]any{"image_id": imageID})
err = ic.ExistImage(ctx, imageID, c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about image with ID %v", imageID), err.Error())
}
if !plan.ExtNets.IsNull() {
extnetList := plan.ExtNets.Elements()
for _, elem := range extnetList {
extNetID := elem.(types.Int64).ValueInt64()
err = ic.ExistExtNet(ctx, uint64(extNetID), c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about extnet with ID %v", extNetID), err.Error())
}
}
}
if !plan.VINSes.IsNull() {
vinsList := plan.VINSes.Elements()
for _, elem := range vinsList {
vinsID := elem.(types.Int64).ValueInt64()
err = ic.ExistVins(ctx, uint64(vinsID), c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about VINS with ID %v", vinsList), err.Error())
}
}
}
if serviceIDValid && !plan.Parents.IsNull() {
parentsList := plan.Parents.Elements()
for _, elem := range parentsList {
parentID := elem.(types.Int64).ValueInt64()
err = ic.ExistBserviseGroup(ctx, serviceID, uint64(parentID), c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about parent group with ID %v", parentID), err.Error())
}
}
}
return diags
}

View File

@@ -19,7 +19,7 @@ type RecordBasicServiceResourceModel struct {
Restore types.Bool `tfsdk:"restore"`
Start types.Bool `tfsdk:"start"`
ServiceId types.Int64 `tfsdk:"service_id"`
Snapshots types.List `tfsdk:"snapshots"`
Snapshots types.Set `tfsdk:"snapshots"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
//computed fields

View File

@@ -67,6 +67,11 @@ func (r *resourceBService) Create(ctx context.Context, req resource.CreateReques
ctx, cancel := context.WithTimeout(ctx, createTimeout)
defer cancel()
if len(plan.Snapshots.Elements()) > 0 {
resp.Diagnostics.AddError("BServiceResourceCreate: snapshot field must be empty when resource is creating", "")
return
}
// Make create request and get response
id, diags := utilities.BServiceResourceCreate(ctx, &plan, r.client)
resp.Diagnostics.Append(diags...)
@@ -74,15 +79,9 @@ func (r *resourceBService) Create(ctx context.Context, req resource.CreateReques
return
}
plan.ID = types.StringValue(strconv.Itoa(int(*id)))
tflog.Info(ctx, "BServiceResourceCreatee: BService created", map[string]any{"service_id": id})
tflog.Info(ctx, "BServiceResourceCreate: BService created", map[string]any{"service_id": id})
tflog.Info(ctx, "BServiceResourceCreatee: resource creation is completed", map[string]any{"service_id": id})
currentSnapshots, diags := types.ListValue(plan.Snapshots.Type(ctx), plan.Snapshots.Elements())
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
tflog.Info(ctx, "BServiceResourceCreate: resource creation is completed", map[string]any{"service_id": id})
// Map response body to schema and populate Computed attribute values
resp.Diagnostics.Append(flattens.BServiceResource(ctx, &plan, r.client)...)
@@ -90,15 +89,6 @@ func (r *resourceBService) Create(ctx context.Context, req resource.CreateReques
return
}
if !plan.Snapshots.Equal(currentSnapshots) && !currentSnapshots.IsNull() {
resp.Diagnostics.Append(utilities.SnapshotsBService(ctx, currentSnapshots, plan.Snapshots, uint64(plan.ServiceId.ValueInt64()), r.client)...)
if resp.Diagnostics.HasError() {
tflog.Warn(ctx, "Create resourceBService: Error snapshosts bservice")
return
}
}
// Set state to fully populated data
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
if resp.Diagnostics.HasError() {
@@ -217,8 +207,7 @@ func (r *resourceBService) Update(ctx context.Context, req resource.UpdateReques
// SnapshotsBService bservice
if !plan.Snapshots.Equal(state.Snapshots) && !plan.Snapshots.IsNull() {
resp.Diagnostics.Append(utilities.SnapshotsBService(ctx, state.Snapshots, plan.Snapshots, uint64(plan.ServiceId.ValueInt64()), r.client)...)
resp.Diagnostics.Append(utilities.SnapshotsBService(ctx, state.Snapshots, plan.Snapshots, uint64(state.ServiceId.ValueInt64()), r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBService: Error snapshosts bservice")
return

View File

@@ -7,6 +7,7 @@ import (
"strings"
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
@@ -69,35 +70,42 @@ func (r *resourceBServiceGroup) Create(ctx context.Context, req resource.CreateR
ctx, cancel := context.WithTimeout(ctx, createTimeout)
defer cancel()
// Check if input values are valid in the platform
tflog.Info(ctx, "Create resourceBServiceGroup: starting input checks", map[string]any{"name": plan.Name.ValueString()})
resp.Diagnostics.Append(resourceBServiceGroupInputCheck(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Create resourceBServiceGroup: Error input checks")
return
}
tflog.Info(ctx, "Create resourceBServiceGroup: input checks successful", map[string]any{"name": plan.Name.ValueString()})
// Make create request and get response
diags = utilities.BServiceGroupResourceCreate(ctx, &plan, r.client)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
tflog.Info(ctx, "BServiceResourceCreatee: BService group created", map[string]any{"service_id": plan.ServiceID.ValueInt64()})
tflog.Info(ctx, "BServiceResourceCreate: BService group created", map[string]any{"service_id": plan.ServiceID.ValueInt64()})
tflog.Info(ctx, "BServiceResourceCreatee: resource creation is completed", map[string]any{"service_id": plan.ServiceID.ValueInt64()})
currentParents, diags := types.ListValue(plan.Parents.Type(ctx), plan.Parents.Elements())
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
if !plan.Parents.IsNull() {
oldParents := types.ListValueMust(
types.Int64Type,
[]attr.Value{},
)
resp.Diagnostics.Append(utilities.BServiceGroupParents(ctx, plan.Parents, oldParents, &plan, r.client)...)
if resp.Diagnostics.HasError() {
return
}
}
tflog.Info(ctx, "BServiceResourceCreate: resource creation is completed", map[string]any{"service_id": plan.ServiceID.ValueInt64()})
// Map response body to schema and populate Computed attribute values
resp.Diagnostics.Append(flattens.BServiceGroupResource(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
return
}
if !plan.Parents.Equal(currentParents) && !currentParents.IsNull() {
resp.Diagnostics.Append(utilities.BServiceGroupParents(ctx, plan.Parents, currentParents, &plan, r.client)...)
if resp.Diagnostics.HasError() {
return
}
}
// Set state to fully populated data
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
if resp.Diagnostics.HasError() {
@@ -163,8 +171,7 @@ func (r *resourceBServiceGroup) Update(ctx context.Context, req resource.UpdateR
return
}
logMap := map[string]any{"service_id": plan.ID.ValueString()}
tflog.Info(ctx, "Update resourceBServiceGroup: got plan successfully", logMap)
tflog.Info(ctx, "Update resourceBServiceGroup: got plan successfully", map[string]any{"compgroup_name": plan.Name.ValueString()})
// Retrieve values from state
var state models.ResourceRecordGroupModel
@@ -173,6 +180,7 @@ func (r *resourceBServiceGroup) Update(ctx context.Context, req resource.UpdateR
tflog.Error(ctx, "Update resourceBServiceGroup: Error receiving the state")
return
}
logMap := map[string]any{"service_id": state.ID.ValueString()}
tflog.Info(ctx, "Update resourceBServiceGroup: got state successfully", logMap)
// Set timeouts
@@ -189,12 +197,23 @@ func (r *resourceBServiceGroup) Update(ctx context.Context, req resource.UpdateR
ctx, cancel := context.WithTimeout(ctx, updateTimeout)
defer cancel()
// Check if input values are valid in the platform
tflog.Info(ctx, "Create resourceBServiceGroup: starting input checks", map[string]any{"name": plan.Name.ValueString()})
resp.Diagnostics.Append(resourceBServiceGroupInputCheck(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Create resourceBServiceGroup: Error input checks")
return
}
tflog.Info(ctx, "Create resourceBServiceGroup: input checks successful", map[string]any{"name": plan.Name.ValueString()})
_, err := strconv.Atoi(state.ID.ValueString())
if err != nil {
resp.Diagnostics.AddError("Update resourceBServiceGroup: Cannot parse ID from state", err.Error())
return
}
plan.ID = state.ID
if !plan.CompCount.Equal(state.CompCount) && !plan.CompCount.IsNull() {
resp.Diagnostics.Append(utilities.BServiceGroupResize(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
@@ -211,7 +230,7 @@ func (r *resourceBServiceGroup) Update(ctx context.Context, req resource.UpdateR
}
}
if !plan.Name.Equal(state.Name) || !plan.RAM.Equal(state.RAM) || !plan.CPU.Equal(state.CPU) || !plan.Disk.Equal(state.Disk) || !plan.Role.Equal(state.Role) {
if !plan.Name.Equal(state.Name) || !plan.RAM.Equal(state.RAM) || !plan.CPU.Equal(state.CPU) || !plan.Disk.Equal(state.Disk) || (!plan.Role.Equal(state.Role) && !plan.Role.IsUnknown()) {
resp.Diagnostics.Append(utilities.BServiceGroupUpdate(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error update bservice group")
@@ -219,7 +238,7 @@ func (r *resourceBServiceGroup) Update(ctx context.Context, req resource.UpdateR
}
}
if !plan.ExtNets.Equal(state.ExtNets) && !plan.ExtNets.IsNull() {
if !plan.ExtNets.Equal(state.ExtNets) && !plan.ExtNets.IsUnknown() {
resp.Diagnostics.Append(utilities.BServiceGroupExtNet(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error update extnets bservice")
@@ -227,7 +246,7 @@ func (r *resourceBServiceGroup) Update(ctx context.Context, req resource.UpdateR
}
}
if !plan.VINSes.Equal(state.VINSes) && !plan.VINSes.IsNull() {
if !plan.VINSes.Equal(state.VINSes) && !plan.VINSes.IsUnknown() {
resp.Diagnostics.Append(utilities.BServiceGroupVinses(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error update vinses bservice")
@@ -331,7 +350,7 @@ func (r *resourceBServiceGroup) Configure(ctx context.Context, req resource.Conf
}
func (r *resourceBServiceGroup) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
idParts := strings.Split(req.ID, ",")
idParts := strings.Split(req.ID, "#")
if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
resp.Diagnostics.AddError(

View File

@@ -38,7 +38,7 @@ func MakeSchemaResourceBService() map[string]schema.Attribute {
Optional: true,
Computed: true,
},
"snapshots": schema.ListNestedAttribute{
"snapshots": schema.SetNestedAttribute{
Optional: true,
Computed: true,
NestedObject: schema.NestedAttributeObject{
@@ -47,7 +47,7 @@ func MakeSchemaResourceBService() map[string]schema.Attribute {
Computed: true,
},
"label": schema.StringAttribute{
Computed: true,
Required: true,
},
"rollback": schema.BoolAttribute{
Optional: true,

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.

View File

@@ -91,7 +91,7 @@ func BServiceGroupResourceCreate(ctx context.Context, plan *models.ResourceRecor
diags.AddError("Unable to add group", err.Error())
return diags
}
plan.ID = types.StringValue(strconv.Itoa(int(plan.CompgroupID.ValueInt64())))
plan.ID = types.StringValue(strconv.Itoa(int(compgroupId)))
plan.SID = types.StringValue(strconv.Itoa(int(plan.ServiceID.ValueInt64())))
if plan.Start.ValueBool() {
@@ -114,35 +114,48 @@ func BServiceGroupResourceCreate(ctx context.Context, plan *models.ResourceRecor
}
func BServiceGroupResize(ctx context.Context, plan *models.ResourceRecordGroupModel, c *client.Client) diag.Diagnostics {
tflog.Info(ctx, "BServiceGroupResize: start.", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "BServiceGroupResize: start.", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
compGroupID, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("BServiceGroupResize: cannot parsed ID compute from plan", err.Error())
return diags
}
req := bservice.GroupResizeRequest{
ServiceID: uint64(plan.ServiceID.ValueInt64()),
CompGroupID: uint64(plan.CompgroupID.ValueInt64()),
CompGroupID: compGroupID,
Count: plan.CompCount.ValueInt64(),
Mode: plan.Mode.ValueString(),
}
_, err := c.CloudAPI().BService().GroupResize(ctx, req)
tflog.Info(ctx, "BServiceGroupResize: before calling CloudAPI().BService().GroupResize", map[string]any{"req": req})
_, 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())
diags.AddError(fmt.Sprintf("Cannot resize group with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), compGroupID), err.Error())
return diags
}
tflog.Info(ctx, "BServiceGroupResize: resize group successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "BServiceGroupResize: resize group successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": compGroupID})
return diags
}
func BServiceGroupUpdate(ctx context.Context, plan *models.ResourceRecordGroupModel, c *client.Client) diag.Diagnostics {
tflog.Info(ctx, "BServiceGroupUpdate: start.", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "BServiceGroupUpdate: start.", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
compGroupID, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("BServiceGroupResize: cannot parsed ID compute from plan", err.Error())
return diags
}
req := bservice.GroupUpdateRequest{
ServiceID: uint64(plan.ServiceID.ValueInt64()),
CompGroupID: uint64(plan.CompgroupID.ValueInt64()),
CompGroupID: compGroupID,
Name: plan.Name.ValueString(),
Role: plan.Role.ValueString(),
CPU: uint64(plan.CPU.ValueInt64()),
@@ -151,18 +164,19 @@ func BServiceGroupUpdate(ctx context.Context, plan *models.ResourceRecordGroupMo
Force: plan.ForceUpdate.ValueBool(),
}
_, err := c.CloudAPI().BService().GroupUpdate(ctx, req)
tflog.Info(ctx, "BServiceGroupResize: before calling CloudAPI().BService().GroupUpdate", map[string]any{"req": req})
_, 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())
diags.AddError(fmt.Sprintf("Cannot update group with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), compGroupID), err.Error())
return diags
}
tflog.Info(ctx, "BServiceGroupUpdate: update group successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "BServiceGroupUpdate: update group successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": compGroupID})
return diags
}
func BServiceGroupReadStatus(ctx context.Context, plan *models.ResourceRecordGroupModel, c *client.Client) diag.Diagnostics {
tflog.Info(ctx, "Read status BServiceGroupReadStatus with ID", map[string]any{"service_id": plan.ServiceID.ValueInt64()})
tflog.Info(ctx, "Read status BServiceGroupReadStatus with ID", map[string]any{"service_id": plan.SID.ValueString()})
diags := diag.Diagnostics{}
@@ -201,43 +215,56 @@ func BServiceGroupReadStatus(ctx context.Context, plan *models.ResourceRecordGro
}
func BServiceGroupStartStop(ctx context.Context, plan *models.ResourceRecordGroupModel, c *client.Client) diag.Diagnostics {
tflog.Info(ctx, "Start/Stop bservice group", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "Start/Stop bservice group", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
compGroupID, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("BServiceGroupStartStop: Cannot parse resource ID from state", err.Error())
return diags
}
if plan.Start.ValueBool() {
req := bservice.GroupStartRequest{
ServiceID: uint64(plan.ServiceID.ValueInt64()),
CompGroupID: uint64(plan.CompgroupID.ValueInt64()),
CompGroupID: compGroupID,
}
tflog.Info(ctx, "BServiceGroupStartStop: before calling CloudAPI().BService().GroupStart", map[string]any{"req": req})
_, 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())
diags.AddError(fmt.Sprintf("Cannot start bservice group with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), compGroupID), err.Error())
return diags
}
} else {
req := bservice.GroupStopRequest{
ServiceID: uint64(plan.ServiceID.ValueInt64()),
CompGroupID: uint64(plan.CompgroupID.ValueInt64()),
CompGroupID: compGroupID,
Force: plan.ForceStop.ValueBool(),
}
tflog.Info(ctx, "BServiceGroupStartStop: before calling CloudAPI().BService().GroupStop", map[string]any{"req": req})
_, 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())
diags.AddError(fmt.Sprintf("Cannot stop bservice group with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), compGroupID), 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()})
tflog.Info(ctx, "Start/Stop bservice group successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": compGroupID})
return diags
}
func BServiceGroupExtNet(ctx context.Context, plan *models.ResourceRecordGroupModel, c *client.Client) diag.Diagnostics {
tflog.Info(ctx, "update ExtNets", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "update ExtNets", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
compGroupID, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("BServiceGroupStartStop: Cannot parse resource ID from state", err.Error())
return diags
}
extnetList := make([]uint64, 0, len(plan.ExtNets.Elements()))
diags.Append(plan.ExtNets.ElementsAs(ctx, &extnetList, true)...)
@@ -248,25 +275,32 @@ func BServiceGroupExtNet(ctx context.Context, plan *models.ResourceRecordGroupMo
req := bservice.GroupUpdateExtNetRequest{
ServiceID: uint64(plan.ServiceID.ValueInt64()),
CompGroupID: uint64(plan.CompgroupID.ValueInt64()),
CompGroupID: compGroupID,
ExtNets: extnetList,
}
_, err := c.CloudAPI().BService().GroupUpdateExtNet(ctx, req)
tflog.Info(ctx, "BServiceGroupExtNet: before calling CloudAPI().BService().GroupUpdateExtNet", map[string]any{"req": req})
_, 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())
diags.AddError(fmt.Sprintf("Cannot update bservice group extnets with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), compGroupID), err.Error())
return diags
}
tflog.Info(ctx, "BServiceGroupExtNet: update successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "BServiceGroupExtNet: update successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": compGroupID})
return diags
}
func BServiceGroupVinses(ctx context.Context, plan *models.ResourceRecordGroupModel, c *client.Client) diag.Diagnostics {
tflog.Info(ctx, "update Vinses", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "update Vinses", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
compGroupID, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("BServiceGroupStartStop: Cannot parse resource ID from state", err.Error())
return diags
}
vinsesList := make([]uint64, 0, len(plan.VINSes.Elements()))
diags.Append(plan.VINSes.ElementsAs(ctx, &vinsesList, true)...)
@@ -277,23 +311,30 @@ func BServiceGroupVinses(ctx context.Context, plan *models.ResourceRecordGroupMo
req := bservice.GroupUpdateVINSRequest{
ServiceID: uint64(plan.ServiceID.ValueInt64()),
CompGroupID: uint64(plan.ServiceID.ValueInt64()),
CompGroupID: compGroupID,
VINSes: vinsesList,
}
_, err := c.CloudAPI().BService().GroupUpdateVINS(ctx, req)
tflog.Info(ctx, "BServiceGroupVinses: before calling CloudAPI().BService().GroupUpdateVINS", map[string]any{"req": req})
_, 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())
diags.AddError(fmt.Sprintf("Cannot update bservice group vinses with ServiceID - %d,CompgroupID - %d ", plan.ServiceID.ValueInt64(), compGroupID), err.Error())
return diags
}
tflog.Info(ctx, "BServiceGroupVinses: update successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "BServiceGroupVinses: update successfully", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": compGroupID})
return diags
}
func BServiceGroupParents(ctx context.Context, newParents basetypes.ListValue, oldParents basetypes.ListValue, plan *models.ResourceRecordGroupModel, c *client.Client) diag.Diagnostics {
diags := diag.Diagnostics{}
tflog.Info(ctx, "Start BServiceGroupParents", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "Start BServiceGroupParents", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.ID.ValueString()})
compGroupID, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("BServiceGroupStartStop: Cannot parse resource ID from state", err.Error())
return diags
}
deletedParents := make([]uint64, 0)
addedParents := make([]uint64, 0)
@@ -330,7 +371,7 @@ func BServiceGroupParents(ctx context.Context, newParents basetypes.ListValue, o
req := bservice.GroupParentRemoveRequest{
ServiceID: uint64(plan.ServiceID.ValueInt64()),
CompGroupID: uint64(plan.CompCount.ValueInt64()),
CompGroupID: compGroupID,
ParentID: parent,
}
@@ -340,7 +381,7 @@ func BServiceGroupParents(ctx context.Context, newParents basetypes.ListValue, o
return diags
}
}
tflog.Info(ctx, "Deleted parents", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
tflog.Info(ctx, "Deleted parents", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": compGroupID})
}
if len(addedParents) > 0 {
@@ -348,17 +389,17 @@ func BServiceGroupParents(ctx context.Context, newParents basetypes.ListValue, o
req := bservice.GroupParentAddRequest{
ServiceID: uint64(plan.ServiceID.ValueInt64()),
CompGroupID: uint64(plan.CompCount.ValueInt64()),
CompGroupID: compGroupID,
ParentID: parent,
}
tflog.Info(ctx, "BServiceGroupParents: before calling CloudAPI().BService().GroupParentAdd", map[string]any{"req": req})
_, 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()})
tflog.Info(ctx, "Added parents", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": compGroupID})
}
return diags
@@ -366,6 +407,14 @@ func BServiceGroupParents(ctx context.Context, newParents basetypes.ListValue, o
func BServiceGroupRemoveComputes(ctx context.Context, plan *models.ResourceRecordGroupModel, c *client.Client) diag.Diagnostics {
diags := diag.Diagnostics{}
tflog.Info(ctx, "Start BServiceGroupRemoveComputes", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.ID.ValueString()})
compGroupID, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("BServiceGroupStartStop: Cannot parse resource ID from state", err.Error())
return diags
}
rcs := plan.RemoveComputes
rcsList := make([]uint64, 0, len(rcs.Elements()))
@@ -379,10 +428,10 @@ func BServiceGroupRemoveComputes(ctx context.Context, plan *models.ResourceRecor
for _, rc := range rcsList {
req := bservice.GroupComputeRemoveRequest{
ServiceID: uint64(plan.ServiceID.ValueInt64()),
CompGroupID: uint64(plan.CompCount.ValueInt64()),
CompGroupID: compGroupID,
ComputeID: rc,
}
tflog.Info(ctx, "BServiceGroupParents: before calling CloudAPI().BService().GroupComputeRemove", map[string]any{"req": req})
_, err := c.CloudAPI().BService().GroupComputeRemove(ctx, req)
if err != nil {
tflog.Error(ctx, "BServiceGroupRemoveComputes: Failed to remove compute")

View File

@@ -6,6 +6,7 @@ import (
"fmt"
account "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/dpdknet"
@@ -523,3 +524,40 @@ func ExistLBFrontend(ctx context.Context, lbId uint64, fName string, c *client.C
return fmt.Errorf("frontend with name %v not found", fName)
}
func ExistBservise(ctx context.Context, serviceID uint64, c *client.Client) error {
req := bservice.ListRequest{
ByID: serviceID,
}
rgList, err := c.CloudAPI().BService().List(ctx, req)
if err != nil {
return err
}
if len(rgList.Data) == 0 {
return fmt.Errorf("Bservice with id %v not found", serviceID)
}
for _, v := range rgList.Data {
if v.Status != "ENABLED" {
return fmt.Errorf("Bservice with id %v should be enabled", serviceID)
}
}
return nil
}
func ExistBserviseGroup(ctx context.Context, serviseID uint64, compGroupID uint64, c *client.Client) error {
req := bservice.GroupGetRequest{
ServiceID: serviseID,
CompGroupID: compGroupID,
}
_, err := c.CloudAPI().BService().GroupGet(ctx, req)
if err != nil {
return err
}
return nil
}

View File

@@ -523,16 +523,7 @@ func MakeSchemaResourceVINS() map[string]schema.Attribute {
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"client_type": schema.StringAttribute{
Computed: true,
},
"desc": schema.StringAttribute{
Computed: true,
},
"domainname": schema.StringAttribute{
Computed: true,
},
"hostname": schema.StringAttribute{
"account_id": schema.Int64Attribute{
Computed: true,
},
"ip": schema.StringAttribute{