This commit is contained in:
asteam
2024-07-25 14:33:38 +03:00
commit 6f40af6a5f
946 changed files with 98335 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
package bservice
import (
"context"
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/schemas"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &dataSourceBService{}
)
func NewDataSourceBService() datasource.DataSource {
return &dataSourceBService{}
}
// dataSourceBService is the data source implementation.
type dataSourceBService struct {
client *decort.DecortClient
}
func (d *dataSourceBService) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// Read Terraform configuration data into the model
var state models.RecordBasicServiceModel
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBService: Error get state")
return
}
bserviceId := uint64(state.ServiceId.ValueInt64())
tflog.Info(ctx, "Read dataSourceBService: got state successfully", map[string]any{"service_id": bserviceId})
// Set timeouts
readTimeout, diags := state.Timeouts.Read(ctx, constants.Timeout30s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBService: Error set timeout")
return
}
tflog.Info(ctx, "Read dataSourceBService: set timeouts successfully", map[string]any{
"service_id": bserviceId,
"readTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// Map response body to schema
resp.Diagnostics.Append(flattens.BServiceDataSource(ctx, &state, d.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBService: Error flatten data source bservice")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBService: Error set state")
return
}
tflog.Info(ctx, "End read dataSourceBService", map[string]any{"service_id": bserviceId})
}
func (d *dataSourceBService) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaDataSourceBService(),
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx),
},
}
}
func (d *dataSourceBService) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_bservice"
}
// Configure adds the provider configured client to the data source.
func (d *dataSourceBService) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
tflog.Info(ctx, "Get Configure dataSourceBService")
d.client = client.DataSource(ctx, &req, resp)
tflog.Info(ctx, "Getting Configure dataSourceBService successfully")
}

View File

@@ -0,0 +1,89 @@
package bservice
import (
"context"
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/schemas"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &dataSourceBServiceDeletedList{}
)
func NewDataSourceBServiceDeletedList() datasource.DataSource {
return &dataSourceBServiceDeletedList{}
}
// dataSourceBServiceDeletedList is the data source implementation.
type dataSourceBServiceDeletedList struct {
client *decort.DecortClient
}
func (d *dataSourceBServiceDeletedList) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// Read Terraform configuration data into the model
var state models.ListBasicServicesDelModel
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceDeletedList: Error get state")
return
}
tflog.Info(ctx, "Read dataSourceBServiceDeletedList: got state successfully")
// Set timeouts
readTimeout, diags := state.Timeouts.Read(ctx, constants.Timeout30s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceDeletedList: Error set timeout")
return
}
tflog.Info(ctx, "Read dataSourceBServiceDeletedList: set timeouts successfully", map[string]any{
"readTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// Map response body to schema
resp.Diagnostics.Append(flattens.BServicesDeletedListDataSource(ctx, &state, d.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceDeletedList: Error flatten data source bservice list")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceDeletedList: Error set state")
return
}
tflog.Info(ctx, "End read dataSourceBServiceDeletedList")
}
func (d *dataSourceBServiceDeletedList) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaDataSourceBServiceDeletedList(),
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx),
},
}
}
func (d *dataSourceBServiceDeletedList) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_bservice_deleted_list"
}
// Configure adds the provider configured client to the data source.
func (d *dataSourceBServiceDeletedList) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
tflog.Info(ctx, "Get Configure dataSourceBServiceDeletedList")
d.client = client.DataSource(ctx, &req, resp)
tflog.Info(ctx, "Getting Configure dataSourceBServiceDeletedList successfully")
}

View File

@@ -0,0 +1,91 @@
package bservice
import (
"context"
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/schemas"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &dataSourceBServiceGroup{}
)
func NewDataSourceBServiceGroup() datasource.DataSource {
return &dataSourceBServiceGroup{}
}
// dataSourceBServiceGroup is the data source implementation.
type dataSourceBServiceGroup struct {
client *decort.DecortClient
}
func (d *dataSourceBServiceGroup) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// Read Terraform configuration data into the model
var state models.RecordGroupModel
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceGroup: Error get state")
return
}
bserviceId := uint64(state.ServiceID.ValueInt64())
tflog.Info(ctx, "Read dataSourceBServiceGroup: got state successfully", map[string]any{"service_id": bserviceId})
// Set timeouts
readTimeout, diags := state.Timeouts.Read(ctx, constants.Timeout30s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceGroup: Error set timeout")
return
}
tflog.Info(ctx, "Read dataSourceBServiceGroup: set timeouts successfully", map[string]any{
"service_id": bserviceId,
"readTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// Map response body to schema
resp.Diagnostics.Append(flattens.BServiceGroupDataSource(ctx, &state, d.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceGroup: Error flatten data source bservice group")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceGroup: Error set state")
return
}
tflog.Info(ctx, "End read dataSourceBServiceGroup", map[string]any{"service_id": bserviceId})
}
func (d *dataSourceBServiceGroup) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaDataSourceBServiceGroup(),
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx),
},
}
}
func (d *dataSourceBServiceGroup) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_bservice_group"
}
// Configure adds the provider configured client to the data source.
func (d *dataSourceBServiceGroup) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
tflog.Info(ctx, "Get Configure dataSourceBServiceGroup")
d.client = client.DataSource(ctx, &req, resp)
tflog.Info(ctx, "Getting Configure dataSourceBServiceGroup successfully")
}

View File

@@ -0,0 +1,89 @@
package bservice
import (
"context"
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/schemas"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &dataSourceBServiceList{}
)
func NewDataSourceBServiceList() datasource.DataSource {
return &dataSourceBServiceList{}
}
// dataSourceBServiceList is the data source implementation.
type dataSourceBServiceList struct {
client *decort.DecortClient
}
func (d *dataSourceBServiceList) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// Read Terraform configuration data into the model
var state models.ListBasicServicesModel
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceList: Error get state")
return
}
tflog.Info(ctx, "Read dataSourceBServiceList: got state successfully")
// Set timeouts
readTimeout, diags := state.Timeouts.Read(ctx, constants.Timeout30s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceList: Error set timeout")
return
}
tflog.Info(ctx, "Read dataSourceBServiceList: set timeouts successfully", map[string]any{
"readTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// Map response body to schema
resp.Diagnostics.Append(flattens.BServicesListDataSource(ctx, &state, d.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceList: Error flatten data source bservice list")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceList: Error set state")
return
}
tflog.Info(ctx, "End read dataSourceBServiceList")
}
func (d *dataSourceBServiceList) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaDataSourceBServiceList(),
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx),
},
}
}
func (d *dataSourceBServiceList) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_bservice_list"
}
// Configure adds the provider configured client to the data source.
func (d *dataSourceBServiceList) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
tflog.Info(ctx, "Get Configure dataSourceBServiceList")
d.client = client.DataSource(ctx, &req, resp)
tflog.Info(ctx, "Getting Configure dataSourceBServiceList successfully")
}

View File

@@ -0,0 +1,91 @@
package bservice
import (
"context"
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/schemas"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &dataSourceBServiceSnapshotList{}
)
func NewDataSourceBServiceSnapshotList() datasource.DataSource {
return &dataSourceBServiceSnapshotList{}
}
// dataSourceBServiceSnapshotList is the data source implementation.
type dataSourceBServiceSnapshotList struct {
client *decort.DecortClient
}
func (d *dataSourceBServiceSnapshotList) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// Read Terraform configuration data into the model
var state models.ListInfoSnapshotsModel
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceSnapshotList: Error get state")
return
}
bserviceId := uint64(state.ServiceID.ValueInt64())
tflog.Info(ctx, "Read dataSourceBServiceSnapshotList: got state successfully", map[string]any{"service_id": bserviceId})
// Set timeouts
readTimeout, diags := state.Timeouts.Read(ctx, constants.Timeout30s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceSnapshotList: Error set timeout")
return
}
tflog.Info(ctx, "Read dataSourceBServiceSnapshotList: set timeouts successfully", map[string]any{
"service_id": bserviceId,
"readTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// Map response body to schema
resp.Diagnostics.Append(flattens.BServiceSnapshotListDataSource(ctx, &state, d.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceSnapshotList: Error flatten data source bservice")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceBServiceSnapshotList: Error set state")
return
}
tflog.Info(ctx, "End read dataSourceBServiceSnapshotList", map[string]any{"service_id": bserviceId})
}
func (d *dataSourceBServiceSnapshotList) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaDataSourceBServiceSnapshotList(),
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx),
},
}
}
func (d *dataSourceBServiceSnapshotList) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_bservice_snapshot_list"
}
// Configure adds the provider configured client to the data source.
func (d *dataSourceBServiceSnapshotList) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
tflog.Info(ctx, "Get Configure dataSourceBServiceSnapshotList")
d.client = client.DataSource(ctx, &req, resp)
tflog.Info(ctx, "Getting Configure dataSourceBServiceSnapshotList successfully")
}

View File

