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.
356 lines
12 KiB
356 lines
12 KiB
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"
|
|
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
|
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb"
|
|
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/lb/models"
|
|
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/status"
|
|
)
|
|
|
|
func CreateResourceLB(ctx context.Context, plan *models.ResourceLBModel, c *decort.DecortClient) (uint64, diag.Diagnostics) {
|
|
tflog.Info(ctx, fmt.Sprintf("Start create ResourceLB: name %s", plan.Name.ValueString()))
|
|
|
|
diags := diag.Diagnostics{}
|
|
|
|
createReq := lb.CreateRequest{
|
|
Name: plan.Name.ValueString(),
|
|
RGID: uint64(plan.RGID.ValueInt64()),
|
|
ExtNetID: uint64(plan.ExtNetID.ValueInt64()),
|
|
VINSID: uint64(plan.VINSID.ValueInt64()),
|
|
Start: plan.Start.ValueBool(),
|
|
}
|
|
|
|
if plan.HAMode.IsUnknown() { // HAMode is optional & computed
|
|
createReq.HighlyAvailable = false
|
|
} else {
|
|
createReq.HighlyAvailable = plan.HAMode.ValueBool()
|
|
}
|
|
|
|
if !plan.Description.IsNull() { // Description is optional & computed
|
|
createReq.Description = plan.Description.ValueString()
|
|
}
|
|
|
|
if !plan.SysctlParams.IsNull() {
|
|
result := make([]map[string]interface{}, 0, len(plan.SysctlParams.Elements()))
|
|
for _, val := range plan.SysctlParams.Elements() {
|
|
objVal := val.(types.Object)
|
|
valMap := objVal.Attributes()
|
|
mapKey := valMap["key"].(types.String).ValueString()
|
|
mapVal := valMap["value"].(types.String).ValueString()
|
|
tempMap := make(map[string]interface{})
|
|
tempMap[mapKey] = mapVal
|
|
result = append(result, tempMap)
|
|
}
|
|
createReq.SysctlParams = result
|
|
}
|
|
|
|
tflog.Info(ctx, "CreateResourceLB: before call CloudAPI().LB().Create", map[string]any{"req": createReq})
|
|
|
|
lbId, err := c.CloudAPI().LB().Create(ctx, createReq)
|
|
if err != nil {
|
|
diags.AddError("CreateResourceLB: unable to create LB", err.Error())
|
|
return 0, diags
|
|
}
|
|
tflog.Info(ctx, "CreateResourceLB: LB created", map[string]any{"lb_id": lbId, "name": plan.Name.ValueString()})
|
|
|
|
return lbId, nil
|
|
}
|
|
|
|
func LBResourceCheckPresence(ctx context.Context, plan *models.ResourceLBModel, c *decort.DecortClient) (*lb.RecordLB, diag.Diagnostics) {
|
|
tflog.Info(ctx, fmt.Sprintf("LBCheckPresence: Get info about LB with ID - %v", plan.ID.ValueString()))
|
|
|
|
diags := diag.Diagnostics{}
|
|
|
|
lbId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
|
if err != nil {
|
|
diags.AddError("Cannot parsed ID lb from state", err.Error())
|
|
return nil, diags
|
|
}
|
|
|
|
lbItem, err := c.CloudAPI().LB().Get(ctx, lb.GetRequest{LBID: lbId})
|
|
if err != nil {
|
|
diags.AddError(fmt.Sprintf("Cannot get info about lb with ID %v", lbId), err.Error())
|
|
return nil, diags
|
|
}
|
|
|
|
return lbItem, nil
|
|
}
|
|
|
|
func LBEnableDisable(ctx context.Context, plan *models.ResourceLBModel, c *decort.DecortClient) diag.Diagnostics {
|
|
tflog.Info(ctx, "EnableDisable lb with ID", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
diags := diag.Diagnostics{}
|
|
lbId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
|
if err != nil {
|
|
diags.AddError("Cannot parsed ID lb from state", err.Error())
|
|
return diags
|
|
}
|
|
if plan.Enable.IsNull() || plan.Enable.ValueBool() {
|
|
tflog.Info(ctx, "Enable lb with ID", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
_, err := c.CloudAPI().LB().Enable(ctx, lb.DisableEnableRequest{LBID: lbId})
|
|
if err != nil {
|
|
diags.AddError("EnableDisableLB: error to enable LB", err.Error())
|
|
return diags
|
|
}
|
|
} else {
|
|
tflog.Info(ctx, "Disable lb with ID", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
_, err := c.CloudAPI().LB().Disable(ctx, lb.DisableEnableRequest{LBID: lbId})
|
|
if err != nil {
|
|
diags.AddError("EnableDisableLB: error to disable LB", err.Error())
|
|
return diags
|
|
}
|
|
}
|
|
return diags
|
|
}
|
|
|
|
func LBReadStatus(ctx context.Context, plan *models.ResourceLBModel, c *decort.DecortClient) diag.Diagnostics {
|
|
tflog.Info(ctx, "Read status lb with ID", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
|
|
diags := diag.Diagnostics{}
|
|
|
|
lbId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
|
if err != nil {
|
|
diags.AddError("Cannot parsed ID lb from state", err.Error())
|
|
return diags
|
|
}
|
|
|
|
lbItem, err := c.CloudAPI().LB().Get(ctx, lb.GetRequest{LBID: lbId})
|
|
if err != nil {
|
|
diags.AddError(fmt.Sprintf("Cannot get info about lb with ID %v", lbItem), err.Error())
|
|
return diags
|
|
}
|
|
|
|
switch lbItem.Status {
|
|
case status.Modeled:
|
|
diags.AddError("Error:", fmt.Sprintf("The lb is in status: %s, please, contact support for more information", lbItem.Status))
|
|
return diags
|
|
case status.Deleted:
|
|
if plan.Restore.ValueBool() || plan.Restore.IsNull() {
|
|
diags = LBRestore(ctx, plan, c)
|
|
if diags.HasError() {
|
|
tflog.Error(ctx, "Error restore lb", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
return diags
|
|
}
|
|
} else {
|
|
diags.AddError("LB in status Deleted:", "please clean state, or restore lb")
|
|
return diags
|
|
}
|
|
if plan.Enable.ValueBool() || plan.Enable.IsNull() {
|
|
diags = LBEnableDisable(ctx, plan, c)
|
|
if diags.HasError() {
|
|
tflog.Error(ctx, "Error enable/disable lb", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
return diags
|
|
}
|
|
if plan.Start.ValueBool() || plan.Start.IsNull() {
|
|
diags = LBStartStop(ctx, plan, c)
|
|
if diags.HasError() {
|
|
tflog.Error(ctx, "Error start/stop lb", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
return diags
|
|
}
|
|
}
|
|
}
|
|
case status.Destroying:
|
|
diags.AddError("Error:", fmt.Sprintf("The lb is in progress with status: %s", lbItem.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 lb successfully", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
return diags
|
|
}
|
|
|
|
func LBRestore(ctx context.Context, plan *models.ResourceLBModel, c *decort.DecortClient) diag.Diagnostics {
|
|
tflog.Info(ctx, "Restore lb with ID", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
|
|
diags := diag.Diagnostics{}
|
|
|
|
lbId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
|
if err != nil {
|
|
diags.AddError("Cannot parsed ID lb from state", err.Error())
|
|
return diags
|
|
}
|
|
|
|
_, err = c.CloudAPI().LB().Restore(ctx, lb.RestoreRequest{LBID: lbId})
|
|
if err != nil {
|
|
diags.AddError(fmt.Sprintf("Cannot restore lb with ID - %s", plan.ID.ValueString()), err.Error())
|
|
return diags
|
|
}
|
|
|
|
tflog.Info(ctx, "Restore lb successfully", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
return diags
|
|
}
|
|
|
|
func LBStartStop(ctx context.Context, plan *models.ResourceLBModel, c *decort.DecortClient) diag.Diagnostics {
|
|
tflog.Info(ctx, "StartStop lb with ID", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
diags := diag.Diagnostics{}
|
|
lbId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
|
if err != nil {
|
|
diags.AddError("Cannot parsed ID lb from state", err.Error())
|
|
return diags
|
|
}
|
|
if plan.Enable.IsNull() || plan.Enable.ValueBool() {
|
|
if plan.Start.ValueBool() || plan.Start.IsNull() {
|
|
tflog.Info(ctx, "Start lb with ID", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
_, err := c.CloudAPI().LB().Start(ctx, lb.StartRequest{LBID: lbId})
|
|
if err != nil {
|
|
diags.AddError(fmt.Sprintf("Cannot start lb with ID - %s", plan.ID.ValueString()), err.Error())
|
|
return diags
|
|
}
|
|
}
|
|
}
|
|
if plan.Enable.ValueBool() || plan.Enable.IsNull() {
|
|
tflog.Info(ctx, "Stop lb with ID", map[string]any{"lb_id": plan.ID.ValueString()})
|
|
if !plan.Start.ValueBool() && !plan.Start.IsNull() {
|
|
_, err := c.CloudAPI().LB().Stop(ctx, lb.StopRequest{LBID: lbId})
|
|
if err != nil {
|
|
diags.AddError(fmt.Sprintf("Cannot stop lb with ID - %s", plan.ID.ValueString()), err.Error())
|
|
return diags
|
|
}
|
|
}
|
|
}
|
|
|
|
return diags
|
|
}
|
|
|
|
func LBUpdateHaMode(ctx context.Context, state *models.ResourceLBModel, c *decort.DecortClient) diag.Diagnostics {
|
|
tflog.Info(ctx, "Update ha mode from lb with ID", map[string]any{"id": state.ID.ValueString()})
|
|
|
|
diags := diag.Diagnostics{}
|
|
|
|
lbId, err := strconv.ParseUint(state.ID.ValueString(), 10, 64)
|
|
if err != nil {
|
|
diags.AddError("Cannot parsed ID lb from state", err.Error())
|
|
return diags
|
|
}
|
|
|
|
_, err = c.CloudAPI().LB().HighlyAvailable(ctx, lb.HighlyAvailableRequest{LBID: lbId})
|
|
if err != nil {
|
|
diags.AddError(fmt.Sprintf("Cannot update ha mode from lb with ID - %s", state.ID.ValueString()), err.Error())
|
|
return diags
|
|
}
|
|
|
|
tflog.Info(ctx, "Update ha mode from LB with ID successfully", map[string]any{"id": state.ID.ValueString()})
|
|
|
|
return diags
|
|
}
|
|
|
|
func LBUpdateSysctlParams(ctx context.Context, plan *models.ResourceLBModel, state *models.ResourceLBModel, c *decort.DecortClient) diag.Diagnostics {
|
|
tflog.Info(ctx, "Update sysctl parameters from LB with ID", map[string]any{"id": state.ID.ValueString()})
|
|
|
|
diags := diag.Diagnostics{}
|
|
|
|
lbId, err := strconv.ParseUint(state.ID.ValueString(), 10, 64)
|
|
if err != nil {
|
|
diags.AddError("Cannot parsed ID lb from state", err.Error())
|
|
return diags
|
|
}
|
|
|
|
sysctlParams := make([]map[string]interface{}, 0, len(plan.SysctlParams.Elements()))
|
|
for _, val := range plan.SysctlParams.Elements() {
|
|
objVal := val.(types.Object)
|
|
valMap := objVal.Attributes()
|
|
mapKey := valMap["key"].(types.String).ValueString()
|
|
mapVal := valMap["value"].(types.String).ValueString()
|
|
tempMap := make(map[string]interface{})
|
|
tempMap[mapKey] = mapVal
|
|
sysctlParams = append(sysctlParams, tempMap)
|
|
}
|
|
|
|
req := lb.UpdateSysctParamsRequest{
|
|
LBID: lbId,
|
|
SysctlParams: sysctlParams,
|
|
}
|
|
|
|
_, err = c.CloudAPI().LB().UpdateSysctlParams(ctx, req)
|
|
if err != nil {
|
|
diags.AddError(fmt.Sprintf("Cannot update sysctl parameters from LB with ID - %s", state.ID.ValueString()), err.Error())
|
|
return diags
|
|
}
|
|
|
|
tflog.Info(ctx, "Update sysctl parameters from LB with ID successfully", map[string]any{"id": state.ID.ValueString()})
|
|
return diags
|
|
}
|
|
|
|
func LBUpdateDescription(ctx context.Context, plan *models.ResourceLBModel, c *decort.DecortClient) diag.Diagnostics {
|
|
tflog.Info(ctx, "Update description from lb with ID", map[string]any{"id": plan.ID.ValueString()})
|
|
|
|
diags := diag.Diagnostics{}
|
|
|
|
lbId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
|
if err != nil {
|
|
diags.AddError("Cannot parsed ID lb from state", err.Error())
|
|
return diags
|
|
}
|
|
|
|
_, err = c.CloudAPI().LB().Update(ctx, lb.UpdateRequest{LBID: lbId, Description: plan.Description.ValueString()})
|
|
if err != nil {
|
|
diags.AddError(fmt.Sprintf("Cannot update description from lb with ID - %s", plan.ID.ValueString()), err.Error())
|
|
return diags
|
|
}
|
|
|
|
tflog.Info(ctx, "Update description from LB with ID successfully", map[string]any{"id": plan.ID.ValueString()})
|
|
|
|
return diags
|
|
}
|
|
|
|
func LBRestart(ctx context.Context, plan *models.ResourceLBModel, c *decort.DecortClient) diag.Diagnostics {
|
|
tflog.Info(ctx, "Restart lb with ID", map[string]any{"id": plan.ID.ValueString()})
|
|
|
|
diags := diag.Diagnostics{}
|
|
|
|
lbId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
|
if err != nil {
|
|
diags.AddError("Cannot parsed ID lb from state", err.Error())
|
|
return diags
|
|
}
|
|
|
|
req := lb.RestartRequest{
|
|
LBID: lbId,
|
|
Safe: false,
|
|
}
|
|
|
|
if plan.Safe.ValueBool() || plan.Safe.IsNull() {
|
|
req.Safe = true
|
|
}
|
|
|
|
_, err = c.CloudAPI().LB().Restart(ctx, req)
|
|
if err != nil {
|
|
diags.AddError(fmt.Sprintf("Cannot restart lb with ID - %s", plan.ID.ValueString()), err.Error())
|
|
return diags
|
|
}
|
|
|
|
tflog.Info(ctx, "Restart LB with ID successfully", map[string]any{"id": plan.ID.ValueString()})
|
|
|
|
return diags
|
|
}
|
|
|
|
func LBConfigReset(ctx context.Context, plan *models.ResourceLBModel, c *decort.DecortClient) diag.Diagnostics {
|
|
tflog.Info(ctx, "Reset config from lb with ID", map[string]any{"id": plan.ID.ValueString()})
|
|
|
|
diags := diag.Diagnostics{}
|
|
|
|
lbId, err := strconv.ParseUint(plan.ID.ValueString(), 10, 64)
|
|
if err != nil {
|
|
diags.AddError("Cannot parsed ID lb from state", err.Error())
|
|
return diags
|
|
}
|
|
|
|
_, err = c.CloudAPI().LB().ConfigReset(ctx, lb.ConfigResetRequest{LBID: lbId})
|
|
if err != nil {
|
|
diags.AddError(fmt.Sprintf("Cannot reset config from lb with ID - %s", plan.ID.ValueString()), err.Error())
|
|
return diags
|
|
}
|
|
|
|
tflog.Info(ctx, "Reset config from LB with ID successfully", map[string]any{"id": plan.ID.ValueString()})
|
|
|
|
return diags
|
|
}
|