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 flipgroup
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/flipgroup/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/schemas"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &dataSourceFlipgroup{}
)
func NewDataSourceFlipgroup() datasource.DataSource {
return &dataSourceFlipgroup{}
}
// dataSourceFlipgroup is the data source implementation.
type dataSourceFlipgroup struct {
client *decort.DecortClient
}
func (d *dataSourceFlipgroup) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// Read Terraform configuration data into the model
var state models.DataSourceFLIPGroupModel
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceFlipgroup: Error get state")
return
}
fgID := uint64(state.FlipgroupID.ValueInt64())
tflog.Info(ctx, "Read dataSourceFlipgroup: got state successfully", map[string]any{"flipgroup_id": fgID})
// Set timeouts
readTimeout, diags := state.Timeouts.Read(ctx, constants.Timeout180s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceFlipgroup: Error set timeout")
return
}
tflog.Info(ctx, "Read dataSourceFlipgroup: set timeouts successfully", map[string]any{
"flipgroup_id": fgID,
"readTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// Map response body to schema
resp.Diagnostics.Append(flattens.FlipgroupDataSource(ctx, &state, d.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceFlipgroup: Error flatten")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceFlipgroup: Error set state")
return
}
tflog.Info(ctx, "End read dataSourceFlipgroup", map[string]any{"flipgroup_id": fgID})
}
func (d *dataSourceFlipgroup) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaDataSourceFlipgroup(),
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx),
},
}
}
func (d *dataSourceFlipgroup) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_flipgroup"
}
// Configure adds the provider configured client to the data source.
func (d *dataSourceFlipgroup) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
tflog.Info(ctx, "Get Configure dataSourceFlipgroup")
d.client = client.DataSource(ctx, &req, resp)
tflog.Info(ctx, "Getting Configure dataSourceFlipgroup successfully")
}

View File

@@ -0,0 +1,91 @@
package flipgroup
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/flipgroup/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/schemas"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &dataSourceFlipgroupList{}
)
func NewDataSourceFlipgroupList() datasource.DataSource {
return &dataSourceFlipgroupList{}
}
// dataSourceFlipgroupList is the data source implementation.
type dataSourceFlipgroupList struct {
client *decort.DecortClient
}
func (d *dataSourceFlipgroupList) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// Read Terraform configuration data into the model
var state models.DataSourceFLIPGroupModelList
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceFlipgroupList: Error get state")
return
}
fgID := uint64(state.FlipgroupID.ValueInt64())
tflog.Info(ctx, "Read dataSourceFlipgroupList: got state successfully", map[string]any{"flipgroup_id": fgID})
// Set timeouts
readTimeout, diags := state.Timeouts.Read(ctx, constants.Timeout180s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceFlipgroupList: Error set timeout")
return
}
tflog.Info(ctx, "Read dataSourceFlipgroupList: set timeouts successfully", map[string]any{
"flipgroup_id": fgID,
"readTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// Map response body to schema
resp.Diagnostics.Append(flattens.FlipgroupListDataSource(ctx, &state, d.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceFlipgroupList: Error flatten")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read dataSourceFlipgroupList: Error set state")
return
}
tflog.Info(ctx, "End read dataSourceFlipgroupList", map[string]any{"flipgroup_id": fgID})
}
func (d *dataSourceFlipgroupList) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaDataSourceFlipgroupList(),
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx),
},
}
}
func (d *dataSourceFlipgroupList) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_flipgroup_list"
}
// Configure adds the provider configured client to the data source.
func (d *dataSourceFlipgroupList) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
tflog.Info(ctx, "Get Configure dataSourceFlipgroupList")
d.client = client.DataSource(ctx, &req, resp)
tflog.Info(ctx, "Getting Configure dataSourceFlipgroupList successfully")
}

View File

@@ -0,0 +1,70 @@
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/flipgroup/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/utilities"
)
// FlipgroupDataSource flattens data source for flipgroup.
// Return error in case data source is not found on the platform.
// Flatten errors are added to tflog.
func FlipgroupDataSource(ctx context.Context, state *models.DataSourceFLIPGroupModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "Start flattens.FlipgroupDataSource")
diags := diag.Diagnostics{}
fgID := uint64(state.FlipgroupID.ValueInt64())
recordFG, diags := utilities.FlipgroupDataSourceCheckPresence(ctx, fgID, c)
if diags.HasError() {
return diags
}
tflog.Info(ctx, "flattens.FlipgroupDataSource: before flatten", map[string]any{"flipgroup_id": fgID})
*state = models.DataSourceFLIPGroupModel{
FlipgroupID: state.FlipgroupID,
Timeouts: state.Timeouts,
AccountID: types.Int64Value(int64(recordFG.AccountID)),
AccountName: types.StringValue(recordFG.AccountName),
ClientType: types.StringValue(recordFG.ClientType),
ConnID: types.Int64Value(int64(recordFG.ConnID)),
ConnType: types.StringValue(recordFG.ConnType),
CreatedBy: types.StringValue(recordFG.CreatedBy),
CreatedTime: types.Int64Value(int64(recordFG.CreatedTime)),
DefaultGW: types.StringValue(recordFG.DefaultGW),
DeletedBy: types.StringValue(recordFG.DeletedBy),
DeletedTime: types.Int64Value(int64(recordFG.DeletedTime)),
Description: types.StringValue(recordFG.Description),
ID: types.Int64Value(int64(recordFG.ID)),
GID: types.Int64Value(int64(recordFG.GID)),
GUID: types.Int64Value(int64(recordFG.GUID)),
IP: types.StringValue(recordFG.IP),
Milestones: types.Int64Value(int64(recordFG.Milestones)),
Name: types.StringValue(recordFG.Name),
NetID: types.Int64Value(int64(recordFG.NetID)),
NetType: types.StringValue(recordFG.NetType),
Network: types.StringValue(recordFG.Network),
RGID: types.Int64Value(int64(recordFG.RGID)),
RGName: types.StringValue(recordFG.RGName),
Status: types.StringValue(recordFG.Status),
UpdatedBy: types.StringValue(recordFG.UpdatedBy),
UpdatedTime: types.Int64Value(int64(recordFG.UpdatedTime)),
}
state.ClientIDs, diags = types.ListValueFrom(ctx, types.Int64Type, recordFG.ClientIDs)
if diags.HasError() {
tflog.Error(ctx, fmt.Sprint("flattens.FlipgroupDataSource: cannot flatten recordFG.ClientIDs to state.ClientIDs", diags))
}
tflog.Info(ctx, "End flattens.FlipgroupDataSource", map[string]any{"flipgroup_id": state.ID.ValueInt64()})
return nil
}