@@ -0,0 +1,116 @@
package flattens
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/utilities"
)
// BServiceDataSource flattens data source for bservice.
// Return error in case data source is not found on the platform.
// Flatten errors are added to tflog.
func BServiceDataSource(ctx context.Context, state *models.RecordBasicServiceModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "Start flattens.BServiceDataSource")
diags := diag.Diagnostics{}
serivceId := uint64(state.ServiceId.ValueInt64())
record, err := utilities.BServiceDataSourceCheckPresence(ctx, serivceId, c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about bservice with ID %v", serivceId), err.Error())
return diags
}
tflog.Info(ctx, "flattens.BServiceDataSource: before flatten", map[string]any{"service_id": serivceId, "record": record})
*state = models.RecordBasicServiceModel{
ServiceId: state.ServiceId,
Timeouts: state.Timeouts,
AccountID: types.Int64Value(int64(record.AccountID)),
AccountName: types.StringValue(record.AccountName),
BaseDomain: types.StringValue(record.BaseDomain),
CPUTotal: types.Int64Value(int64(record.CPUTotal)),
CreatedBy: types.StringValue(record.CreatedBy),
CreatedTime: types.Int64Value(int64(record.CreatedTime)),
DeletedBy: types.StringValue(record.DeletedBy),
DeletedTime: types.Int64Value(int64(record.DeletedTime)),
DiskTotal: types.Int64Value(int64(record.DiskTotal)),
GID: types.Int64Value(int64(record.GID)),
GUID: types.Int64Value(int64(record.GUID)),
Milestones: types.Int64Value(int64(record.Milestones)),
Name: types.StringValue(record.Name),
ParentSrvID: types.Int64Value(int64(record.ParentSrvID)),
ParentSrvType: types.StringValue(record.ParentSrvType),
RAMTotal: types.Int64Value(int64(record.RAMTotal)),
RGID: types.Int64Value(int64(record.RGID)),
RGName: types.StringValue(record.RGName),
SSHKey: types.StringValue(record.SSHKey),
SSHUser: types.StringValue(record.SSHUser),
Status: types.StringValue(record.Status),
TechStatus: types.StringValue(record.TechStatus),
UpdatedBy: types.StringValue(record.UpdatedBy),
UpdatedTime: types.Int64Value(int64(record.UpdatedTime)),
UserManaged: types.BoolValue(record.UserManaged),
}
computesList := make([]models.ItemComputeModel, 0, len(record.Computes))
for _, v := range record.Computes {
temp := models.ItemComputeModel{
AccountID: types.Int64Value(int64(v.AccountID)),
Architecture: types.StringValue(v.Architecture),
CompGroupID: types.Int64Value(int64(v.CompGroupID)),
CompGroupName: types.StringValue(v.CompGroupName),
CompGroupRole: types.StringValue(v.CompGroupRole),
ID: types.Int64Value(int64(v.ID)),
Name: types.StringValue(v.Name),
RGID: types.Int64Value(int64(v.RGID)),
StackID: types.Int64Value(int64(v.StackID)),
Status: types.StringValue(v.Status),
TechStatus: types.StringValue(v.TechStatus),
}
computesList = append(computesList, temp)
}
state.Computes = computesList
groupsList := make([]models.ItemGroupModel, 0, len(record.Groups))
for _, v := range record.Groups {
temp := models.ItemGroupModel{
Computes: types.Int64Value(int64(v.Computes)),
Consistency: types.BoolValue(v.Consistency),
ID: types.Int64Value(int64(v.ID)),
Name: types.StringValue(v.Name),
Status: types.StringValue(v.Status),
TechStatus: types.StringValue(v.TechStatus),
}
groupsList = append(groupsList, temp)
}
state.Groups = groupsList
snapshotsList := make([]models.ItemSnapshotModel, 0, len(record.Snapshots))
for _, v := range record.Snapshots {
temp := models.ItemSnapshotModel{
GUID: types.StringValue(v.GUID),
Label: types.StringValue(v.Label),
Timestamp: types.Int64Value(int64(v.Timestamp)),
Valid: types.BoolValue(v.Valid),
}
snapshotsList = append(snapshotsList, temp)
}
state.Snapshots = snapshotsList
tflog.Info(ctx, "flattens.BServiceDataSource: after flatten", map[string]any{"service_id": state.ServiceId.ValueInt64()})
tflog.Info(ctx, "End flattens.BServiceDataSource", map[string]any{"service_id": state.ServiceId.ValueInt64()})
return nil
}

View File

@@ -0,0 +1,75 @@
package flattens
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/utilities"
)
// BServicesDeletedListDataSource flattens data source for a list of basic services.
// Return error in case data source is not found on the platform.
// Flatten errors are added to tflog.
func BServicesDeletedListDataSource(ctx context.Context, state *models.ListBasicServicesDelModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "Start flattens.BServicesDeletedListDataSource")
diags := diag.Diagnostics{}
// Fetch the list of basic services from the API
recordList, err := utilities.BServiceDeletedListDataSourceCheckPresence(ctx, *state, c)
if err != nil {
diags.AddError("Cannot get list of basic services", err.Error())
return diags
}
tflog.Info(ctx, "flattens.BServicesDeletedListDataSource: before flatten", map[string]any{"record_list": recordList})
// Flatten the fetched data into the state
var itemList []models.ItemBasicServiceDelModel
for _, record := range recordList.Data {
item := models.ItemBasicServiceDelModel{
AccountID: types.Int64Value(int64(record.AccountID)),
AccountName: types.StringValue(record.AccountName),
BaseDomain: types.StringValue(record.BaseDomain),
CreatedBy: types.StringValue(record.CreatedBy),
CreatedTime: types.Int64Value(int64(record.CreatedTime)),
DeletedBy: types.StringValue(record.DeletedBy),
DeletedTime: types.Int64Value(int64(record.DeletedTime)),
GID: types.Int64Value(int64(record.GID)),
GUID: types.Int64Value(int64(record.GUID)),
ID: types.Int64Value(int64(record.ID)),
Name: types.StringValue(record.Name),
ParentSrvID: types.Int64Value(int64(record.ParentSrvID)),
ParentSrvType: types.StringValue(record.ParentSrvType),
RGID: types.Int64Value(int64(record.RGID)),
RGName: types.StringValue(record.RGName),
SSHUser: types.StringValue(record.SSHUser),
Status: types.StringValue(record.Status),
TechStatus: types.StringValue(record.TechStatus),
UpdatedBy: types.StringValue(record.UpdatedBy),
UpdatedTime: types.Int64Value(int64(record.UpdatedTime)),
UserManaged: types.BoolValue(record.UserManaged),
}
// Handle groups as a list of strings
groupList := make([]types.Int64, len(record.Groups))
for i, group := range record.Groups {
groupList[i] = types.Int64Value(int64(group))
}
itemList = append(itemList, item)
}
// Update state with the flattened data
state.Data = itemList
state.EntryCount = types.Int64Value(int64(len(itemList)))
tflog.Info(ctx, "flattens.BServicesDeletedListDataSource: after flatten", map[string]any{"entry_count": state.EntryCount.ValueInt64()})
tflog.Info(ctx, "End flattens.BServicesDeletedListDataSource")
return nil
}

View File

@@ -0,0 +1,118 @@
package flattens
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/utilities"
)
// BServiceGroupDataSource flattens data source for a group.
// Return error in case data source is not found on the platform.
// Flatten errors are added to tflog.
func BServiceGroupDataSource(ctx context.Context, state *models.RecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "Start flattens.BServiceGroupDataSource")
diags := diag.Diagnostics{}
serviceId := uint64(state.ServiceID.ValueInt64())
record, err := utilities.BServiceGroupDataSourceCheckPresence(ctx, *state, c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about group with ID %v", serviceId), err.Error())
return diags
}
tflog.Info(ctx, "flattens.BServiceGroupDataSource: before flatten", map[string]any{"service_id": serviceId, "record": record})
*state = models.RecordGroupModel{
ServiceID: state.ServiceID,
ID: state.ID,
Timeouts: state.Timeouts,
AccountID: types.Int64Value(int64(record.AccountID)),
AccountName: types.StringValue(record.AccountName),
Consistency: types.BoolValue(record.Consistency),
CPU: types.Int64Value(int64(record.CPU)),
CreatedBy: types.StringValue(record.CreatedBy),
CreatedTime: types.Int64Value(int64(record.CreatedTime)),
DeletedBy: types.StringValue(record.DeletedBy),
DeletedTime: types.Int64Value(int64(record.DeletedTime)),
Disk: types.Int64Value(int64(record.Disk)),
Driver: types.StringValue(record.Driver),
GID: types.Int64Value(int64(record.GID)),
GUID: types.Int64Value(int64(record.GUID)),
ImageID: types.Int64Value(int64(record.ImageID)),
Milestones: types.Int64Value(int64(record.Milestones)),
Name: types.StringValue(record.Name),
RAM: types.Int64Value(int64(record.RAM)),
RGID: types.Int64Value(int64(record.RGID)),
RGName: types.StringValue(record.RGName),
Role: types.StringValue(record.Role),
SEPID: types.Int64Value(int64(record.SEPID)),
SeqNo: types.Int64Value(int64(record.SeqNo)),
Status: types.StringValue(record.Status),
TechStatus: types.StringValue(record.TechStatus),
TimeoutStart: types.Int64Value(int64(record.TimeoutStart)),
UpdatedBy: types.StringValue(record.UpdatedBy),
UpdatedTime: types.Int64Value(int64(record.UpdatedTime)),
}
// Handle computes
computesList := make([]models.ItemGroupComputeModel, 0, len(record.Computes))
for _, v := range record.Computes {
ipAddresses := make([]types.String, len(v.IPAddresses))
for i, ip := range v.IPAddresses {
ipAddresses[i] = types.StringValue(ip)
}
osUsers := make([]models.ItemOSUserModel, len(v.OSUsers))
for j, user := range v.OSUsers {
osUsers[j] = models.ItemOSUserModel{
Login: types.StringValue(user.Login),
Password: types.StringValue(user.Password),
}
}
temp := models.ItemGroupComputeModel{
ID: types.Int64Value(int64(v.ID)),
IPAddresses: flattens.FlattenSimpleTypeToList(ctx, types.StringType, ipAddresses),
Name: types.StringValue(v.Name),
OSUsers: osUsers,
}
computesList = append(computesList, temp)
}
state.Computes = computesList
// Handle ExtNets
extNetsList := make([]types.Int64, len(record.ExtNets))
for i, extNet := range record.ExtNets {
extNetsList[i] = types.Int64Value(int64(extNet))
}
state.ExtNets = flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, extNetsList)
// Handle Parents
parentsList := make([]types.Int64, len(record.Parents))
for i, parent := range record.Parents {
parentsList[i] = types.Int64Value(int64(parent))
}
state.Parents = flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, parentsList)
// Handle VINSes
vinsesList := make([]types.Int64, len(record.VINSes))
for i, vins := range record.VINSes {
vinsesList[i] = types.Int64Value(int64(vins))
}
state.VINSes = flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, vinsesList)
tflog.Info(ctx, "flattens.BServiceGroupDataSource: after flatten", map[string]any{"service_id": state.ID.ValueInt64()})
tflog.Info(ctx, "End flattens.BServiceGroupDataSource", map[string]any{"service_id": state.ID.ValueInt64()})
return nil
}

View File

