You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
terraform-provider-dynamix/internal/service/cloudbroker/vfpool/utilities/utility_resource_cb_vfpool.go

295 lines
9.5 KiB

12 months ago
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-log/tflog"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vfpool"
6 months ago
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
12 months ago
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/ic"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/vfpool/models"
)
6 months ago
func ResourceVFPoolCheckPresence(ctx context.Context, vfPoolID uint64, c *client.Client) (*vfpool.RecordVFPool,
12 months ago
error) {
req := vfpool.GetRequest{VFPoolID: vfPoolID}
tflog.Info(ctx, "ResourceVFPoolCheckPresence: before call CloudBroker().VFPool().Get", map[string]any{"req": req})
vfPool, err := c.CloudBroker().VFPool().Get(ctx, req)
if err != nil {
return nil, fmt.Errorf("VFPoolCheckPresence: cannot get info about vfpool")
}
tflog.Info(ctx, "ResourceVFPoolCheckPresence: response from CloudBroker().VFPool().Get", map[string]any{"response": vfPool})
return vfPool, err
}
6 months ago
func VFpoolResourceCreate(ctx context.Context, plan *models.ResourceItemVFPoolModel, c *client.Client) (*uint64, diag.Diagnostics) {
12 months ago
tflog.Info(ctx, "Start VFpoolResourceCreate", map[string]any{"name": plan.Name.ValueString()})
diags := diag.Diagnostics{}
req := vfpool.CreateRequest{
Name: plan.Name.ValueString(),
}
if !plan.Description.IsNull() {
req.Description = plan.Description.ValueString()
}
if !plan.AccountAccess.IsNull() {
accountAccessList := make([]uint64, len(plan.AccountAccess.Elements()))
diags.Append(plan.AccountAccess.ElementsAs(ctx, &accountAccessList, true)...)
if diags.HasError() {
tflog.Error(ctx, "VFpoolResourceCreate: cannot populate VFpoolResourceCreate with plan.AccountAccess object element")
return nil, diags
}
req.AccountAccess = accountAccessList
}
if !plan.RGAccess.IsNull() {
RGAccessList := make([]uint64, len(plan.RGAccess.Elements()))
diags.Append(plan.RGAccess.ElementsAs(ctx, &RGAccessList, true)...)
if diags.HasError() {
tflog.Error(ctx, "VFpoolResourceCreate: cannot populate VFpoolResourceCreate with plan.RGAccess object element")
return nil, diags
}
req.RGAccess = RGAccessList
}
diags.Append(checkParamsExistence(ctx, req.AccountAccess, req.RGAccess, c)...)
if diags.HasError() {
tflog.Error(ctx, "VFpoolResourceCreate: RGAccess or AccountAccess does not exist")
return nil, diags
}
if !plan.Config.IsNull() {
configList := make([]models.ResourceItemVFPoolConfigModel, 0, len(plan.Config.Elements()))
diags.Append(plan.Config.ElementsAs(ctx, &configList, true)...)
if diags.HasError() {
tflog.Error(ctx, "VFpoolResourceCreate: cannot populate VFpoolResourceCreate with v.Config object element")
return nil, diags
}
config := make([]vfpool.Config, 0, len(configList))
for _, v := range configList {
vfIDs := make([]uint64, 0, len(v.VFIDs.Elements()))
diags.Append(v.VFIDs.ElementsAs(ctx, &vfIDs, true)...)
if diags.HasError() {
tflog.Error(ctx, "VFpoolResourceCreate: cannot populate UpdateVFpool with vfIDs object element")
return nil, diags
}
item := vfpool.Config{
NodeID: uint64(v.NodeID.ValueInt64()),
NicName: v.NicName.ValueString(),
VFIDs: vfIDs}
config = append(config, item)
}
req.Config = config
}
vfPoolID, err := c.CloudBroker().VFPool().Create(ctx, req)
if err != nil {
tflog.Error(ctx, "Error response for create VFpool", map[string]any{"error": err.Error()})
diags.AddError("Unable to Create VFpool", err.Error())
return nil, diags
}
plan.ID = types.StringValue(strconv.Itoa(int(vfPoolID)))
if !plan.Enable.IsNull() {
EnableDisableVFpool(ctx, plan, c)
}
tflog.Info(ctx, "End VFpoolResourceCreate", map[string]any{"vfpool_id": vfPoolID})
return &vfPoolID, diags
}
// EnableDisableVFpool performs VFpool Enable/Disable request.
// Returns error in case of failures.
6 months ago
func EnableDisableVFpool(ctx context.Context, plan *models.ResourceItemVFPoolModel, c *client.Client) diag.Diagnostics {
12 months ago
tflog.Info(ctx, "Start EnableDisableVFpool", map[string]any{"vfpool_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
ID, err := strconv.Atoi(plan.ID.ValueString())
if err != nil {
diags.AddError("EnableDisableVFpool: Cannot parse ID from state", err.Error())
return diags
}
if plan.Enable.ValueBool() {
tflog.Info(ctx, "EnableDisableVFpool: before calling CloudBroker().VFPool().Enable", map[string]any{"vfpool_id": ID})
res, err := c.CloudBroker().VFPool().Enable(ctx, vfpool.EnableRequest{VFPoolID: uint64(ID)})
if err != nil {
diags.AddError(
"EnableDisableVFpool: cannot enable VFpool",
err.Error(),
)
return diags
}
tflog.Info(ctx, "EnableDisableVFpool: response from CloudBroker().VFPool().Enable", map[string]any{"vfpool_id": ID, "response": res})
return nil
} else {
tflog.Info(ctx, "EnableDisableVFpool: before calling CloudBroker().VFPool().Disable", map[string]any{"vfpool_id": ID})
res, err := c.CloudBroker().VFPool().Disable(ctx, vfpool.DisableRequest{VFPoolID: uint64(ID)})
if err != nil {
diags.AddError(
"EnableDisableVFpool: cannot disable VFPool",
err.Error(),
)
return diags
}
tflog.Info(ctx, "EnableDisableVFpool: response from CloudBroker().VFPool().Disable", map[string]any{"vfpool_id": ID, "response": res})
}
return nil
}
6 months ago
func UpdateVFpool(ctx context.Context, state *models.ResourceItemVFPoolModel, plan *models.ResourceItemVFPoolModel, c *client.Client) diag.Diagnostics {
12 months ago
tflog.Info(ctx, "Start UpdateVFpool", map[string]any{"vfpool_id": plan.ID.ValueString()})
diags := diag.Diagnostics{}
ID, err := strconv.Atoi(plan.ID.ValueString())
if err != nil {
diags.AddError("UpdateVFpool: Cannot parse ID from state", err.Error())
return diags
}
req := vfpool.UpdateRequest{
VFPoolID: uint64(ID),
}
if !plan.Name.Equal(state.Name) {
req.Name = plan.Name.ValueString()
}
if !plan.Description.Equal(state.Description) {
req.Description = plan.Description.ValueString()
}
if !plan.Config.Equal(state.Config) && !plan.Config.IsNull() {
configList := make([]models.ResourceItemVFPoolConfigModel, 0, len(plan.Config.Elements()))
diags.Append(plan.Config.ElementsAs(ctx, &configList, true)...)
if diags.HasError() {
tflog.Error(ctx, "UpdateVFpool: cannot populate UpdateVFpool with plan.Config object element")
return diags
}
config := make([]vfpool.Config, 0, len(configList))
for _, v := range configList {
vfIDs := make([]uint64, 0, len(v.VFIDs.Elements()))
diags.Append(v.VFIDs.ElementsAs(ctx, &vfIDs, true)...)
if diags.HasError() {
tflog.Error(ctx, "UpdateVFpool: cannot populate UpdateVFpool with vfIDs object element")
return diags
}
item := vfpool.Config{
NodeID: uint64(v.NodeID.ValueInt64()),
NicName: v.NicName.ValueString(),
VFIDs: vfIDs}
config = append(config, item)
}
req.Config = config
}
if !plan.AccountAccess.Equal(state.AccountAccess) && !plan.AccountAccess.IsNull() {
aaList := make([]uint64, 0, len(plan.AccountAccess.Elements()))
diags.Append(plan.AccountAccess.ElementsAs(ctx, &aaList, true)...)
if diags.HasError() {
tflog.Error(ctx, "UpdateVFpool: cannot populate UpdateVFpool with plan.AccountAccess object element")
return diags
}
req.AccountAccess = aaList
}
if !plan.RGAccess.Equal(state.RGAccess) && !plan.RGAccess.IsNull() {
rgAccessList := make([]uint64, 0, len(plan.RGAccess.Elements()))
diags.Append(plan.RGAccess.ElementsAs(ctx, &rgAccessList, true)...)
if diags.HasError() {
tflog.Error(ctx, "UpdateVFpool: cannot populate UpdateVFpool with plan.RGAccess object element")
return diags
}
req.RGAccess = rgAccessList
}
if state.Status.ValueString() == "ENABLED" || state.Status.ValueString() == "CREATED" {
reqDisable := vfpool.DisableRequest{
VFPoolID: uint64(ID),
}
tflog.Info(ctx, fmt.Sprintf("UpdateVFpool: need to disable vfPool with ID: %d, after update", ID))
_, err = c.CloudBroker().VFPool().Disable(ctx, reqDisable)
if err != nil {
diags.AddWarning(
"UpdateVFpool: cannot disable VFPool",
err.Error(),
)
return diags
}
tflog.Info(ctx, "utilityVFPoolUpdate: disable VFPool with complete")
}
_, err = c.CloudBroker().VFPool().Update(ctx, req)
if err != nil {
diags.AddError("EnableDisableVFpool: Cannot update", err.Error())
return diags
}
tflog.Info(ctx, fmt.Sprintf("utilityVFPoolUpdate: update vfPool with ID: %d, complete with params=%v", ID, req))
if plan.Enable.ValueBool() {
reqEnable := vfpool.EnableRequest{
VFPoolID: uint64(ID),
}
tflog.Info(ctx, fmt.Sprintf("utilityVFPoolUpdate: start to enable vfPool with ID: %d, after update", ID))
_, err = c.CloudBroker().VFPool().Enable(ctx, reqEnable)
if err != nil {
diags.AddWarning(
"UpdateVFpool: cannot enable VFPool",
err.Error(),
)
return diags
}
tflog.Info(ctx, fmt.Sprintf("utilityVFPoolUpdate: enable vfPool with ID: %d, complete", ID))
} else {
diags.AddWarning(
"UpdateVFpool: vfPool is not enabled",
"the vfPool is not enabled after update, you must provide configuration for this resource, after enabling it",
)
return diags
}
return nil
}
6 months ago
func checkParamsExistence(ctx context.Context, accountIDs, rgIDs []uint64, c *client.Client) diag.Diagnostics {
12 months ago
diags := diag.Diagnostics{}
if err := ic.ExistAccounts(ctx, accountIDs, c); err != nil {
diags.AddError("Error check input values", err.Error())
}
if err := ic.ExistRGs(ctx, rgIDs, c); err != nil {
diags.AddError("Error check input values", err.Error())
}
return diags
}