View File

@@ -0,0 +1,80 @@
package flattens
import (
"context"
"github.com/google/uuid"
"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/flipgroup/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/utilities"
)
// FlipgroupListDataSource flattens data source for flipgroup.
// Return error in case data source is not found on the platform.
// Flatten errors are added to tflog.
func FlipgroupListDataSource(ctx context.Context, state *models.DataSourceFLIPGroupModelList, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "Start flattens.FlipgroupListDataSource")
diags := diag.Diagnostics{}
recordFG, diags := utilities.FlipgroupListDataSourceCheckPresence(ctx, state, c)
if diags.HasError() {
return diags
}
id := uuid.New()
*state = models.DataSourceFLIPGroupModelList{
FlipgroupID: state.FlipgroupID,
Name: state.Name,
VinsID: state.VinsID,
VinsName: state.VinsName,
ExtnetID: state.ExtnetID,
ByIP: state.ByIP,
AccountID: state.AccountID,
RgID: state.RgID,
SortBy: state.SortBy,
Page: state.Page,
Size: state.Size,
Timeouts: state.Timeouts,
ConnID: state.ConnID,
CliendIDs: state.CliendIDs,
Status: state.Status,
ID: types.StringValue(id.String()),
EntryCount: types.Int64Value(int64(recordFG.EntryCount)),
}
items := make([]models.ItemFLIPGroupModel, 0, len(recordFG.Data))
for _, item := range recordFG.Data {
fg := models.ItemFLIPGroupModel{
CKey: types.StringValue(item.CKey),
Meta: flattens.FlattenSimpleTypeToList(ctx, types.StringType, item.Meta),
AccountID: types.Int64Value(int64(item.AccountID)),
ClientIDs: flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, item.Meta),
ClientType: types.StringValue(item.ClientType),
ConnID: types.Int64Value(int64(item.ConnID)),
ConnType: types.StringValue(item.ConnType),
DefaultGW: types.StringValue(item.DefaultGW),
Description: types.StringValue(item.Description),
GID: types.Int64Value(int64(item.GID)),
GUID: types.Int64Value(int64(item.GUID)),
ID: types.Int64Value(int64(item.ID)),
IP: types.StringValue(item.IP),
Milestones: types.Int64Value(int64(item.Milestones)),
Name: types.StringValue(item.Name),
NetID: types.Int64Value(int64(item.NetID)),
NetType: types.StringValue(item.NetType),
NetMask: types.Int64Value(int64(item.NetMask)),
Status: types.StringValue(item.Status),
}
items = append(items, fg)
}
state.Items = items
tflog.Info(ctx, "End flattens.FlipgroupListDataSource")
return nil
}

View File

@@ -0,0 +1,78 @@
package flattens
import (
"context"
"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/terraform-provider-dynamix/internal/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/utilities"
)
// FlipgroupResource flattens resource for flipgroup.
// Return error in case resource is not found on the platform.
// Flatten errors are added to tflog.
func FlipgroupResource(ctx context.Context, plan *models.ResourceFLIPGroupModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "Start flattens.FlipgroupResource")
diags := diag.Diagnostics{}
flipgroupID, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("Cannot parse flipgroup ID from state", err.Error())
return diags
}
recordFG, diags := utilities.FlipgroupResourceCheckPresence(ctx, flipgroupID, c)
if diags.HasError() {
return diags
}
*plan = models.ResourceFLIPGroupModel{
AccountID: plan.AccountID,
Name: plan.Name,
NetType: plan.NetType,
NetID: plan.NetID,
ClientType: plan.ClientType,
Timeouts: plan.Timeouts,
Description: plan.Description,
ClientIDs: plan.ClientIDs,
ID: plan.ID,
IP: plan.IP,
AccountName: types.StringValue(recordFG.AccountName),
ConnID: types.Int64Value(int64(recordFG.ConnID)),
ConnType: types.StringValue(recordFG.ConnType),
CreatedBy: types.StringValue(recordFG.CreatedBy),
CreatedTime: types.Int64Value(int64(recordFG.CreatedTime)),
DefaultGW: types.StringValue(recordFG.DefaultGW),
DeletedBy: types.StringValue(recordFG.DeletedBy),
DeletedTime: types.Int64Value(int64(recordFG.DeletedTime)),
FlipgroupID: types.Int64Value(int64(recordFG.ID)),
//ID: types.StringValue(strconv.Itoa(int(recordFG.ID))),
GID: types.Int64Value(int64(recordFG.GID)),
GUID: types.Int64Value(int64(recordFG.GUID)),
Milestones: types.Int64Value(int64(recordFG.Milestones)),
Network: types.StringValue(recordFG.Network),
RGID: types.Int64Value(int64(recordFG.RGID)),
RGName: types.StringValue(recordFG.RGName),
Status: types.StringValue(recordFG.Status),
UpdatedBy: types.StringValue(recordFG.UpdatedBy),
UpdatedTime: types.Int64Value(int64(recordFG.UpdatedTime)),
}
if plan.IP.IsUnknown() {
plan.IP = types.StringValue(recordFG.IP)
}
if plan.ClientIDs.IsUnknown() {
plan.ClientIDs = flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, recordFG.ClientIDs)
}
tflog.Info(ctx, "End flattens.FlipgroupResource", map[string]any{"flipgroup_id": plan.ID.ValueString()})
return nil
}