@@ -0,0 +1,75 @@
package flattens
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/utilities"
)
// BServicesListDataSource flattens data source for a list of basic services.
// Return error in case data source is not found on the platform.
// Flatten errors are added to tflog.
func BServicesListDataSource(ctx context.Context, state *models.ListBasicServicesModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "Start flattens.BServicesListDataSource")
diags := diag.Diagnostics{}
// Fetch the list of basic services from the API
recordList, err := utilities.BServiceListDataSourceCheckPresence(ctx, *state, c)
if err != nil {
diags.AddError("Cannot get list of basic services", err.Error())
return diags
}
tflog.Info(ctx, "flattens.BServicesListDataSource: before flatten", map[string]any{"record_list": recordList})
// Flatten the fetched data into the state
var itemList []models.ItemBasicServiceModel
for _, record := range recordList.Data {
item := models.ItemBasicServiceModel{
AccountID: types.Int64Value(int64(record.AccountID)),
AccountName: types.StringValue(record.AccountName),
BaseDomain: types.StringValue(record.BaseDomain),
CreatedBy: types.StringValue(record.CreatedBy),
CreatedTime: types.Int64Value(int64(record.CreatedTime)),
DeletedBy: types.StringValue(record.DeletedBy),
DeletedTime: types.Int64Value(int64(record.DeletedTime)),
GID: types.Int64Value(int64(record.GID)),
GUID: types.Int64Value(int64(record.GUID)),
ID: types.Int64Value(int64(record.ID)),
Name: types.StringValue(record.Name),
ParentSrvID: types.Int64Value(int64(record.ParentSrvID)),
ParentSrvType: types.StringValue(record.ParentSrvType),
RGID: types.Int64Value(int64(record.RGID)),
RGName: types.StringValue(record.RGName),
SSHUser: types.StringValue(record.SSHUser),
Status: types.StringValue(record.Status),
TechStatus: types.StringValue(record.TechStatus),
UpdatedBy: types.StringValue(record.UpdatedBy),
UpdatedTime: types.Int64Value(int64(record.UpdatedTime)),
UserManaged: types.BoolValue(record.UserManaged),
}
// Handle groups as a list of strings
groupList := make([]types.Int64, len(record.Groups))
for i, group := range record.Groups {
groupList[i] = types.Int64Value(int64(group))
}
itemList = append(itemList, item)
}
// Update state with the flattened data
state.Data = itemList
state.EntryCount = types.Int64Value(int64(len(itemList)))
tflog.Info(ctx, "flattens.BServicesListDataSource: after flatten", map[string]any{"entry_count": state.EntryCount.ValueInt64()})
tflog.Info(ctx, "End flattens.BServicesListDataSource")
return nil
}

View File

@@ -0,0 +1,56 @@
package flattens
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/utilities"
)
// BServiceSnapshotListDataSource flattens data source for account.
// Return error in case data source is not found on the platform.
// Flatten errors are added to tflog.
func BServiceSnapshotListDataSource(ctx context.Context, state *models.ListInfoSnapshotsModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "Start flattens.BServiceSnapshotListDataSource")
diags := diag.Diagnostics{}
serivceId := uint64(state.ServiceID.ValueInt64())
record, err := utilities.BServiceSnapshotListDataSourceCheckPresence(ctx, serivceId, c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about bservice with ID %v", serivceId), err.Error())
return diags
}
tflog.Info(ctx, "flattens.BServiceSnapshotListDataSource: before flatten", map[string]any{"service_id": serivceId, "record": record})
*state = models.ListInfoSnapshotsModel{
ServiceID: state.ServiceID,
Timeouts: state.Timeouts,
EntryCount: types.Int64Value(int64(record.EntryCount)),
}
dataList := make([]models.ItemSnapshotsModel, 0, len(record.Data))
for _, v := range record.Data {
temp := models.ItemSnapshotsModel{
GUID: types.StringValue(v.GUID),
Label: types.StringValue(v.Label),
Timestamp: types.Int64Value(int64(v.Timestamp)),
Valid: types.BoolValue(v.Valid),
}
dataList = append(dataList, temp)
}
state.Data = dataList
tflog.Info(ctx, "flattens.BServiceSnapshotListDataSource: after flatten", map[string]any{"service_id": state.ServiceID.ValueInt64()})
tflog.Info(ctx, "End flattens.BServiceSnapshotListDataSource", map[string]any{"service_id": state.ServiceID.ValueInt64()})
return nil
}

View File

@@ -0,0 +1,144 @@
package flattens
import (
"context"
"fmt"
"strconv"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/utilities"
)
func BServiceResource(ctx context.Context, state *models.RecordBasicServiceResourceModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "Start flattens.BServiceResource")
diags := diag.Diagnostics{}
serviceId := uint64(state.ServiceId.ValueInt64())
if serviceId == 0 {
id, err := strconv.Atoi(state.ID.ValueString())
if err != nil {
diags.AddError(
"flattens.BServiceResource: cannot parse resource ID from state",
err.Error())
return diags
}
serviceId = uint64(id)
}
recordBService, err := utilities.BServiceResourceCheckPresence(ctx, serviceId, c)
if err != nil {
diags.AddError(fmt.Sprintf("flattens.BServiceResource: Cannot get info about resource with ID %v", serviceId), err.Error())
return diags
}
tflog.Info(ctx, "flattens.BServiceResource: before flatten", map[string]any{"service_id": serviceId, "recordBService": recordBService})
*state = models.RecordBasicServiceResourceModel{
Name: state.Name,
RGID: state.RGID,
Permanently: state.Permanently,
Enable: state.Enable,
Restore: state.Restore,
Start: state.Start,
Snapshots: state.Snapshots,
Timeouts: state.Timeouts,
SSHKey: types.StringValue(recordBService.SSHKey),
SSHUser: types.StringValue(recordBService.SSHUser),
ServiceId: types.Int64Value(int64(recordBService.ID)),
AccountID: types.Int64Value(int64(recordBService.AccountID)),
Computes: flattenComputes(ctx, recordBService.Computes),
Groups: flattenGroups(ctx, recordBService.Groups),
AccountName: types.StringValue(recordBService.Name),
BaseDomain: types.StringValue(recordBService.BaseDomain),
CPUTotal: types.Int64Value(int64(recordBService.CPUTotal)),
CreatedBy: types.StringValue(recordBService.CreatedBy),
CreatedTime: types.Int64Value(int64(recordBService.CreatedTime)),
DeletedBy: types.StringValue(recordBService.DeletedBy),
DeletedTime: types.Int64Value(int64(recordBService.DeletedTime)),
DiskTotal: types.Int64Value(int64(recordBService.DiskTotal)),
GID: types.Int64Value(int64(recordBService.GID)),
GUID: types.Int64Value(int64(recordBService.GUID)),
Milestones: types.Int64Value(int64(recordBService.Milestones)),
ParentSrvID: types.Int64Value(int64(recordBService.ParentSrvID)),
ParentSrvType: types.StringValue(recordBService.ParentSrvType),
RAMTotal: types.Int64Value(int64(recordBService.RAMTotal)),
RGName: types.StringValue(recordBService.RGName),
Status: types.StringValue(recordBService.Status),
TechStatus: types.StringValue(recordBService.TechStatus),
UpdatedBy: types.StringValue(recordBService.UpdatedBy),
UpdatedTime: types.Int64Value(int64(recordBService.UpdatedTime)),
UserManaged: types.BoolValue(recordBService.UserManaged),
ID: types.StringValue(strconv.Itoa(int(serviceId))),
}
tflog.Info(ctx, "flattens.BServiceResource: after flatten", map[string]any{"service_id": state.ID.ValueString()})
tflog.Info(ctx, "End flattens.BServiceResource", map[string]any{"service_id": state.ID.ValueString()})
return nil
}
func flattenComputes(ctx context.Context, items bservice.ListComputes) types.List {
tflog.Info(ctx, "Start flattenComputes")
tempSlice := make([]types.Object, 0, len(items))
for _, v := range items {
temp := models.ItemComputeResourceModel{
AccountID: types.Int64Value(int64(v.AccountID)),
Architecture: types.StringValue(v.Architecture),
CompGroupID: types.Int64Value(int64(v.CompGroupID)),
CompGroupName: types.StringValue(v.CompGroupName),
CompGroupRole: types.StringValue(v.CompGroupRole),
ID: types.Int64Value(int64(v.ID)),
Name: types.StringValue(v.Name),
RGID: types.Int64Value(int64(v.RGID)),
StackID: types.Int64Value(int64(v.StackID)),
Status: types.StringValue(v.Status),
TechStatus: types.StringValue(v.TechStatus),
}
obj, diags := types.ObjectValueFrom(ctx, models.ItemComputeResource, temp)
if diags != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenComputes struct to obj", diags))
}
tempSlice = append(tempSlice, obj)
}
res, diags := types.ListValueFrom(ctx, types.ObjectType{AttrTypes: models.ItemComputeResource}, tempSlice)
if diags != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenComputes", diags))
}
tflog.Info(ctx, "End flattenComputes")
return res
}
func flattenGroups(ctx context.Context, items bservice.ListGroups) types.List {
tflog.Info(ctx, "Start flattenGroups")
tempSlice := make([]types.Object, 0, len(items))
for _, v := range items {
temp := models.ItemGroupResourceModel{
Computes: types.Int64Value(int64(v.Computes)),
Consistency: types.BoolValue(v.Consistency),
ID: types.Int64Value(int64(v.ID)),
Name: types.StringValue(v.Name),
Status: types.StringValue(v.Status),
TechStatus: types.StringValue(v.TechStatus),
}
obj, diags := types.ObjectValueFrom(ctx, models.ItemGroupResource, temp)
if diags != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenGroups struct to obj", diags))
}
tempSlice = append(tempSlice, obj)
}
res, diags := types.ListValueFrom(ctx, types.ObjectType{AttrTypes: models.ItemGroupResource}, tempSlice)
if diags != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenGroups", diags))
}
tflog.Info(ctx, "End flattenGroups")
return res
}

View File

@@ -0,0 +1,151 @@
package flattens
import (
"context"
"fmt"
"strconv"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/utilities"
)
func BServiceGroupResource(ctx context.Context, plan *models.ResourceRecordGroupModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "Start BServiceGroupResource", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
diags := diag.Diagnostics{}
serviceID := plan.ServiceID.ValueInt64()
comgroupID := plan.CompgroupID.ValueInt64()
if serviceID == 0 {
id, err := strconv.Atoi(plan.SID.ValueString())
if err != nil {
diags.AddError(
"flattens.BServiceGroupResource: cannot parse resource ID from state",
err.Error())
return diags
}
serviceID = int64(id)
}
if comgroupID == 0 {
id, err := strconv.Atoi(plan.ID.ValueString())
if err != nil {
diags.AddError(
"flattens.BServiceGroupResource: cannot parse resource ID from state",
err.Error())
return diags
}
comgroupID = int64(id)
}
recordResourceGroup, err := utilities.BServiceGroupResourceCheckPresence(ctx, uint64(serviceID), uint64(comgroupID), c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about bservice group with service_id %d and compgroup_id %d", serviceID, comgroupID), err.Error())
return diags
}
*plan = models.ResourceRecordGroupModel{
ServiceID: plan.ServiceID,
CompCount: plan.CompCount,
Name: plan.Name,
CPU: plan.CPU,
RAM: plan.RAM,
Disk: plan.Disk,
ImageID: plan.ImageID,
Driver: plan.Driver,
SEPID: types.Int64Value(int64(recordResourceGroup.SEPID)),
SepPool: types.StringValue(recordResourceGroup.PoolName),
CloudInit: plan.CloudInit,
Role: types.StringValue(recordResourceGroup.Role),
TimeoutStart: types.Int64Value(int64(recordResourceGroup.TimeoutStart)),
VINSes: flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, recordResourceGroup.VINSes),
ExtNets: flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, recordResourceGroup.ExtNets),
Mode: plan.Mode,
Start: plan.Start,
ForceStop: plan.ForceStop,
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()))),
Timeouts: plan.Timeouts,
AccountID: types.Int64Value(int64(recordResourceGroup.AccountID)),
AccountName: types.StringValue(recordResourceGroup.AccountName),
Computes: flattenGroupComputes(ctx, recordResourceGroup.Computes),
Consistency: types.BoolValue(recordResourceGroup.Consistency),
CreatedBy: types.StringValue(recordResourceGroup.CreatedBy),
CreatedTime: types.Int64Value(int64(recordResourceGroup.CreatedTime)),
DeletedBy: types.StringValue(recordResourceGroup.DeletedBy),
DeletedTime: types.Int64Value(int64(recordResourceGroup.DeletedTime)),
GID: types.Int64Value(int64(recordResourceGroup.GID)),
GUID: types.Int64Value(int64(recordResourceGroup.GUID)),
Milestones: types.Int64Value(int64(recordResourceGroup.Milestones)),
RGID: types.Int64Value(int64(recordResourceGroup.RGID)),
RGName: types.StringValue(recordResourceGroup.RGName),
SeqNo: types.Int64Value(int64(recordResourceGroup.SeqNo)),
Status: types.StringValue(recordResourceGroup.Status),
TechStatus: types.StringValue(recordResourceGroup.TechStatus),
UpdatedBy: types.StringValue(recordResourceGroup.UpdatedBy),
UpdatedTime: types.Int64Value(int64(recordResourceGroup.UpdatedTime)),
}
tflog.Info(ctx, "End BServiceGroupResource", map[string]any{"service_id": plan.ServiceID.ValueInt64(), "compgroup_id": plan.CompgroupID.ValueInt64()})
return nil
}
func flattenGroupComputes(ctx context.Context, items bservice.ListGroupComputes) types.List {
tflog.Info(ctx, "Start flattenGroupComputes")
tempSlice := make([]types.Object, 0, len(items))
for _, v := range items {
temp := models.ResourceItemGroupComputeModel{
ID: types.Int64Value(int64(v.ID)),
Name: types.StringValue(v.Name),
IPAddresses: flattens.FlattenSimpleTypeToList(ctx, types.StringType, v.IPAddresses),
OSUsers: flattenOSuser(ctx, v.OSUsers),
}
obj, diags := types.ObjectValueFrom(ctx, models.ResourceItemGroupCompute, temp)
if diags != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenGroupComputes struct to obj", diags))
}
tempSlice = append(tempSlice, obj)
}
res, diags := types.ListValueFrom(ctx, types.ObjectType{AttrTypes: models.ResourceItemGroupCompute}, tempSlice)
if diags != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenGroupComputes", diags))
}
tflog.Info(ctx, "End flattenGroupComputes")
return res
}
func flattenOSuser(ctx context.Context, items bservice.ListOSUsers) types.List {
tflog.Info(ctx, "Start flattenOSuser")
tempSlice := make([]types.Object, 0, len(items))
for _, v := range items {
temp := models.ResourceItemOSUserModel{
Login: types.StringValue(v.Login),
Password: types.StringValue(v.Password),
}
obj, diags := types.ObjectValueFrom(ctx, models.ResourceItemOSUser, temp)
if diags != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenOSuser struct to obj", diags))
}
tempSlice = append(tempSlice, obj)
}
res, diags := types.ListValueFrom(ctx, types.ObjectType{AttrTypes: models.ResourceItemOSUser}, tempSlice)
if diags != nil {
tflog.Error(ctx, fmt.Sprint("Error flattenOSuser", diags))
}
tflog.Info(ctx, "End flattenOSuser")
return res
}

View File

@@ -0,0 +1,69 @@
package models
import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type RecordBasicServiceModel struct {
ServiceId types.Int64 `tfsdk:"service_id"`
AccountID types.Int64 `tfsdk:"account_id"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
AccountName types.String `tfsdk:"account_name"`
BaseDomain types.String `tfsdk:"base_domain"`
Computes []ItemComputeModel `tfsdk:"computes"`
CPUTotal types.Int64 `tfsdk:"cpu_total"`
CreatedBy types.String `tfsdk:"created_by"`
CreatedTime types.Int64 `tfsdk:"created_time"`
DeletedBy types.String `tfsdk:"deleted_by"`
DeletedTime types.Int64 `tfsdk:"deleted_time"`
DiskTotal types.Int64 `tfsdk:"disk_total"`
GID types.Int64 `tfsdk:"gid"`
Groups []ItemGroupModel `tfsdk:"groups"`
GUID types.Int64 `tfsdk:"guid"`
Milestones types.Int64 `tfsdk:"milestones"`
Name types.String `tfsdk:"service_name"`
ParentSrvID types.Int64 `tfsdk:"parent_srv_id"`
ParentSrvType types.String `tfsdk:"parent_srv_type"`
RAMTotal types.Int64 `tfsdk:"ram_total"`
RGID types.Int64 `tfsdk:"rg_id"`
RGName types.String `tfsdk:"rg_name"`
Snapshots []ItemSnapshotModel `tfsdk:"snapshots"`
SSHKey types.String `tfsdk:"ssh_key"`
SSHUser types.String `tfsdk:"ssh_user"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
UpdatedBy types.String `tfsdk:"updated_by"`
UpdatedTime types.Int64 `tfsdk:"updated_time"`
UserManaged types.Bool `tfsdk:"user_managed"`
}
type ItemComputeModel struct {
AccountID types.Int64 `tfsdk:"account_id"`
Architecture types.String `tfsdk:"architecture"`
CompGroupID types.Int64 `tfsdk:"compgroup_id"`
CompGroupName types.String `tfsdk:"compgroup_name"`
CompGroupRole types.String `tfsdk:"compgroup_role"`
ID types.Int64 `tfsdk:"id"`
Name types.String `tfsdk:"name"`
RGID types.Int64 `tfsdk:"rg_id"`
StackID types.Int64 `tfsdk:"stack_id"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
}
type ItemGroupModel struct {
Computes types.Int64 `tfsdk:"computes"`
Consistency types.Bool `tfsdk:"consistency"`
ID types.Int64 `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
}
type ItemSnapshotModel struct {
GUID types.String `tfsdk:"guid"`
Label types.String `tfsdk:"label"`
Timestamp types.Int64 `tfsdk:"timestamp"`
Valid types.Bool `tfsdk:"valid"`
}

View File

@@ -0,0 +1,45 @@
package models
import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type ListBasicServicesDelModel struct {
//optional fields
AccountID types.Int64 `tfsdk:"account_id"`
RGID types.Int64 `tfsdk:"rg_id"`
SortBy types.String `tfsdk:"sort_by"`
Page types.Int64 `tfsdk:"page"`
Size types.Int64 `tfsdk:"size"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
//computed fields
Data []ItemBasicServiceDelModel `tfsdk:"items"`
EntryCount types.Int64 `tfsdk:"entry_count"`
}
type ItemBasicServiceDelModel struct {
AccountID types.Int64 `tfsdk:"account_id"`
AccountName types.String `tfsdk:"account_name"`
BaseDomain types.String `tfsdk:"base_domain"`
CreatedBy types.String `tfsdk:"created_by"`
CreatedTime types.Int64 `tfsdk:"created_time"`
DeletedBy types.String `tfsdk:"deleted_by"`
DeletedTime types.Int64 `tfsdk:"deleted_time"`
GID types.Int64 `tfsdk:"gid"`
Groups []uint64 `tfsdk:"groups"`
GUID types.Int64 `tfsdk:"guid"`
ID types.Int64 `tfsdk:"service_id"`
Name types.String `tfsdk:"service_name"`
ParentSrvID types.Int64 `tfsdk:"parent_srv_id"`
ParentSrvType types.String `tfsdk:"parent_srv_type"`
RGID types.Int64 `tfsdk:"rg_id"`
RGName types.String `tfsdk:"rg_name"`
SSHUser types.String `tfsdk:"ssh_user"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
UpdatedBy types.String `tfsdk:"updated_by"`
UpdatedTime types.Int64 `tfsdk:"updated_time"`
UserManaged types.Bool `tfsdk:"user_managed"`
}

View File

@@ -0,0 +1,57 @@
package models
import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type RecordGroupModel struct {
//required and optional fields
ServiceID types.Int64 `tfsdk:"service_id"`
ID types.Int64 `tfsdk:"compgroup_id"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
//compute fields
AccountID types.Int64 `tfsdk:"account_id"`
AccountName types.String `tfsdk:"account_name"`
Computes []ItemGroupComputeModel `tfsdk:"computes"`
Consistency types.Bool `tfsdk:"consistency"`
CPU types.Int64 `tfsdk:"cpu"`
CreatedBy types.String `tfsdk:"created_by"`
CreatedTime types.Int64 `tfsdk:"created_time"`
DeletedBy types.String `tfsdk:"deleted_by"`
DeletedTime types.Int64 `tfsdk:"deleted_time"`
Disk types.Int64 `tfsdk:"disk"`
Driver types.String `tfsdk:"driver"`
ExtNets types.List `tfsdk:"extnets"`
GID types.Int64 `tfsdk:"gid"`
GUID types.Int64 `tfsdk:"guid"`
ImageID types.Int64 `tfsdk:"image_id"`
Milestones types.Int64 `tfsdk:"milestones"`
Name types.String `tfsdk:"compgroup_name"`
Parents types.List `tfsdk:"parents"`
RAM types.Int64 `tfsdk:"ram"`
RGID types.Int64 `tfsdk:"rg_id"`
RGName types.String `tfsdk:"rg_name"`
Role types.String `tfsdk:"role"`
SEPID types.Int64 `tfsdk:"sep_id"`
SeqNo types.Int64 `tfsdk:"seq_no"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
TimeoutStart types.Int64 `tfsdk:"timeout_start"`
UpdatedBy types.String `tfsdk:"updated_by"`
UpdatedTime types.Int64 `tfsdk:"updated_time"`
VINSes types.List `tfsdk:"vinses"`
}
type ItemGroupComputeModel struct {
ID types.Int64 `tfsdk:"id"`
IPAddresses types.List `tfsdk:"ip_addresses"`
Name types.String `tfsdk:"name"`
OSUsers []ItemOSUserModel `tfsdk:"os_users"`
}
type ItemOSUserModel struct {
Login types.String `tfsdk:"login"`
Password types.String `tfsdk:"password"`
}