View File

@@ -0,0 +1,45 @@
package flipgroup
import (
"context"
"fmt"
"strings"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/ic"
)
// resourceFlipgroupInputChecks checks if user provided, account_id and net_id are valid.
// It also checks that either account_id or net_id is specified.
func resourceFlipgroupInputChecks(ctx context.Context, plan *models.ResourceFLIPGroupModel, c *decort.DecortClient) diag.Diagnostics {
diags := diag.Diagnostics{}
accoundID := uint64(plan.AccountID.ValueInt64())
tflog.Info(ctx, "resourceFlipgroupInputChecks: exist resource account", map[string]any{"account_id": accoundID})
err := ic.ExistAccount(ctx, accoundID, c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about account with ID %v", accoundID), err.Error())
}
netType := plan.NetType.ValueString()
netId := uint64(plan.NetID.ValueInt64())
if strings.EqualFold(netType, "EXTNET") {
tflog.Info(ctx, "resourceFlipgroupInputChecks: exist extnet id", map[string]any{"extnet_id": netId})
err := ic.ExistExtNet(ctx, netId, c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about extnet with ID %v", netId), err.Error())
}
} else {
tflog.Info(ctx, "resourceFlipgroupInputChecks: exist VINS id", map[string]any{"vins_id": netId})
err := ic.ExistVins(ctx, netId, c)
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about VINS with ID %v", netId), err.Error())
}
}
return diags
}

View File

@@ -0,0 +1,41 @@
package models
import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type DataSourceFLIPGroupModel struct {
// request fields
FlipgroupID types.Int64 `tfsdk:"flipgroup_id"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
// response fields
AccountID types.Int64 `tfsdk:"account_id"`
AccountName types.String `tfsdk:"account_name"`
ClientIDs types.List `tfsdk:"client_ids"`
//ClientNames types.List `tfsdk:"client_names"`
ClientType types.String `tfsdk:"client_type"`
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
CreatedBy types.String `tfsdk:"created_by"`
CreatedTime types.Int64 `tfsdk:"created_time"`
DefaultGW types.String `tfsdk:"default_gw"`
DeletedBy types.String `tfsdk:"deleted_by"`
DeletedTime types.Int64 `tfsdk:"deleted_time"`
Description types.String `tfsdk:"desc"`
GID types.Int64 `tfsdk:"gid"`
GUID types.Int64 `tfsdk:"guid"`
ID types.Int64 `tfsdk:"id"`
IP types.String `tfsdk:"ip"`
Milestones types.Int64 `tfsdk:"milestones"`
Name types.String `tfsdk:"name"`
NetID types.Int64 `tfsdk:"net_id"`
NetType types.String `tfsdk:"net_type"`
Network types.String `tfsdk:"network"`
RGID types.Int64 `tfsdk:"rg_id"`
RGName types.String `tfsdk:"rg_name"`
Status types.String `tfsdk:"status"`
UpdatedBy types.String `tfsdk:"updated_by"`
UpdatedTime types.Int64 `tfsdk:"updated_time"`
}

View File

@@ -0,0 +1,53 @@
package models
import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type DataSourceFLIPGroupModelList struct {
// optional fields
FlipgroupID types.Int64 `tfsdk:"by_id"`
Name types.String `tfsdk:"name"`
VinsID types.Int64 `tfsdk:"vins_id"`
VinsName types.String `tfsdk:"vins_name"`
ExtnetID types.Int64 `tfsdk:"extnet_id"`
ByIP types.String `tfsdk:"by_ip"`
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"`
ConnID types.Int64 `tfsdk:"conn_id"`
CliendIDs types.List `tfsdk:"client_ids"`
Status types.String `tfsdk:"status"`
// response fields
ID types.String `tfsdk:"id"`
Items []ItemFLIPGroupModel `tfsdk:"items"`
EntryCount types.Int64 `tfsdk:"entry_count"`
}
type ItemFLIPGroupModel struct {
CKey types.String `tfsdk:"ckey"`
Meta types.List `tfsdk:"meta"`
AccountID types.Int64 `tfsdk:"account_id"`
ClientIDs types.List `tfsdk:"client_ids"`
ClientType types.String `tfsdk:"client_type"`
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
DefaultGW types.String `tfsdk:"default_gw"`
Description types.String `tfsdk:"desc"`
GID types.Int64 `tfsdk:"gid"`
GUID types.Int64 `tfsdk:"guid"`
ID types.Int64 `tfsdk:"flipgroup_id"`
IP types.String `tfsdk:"ip"`
Milestones types.Int64 `tfsdk:"milestones"`
Name types.String `tfsdk:"name"`
NetID types.Int64 `tfsdk:"net_id"`
NetType types.String `tfsdk:"net_type"`
NetMask types.Int64 `tfsdk:"net_mask"`
Status types.String `tfsdk:"status"`
}

View File