View File

@@ -0,0 +1,48 @@
package models
import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type ListBasicServicesModel struct {
ByID types.Int64 `tfsdk:"by_id"`
Name types.String `tfsdk:"name"`
RGName types.String `tfsdk:"rg_name"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
AccountName types.String `tfsdk:"account_name"`
AccountID types.Int64 `tfsdk:"account_id"`
RGID types.Int64 `tfsdk:"rg_id"`
SortBy types.String `tfsdk:"sort_by"`
Page types.Int64 `tfsdk:"page"`
Size types.Int64 `tfsdk:"size"`
Data []ItemBasicServiceModel `tfsdk:"items"`
EntryCount types.Int64 `tfsdk:"entry_count"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
}
type ItemBasicServiceModel struct {
AccountID types.Int64 `tfsdk:"account_id"`
AccountName types.String `tfsdk:"account_name"`
BaseDomain types.String `tfsdk:"base_domain"`
CreatedBy types.String `tfsdk:"created_by"`
CreatedTime types.Int64 `tfsdk:"created_time"`
DeletedBy types.String `tfsdk:"deleted_by"`
DeletedTime types.Int64 `tfsdk:"deleted_time"`
GID types.Int64 `tfsdk:"gid"`
Groups []uint64 `tfsdk:"groups"`
GUID types.Int64 `tfsdk:"guid"`
ID types.Int64 `tfsdk:"service_id"`
Name types.String `tfsdk:"service_name"`
ParentSrvID types.Int64 `tfsdk:"parent_srv_id"`
ParentSrvType types.String `tfsdk:"parent_srv_type"`
RGID types.Int64 `tfsdk:"rg_id"`
RGName types.String `tfsdk:"rg_name"`
SSHUser types.String `tfsdk:"ssh_user"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
UpdatedBy types.String `tfsdk:"updated_by"`
UpdatedTime types.Int64 `tfsdk:"updated_time"`
UserManaged types.Bool `tfsdk:"user_managed"`
}

View File

@@ -0,0 +1,23 @@
package models
import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type ListInfoSnapshotsModel struct {
//required fields
ServiceID types.Int64 `tfsdk:"service_id"`
//computed fields
Data []ItemSnapshotsModel `tfsdk:"items"`
EntryCount types.Int64 `tfsdk:"entry_count"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
}
type ItemSnapshotsModel struct {
GUID types.String `tfsdk:"guid"`
Label types.String `tfsdk:"label"`
Timestamp types.Int64 `tfsdk:"timestamp"`
Valid types.Bool `tfsdk:"valid"`
}

View File

@@ -0,0 +1,112 @@
package models
import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type RecordBasicServiceResourceModel struct {
//required fields
Name types.String `tfsdk:"service_name"`
RGID types.Int64 `tfsdk:"rg_id"`
//optional fields
SSHKey types.String `tfsdk:"ssh_key"`
SSHUser types.String `tfsdk:"ssh_user"`
Permanently types.Bool `tfsdk:"permanently"`
Enable types.Bool `tfsdk:"enable"`
Restore types.Bool `tfsdk:"restore"`
Start types.Bool `tfsdk:"start"`
ServiceId types.Int64 `tfsdk:"service_id"`
Snapshots types.List `tfsdk:"snapshots"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
//computed fields
AccountID types.Int64 `tfsdk:"account_id"`
AccountName types.String `tfsdk:"account_name"`
BaseDomain types.String `tfsdk:"base_domain"`
Computes types.List `tfsdk:"computes"`
CPUTotal types.Int64 `tfsdk:"cpu_total"`
CreatedBy types.String `tfsdk:"created_by"`
CreatedTime types.Int64 `tfsdk:"created_time"`
DeletedBy types.String `tfsdk:"deleted_by"`
DeletedTime types.Int64 `tfsdk:"deleted_time"`
DiskTotal types.Int64 `tfsdk:"disk_total"`
GID types.Int64 `tfsdk:"gid"`
Groups types.List `tfsdk:"groups"`
GUID types.Int64 `tfsdk:"guid"`
Milestones types.Int64 `tfsdk:"milestones"`
ParentSrvID types.Int64 `tfsdk:"parent_srv_id"`
ParentSrvType types.String `tfsdk:"parent_srv_type"`
RAMTotal types.Int64 `tfsdk:"ram_total"`
RGName types.String `tfsdk:"rg_name"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
UpdatedBy types.String `tfsdk:"updated_by"`
UpdatedTime types.Int64 `tfsdk:"updated_time"`
UserManaged types.Bool `tfsdk:"user_managed"`
ID types.String `tfsdk:"id"`
}
type ItemComputeResourceModel struct {
AccountID types.Int64 `tfsdk:"account_id"`
Architecture types.String `tfsdk:"architecture"`
CompGroupID types.Int64 `tfsdk:"compgroup_id"`
CompGroupName types.String `tfsdk:"compgroup_name"`
CompGroupRole types.String `tfsdk:"compgroup_role"`
ID types.Int64 `tfsdk:"id"`
Name types.String `tfsdk:"name"`
RGID types.Int64 `tfsdk:"rg_id"`
StackID types.Int64 `tfsdk:"stack_id"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
}
var ItemComputeResource = map[string]attr.Type{
"account_id": types.Int64Type,
"architecture": types.StringType,
"compgroup_id": types.Int64Type,
"compgroup_name": types.StringType,
"compgroup_role": types.StringType,
"id": types.Int64Type,
"name": types.StringType,
"rg_id": types.Int64Type,
"stack_id": types.Int64Type,
"status": types.StringType,
"tech_status": types.StringType,
}
type ItemGroupResourceModel struct {
Computes types.Int64 `tfsdk:"computes"`
Consistency types.Bool `tfsdk:"consistency"`
ID types.Int64 `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
}
var ItemGroupResource = map[string]attr.Type{
"computes": types.Int64Type,
"consistency": types.BoolType,
"id": types.Int64Type,
"name": types.StringType,
"status": types.StringType,
"tech_status": types.StringType,
}
type ItemSnapshotResourceModel struct {
GUID types.String `tfsdk:"guid"`
Label types.String `tfsdk:"label"`
Rollback types.Bool `tfsdk:"rollback"`
Timestamp types.Int64 `tfsdk:"timestamp"`
Valid types.Bool `tfsdk:"valid"`
}
var ItemSnapshotResource = map[string]attr.Type{
"guid": types.StringType,
"label": types.StringType,
"rollback": types.BoolType,
"timestamp": types.Int64Type,
"valid": types.BoolType,
}

View File

@@ -0,0 +1,82 @@
package models
import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type ResourceRecordGroupModel struct {
//required fields
ServiceID types.Int64 `tfsdk:"service_id"`
CompCount types.Int64 `tfsdk:"comp_count"`
Name types.String `tfsdk:"compgroup_name"`
CPU types.Int64 `tfsdk:"cpu"`
RAM types.Int64 `tfsdk:"ram"`
Disk types.Int64 `tfsdk:"disk"`
ImageID types.Int64 `tfsdk:"image_id"`
Driver types.String `tfsdk:"driver"`
//optional fields
SEPID types.Int64 `tfsdk:"sep_id"`
SepPool types.String `tfsdk:"sep_pool"`
CloudInit types.String `tfsdk:"cloud_init"`
Role types.String `tfsdk:"role"`
TimeoutStart types.Int64 `tfsdk:"timeout_start"`
VINSes types.List `tfsdk:"vinses"`
ExtNets types.List `tfsdk:"extnets"`
Mode types.String `tfsdk:"mode"`
Start types.Bool `tfsdk:"start"`
ForceStop types.Bool `tfsdk:"force_stop"`
ForceUpdate types.Bool `tfsdk:"force_update"`
Parents types.List `tfsdk:"parents"`
RemoveComputes types.List `tfsdk:"remove_computes"`
CompgroupID types.Int64 `tfsdk:"compgroup_id"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
//compute fields
AccountID types.Int64 `tfsdk:"account_id"`
AccountName types.String `tfsdk:"account_name"`
Computes types.List `tfsdk:"computes"`
Consistency types.Bool `tfsdk:"consistency"`
CreatedBy types.String `tfsdk:"created_by"`
CreatedTime types.Int64 `tfsdk:"created_time"`
DeletedBy types.String `tfsdk:"deleted_by"`
DeletedTime types.Int64 `tfsdk:"deleted_time"`
GID types.Int64 `tfsdk:"gid"`
GUID types.Int64 `tfsdk:"guid"`
Milestones types.Int64 `tfsdk:"milestones"`
RGID types.Int64 `tfsdk:"rg_id"`
RGName types.String `tfsdk:"rg_name"`
SeqNo types.Int64 `tfsdk:"seq_no"`
Status types.String `tfsdk:"status"`
TechStatus types.String `tfsdk:"tech_status"`
UpdatedBy types.String `tfsdk:"updated_by"`
UpdatedTime types.Int64 `tfsdk:"updated_time"`
ID types.String `tfsdk:"id"`
SID types.String `tfsdk:"sid"`
}
type ResourceItemGroupComputeModel struct {
ID types.Int64 `tfsdk:"id"`
IPAddresses types.List `tfsdk:"ip_addresses"`
Name types.String `tfsdk:"name"`
OSUsers types.List `tfsdk:"os_users"`
}
var ResourceItemGroupCompute = map[string]attr.Type{
"id": types.Int64Type,
"ip_addresses": types.ListType{ElemType: types.StringType},
"name": types.StringType,
"os_users": types.ListType{ElemType: types.ObjectType{AttrTypes: ResourceItemOSUser}},
}
type ResourceItemOSUserModel struct {
Login types.String `tfsdk:"login"`
Password types.String `tfsdk:"password"`
}
var ResourceItemOSUser = map[string]attr.Type{
"login": types.StringType,
"password": types.StringType,
}

View File

@@ -0,0 +1,316 @@
package bservice
import (
"context"
"strconv"
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/schemas"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/utilities"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ resource.Resource = &resourceBService{}
_ resource.ResourceWithImportState = &resourceBService{}
)
// NewresourceBService is a helper function to simplify the provider implementation.
func NewResourceBService() resource.Resource {
return &resourceBService{}
}
// resourceBService is the resource implementation.
type resourceBService struct {
client *decort.DecortClient
}
// Create creates the resource and sets the initial Terraform state.
func (r *resourceBService) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
// Get plan to create resource group
var plan models.RecordBasicServiceResourceModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Create resourceBService: Error receiving the plan")
return
}
contextCreateMap := map[string]any{
"name": plan.Name.ValueString(),
"rg_id": plan.RGID.ValueInt64(),
}
tflog.Info(ctx, "Create resourceBService: got plan successfully", contextCreateMap)
tflog.Info(ctx, "Create resourceBService: start creating", contextCreateMap)
// Set timeouts
createTimeout, diags := plan.Timeouts.Create(ctx, constants.Timeout600s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Create resourceBService: Error set timeout")
return
}
tflog.Info(ctx, "Create resourceBService: set timeouts successfully", map[string]any{
"name": plan.Name.ValueString(),
"rg_id": plan.RGID.ValueInt64(),
"createTimeout": createTimeout})
ctx, cancel := context.WithTimeout(ctx, createTimeout)
defer cancel()
// Make create request and get response
id, diags := utilities.BServiceResourceCreate(ctx, &plan, r.client)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
plan.ID = types.StringValue(strconv.Itoa(int(*id)))
tflog.Info(ctx, "BServiceResourceCreatee: 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
}
// Map response body to schema and populate Computed attribute values
resp.Diagnostics.Append(flattens.BServiceResource(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
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() {
return
}
}
// Read refreshes the Terraform state with the latest data.
func (r *resourceBService) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
// Get current state
var state models.RecordBasicServiceResourceModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceBService: Error get state")
return
}
tflog.Info(ctx, "Read resourceBService: got state successfully", map[string]any{"service_id": state.ID.ValueString()})
// Set timeouts
readTimeout, diags := state.Timeouts.Read(ctx, constants.Timeout300s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceBService: Error set timeout")
return
}
tflog.Info(ctx, "Read resourceBService: set timeouts successfully", map[string]any{
"service_id": state.ID.ValueString(),
"readTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// read status
resp.Diagnostics.Append(utilities.BSerivceReadStatus(ctx, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceBService: Error reading status")
return
}
// Overwrite items with refreshed state
resp.Diagnostics.Append(flattens.BServiceResource(ctx, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceBService: Error flatten")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceBService: Error set state")
return
}
tflog.Info(ctx, "End read resourceBService")
}
// Update updates the resource and sets the updated Terraform state on success.
func (r *resourceBService) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
// Retrieve values from plan
var plan models.RecordBasicServiceResourceModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBService: Error receiving the plan")
return
}
logMap := map[string]any{"service_id": plan.ID.ValueString()}
tflog.Info(ctx, "Update resourceBService: got plan successfully", logMap)
// Retrieve values from state
var state models.RecordBasicServiceResourceModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBService: Error receiving the state")
return
}
tflog.Info(ctx, "Update resourceBService: got state successfully", logMap)
// Set timeouts
updateTimeout, diags := plan.Timeouts.Update(ctx, constants.Timeout300s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBService: Error set timeout")
return
}
tflog.Info(ctx, "Update resourceBService: set timeouts successfully", map[string]any{
"service_id": state.ID.ValueString(),
"updateTimeout": updateTimeout})
ctx, cancel := context.WithTimeout(ctx, updateTimeout)
defer cancel()
_, err := strconv.Atoi(state.ID.ValueString())
if err != nil {
resp.Diagnostics.AddError("Update resourceBService: Cannot parse ID from state", err.Error())
return
}
// enable/disable bservice
if !plan.Enable.Equal(state.Enable) && !plan.Enable.IsNull() {
resp.Diagnostics.Append(utilities.EnableDisableBService(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBService: Error enabling/disabling bservice")
return
}
}
// start/stop bservice
if !plan.Start.Equal(state.Start) && !plan.Start.IsNull() {
resp.Diagnostics.Append(utilities.StartStopBService(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBService: Error start/stop bservice")
return
}
}
// 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)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBService: Error snapshosts bservice")
return
}
}
tflog.Info(ctx, "Update resourceBService: bservice update is completed", logMap)
// Map response body to schema and populate Computed attribute values
resp.Diagnostics.Append(flattens.BServiceResource(ctx, &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() {
return
}
}
// Delete deletes the resource and removes the Terraform state on success.
func (r *resourceBService) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
// Get current state
var state models.RecordBasicServiceResourceModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Delete resourceBService: Error get state")
return
}
tflog.Info(ctx, "Delete resourceBService: got state successfully", map[string]any{"serice_id": state.ID.ValueString()})
// Set timeouts
deleteTimeout, diags := state.Timeouts.Delete(ctx, constants.Timeout300s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Delete resourceBService: Error set timeout")
return
}
tflog.Info(ctx, "Delete resourceBService: set timeouts successfully", map[string]any{
"service_id": state.ID.ValueString(),
"deleteTimeout": deleteTimeout})
ctx, cancel := context.WithTimeout(ctx, deleteTimeout)
defer cancel()
permanently := state.Permanently.ValueBool()
if state.Permanently.IsNull() {
permanently = true
} // default true
// Delete existing resource group
delReq := bservice.DeleteRequest{
ServiceID: uint64(state.ServiceId.ValueInt64()),
Permanently: permanently,
}
tflog.Info(ctx, "Delete resourceBService: before call CloudAPI().BService().Delete", map[string]any{"req": delReq})
_, err := r.client.CloudAPI().BService().Delete(ctx, delReq)
if err != nil {
resp.Diagnostics.AddError("Delete resourceBService: Error deleting BService with error: ", err.Error())
return
}
tflog.Info(ctx, "End delete resourceBService", map[string]any{"service_id": state.ID.ValueString()})
}
// Schema defines the schema for the resource.
func (r *resourceBService) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaResourceBService(),
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx, timeouts.Opts{Create: true, Read: true, Update: true, Delete: true}),
},
}
}
// Metadata returns the resource type name.
func (r *resourceBService) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_bservice"
}
// Configure adds the provider configured client to the resource.
func (r *resourceBService) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
tflog.Info(ctx, "Get Configure resourceBService")
r.client = client.Resource(ctx, &req, resp)
tflog.Info(ctx, "Getting Configure resourceBService successfully")
}
func (r *resourceBService) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
// Retrieve import ID and save to id attribute
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
}

View File

@@ -0,0 +1,347 @@
package bservice
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/schemas"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/utilities"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ resource.Resource = &resourceBServiceGroup{}
_ resource.ResourceWithImportState = &resourceBServiceGroup{}
)
// NewResourceBServiceGroup is a helper function to simplify the provider implementation.
func NewResourceBServiceGroup() resource.Resource {
return &resourceBServiceGroup{}
}
// resourceBServiceGroup is the resource implementation.
type resourceBServiceGroup struct {
client *decort.DecortClient
}
// Create creates the resource and sets the initial Terraform state.
func (r *resourceBServiceGroup) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
// Get plan to create resource group
var plan models.ResourceRecordGroupModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Create resourceBServiceGroup: Error receiving the plan")
return
}
contextCreateMap := map[string]any{
"service_id": plan.ServiceID.ValueInt64(),
"compgroup_id": plan.CompgroupID.ValueInt64(),
}
tflog.Info(ctx, "Create resourceBServiceGroup: got plan successfully", contextCreateMap)
tflog.Info(ctx, "Create resourceBServiceGroup: start creating", contextCreateMap)
// Set timeouts
createTimeout, diags := plan.Timeouts.Create(ctx, constants.Timeout600s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Create resourceBServiceGroup: Error set timeout")
return
}
tflog.Info(ctx, "Create resourceBServiceGroup: set timeouts successfully", map[string]any{
"service_id": plan.ServiceID.ValueInt64(),
"compgroup_id": plan.CompgroupID.ValueInt64(),
"createTimeout": createTimeout})
ctx, cancel := context.WithTimeout(ctx, createTimeout)
defer cancel()
// 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, "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
}
// 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() {
return
}
}
// Read refreshes the Terraform state with the latest data.
func (r *resourceBServiceGroup) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
// Get current state
var state models.ResourceRecordGroupModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceBServiceGroup: Error get state")
return
}
tflog.Info(ctx, "Read resourceBServiceGroup: got state successfully", map[string]any{"service_id": state.ID.ValueString()})
// Set timeouts
readTimeout, diags := state.Timeouts.Read(ctx, constants.Timeout300s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceBServiceGroup: Error set timeout")
return
}
tflog.Info(ctx, "Read resourceBServiceGroup: set timeouts successfully", map[string]any{
"service_id": state.ID.ValueString(),
"readTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// read status
resp.Diagnostics.Append(utilities.BServiceGroupReadStatus(ctx, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceBServiceGroup: Error reading status")
return
}
// Overwrite items with refreshed state
resp.Diagnostics.Append(flattens.BServiceGroupResource(ctx, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceBServiceGroup: Error flatten")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceBServiceGroup: Error set state")
return
}
tflog.Info(ctx, "End read resourceBServiceGroup")
}
// Update updates the resource and sets the updated Terraform state on success.
func (r *resourceBServiceGroup) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
// Retrieve values from plan
var plan models.ResourceRecordGroupModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error receiving the plan")
return
}
logMap := map[string]any{"service_id": plan.ID.ValueString()}
tflog.Info(ctx, "Update resourceBServiceGroup: got plan successfully", logMap)
// Retrieve values from state
var state models.ResourceRecordGroupModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error receiving the state")
return
}
tflog.Info(ctx, "Update resourceBServiceGroup: got state successfully", logMap)
// Set timeouts
updateTimeout, diags := plan.Timeouts.Update(ctx, constants.Timeout300s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error set timeout")
return
}
tflog.Info(ctx, "Update resourceBServiceGroup: set timeouts successfully", map[string]any{
"service_id": state.ID.ValueString(),
"updateTimeout": updateTimeout})
ctx, cancel := context.WithTimeout(ctx, updateTimeout)
defer cancel()
_, err := strconv.Atoi(state.ID.ValueString())
if err != nil {
resp.Diagnostics.AddError("Update resourceBServiceGroup: Cannot parse ID from state", err.Error())
return
}
if !plan.CompCount.Equal(state.CompCount) && !plan.CompCount.IsNull() {
resp.Diagnostics.Append(utilities.BServiceGroupResize(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error enabling/disabling bservice")
return
}
}
if !plan.Start.Equal(state.Start) && !plan.Start.IsNull() {
resp.Diagnostics.Append(utilities.BServiceGroupStartStop(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error start/stop bservice")
return
}
}
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) {
resp.Diagnostics.Append(utilities.BServiceGroupUpdate(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error update bservice group")
return
}
}
if !plan.ExtNets.Equal(state.ExtNets) && !plan.ExtNets.IsNull() {
resp.Diagnostics.Append(utilities.BServiceGroupExtNet(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error update extnets bservice")
return
}
}
if !plan.VINSes.Equal(state.VINSes) && !plan.VINSes.IsNull() {
resp.Diagnostics.Append(utilities.BServiceGroupVinses(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error update vinses bservice")
return
}
}
if !plan.Parents.Equal(state.Parents) && !plan.Parents.IsNull() {
resp.Diagnostics.Append(utilities.BServiceGroupParents(ctx, plan.Parents, state.Parents, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error update parents bservice")
return
}
}
if !plan.RemoveComputes.Equal(state.RemoveComputes) && !plan.RemoveComputes.IsNull() {
resp.Diagnostics.Append(utilities.BServiceGroupRemoveComputes(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceBServiceGroup: Error remove computes bservice")
return
}
}
tflog.Info(ctx, "Update resourceBServiceGroup: bservice update is completed", logMap)
// Map response body to schema and populate Computed attribute values
resp.Diagnostics.Append(flattens.BServiceGroupResource(ctx, &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() {
return
}
}
// Delete deletes the resource and removes the Terraform state on success.
func (r *resourceBServiceGroup) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
// Get current state
var state models.ResourceRecordGroupModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Delete resourceBServiceGroup: Error get state")
return
}
tflog.Info(ctx, "Delete resourceBServiceGroup: got state successfully", map[string]any{"serice_id": state.ID.ValueString()})
// Set timeouts
deleteTimeout, diags := state.Timeouts.Delete(ctx, constants.Timeout300s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Delete resourceBServiceGroup: Error set timeout")
return
}
tflog.Info(ctx, "Delete resourceBServiceGroup: set timeouts successfully", map[string]any{
"service_id": state.ID.ValueString(),
"deleteTimeout": deleteTimeout})
ctx, cancel := context.WithTimeout(ctx, deleteTimeout)
defer cancel()
// Delete existing resource group
delReq := bservice.GroupRemoveRequest{
ServiceID: uint64(state.ServiceID.ValueInt64()),
CompGroupID: uint64(state.CompgroupID.ValueInt64()),
}
tflog.Info(ctx, "Delete resourceBServiceGroup: before call CloudAPI().BService().GroupRemove", map[string]any{"req": delReq})
_, err := r.client.CloudAPI().BService().GroupRemove(ctx, delReq)
if err != nil {
resp.Diagnostics.AddError("Delete resourceBServiceGroup: Error deleting BService group with error: ", err.Error())
return
}
tflog.Info(ctx, "End delete resourceBServiceGroup", map[string]any{"service_id": state.ID.ValueString()})
}
// Schema defines the schema for the resource.
func (r *resourceBServiceGroup) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaResourceBServiceGroup(),
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx, timeouts.Opts{Create: true, Read: true, Update: true, Delete: true}),
},
}
}
// Metadata returns the resource type name.
func (r *resourceBServiceGroup) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_bservice_group"
}
// Configure adds the provider configured client to the resource.
func (r *resourceBServiceGroup) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
tflog.Info(ctx, "Get Configure resourceBServiceGroup")
r.client = client.Resource(ctx, &req, resp)
tflog.Info(ctx, "Getting Configure resourceBServiceGroup successfully")
}
func (r *resourceBServiceGroup) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
idParts := strings.Split(req.ID, ",")
if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
resp.Diagnostics.AddError(
"Unexpected Import Identifier",
fmt.Sprintf("Expected import identifier with format: service_id,compgroup_name. Got: %q", req.ID),
)
return
}
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("sid"), idParts[0])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), idParts[1])...)
}

View File

@@ -0,0 +1,172 @@
package schemas
import (
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
)
func MakeSchemaDataSourceBService() map[string]schema.Attribute {
return map[string]schema.Attribute{
"service_id": schema.Int64Attribute{
Required: true,
},
"account_id": schema.Int64Attribute{
Computed: true,
},
"account_name": schema.StringAttribute{
Computed: true,
},
"base_domain": schema.StringAttribute{
Computed: true,
},
"computes": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"account_id": schema.Int64Attribute{
Computed: true,
},
"architecture": schema.StringAttribute{
Computed: true,
},
"compgroup_id": schema.Int64Attribute{
Computed: true,
},
"compgroup_name": schema.StringAttribute{
Computed: true,
},
"compgroup_role": schema.StringAttribute{
Computed: true,
},
"id": schema.Int64Attribute{
Computed: true,
},
"rg_id": schema.Int64Attribute{
Computed: true,
},
"stack_id": schema.Int64Attribute{
Computed: true,
},
"name": schema.StringAttribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"tech_status": schema.StringAttribute{
Computed: true,
},
},
},
},
"cpu_total": schema.Int64Attribute{
Computed: true,
},
"created_by": schema.StringAttribute{
Computed: true,
},
"created_time": schema.Int64Attribute{
Computed: true,
},
"deleted_by": schema.StringAttribute{
Computed: true,
},
"deleted_time": schema.Int64Attribute{
Computed: true,
},
"disk_total": schema.Int64Attribute{
Computed: true,
},
"gid": schema.Int64Attribute{
Computed: true,
},
"groups": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"computes": schema.Int64Attribute{
Computed: true,
},
"consistency": schema.BoolAttribute{
Computed: true,
},
"id": schema.Int64Attribute{
Computed: true,
},
"name": schema.StringAttribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"tech_status": schema.StringAttribute{
Computed: true,
},
},
},
},
"guid": schema.Int64Attribute{
Computed: true,
},
"milestones": schema.Int64Attribute{
Computed: true,
},
"service_name": schema.StringAttribute{
Computed: true,
},
"parent_srv_id": schema.Int64Attribute{
Computed: true,
},
"parent_srv_type": schema.StringAttribute{
Computed: true,
},
"ram_total": schema.Int64Attribute{
Computed: true,
},
"rg_id": schema.Int64Attribute{
Computed: true,
},
"rg_name": schema.StringAttribute{
Computed: true,
},
"snapshots": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"guid": schema.StringAttribute{
Computed: true,
},
"label": schema.StringAttribute{
Computed: true,
},
"timestamp": schema.Int64Attribute{
Computed: true,
},
"valid": schema.BoolAttribute{
Computed: true,
},
},
},
},
"ssh_key": schema.StringAttribute{
Computed: true,
},
"ssh_user": schema.StringAttribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"tech_status": schema.StringAttribute{
Computed: true,
},
"updated_by": schema.StringAttribute{
Computed: true,
},
"updated_time": schema.Int64Attribute{
Computed: true,
},
"user_managed": schema.BoolAttribute{
Computed: true,
},
}
}

View File

@@ -0,0 +1,103 @@
package schemas
import (
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
func MakeSchemaDataSourceBServiceDeletedList() map[string]schema.Attribute {
return map[string]schema.Attribute{
"account_id": schema.Int64Attribute{
Optional: true,
},
"rg_id": schema.Int64Attribute{
Optional: true,
},
"sort_by": schema.StringAttribute{
Optional: true,
},
"page": schema.Int64Attribute{
Optional: true,
},
"size": schema.Int64Attribute{
Optional: true,
},
"items": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"account_id": schema.Int64Attribute{
Computed: true,
},
"account_name": schema.StringAttribute{
Computed: true,
},
"base_domain": schema.StringAttribute{
Computed: true,
},
"created_by": schema.StringAttribute{
Computed: true,
},
"created_time": schema.Int64Attribute{
Computed: true,
},
"deleted_by": schema.StringAttribute{
Computed: true,
},
"deleted_time": schema.Int64Attribute{
Computed: true,
},
"gid": schema.Int64Attribute{
Computed: true,
},
"groups": schema.ListAttribute{
Computed: true,
ElementType: types.Int64Type,
},
"guid": schema.Int64Attribute{
Computed: true,
},
"service_id": schema.Int64Attribute{
Computed: true,
},
"service_name": schema.StringAttribute{
Computed: true,
},
"parent_srv_id": schema.Int64Attribute{
Computed: true,
},
"parent_srv_type": schema.StringAttribute{
Computed: true,
},
"rg_id": schema.Int64Attribute{
Computed: true,
},
"rg_name": schema.StringAttribute{
Computed: true,
},
"ssh_user": schema.StringAttribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"tech_status": schema.StringAttribute{
Computed: true,
},
"updated_by": schema.StringAttribute{
Computed: true,
},
"updated_time": schema.Int64Attribute{
Computed: true,
},
"user_managed": schema.BoolAttribute{
Computed: true,
},
},
},
},
"entry_count": schema.Int64Attribute{
Computed: true,
},
}
}

View File

@@ -0,0 +1,137 @@
package schemas
import (
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
func MakeSchemaDataSourceBServiceGroup() map[string]schema.Attribute {
return map[string]schema.Attribute{
"service_id": schema.Int64Attribute{
Required: true,
},
"compgroup_id": schema.Int64Attribute{
Required: true,
},
"account_id": schema.Int64Attribute{
Computed: true,
},
"account_name": schema.StringAttribute{
Computed: true,
},
"computes": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"id": schema.Int64Attribute{
Computed: true,
},
"ip_addresses": schema.ListAttribute{
Computed: true,
ElementType: types.StringType,
},
"name": schema.StringAttribute{
Computed: true,
},
"os_users": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"login": schema.StringAttribute{
Computed: true,
},
"password": schema.StringAttribute{
Computed: true,
},
},
},
},
},
},
},
"consistency": schema.BoolAttribute{
Computed: true,
},
"cpu": schema.Int64Attribute{
Computed: true,
},
"created_by": schema.StringAttribute{
Computed: true,
},
"created_time": schema.Int64Attribute{
Computed: true,
},
"deleted_by": schema.StringAttribute{
Computed: true,
},
"deleted_time": schema.Int64Attribute{
Computed: true,
},
"disk": schema.Int64Attribute{
Computed: true,
},
"driver": schema.StringAttribute{
Computed: true,
},
"extnets": schema.ListAttribute{
Computed: true,
ElementType: types.Int64Type,
},
"gid": schema.Int64Attribute{
Computed: true,
},
"guid": schema.Int64Attribute{
Computed: true,
},
"image_id": schema.Int64Attribute{
Computed: true,
},
"milestones": schema.Int64Attribute{
Computed: true,
},
"compgroup_name": schema.StringAttribute{
Computed: true,
},
"parents": schema.ListAttribute{
Computed: true,
ElementType: types.Int64Type,
},
"ram": schema.Int64Attribute{
Computed: true,
},
"rg_id": schema.Int64Attribute{
Computed: true,
},
"rg_name": schema.StringAttribute{
Computed: true,
},
"role": schema.StringAttribute{
Computed: true,
},
"sep_id": schema.Int64Attribute{
Computed: true,
},
"seq_no": schema.Int64Attribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"tech_status": schema.StringAttribute{
Computed: true,
},
"timeout_start": schema.Int64Attribute{
Computed: true,
},
"updated_by": schema.StringAttribute{
Computed: true,
},
"updated_time": schema.Int64Attribute{
Computed: true,
},
"vinses": schema.ListAttribute{
Computed: true,
ElementType: types.Int64Type,
},
}
}

View File

@@ -0,0 +1,121 @@
package schemas
import (
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
func MakeSchemaDataSourceBServiceList() map[string]schema.Attribute {
return map[string]schema.Attribute{
"by_id": schema.Int64Attribute{
Optional: true,
},
"name": schema.StringAttribute{
Optional: true,
},
"rg_name": schema.StringAttribute{
Optional: true,
},
"status": schema.StringAttribute{
Optional: true,
},
"tech_status": schema.StringAttribute{
Optional: true,
},
"account_name": schema.StringAttribute{
Optional: true,
},
"account_id": schema.Int64Attribute{
Optional: true,
},
"rg_id": schema.Int64Attribute{
Optional: true,
},
"sort_by": schema.StringAttribute{
Optional: true,
},
"page": schema.Int64Attribute{
Optional: true,
},
"size": schema.Int64Attribute{
Optional: true,
},
"items": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"account_id": schema.Int64Attribute{
Computed: true,
},
"account_name": schema.StringAttribute{
Computed: true,
},
"base_domain": schema.StringAttribute{
Computed: true,
},
"created_by": schema.StringAttribute{
Computed: true,
},
"created_time": schema.Int64Attribute{
Computed: true,
},
"deleted_by": schema.StringAttribute{
Computed: true,
},
"deleted_time": schema.Int64Attribute{
Computed: true,
},
"gid": schema.Int64Attribute{
Computed: true,
},
"groups": schema.ListAttribute{
Computed: true,
ElementType: types.Int64Type,
},
"guid": schema.Int64Attribute{
Computed: true,
},
"service_id": schema.Int64Attribute{
Computed: true,
},
"service_name": schema.StringAttribute{
Computed: true,
},
"parent_srv_id": schema.Int64Attribute{
Computed: true,
},
"parent_srv_type": schema.StringAttribute{
Computed: true,
},
"rg_id": schema.Int64Attribute{
Computed: true,
},
"rg_name": schema.StringAttribute{
Computed: true,
},
"ssh_user": schema.StringAttribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"tech_status": schema.StringAttribute{
Computed: true,
},
"updated_by": schema.StringAttribute{
Computed: true,
},
"updated_time": schema.Int64Attribute{
Computed: true,
},
"user_managed": schema.BoolAttribute{
Computed: true,
},
},
},
},
"entry_count": schema.Int64Attribute{
Computed: true,
},
}
}

View File

@@ -0,0 +1,35 @@
package schemas
import (
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
)
func MakeSchemaDataSourceBServiceSnapshotList() map[string]schema.Attribute {
return map[string]schema.Attribute{
"service_id": schema.Int64Attribute{
Required: true,
},
"items": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"guid": schema.StringAttribute{
Computed: true,
},
"label": schema.StringAttribute{
Computed: true,
},
"timestamp": schema.Int64Attribute{
Computed: true,
},
"valid": schema.BoolAttribute{
Computed: true,
},
},
},
},
"entry_count": schema.Int64Attribute{
Computed: true,
},
}
}

View File

@@ -0,0 +1,199 @@
package schemas
import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
)
func MakeSchemaResourceBService() map[string]schema.Attribute {
return map[string]schema.Attribute{
"service_name": schema.StringAttribute{
Required: true,
},
"rg_id": schema.Int64Attribute{
Required: true,
},
"ssh_key": schema.StringAttribute{
Optional: true,
Computed: true,
},
"ssh_user": schema.StringAttribute{
Optional: true,
Computed: true,
},
"permanently": schema.BoolAttribute{
Optional: true,
},
"enable": schema.BoolAttribute{
Optional: true,
},
"restore": schema.BoolAttribute{
Optional: true,
},
"start": schema.BoolAttribute{
Optional: true,
},
"service_id": schema.Int64Attribute{
Optional: true,
Computed: true,
},
"snapshots": schema.ListNestedAttribute{
Optional: true,
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"guid": schema.StringAttribute{
Computed: true,
},
"label": schema.StringAttribute{
Computed: true,
},
"rollback": schema.BoolAttribute{
Optional: true,
},
"timestamp": schema.Int64Attribute{
Computed: true,
},
"valid": schema.BoolAttribute{
Computed: true,
},
},
},
},
"account_id": schema.Int64Attribute{
Computed: true,
},
"account_name": schema.StringAttribute{
Computed: true,
},
"base_domain": schema.StringAttribute{
Computed: true,
},
"computes": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"account_id": schema.Int64Attribute{
Computed: true,
},
"architecture": schema.StringAttribute{
Computed: true,
},
"compgroup_id": schema.Int64Attribute{
Computed: true,
},
"compgroup_name": schema.StringAttribute{
Computed: true,
},
"compgroup_role": schema.StringAttribute{
Computed: true,
},
"id": schema.Int64Attribute{
Computed: true,
},
"rg_id": schema.Int64Attribute{
Computed: true,
},
"stack_id": schema.Int64Attribute{
Computed: true,
},
"name": schema.StringAttribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"tech_status": schema.StringAttribute{
Computed: true,
},
},
},
},
"cpu_total": schema.Int64Attribute{
Computed: true,
},
"created_by": schema.StringAttribute{
Computed: true,
},
"created_time": schema.Int64Attribute{
Computed: true,
},
"deleted_by": schema.StringAttribute{
Computed: true,
},
"deleted_time": schema.Int64Attribute{
Computed: true,
},
"disk_total": schema.Int64Attribute{
Computed: true,
},
"gid": schema.Int64Attribute{
Computed: true,
},
"groups": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"computes": schema.Int64Attribute{
Computed: true,
},
"consistency": schema.BoolAttribute{
Computed: true,
},
"id": schema.Int64Attribute{
Computed: true,
},
"name": schema.StringAttribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"tech_status": schema.StringAttribute{
Computed: true,
},
},
},
},
"guid": schema.Int64Attribute{
Computed: true,
},
"milestones": schema.Int64Attribute{
Computed: true,
},
"parent_srv_id": schema.Int64Attribute{
Computed: true,
},
"parent_srv_type": schema.StringAttribute{
Computed: true,
},
"ram_total": schema.Int64Attribute{
Computed: true,
},
"rg_name": schema.StringAttribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"tech_status": schema.StringAttribute{
Computed: true,
},
"updated_by": schema.StringAttribute{
Computed: true,
},
"updated_time": schema.Int64Attribute{
Computed: true,
},
"user_managed": schema.BoolAttribute{
Computed: true,
},
"id": schema.StringAttribute{
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
}
}

View File

@@ -0,0 +1,196 @@
package schemas
import (
"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/validate"
)
func MakeSchemaResourceBServiceGroup() map[string]schema.Attribute {
return map[string]schema.Attribute{
"service_id": schema.Int64Attribute{
Required: true,
},
"compgroup_name": schema.StringAttribute{
Required: true,
},
"comp_count": schema.Int64Attribute{
Required: true,
},
"cpu": schema.Int64Attribute{
Required: true,
},
"ram": schema.Int64Attribute{
Required: true,
Validators: []validator.Int64{
validate.DivisibleBy(constants.DivisibleByRAM),
int64validator.AtLeast(constants.MinRamPerCompute),
},
},
"disk": schema.Int64Attribute{
Required: true,
},
"image_id": schema.Int64Attribute{
Required: true,
},
"driver": schema.StringAttribute{
Required: true,
},
"sep_id": schema.Int64Attribute{
Optional: true,
Computed: true,
},
"sep_pool": schema.StringAttribute{
Optional: true,
Computed: true,
},
"cloud_init": schema.StringAttribute{
Optional: true,
},
"role": schema.StringAttribute{
Optional: true,
Computed: true,
},
"timeout_start": schema.Int64Attribute{
Optional: true,
Computed: true,
},
"extnets": schema.ListAttribute{
Optional: true,
Computed: true,
ElementType: types.Int64Type,
},
"vinses": schema.ListAttribute{
Optional: true,
Computed: true,
ElementType: types.Int64Type,
},
"mode": schema.StringAttribute{
Optional: true,
Validators: []validator.String{
stringvalidator.OneOf("RELATIVE", "ABSOLUTE"),
},
},
"start": schema.BoolAttribute{
Optional: true,
},
"force_stop": schema.BoolAttribute{
Optional: true,
},
"force_update": schema.BoolAttribute{
Optional: true,
},
"parents": schema.ListAttribute{
Optional: true,
Computed: true,
ElementType: types.Int64Type,
},
"remove_computes": schema.ListAttribute{
Optional: true,
ElementType: types.Int64Type,
},
"compgroup_id": schema.Int64Attribute{
Optional: true,
Computed: true,
},
"account_id": schema.Int64Attribute{
Computed: true,
},
"account_name": schema.StringAttribute{
Computed: true,
},
"computes": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"id": schema.Int64Attribute{
Computed: true,
},
"ip_addresses": schema.ListAttribute{
Computed: true,
ElementType: types.StringType,
},
"name": schema.StringAttribute{
Computed: true,
},
"os_users": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"login": schema.StringAttribute{
Computed: true,
},
"password": schema.StringAttribute{
Computed: true,
},
},
},
},
},
},
},
"consistency": schema.BoolAttribute{
Computed: true,
},
"created_by": schema.StringAttribute{
Computed: true,
},
"created_time": schema.Int64Attribute{
Computed: true,
},
"deleted_by": schema.StringAttribute{
Computed: true,
},
"deleted_time": schema.Int64Attribute{
Computed: true,
},
"gid": schema.Int64Attribute{
Computed: true,
},
"guid": schema.Int64Attribute{
Computed: true,
},
"milestones": schema.Int64Attribute{
Computed: true,
},
"rg_id": schema.Int64Attribute{
Computed: true,
},
"rg_name": schema.StringAttribute{
Computed: true,
},
"seq_no": schema.Int64Attribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"tech_status": schema.StringAttribute{
Computed: true,
},
"updated_by": schema.StringAttribute{
Computed: true,
},
"updated_time": schema.Int64Attribute{
Computed: true,
},
"id": schema.StringAttribute{
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"sid": schema.StringAttribute{
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}