@@ -0,0 +1,42 @@
package models
import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type ResourceFLIPGroupModel struct {
// request fields - required
AccountID types.Int64 `tfsdk:"account_id"`
Name types.String `tfsdk:"name"`
NetType types.String `tfsdk:"net_type"`
NetID types.Int64 `tfsdk:"net_id"`
ClientType types.String `tfsdk:"client_type"`
// request fields - optional
IP types.String `tfsdk:"ip"`
Description types.String `tfsdk:"desc"`
// response fields
FlipgroupID types.Int64 `tfsdk:"flipgroup_id"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
AccountName types.String `tfsdk:"account_name"`
ClientIDs types.List `tfsdk:"client_ids"`
ConnID types.Int64 `tfsdk:"conn_id"`
ConnType types.String `tfsdk:"conn_type"`
CreatedBy types.String `tfsdk:"created_by"`
CreatedTime types.Int64 `tfsdk:"created_time"`
DefaultGW types.String `tfsdk:"default_gw"`
DeletedBy types.String `tfsdk:"deleted_by"`
DeletedTime types.Int64 `tfsdk:"deleted_time"`
GID types.Int64 `tfsdk:"gid"`
GUID types.Int64 `tfsdk:"guid"`
ID types.String `tfsdk:"id"`
Milestones types.Int64 `tfsdk:"milestones"`
Network types.String `tfsdk:"network"`
RGID types.Int64 `tfsdk:"rg_id"`
RGName types.String `tfsdk:"rg_name"`
Status types.String `tfsdk:"status"`
UpdatedBy types.String `tfsdk:"updated_by"`
UpdatedTime types.Int64 `tfsdk:"updated_time"`
}

View File

@@ -0,0 +1,300 @@
package flipgroup
import (
"context"
"fmt"
"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/flipgroup"
"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/flipgroup/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/schemas"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/utilities"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ resource.Resource = &resourceFlipgroup{}
_ resource.ResourceWithImportState = &resourceFlipgroup{}
)
// NewResourceFlipgroup is a helper function to simplify the provider implementation.
func NewResourceFlipgroup() resource.Resource {
return &resourceFlipgroup{}
}
// resourceFlipgroup is the resource implementation.
type resourceFlipgroup struct {
client *decort.DecortClient
}
// Create creates the resource and sets the initial Terraform state.
func (r *resourceFlipgroup) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
// Get plan to create flipgroup
var plan models.ResourceFLIPGroupModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Create resourceFlipgroup: Error receiving the plan")
return
}
tflog.Info(ctx, "Create resourceFlipgroup: start creating", map[string]any{"name": plan.Name.ValueString()})
// Set timeouts
createTimeout, diags := plan.Timeouts.Create(ctx, constants.Timeout300s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Create resourceFlipgroup: Error set timeout")
return
}
tflog.Info(ctx, "Create resourceFlipgroup: set timeouts successfully", map[string]any{
"name": plan.Name.ValueString(),
"createTimeout": createTimeout})
ctx, cancel := context.WithTimeout(ctx, createTimeout)
defer cancel()
// Check if input values are valid in the platform
tflog.Info(ctx, "Create resourceFlipgroup: starting input checks", map[string]any{"name": plan.Name.ValueString()})
resp.Diagnostics.Append(resourceFlipgroupInputChecks(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Create resourceFlipgroup: Error input checks")
return
}
tflog.Info(ctx, "Create resourceFlipgroup: input checks successful", map[string]any{"name": plan.Name.ValueString()})
// Make create request and get response for creation
flipgroupID, diags := utilities.CreateResourceFlipgroup(ctx, &plan, r.client)
if diags.HasError() {
resp.Diagnostics.Append(diags...)
tflog.Error(ctx, "Create resourceFlipgroup: Error response for create resource flipgroup")
return
}
plan.ID = types.StringValue(strconv.Itoa(int(flipgroupID)))
//plan.CreatedBy = types.StringValue(time.Now().Format(time.RFC850))
tflog.Info(ctx, "Create resourceFlipgroup: flipgroup created", map[string]any{"flipgroup_id": flipgroupID, "name": plan.Name.ValueString()})
// Add computes after flipgroup creation, warnings added to resp.Diagnostics in case of failure
if !plan.ClientIDs.IsUnknown() { // ClientIDs optional & computed
resp.Diagnostics.Append(utilities.AddClientsFlipgroup(ctx, flipgroupID, &plan, r.client)...)
}
tflog.Info(ctx, "Create resourceFlipgroup: resource creation is completed", map[string]any{"flipgroup_id": flipgroupID})
// Map response body to schema and populate Computed attribute values
resp.Diagnostics.Append(flattens.FlipgroupResource(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
}
}
func (r *resourceFlipgroup) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
// Get current state
var state models.ResourceFLIPGroupModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceFlipgroup: Error get state")
return
}
tflog.Info(ctx, "Read resourceFlipgroup: got state successfully", map[string]any{"flipgroup_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 resourceFlipgroup: Error set timeout")
return
}
tflog.Info(ctx, "Read resourceFlipgroup: set timeouts successfully", map[string]any{
"flipgroup_id": state.ID.ValueString(),
"createTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// Read status
tflog.Info(ctx, "Read resourceFlipgroup: before FlipgroupReadStatus", map[string]any{"flipgroup_id": state.ID.ValueString()})
resp.Diagnostics.Append(utilities.FlipgroupReadStatus(ctx, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceFlipgroup: Error reading status")
return
}
// Overwrite items with refreshed state
resp.Diagnostics.Append(flattens.FlipgroupResource(ctx, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceFlipgroup: Error flatten")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Read resourceFlipgroup: Error set state")
return
}
tflog.Info(ctx, "End read resourceFlipgroup")
}
func (r *resourceFlipgroup) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
// Retrieve values from plan
var plan models.ResourceFLIPGroupModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceFlipgroup: Error receiving the plan")
return
}
tflog.Info(ctx, "Update resourceFlipgroup: got plan successfully", map[string]any{"flipgroup_id": plan.ID.ValueString()})
// Retrieve values from state
var state models.ResourceFLIPGroupModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceFlipgroup: Error receiving the state")
return
}
tflog.Info(ctx, "Update resourceFlipgroup: got state successfully", map[string]any{"flipgroup_id": plan.ID.ValueString()})
// Set timeouts
updateTimeout, diags := plan.Timeouts.Update(ctx, constants.Timeout300s)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error set timeout")
return
}
tflog.Info(ctx, "Update resourceFlipgroup: set timeouts successfully", map[string]any{
"flipgroup_id": state.ID.ValueString(),
"updateTimeout": updateTimeout})
ctx, cancel := context.WithTimeout(ctx, updateTimeout)
defer cancel()
// Checking for values in the platform
tflog.Info(ctx, "Update resourceFlipgroup: starting input checks", map[string]any{"flipgroup_id": plan.ID.ValueString()})
resp.Diagnostics.Append(resourceFlipgroupInputChecks(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceFlipgroup: Error input checks")
return
}
tflog.Info(ctx, "Update resourceFlipgroup: input checks successful", map[string]any{"flipgroup_id": plan.ID.ValueString()})
flipgroupId, err := strconv.ParseUint(state.ID.ValueString(), 10, 64)
if err != nil {
resp.Diagnostics.AddError(fmt.Sprintf("Cannot parse flipgroup ID %s from state", state.ID.ValueString()), err.Error())
return
}
if !plan.Name.Equal(state.Name) || (!plan.Description.IsNull() && !plan.Description.Equal(state.Description)) {
resp.Diagnostics.Append(utilities.EditFlipgroup(ctx, flipgroupId, &plan, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceFlipgroup: Error editing flipgroup")
return
}
}
if !plan.ClientIDs.IsUnknown() && !plan.ClientIDs.Equal(state.ClientIDs) {
resp.Diagnostics.Append(utilities.UpdateClientIDsFlipgroup(ctx, flipgroupId, &plan, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Update resourceFlipgroup: Error editing client IDs")
return
}
}
tflog.Info(ctx, "Update resourceFlipgroup: resource update is completed", map[string]any{"flipgroup_id": plan.ID.ValueString()})
// Map response body to schema and populate Computed attribute values
resp.Diagnostics.Append(flattens.FlipgroupResource(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
}
}
func (r *resourceFlipgroup) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
// Get current state
var state models.ResourceFLIPGroupModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Delete resourceFlipgroup: Error get state")
return
}
tflog.Info(ctx, "Delete resourceFlipgroup: got state successfully", map[string]any{"flipgroup_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, "Delete resourceFlipgroup: Error set timeout")
return
}
tflog.Info(ctx, "Delete resourceFlipgroup: set timeouts successfully", map[string]any{
"flipgroup_id": state.ID.ValueString(),
"createTimeout": readTimeout})
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// Delete existing flipgroup
delReq := flipgroup.DeleteRequest{
FLIPGroupID: uint64(state.FlipgroupID.ValueInt64()),
}
tflog.Info(ctx, "Delete resourceFlipgroup: calling CloudAPI().FLIPGroup().Delete", map[string]any{
"flipgroup_id": state.ID.ValueString(),
"req": delReq,
})
_, err := r.client.CloudAPI().FLIPGroup().Delete(ctx, delReq)
if err != nil {
resp.Diagnostics.AddError("Delete resourceFlipgroup: Error deleting", err.Error())
return
}
tflog.Info(ctx, "End delete resource flipgroup", map[string]any{"flipgroup_id": state.ID.ValueString()})
}
// Schema defines the schema for the resource.
func (r *resourceFlipgroup) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaResourceFlipgroup(),
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 *resourceFlipgroup) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_flipgroup"
}
// Configure adds the provider configured client to the resource.
func (r *resourceFlipgroup) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
tflog.Info(ctx, "Get Configure resourceFlipgroup")
r.client = client.Resource(ctx, &req, resp)
tflog.Info(ctx, "Getting Configure resourceFlipgroup successfully")
}
func (r *resourceFlipgroup) 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,93 @@
package schemas
import (
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
func MakeSchemaDataSourceFlipgroup() map[string]schema.Attribute {
return map[string]schema.Attribute{
"flipgroup_id": schema.Int64Attribute{
Required: true,
},
"account_id": schema.Int64Attribute{
Computed: true,
},
"account_name": schema.StringAttribute{
Computed: true,
},
"client_ids": schema.ListAttribute{
Computed: true,
ElementType: types.Int64Type,
},
"client_type": schema.StringAttribute{
Computed: true,
},
"conn_id": schema.Int64Attribute{
Computed: true,
},
"conn_type": schema.StringAttribute{
Computed: true,
},
"created_by": schema.StringAttribute{
Computed: true,
},
"created_time": schema.Int64Attribute{
Computed: true,
},
"default_gw": schema.StringAttribute{
Computed: true,
},
"deleted_by": schema.StringAttribute{
Computed: true,
},
"deleted_time": schema.Int64Attribute{
Computed: true,
},
"desc": schema.StringAttribute{
Computed: true,
},
"gid": schema.Int64Attribute{
Computed: true,
},
"guid": schema.Int64Attribute{
Computed: true,
},
"id": schema.Int64Attribute{
Computed: true,
},
"ip": schema.StringAttribute{
Computed: true,
},
"milestones": schema.Int64Attribute{
Computed: true,
},
"name": schema.StringAttribute{
Computed: true,
},
"net_id": schema.Int64Attribute{
Computed: true,
},
"net_type": schema.StringAttribute{
Computed: true,
},
"network": schema.StringAttribute{
Computed: true,
},
"rg_id": schema.Int64Attribute{
Computed: true,
},
"rg_name": schema.StringAttribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"updated_by": schema.StringAttribute{
Computed: true,
},
"updated_time": schema.Int64Attribute{
Computed: true,
},
}
}

View File

@@ -0,0 +1,140 @@
package schemas
import (
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
func MakeSchemaDataSourceFlipgroupList() map[string]schema.Attribute {
return map[string]schema.Attribute{
"by_id": schema.Int64Attribute{
Optional: true,
Description: "Filter by ID",
},
"name": schema.StringAttribute{
Optional: true,
Description: "Filter by Name",
},
"vins_id": schema.Int64Attribute{
Optional: true,
Description: "Filter by ViNS ID",
},
"vins_name": schema.StringAttribute{
Optional: true,
Description: "Filter by ViNS name",
},
"extnet_id": schema.Int64Attribute{
Optional: true,
Description: "Filter by ExtNetID",
},
"by_ip": schema.StringAttribute{
Optional: true,
Description: "Filter by IP-address",
},
"rg_id": schema.Int64Attribute{
Optional: true,
Description: "Filter by RG ID",
},
"sort_by": schema.StringAttribute{
Optional: true,
Description: "sort by one of supported fields, format +|-(field)",
},
"page": schema.Int64Attribute{
Optional: true,
Description: "Page number",
},
"size": schema.Int64Attribute{
Optional: true,
Description: "Page size",
},
"account_id": schema.Int64Attribute{
Optional: true,
Description: "Account id",
},
"conn_id": schema.Int64Attribute{
Optional: true,
Description: "Conn id",
},
"client_ids": schema.ListAttribute{
Optional: true,
ElementType: types.Int64Type,
Description: "client_ids",
},
"status": schema.StringAttribute{
Optional: true,
Description: "Status",
},
"id": schema.StringAttribute{
Computed: true,
},
"items": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"flipgroup_id": schema.Int64Attribute{
Computed: true,
},
"account_id": schema.Int64Attribute{
Computed: true,
},
"client_ids": schema.ListAttribute{
Computed: true,
ElementType: types.Int64Type,
},
"client_type": schema.StringAttribute{
Computed: true,
},
"conn_id": schema.Int64Attribute{
Computed: true,
},
"conn_type": schema.StringAttribute{
Computed: true,
},
"default_gw": schema.StringAttribute{
Computed: true,
},
"desc": schema.StringAttribute{
Computed: true,
},
"gid": schema.Int64Attribute{
Computed: true,
},
"guid": schema.Int64Attribute{
Computed: true,
},
"milestones": schema.Int64Attribute{
Computed: true,
},
"name": schema.StringAttribute{
Computed: true,
},
"net_id": schema.Int64Attribute{
Computed: true,
},
"net_type": schema.StringAttribute{
Computed: true,
},
"ip": schema.StringAttribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"net_mask": schema.Int64Attribute{
Computed: true,
},
"ckey": schema.StringAttribute{
Computed: true,
},
"meta": schema.ListAttribute{
Computed: true,
ElementType: types.StringType,
},
},
},
},
"entry_count": schema.Int64Attribute{
Computed: true,
},
}
}

View File

@@ -0,0 +1,116 @@
package schemas
import (
"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"
)
func MakeSchemaResourceFlipgroup() map[string]schema.Attribute {
return map[string]schema.Attribute{
"account_id": schema.Int64Attribute{
Required: true,
Description: "Account ID",
},
"name": schema.StringAttribute{
Required: true,
Description: "Flipgroup name",
},
"net_id": schema.Int64Attribute{
Required: true,
Description: "EXTNET or ViNS ID",
},
"net_type": schema.StringAttribute{
Required: true,
Validators: []validator.String{
stringvalidator.OneOf("EXTNET", "VINS"),
},
Description: "Network type, EXTNET or VINS",
},
"client_type": schema.StringAttribute{
Required: true,
Validators: []validator.String{
stringvalidator.OneOf("compute"),
},
Description: "Type of client, 'compute' ('vins' will be later)",
},
"ip": schema.StringAttribute{
Optional: true,
Computed: true,
Description: "IP address to associate with this group. If empty, the platform will autoselect IP address",
},
"desc": schema.StringAttribute{
Optional: true,
Description: "Text description of this Flipgroup instance",
},
"client_ids": schema.ListAttribute{
Optional: true,
Computed: true,
ElementType: types.Int64Type,
Description: "List of clients attached to this Flipgroup instance",
},
"flipgroup_id": schema.Int64Attribute{
Computed: true,
},
"account_name": schema.StringAttribute{
Computed: true,
},
"conn_id": schema.Int64Attribute{
Computed: true,
},
"conn_type": schema.StringAttribute{
Computed: true,
},
"created_by": schema.StringAttribute{
Computed: true,
},
"created_time": schema.Int64Attribute{
Computed: true,
},
"default_gw": schema.StringAttribute{
Computed: true,
},
"deleted_by": schema.StringAttribute{
Computed: true,
},
"deleted_time": schema.Int64Attribute{
Computed: true,
},
"gid": schema.Int64Attribute{
Computed: true,
},
"guid": schema.Int64Attribute{
Computed: true,
},
"id": schema.StringAttribute{
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"milestones": schema.Int64Attribute{
Computed: true,
},
"status": schema.StringAttribute{
Computed: true,
},
"network": schema.StringAttribute{
Computed: true,
},
"rg_id": schema.Int64Attribute{
Computed: true,
},
"rg_name": schema.StringAttribute{
Computed: true,
},
"updated_by": schema.StringAttribute{
Computed: true,
},
"updated_time": schema.Int64Attribute{
Computed: true,
},
}
}

View File

@@ -0,0 +1,27 @@
package utilities
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/flipgroup"
)
func FlipgroupDataSourceCheckPresence(ctx context.Context, fgId uint64, c *decort.DecortClient) (*flipgroup.RecordFLIPGroup, diag.Diagnostics) {
tflog.Info(ctx, fmt.Sprintf("FlipgroupDataSourceCheckPresence: Get info about flipgroup with ID - %v", fgId))
diags := diag.Diagnostics{}
recordFG, err := c.CloudAPI().FLIPGroup().Get(ctx, flipgroup.GetRequest{FLIPGroupID: fgId})
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about flipgroup with ID %v", fgId), err.Error())
return nil, diags
}
tflog.Info(ctx, "FlipgroupDataSourceCheckPresence: response from CloudAPI().FLIPGroup().Get", map[string]any{"flipgroup_id": fgId, "response": recordFG})
return recordFG, nil
}

View File

@@ -0,0 +1,90 @@
package utilities
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/decort-golang-sdk/pkg/cloudapi/flipgroup"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/models"
)
func FlipgroupListDataSourceCheckPresence(ctx context.Context, plan *models.DataSourceFLIPGroupModelList, c *decort.DecortClient) (*flipgroup.ListFLIPGroups, diag.Diagnostics) {
tflog.Info(ctx, fmt.Sprintf("FlipgroupListDataSourceCheckPresence: Get info about flipgroup list"))
diags := diag.Diagnostics{}
listFlipgroupReq := flipgroup.ListRequest{}
if !plan.Name.IsNull() {
listFlipgroupReq.Name = plan.Name.ValueString()
}
if !plan.VinsID.IsNull() {
listFlipgroupReq.VINSID = uint64(plan.VinsID.ValueInt64())
}
if !plan.VinsName.IsNull() {
listFlipgroupReq.VINSName = plan.VinsName.ValueString()
}
if !plan.ExtnetID.IsNull() {
listFlipgroupReq.ExtNetID = uint64(plan.ExtnetID.ValueInt64())
}
if !plan.ByIP.IsNull() {
listFlipgroupReq.ByIP = plan.ByIP.ValueString()
}
if !plan.AccountID.IsNull() {
listFlipgroupReq.AccountId = uint64(plan.AccountID.ValueInt64())
}
if !plan.RgID.IsNull() {
listFlipgroupReq.RGID = uint64(plan.RgID.ValueInt64())
}
if !plan.FlipgroupID.IsNull() {
listFlipgroupReq.ByID = uint64(plan.FlipgroupID.ValueInt64())
}
if !plan.Page.IsNull() {
listFlipgroupReq.Page = uint64(plan.Page.ValueInt64())
}
if !plan.Size.IsNull() {
listFlipgroupReq.Size = uint64(plan.Size.ValueInt64())
}
if !plan.ConnID.IsNull() {
listFlipgroupReq.ConnId = uint64(plan.ConnID.ValueInt64())
}
if !plan.CliendIDs.IsNull() {
result := make([]uint64, 0, len(plan.CliendIDs.Elements()))
for _, val := range plan.CliendIDs.Elements() {
result = append(result, uint64(val.(types.Int64).ValueInt64()))
}
listFlipgroupReq.ClientIDs = result
}
if !plan.Status.IsNull() {
listFlipgroupReq.Status = plan.Status.ValueString()
}
if !plan.SortBy.IsNull() {
listFlipgroupReq.SortBy = plan.SortBy.ValueString()
}
recordFG, err := c.CloudAPI().FLIPGroup().List(ctx, listFlipgroupReq)
if err != nil {
diags.AddError(fmt.Sprintf("FlipgroupDataSourceCheckPresence: Cannot get info about flipgroup list"), err.Error())
return nil, diags
}
tflog.Info(ctx, "FlipgroupDataSourceCheckPresence: successfull response from CloudAPI().FLIPGroup().List")
return recordFG, nil
}

View File

@@ -0,0 +1,227 @@
package utilities
import (
"context"
"fmt"
"strconv"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-log/tflog"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/flipgroup"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/status"
)
func CreateResourceFlipgroup(ctx context.Context, plan *models.ResourceFLIPGroupModel, c *decort.DecortClient) (uint64, diag.Diagnostics) {
tflog.Info(ctx, fmt.Sprintf("Start create ResourceFlipgroup: flipgroup_name %s", plan.Name.ValueString()))
diags := diag.Diagnostics{}
createReq := flipgroup.CreateRequest{
AccountID: uint64(plan.AccountID.ValueInt64()),
Name: plan.Name.ValueString(),
NetType: plan.NetType.ValueString(),
NetID: uint64(plan.NetID.ValueInt64()),
ClientType: plan.ClientType.ValueString(),
}
if !plan.IP.IsUnknown() { // IP is optional & computed
createReq.IP = plan.IP.ValueString()
}
if !plan.Description.IsNull() { // Description is optional
createReq.Description = plan.Description.ValueString()
}
tflog.Info(ctx, "CreateResourceFlipgroup: before call CloudAPI().FLIPGroup().Create", map[string]any{"req": createReq})
resp, err := c.CloudAPI().FLIPGroup().Create(ctx, createReq)
if err != nil {
diags.AddError("CreateResourceFlipgroup: unable to create flipgroup", err.Error())
return 0, diags
}
tflog.Info(ctx, "CreateResourceFlipgroup: flipgroup created", map[string]any{"flipgroup_id": resp.ID, "name": plan.Name.ValueString()})
return resp.ID, nil
}
// AddClientsFlipgroup add computes in flipgroup for created resource.
// In case of failure returns warnings.
func AddClientsFlipgroup(ctx context.Context, flipgroupID uint64, plan *models.ResourceFLIPGroupModel, c *decort.DecortClient) diag.Diagnostics {
diags := diag.Diagnostics{}
tflog.Info(ctx, "AddClientsFlipgroup: start add clients", map[string]any{"flipgroup_id": flipgroupID})
clientIDs := make([]int, 0, len(plan.ClientIDs.Elements()))
diagsItem := plan.ClientIDs.ElementsAs(ctx, &clientIDs, true)
if diagsItem.HasError() {
tflog.Error(ctx, fmt.Sprintf("AddClientsFlipgroup: cannot populate clientIDs with plan.ClientIDs list elements: %v", diagsItem))
diags.AddWarning("AddClientsFlipgroup: Unable to read clientIDs for flipgroup", fmt.Sprintf("%v", diagsItem))
return diags
}
for _, computeID := range clientIDs {
addClientsReq := flipgroup.ComputeAddRequest{
FLIPGroupID: flipgroupID,
ComputeID: uint64(computeID),
}
res, err := c.CloudAPI().FLIPGroup().ComputeAdd(ctx, addClientsReq)
if err != nil {
diags.AddWarning("AddClientsFlipgroup: Unable to add compute for flipgroup", err.Error())
}
tflog.Info(ctx, "AddClientsFlipgroup: response from CloudAPI().FLIPGroup().ComputeAdd", map[string]any{
"flipgroup_id": flipgroupID,
"response": res})
}
return diags
}
// FlipgroupReadStatus loads flipgroup resource by id, gets it current status
// In case of failure returns errors.
func FlipgroupReadStatus(ctx context.Context, state *models.ResourceFLIPGroupModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, "FlipgroupReadStatus: Read status flipgroup with ID", map[string]any{"flipgroup_id": state.ID.ValueString()})
diags := diag.Diagnostics{}
flipgroupId, err := strconv.ParseUint(state.ID.ValueString(), 10, 64)
if err != nil {
diags.AddError("FlipgroupReadStatus: Cannot parse flipgroup ID from state", err.Error())
return diags
}
recordFG, diags := FlipgroupResourceCheckPresence(ctx, flipgroupId, c)
if err != nil {
diags.AddError("FlipgroupReadStatus: Unable to Read/Update flipgroup before status check", err.Error())
return diags
}
//check resource status
switch recordFG.Status {
case status.Modeled:
diags.AddError(
"FlipgroupReadStatus: flipgroup is in status Modeled",
"please, contact support for more information",
)
return diags
case status.Destroyed:
diags.AddError(
"FlipgroupReadStatus: flipgroup is in status Destroyed",
fmt.Sprintf("the resource with flipgroup_id %d cannot be read or updated because it has been destroyed", flipgroupId),
)
return diags
}
return nil
}
func FlipgroupResourceCheckPresence(ctx context.Context, flipgroupId uint64, c *decort.DecortClient) (*flipgroup.RecordFLIPGroup, diag.Diagnostics) {
tflog.Info(ctx, fmt.Sprintf("FlipgroupResourceCheckPresence: Get info about flipgroup with ID - %v", flipgroupId))
diags := diag.Diagnostics{}
recordFG, err := c.CloudAPI().FLIPGroup().Get(ctx, flipgroup.GetRequest{FLIPGroupID: flipgroupId})
if err != nil {
diags.AddError(fmt.Sprintf("Cannot get info about flipgroup with ID %v", flipgroupId), err.Error())
return nil, diags
}
tflog.Info(ctx, "FlipgroupResourceCheckPresence: response from CloudAPI().FLIPGroup().Get", map[string]any{"flipgroup_id": flipgroupId, "response": recordFG})
return recordFG, nil
}
func EditFlipgroup(ctx context.Context, flipgroupId uint64, plan, state *models.ResourceFLIPGroupModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, fmt.Sprintf("EditFlipgroup: Start edit flipgroup with ID - %v", flipgroupId))
diags := diag.Diagnostics{}
editReq := flipgroup.EditRequest{
FLIPGroupID: flipgroupId,
}
if !plan.Name.Equal(state.Name) {
editReq.Name = plan.Name.ValueString()
}
if !plan.Description.IsNull() && !plan.Description.Equal(state.Description) {
editReq.Description = plan.Description.ValueString()
}
_, err := c.CloudAPI().FLIPGroup().Edit(ctx, editReq)
if err != nil {
diags.AddError("EditFlipgroup: cannot edit flipgroup", err.Error())
return diags
}
tflog.Info(ctx, fmt.Sprintf("EditFlipgroup: Finish edit flipgroup with ID - %v", flipgroupId))
return nil
}
func UpdateClientIDsFlipgroup(ctx context.Context, flipgroupId uint64, plan, state *models.ResourceFLIPGroupModel, c *decort.DecortClient) diag.Diagnostics {
tflog.Info(ctx, fmt.Sprintf("UpdateClientIDsFlipgroup: Start update flipgroup with ID - %v", flipgroupId))
diags := diag.Diagnostics{}
clientIDsPlan := make([]int, 0, len(plan.ClientIDs.Elements()))
diags.Append(plan.ClientIDs.ElementsAs(ctx, &clientIDsPlan, true)...)
if diags.HasError() {
tflog.Error(ctx, fmt.Sprintf("UpdateClientIDsFlipgroup: cannot populate clientIDs with plan.ClientIDs list elements"))
return diags
}
clientIDsState := make([]int, 0, len(state.ClientIDs.Elements()))
diags.Append(state.ClientIDs.ElementsAs(ctx, &clientIDsState, true)...)
if diags.HasError() {
tflog.Error(ctx, fmt.Sprintf("UpdateClientIDsFlipgroup: cannot populate clientIDs with state.ClientIDs list elements"))
return diags
}
deleteIDs := difference(clientIDsState, clientIDsPlan)
addIDs := difference(clientIDsPlan, clientIDsState)
for _, id := range deleteIDs {
tflog.Info(ctx, fmt.Sprintf("UpdateClientIDsFlipgroup: Start remove client with ID - %v", id))
req := flipgroup.ComputeRemoveRequest{
FLIPGroupID: flipgroupId,
ComputeID: id,
}
res, err := c.CloudAPI().FLIPGroup().ComputeRemove(ctx, req)
tflog.Info(ctx, "UpdateClientIDsFlipgroup: response from CloudAPI().FLIPGroup().ComputeRemove", map[string]any{"flipgroup_id": plan.ID.ValueString(), "response": res})
if err != nil {
diags.AddError("UpdateClientIDsFlipgroup: can not remove client for flipgroup", err.Error())
}
}
for _, id := range addIDs {
tflog.Info(ctx, fmt.Sprintf("UpdateClientIDsFlipgroup: Start add client with ID - %v", id))
req := flipgroup.ComputeAddRequest{
FLIPGroupID: flipgroupId,
ComputeID: id,
}
res, err := c.CloudAPI().FLIPGroup().ComputeAdd(ctx, req)
tflog.Info(ctx, "UpdateClientIDsFlipgroup: response from CloudAPI().FLIPGroup().ComputeAdd", map[string]any{"flipgroup_id": plan.ID.ValueString(), "response": res})
if err != nil {
diags.AddError("UpdateClientIDsFlipgroup: can not add client for flipgroup", err.Error())
}
}
tflog.Info(ctx, fmt.Sprintf("UpdateClientIDsFlipgroup: Finish update flipgroup with ID - %v", flipgroupId))
return diags
}
func difference(set, check []int) []uint64 {
mapCheck := make(map[int]struct{})
for _, id := range check {
mapCheck[id] = struct{}{}
}
var diff []uint64
for _, id := range set {
if _, ok := mapCheck[id]; !ok {
diff = append(diff, uint64(id))
}
}
return diff
}