1.0.0
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/ic"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s/models"
|
||||
)
|
||||
|
||||
func CheckParamsExistenceCP(ctx context.Context, plan *models.ResourceK8SCPModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
if err := ic.ExistRG(ctx, uint64(plan.RGID.ValueInt64()), c); err != nil {
|
||||
diags.AddError("Error check input values", err.Error())
|
||||
}
|
||||
|
||||
if err := ic.ExistK8CI(ctx, uint64(plan.K8SCIID.ValueInt64()), c); err != nil {
|
||||
diags.AddError("Error check input values", err.Error())
|
||||
}
|
||||
|
||||
if err := ic.ExistExtNetInK8s(ctx, uint64(plan.ExtNetID.ValueInt64()), c); err != nil {
|
||||
diags.AddError("Error check input values", err.Error())
|
||||
}
|
||||
|
||||
if err := ic.ExistVinsInK8s(ctx, uint64(plan.VinsId.ValueInt64()), c); err != nil {
|
||||
diags.AddError("Error check input values", err.Error())
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
func CheckParamsExistenceWG(ctx context.Context, plan *models.ResourceK8SWGModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
if err := ic.ExistK8s(ctx, uint64(plan.K8SID.ValueInt64()), c); err != nil {
|
||||
diags.AddError("Error check input values", err.Error())
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8ci"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s/models"
|
||||
)
|
||||
|
||||
func K8ciListCheckPresence(ctx context.Context, state *models.K8ciListModel, c *decort.DecortClient) (*k8ci.ListK8CI, error) {
|
||||
tflog.Info(ctx, "Get k8ci list info")
|
||||
|
||||
req := k8ci.ListRequest{}
|
||||
|
||||
if !state.ByID.IsNull() {
|
||||
req.ByID = uint64(state.ByID.ValueInt64())
|
||||
}
|
||||
if !state.Name.IsNull() {
|
||||
req.Name = state.Name.ValueString()
|
||||
}
|
||||
if !state.Status.IsNull() {
|
||||
req.Status = state.Status.ValueString()
|
||||
}
|
||||
if !state.WorkerDriver.IsNull() {
|
||||
req.WorkerDriver = state.WorkerDriver.ValueString()
|
||||
}
|
||||
if !state.MasterDriver.IsNull() {
|
||||
req.MasterDriver = state.MasterDriver.ValueString()
|
||||
}
|
||||
if !state.NetworkPlugins.IsNull() {
|
||||
req.NetworkPlugins = state.NetworkPlugins.ValueString()
|
||||
}
|
||||
if !state.IncludeDisabled.IsNull() {
|
||||
req.IncludeDisabled = state.IncludeDisabled.ValueBool()
|
||||
}
|
||||
if !state.SortBy.IsNull() {
|
||||
req.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
req.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
req.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
|
||||
k8sList, err := c.CloudAPI().K8CI().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting k8ci list info, successfully")
|
||||
return k8sList, nil
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s/models"
|
||||
)
|
||||
|
||||
func K8sListCheckPresence(ctx context.Context, state *models.K8SListModel, c *decort.DecortClient) (*k8s.ListK8SClusters, error) {
|
||||
tflog.Info(ctx, "Get k8s list info")
|
||||
|
||||
req := k8s.ListRequest{}
|
||||
|
||||
if !state.ByID.IsNull() {
|
||||
req.ByID = uint64(state.ByID.ValueInt64())
|
||||
}
|
||||
if !state.Name.IsNull() {
|
||||
req.Name = state.Name.ValueString()
|
||||
}
|
||||
if !state.IPAddress.IsNull() {
|
||||
req.IPAddress = state.IPAddress.ValueString()
|
||||
}
|
||||
if !state.RGID.IsNull() {
|
||||
req.RGID = uint64(state.RGID.ValueInt64())
|
||||
}
|
||||
if !state.LBID.IsNull() {
|
||||
req.LBID = uint64(state.LBID.ValueInt64())
|
||||
}
|
||||
if !state.BasicServiceID.IsNull() {
|
||||
req.BasicServiceID = uint64(state.BasicServiceID.ValueInt64())
|
||||
}
|
||||
if !state.Status.IsNull() {
|
||||
req.Status = state.Status.ValueString()
|
||||
}
|
||||
if !state.TechStatus.IsNull() {
|
||||
req.TechStatus = state.TechStatus.ValueString()
|
||||
}
|
||||
if !state.IncludeDeleted.IsNull() {
|
||||
req.IncludeDeleted = state.IncludeDeleted.ValueBool()
|
||||
}
|
||||
if !state.SortBy.IsNull() {
|
||||
req.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
req.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
req.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
|
||||
k8sList, err := c.CloudAPI().K8S().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting k8s list info, successfully")
|
||||
return k8sList, nil
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s/models"
|
||||
)
|
||||
|
||||
func K8sListDeletedCheckPresence(ctx context.Context, state *models.K8SListDeletedModel, c *decort.DecortClient) (*k8s.ListK8SClusters, error) {
|
||||
tflog.Info(ctx, "Get k8s list deleted info")
|
||||
|
||||
req := k8s.ListDeletedRequest{}
|
||||
|
||||
if !state.ByID.IsNull() {
|
||||
req.ByID = uint64(state.ByID.ValueInt64())
|
||||
}
|
||||
if !state.Name.IsNull() {
|
||||
req.Name = state.Name.ValueString()
|
||||
}
|
||||
if !state.IPAddress.IsNull() {
|
||||
req.IPAddress = state.IPAddress.ValueString()
|
||||
}
|
||||
if !state.RGID.IsNull() {
|
||||
req.RGID = uint64(state.RGID.ValueInt64())
|
||||
}
|
||||
if !state.LBID.IsNull() {
|
||||
req.LBID = uint64(state.LBID.ValueInt64())
|
||||
}
|
||||
if !state.BasicServiceID.IsNull() {
|
||||
req.BasicServiceID = uint64(state.BasicServiceID.ValueInt64())
|
||||
}
|
||||
if !state.TechStatus.IsNull() {
|
||||
req.TechStatus = state.TechStatus.ValueString()
|
||||
}
|
||||
if !state.SortBy.IsNull() {
|
||||
req.SortBy = state.SortBy.ValueString()
|
||||
}
|
||||
if !state.Size.IsNull() {
|
||||
req.Size = uint64(state.Size.ValueInt64())
|
||||
}
|
||||
if !state.Page.IsNull() {
|
||||
req.Page = uint64(state.Page.ValueInt64())
|
||||
}
|
||||
|
||||
k8sList, err := c.CloudAPI().K8S().ListDeleted(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting k8s list deleted info, successfully")
|
||||
return k8sList, nil
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"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/compute"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s/models"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/status"
|
||||
)
|
||||
|
||||
func CreateRequestResourceK8CP(ctx context.Context, plan *models.ResourceK8SCPModel) k8s.CreateRequest {
|
||||
tflog.Info(ctx, "Start CreateRequestResourceK8CP", map[string]any{"name": plan.Name.ValueString()})
|
||||
req := k8s.CreateRequest{
|
||||
Name: plan.Name.ValueString(),
|
||||
RGID: uint64(plan.RGID.ValueInt64()),
|
||||
K8SCIID: uint64(plan.K8SCIID.ValueInt64()),
|
||||
WorkerGroupName: "temp",
|
||||
NetworkPlugin: plan.NetworkPlugin.ValueString(),
|
||||
}
|
||||
|
||||
if !plan.Num.IsUnknown() {
|
||||
req.MasterNum = uint(plan.Num.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.CPU.IsUnknown() {
|
||||
req.MasterCPU = uint(plan.CPU.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.RAM.IsUnknown() {
|
||||
req.MasterRAM = uint64(plan.RAM.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.Disk.IsUnknown() {
|
||||
req.MasterDisk = uint(plan.Disk.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.SEPID.IsNull() {
|
||||
req.MasterSEPID = uint64(plan.SEPID.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.SEPPool.IsNull() {
|
||||
req.MasterSEPPool = plan.SEPPool.ValueString()
|
||||
}
|
||||
|
||||
if !plan.WithLB.IsNull() {
|
||||
req.WithLB = plan.WithLB.ValueBool()
|
||||
} else {
|
||||
req.WithLB = true
|
||||
}
|
||||
|
||||
if !plan.ExtNetID.IsUnknown() {
|
||||
req.ExtNetID = uint64(plan.ExtNetID.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.VinsId.IsUnknown() {
|
||||
req.VinsId = uint64(plan.VinsId.ValueInt64())
|
||||
}
|
||||
|
||||
if !plan.HighlyAvailable.IsNull() {
|
||||
req.HighlyAvailable = plan.HighlyAvailable.ValueBool()
|
||||
}
|
||||
|
||||
if !plan.AdditionalSANs.IsNull() {
|
||||
result := make([]string, 0, len(plan.AdditionalSANs.Elements()))
|
||||
for _, val := range plan.AdditionalSANs.Elements() {
|
||||
result = append(result, strings.Trim(val.String(), "\""))
|
||||
}
|
||||
req.AdditionalSANs = result
|
||||
}
|
||||
|
||||
if !plan.ClusterConfiguration.IsNull() {
|
||||
req.ClusterConfiguration = plan.ClusterConfiguration.ValueString()
|
||||
}
|
||||
|
||||
if !plan.KubeletConfiguration.IsNull() {
|
||||
req.KubeletConfiguration = plan.KubeletConfiguration.ValueString()
|
||||
}
|
||||
|
||||
if !plan.KubeProxyConfiguration.IsNull() {
|
||||
req.KubeProxyConfiguration = plan.KubeProxyConfiguration.ValueString()
|
||||
}
|
||||
|
||||
if !plan.InitConfiguration.IsNull() {
|
||||
req.InitConfiguration = plan.InitConfiguration.ValueString()
|
||||
}
|
||||
|
||||
if !plan.OidcCertificate.IsNull() {
|
||||
req.OidcCertificate = plan.OidcCertificate.ValueString()
|
||||
}
|
||||
|
||||
if !plan.Description.IsNull() {
|
||||
req.Description = plan.Description.ValueString()
|
||||
}
|
||||
|
||||
if !plan.ExtNetOnly.IsNull() {
|
||||
req.ExtNetOnly = plan.ExtNetOnly.ValueBool()
|
||||
}
|
||||
|
||||
if !plan.LBSysctlParams.IsNull() {
|
||||
result := make([]map[string]interface{}, 0, len(plan.LBSysctlParams.Elements()))
|
||||
for _, val := range plan.LBSysctlParams.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)
|
||||
}
|
||||
req.LbSysctlParams = result
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "End CreateRequestResourceK8CP", map[string]any{"name": plan.Name.String()})
|
||||
return req
|
||||
}
|
||||
|
||||
func CheckResourceK8SCPCreateAndDeleteWG(ctx context.Context, plan *models.ResourceK8SCPModel, c *decort.DecortClient, resp string) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start CheckResourceK8CPCreateAndDeleteWG", map[string]any{"name": plan.Name.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
taskReq := tasks.GetRequest{
|
||||
AuditID: strings.Trim(resp, `"`),
|
||||
}
|
||||
for {
|
||||
task, err := c.CloudAPI().Tasks().Get(ctx, taskReq)
|
||||
if err != nil {
|
||||
diags.AddError("The audit cannot be found", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, fmt.Sprintf("ResourceK8sControlPlaneCreate instance creating - %s", task.Stage))
|
||||
|
||||
if task.Completed {
|
||||
if task.Error != "" {
|
||||
diags.AddError("Cannot create cluster instance:", task.Error)
|
||||
return diags
|
||||
}
|
||||
|
||||
result, err := task.Result.ID()
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get cluster ID:", err.Error())
|
||||
return diags
|
||||
}
|
||||
plan.Id = types.StringValue(strconv.Itoa(result))
|
||||
plan.LastUpdated = types.StringValue(time.Now().Format(time.RFC850))
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 20)
|
||||
}
|
||||
|
||||
k8sID, err := strconv.ParseUint(plan.Id.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot parsed ID cluster from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
cluster, err := K8SCPResourceCheckPresence(ctx, k8sID, c)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about cluster ", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Start delete Work Group from cluster with ID", map[string]any{"k8s_id": k8sID})
|
||||
|
||||
delWGReq := k8s.WorkersGroupDeleteRequest{
|
||||
K8SID: cluster.ID,
|
||||
WorkersGroupID: cluster.K8SGroups.Workers[0].ID,
|
||||
}
|
||||
|
||||
_, err = c.CloudAPI().K8S().WorkersGroupDelete(ctx, delWGReq)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot create cluster with ID - %d: platform error, creation cancelled, cluster will be delete permanently", cluster.ID), err.Error())
|
||||
|
||||
tflog.Error(ctx, "Start delete cluster with ID", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
|
||||
_, err = c.CloudAPI().K8S().Delete(ctx, k8s.DeleteRequest{K8SID: cluster.ID, Permanently: true})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot delete cluster with ID - %d, after error creation. Please report this issue to the provider developers.", cluster.ID), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Error(ctx, "Delete cluster successfully", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "End CheckResourceK8CPCreateAndDeleteWG", map[string]any{"k8s_id": cluster.ID})
|
||||
return diags
|
||||
}
|
||||
|
||||
func K8SCPResourceCheckPresence(ctx context.Context, k8SID uint64, c *decort.DecortClient) (*k8s.RecordK8S, error) {
|
||||
tflog.Info(ctx, "Get info about cluster with ID", map[string]any{"k8s_id": k8SID})
|
||||
|
||||
cluster, err := c.CloudAPI().K8S().Get(ctx, k8s.GetRequest{K8SID: k8SID})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get info about cluster with error: %w", err)
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting info about cluster successfully", map[string]any{"k8s_id": k8SID})
|
||||
return cluster, nil
|
||||
}
|
||||
|
||||
func K8sListForResourceCheckPresence(ctx context.Context, k8SID uint64, c *decort.DecortClient) (*k8s.ListK8SClusters, error) {
|
||||
tflog.Info(ctx, "Get info in List about cluster with ID", map[string]any{"k8s_id": k8SID})
|
||||
|
||||
req := k8s.ListRequest{
|
||||
IncludeDeleted: false,
|
||||
ByID: k8SID,
|
||||
}
|
||||
|
||||
k8sList, err := c.CloudAPI().K8S().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Getting info in List about cluster successfully", map[string]any{"k8s_id": k8SID})
|
||||
return k8sList, nil
|
||||
}
|
||||
|
||||
func ComputeCheckPresence(ctx context.Context, computeID uint64, c *decort.DecortClient) (*compute.RecordCompute, error) {
|
||||
tflog.Info(ctx, "Start utilityComputeCheckPresence", map[string]any{"compute_id": computeID})
|
||||
|
||||
req := compute.GetRequest{
|
||||
ComputeID: computeID,
|
||||
}
|
||||
|
||||
compute, err := c.CloudAPI().Compute().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "End utilityComputeCheckPresence", map[string]any{"compute_id": computeID})
|
||||
return compute, nil
|
||||
}
|
||||
|
||||
func K8SCPUpdateNameOrDescription(ctx context.Context, plan, state *models.ResourceK8SCPModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Update info about cluster with ID", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
k8sID, err := strconv.ParseUint(plan.Id.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot parsed ID cluster from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
req := k8s.UpdateRequest{
|
||||
K8SID: k8sID,
|
||||
}
|
||||
|
||||
if !plan.Name.Equal(state.Name) {
|
||||
req.Name = plan.Name.ValueString()
|
||||
}
|
||||
|
||||
if !plan.Description.Equal(state.Description) {
|
||||
req.Description = plan.Description.ValueString()
|
||||
}
|
||||
|
||||
_, err = c.CloudAPI().K8S().Update(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot update cluster with ID - %s", plan.Id.ValueString()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Update info about cluster successfully", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func K8SCPReadStatus(ctx context.Context, plan *models.ResourceK8SCPModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Read status cluster with ID", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
k8sID, err := strconv.ParseUint(plan.Id.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot parsed ID cluster from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
cluster, err := K8SCPResourceCheckPresence(ctx, k8sID, c)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about cluster ", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
switch cluster.Status {
|
||||
case status.Modeled:
|
||||
diags.AddError("Error:", fmt.Sprintf("The k8s cluster is in status: %s, please, contact support for more information", cluster.Status))
|
||||
return diags
|
||||
case status.Deleted:
|
||||
if plan.Restore.ValueBool() || plan.Restore.IsNull() {
|
||||
diags = K8SCPRestore(ctx, plan, c)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "Error restore cluster", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
} else {
|
||||
diags.AddError("Cluster in status Deleted:", "please clean state, or restore cluster")
|
||||
return diags
|
||||
}
|
||||
if plan.Enabled.ValueBool() || plan.Enabled.IsNull() {
|
||||
diags = K8SCPEnableDisable(ctx, plan, c)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "Error enable/disable cluster", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
if plan.Start.ValueBool() || plan.Start.IsNull() {
|
||||
diags = K8SCPStartStop(ctx, plan, c)
|
||||
if diags.HasError() {
|
||||
tflog.Error(ctx, "Error start/stop cluster", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
}
|
||||
}
|
||||
case status.Destroying:
|
||||
diags.AddError("Error:", fmt.Sprintf("The k8s cluster is in progress with status: %s", cluster.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 cluster successfully", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func K8SCPRestore(ctx context.Context, plan *models.ResourceK8SCPModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Restore cluster with ID", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
k8sID, err := strconv.ParseUint(plan.Id.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot parsed ID cluster from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
_, err = c.CloudAPI().K8S().Restore(ctx, k8s.RestoreRequest{K8SID: k8sID})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot restore cluster with ID - %s", plan.Id.ValueString()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Restore cluster successfully", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func K8SCPEnableDisable(ctx context.Context, plan *models.ResourceK8SCPModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Enable/Disable cluster with ID", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
k8sID, err := strconv.ParseUint(plan.Id.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot parsed ID cluster from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
if plan.Enabled.ValueBool() || plan.Enabled.IsNull() {
|
||||
_, err := c.CloudAPI().K8S().Enable(ctx, k8s.DisableEnableRequest{K8SID: k8sID})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot enable cluster with ID - %s", plan.Id.ValueString()), err.Error())
|
||||
return diags
|
||||
}
|
||||
}
|
||||
if !plan.Enabled.ValueBool() && !plan.Enabled.IsNull() {
|
||||
_, err := c.CloudAPI().K8S().Disable(ctx, k8s.DisableEnableRequest{K8SID: k8sID})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot disable cluster with ID - %s", plan.Id.ValueString()), err.Error())
|
||||
return diags
|
||||
}
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Enable/Disable cluster successfully", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func K8SCPStartStop(ctx context.Context, plan *models.ResourceK8SCPModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start/Stop cluster with ID", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
k8sID, err := strconv.ParseUint(plan.Id.ValueString(), 10, 64)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot parsed ID cluster from state", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
if plan.Enabled.ValueBool() || plan.Enabled.IsNull() {
|
||||
if plan.Start.ValueBool() || plan.Start.IsNull() {
|
||||
_, err := c.CloudAPI().K8S().Start(ctx, k8s.StartRequest{K8SID: k8sID})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot start cluster with ID - %s", plan.Id.ValueString()), err.Error())
|
||||
return diags
|
||||
}
|
||||
}
|
||||
}
|
||||
if plan.Enabled.ValueBool() || plan.Enabled.IsNull() {
|
||||
if !plan.Start.ValueBool() && !plan.Start.IsNull() {
|
||||
_, err := c.CloudAPI().K8S().Stop(ctx, k8s.StopRequest{K8SID: k8sID})
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot stop cluster with ID - %s", plan.Id.ValueString()), err.Error())
|
||||
return diags
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Start/Stop cluster successfully", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func K8SCPDeleteMaster(ctx context.Context, plan *models.ResourceK8SCPModel, state *models.ResourceK8SCPModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Delete Master node from cluster with ID", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
deleteMasterComp := make([]string, 0)
|
||||
|
||||
for i, val := range state.DetailedInfo.Elements() {
|
||||
if i == 2 {
|
||||
break
|
||||
}
|
||||
obj, err := types.ObjectValueFrom(ctx, models.ItemDetailedInfo, val)
|
||||
if err != nil {
|
||||
tflog.Error(ctx, fmt.Sprint("Error flattenDetailedInfo struct to obj", err), map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
}
|
||||
id := obj.Attributes()["compute_id"]
|
||||
|
||||
deleteMasterComp = append(deleteMasterComp, id.String())
|
||||
}
|
||||
|
||||
req := k8s.DeleteMasterFromGroupRequest{
|
||||
K8SID: uint64(state.K8SID.ValueInt64()),
|
||||
MasterGroupID: uint64(state.MasterGroupId.ValueInt64()),
|
||||
MasterIDs: deleteMasterComp,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().K8S().DeleteMasterFromGroup(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot delete master node from cluster with ID - %s", plan.Id.ValueString()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Delete Master node from cluster successfully", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func K8CPUpdateSysctlParams(ctx context.Context, plan *models.ResourceK8SCPModel, state *models.ResourceK8SCPModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Update LB parameters from cluster with ID", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
diags := diag.Diagnostics{}
|
||||
result := make([]map[string]interface{}, 0, len(plan.LBSysctlParams.Elements()))
|
||||
for _, val := range plan.LBSysctlParams.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)
|
||||
}
|
||||
|
||||
req := lb.UpdateSysctParamsRequest{
|
||||
LBID: uint64(state.LBID.ValueInt64()),
|
||||
SysctlParams: result,
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().LB().UpdateSysctlParams(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot update LB parameters from cluster with ID - %s", plan.Id.ValueString()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Update LB parameters from cluster with ID successfully", map[string]any{"k8s_id": plan.Id.ValueString()})
|
||||
return diags
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package utilities
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"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/k8s"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s/models"
|
||||
)
|
||||
|
||||
func CreateRequestResourceK8WG(ctx context.Context, plan *models.ResourceK8SWGModel) k8s.WorkersGroupAddRequest {
|
||||
tflog.Info(ctx, "Start CreateRequestResourceK8WG", map[string]any{"name": plan.Name.ValueString()})
|
||||
req := k8s.WorkersGroupAddRequest{
|
||||
K8SID: uint64(plan.K8SID.ValueInt64()),
|
||||
Name: plan.Name.ValueString(),
|
||||
}
|
||||
|
||||
if !plan.WorkerSEPID.IsNull() {
|
||||
req.WorkerSEPID = uint64(plan.WorkerSEPID.ValueInt64())
|
||||
} else {
|
||||
req.WorkerSEPID = 0
|
||||
}
|
||||
if !plan.WorkerSEPPool.IsNull() {
|
||||
req.WorkerSEPPool = plan.WorkerSEPPool.ValueString()
|
||||
}
|
||||
if !plan.Num.IsUnknown() {
|
||||
req.WorkerNum = uint64(plan.Num.ValueInt64())
|
||||
} else {
|
||||
req.WorkerNum = 1
|
||||
}
|
||||
if !plan.CPU.IsUnknown() {
|
||||
req.WorkerCPU = uint64(plan.CPU.ValueInt64())
|
||||
} else {
|
||||
req.WorkerCPU = 1
|
||||
}
|
||||
if !plan.RAM.IsUnknown() {
|
||||
req.WorkerRAM = uint64(plan.RAM.ValueInt64())
|
||||
} else {
|
||||
req.WorkerRAM = 1024
|
||||
}
|
||||
if !plan.Disk.IsUnknown() {
|
||||
req.WorkerDisk = uint64(plan.Disk.ValueInt64())
|
||||
} else {
|
||||
req.WorkerDisk = 0
|
||||
}
|
||||
if !plan.Annotations.IsUnknown() {
|
||||
result := make([]string, 0, len(plan.Annotations.Elements()))
|
||||
for _, val := range plan.Annotations.Elements() {
|
||||
result = append(result, strings.Trim(val.String(), "\""))
|
||||
}
|
||||
req.Annotations = result
|
||||
}
|
||||
if !plan.Labels.IsUnknown() {
|
||||
result := make([]string, 0, len(plan.Labels.Elements()))
|
||||
for _, val := range plan.Labels.Elements() {
|
||||
result = append(result, strings.Trim(val.String(), "\""))
|
||||
}
|
||||
|
||||
req.Labels = result
|
||||
}
|
||||
if !plan.Taints.IsUnknown() {
|
||||
result := make([]string, 0, len(plan.Taints.Elements()))
|
||||
for _, val := range plan.Taints.Elements() {
|
||||
result = append(result, strings.Trim(val.String(), "\""))
|
||||
}
|
||||
req.Taints = result
|
||||
}
|
||||
if !plan.CloudInit.IsNull() {
|
||||
req.UserData = plan.CloudInit.ValueString()
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "End CreateRequestResourceK8WG", map[string]any{"name": plan.Name.ValueString()})
|
||||
return req
|
||||
}
|
||||
|
||||
func ResourceK8SWGCreate(ctx context.Context, plan *models.ResourceK8SWGModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Start ResourceK8SWGCreate", map[string]any{"name": plan.Name.ValueString(), "k8s_id": plan.K8SID.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
// Make request and get response
|
||||
wgId, err := c.CloudAPI().K8S().WorkersGroupAdd(ctx, CreateRequestResourceK8WG(ctx, plan))
|
||||
if err != nil {
|
||||
tflog.Error(ctx, "Error response for create k8s_wg")
|
||||
diags.AddError("Unable to Create K8SWG", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
plan.Id = types.StringValue(strconv.Itoa(int(wgId)))
|
||||
plan.LastUpdated = types.StringValue(time.Now().Format(time.RFC850))
|
||||
|
||||
wg, k8sId, err := K8SWGResourceCheckPresence(ctx, plan, c)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about wg ", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "End ResourceK8SWGCreate", map[string]any{"k8s_id": k8sId, "k8s_wg": wg.ID})
|
||||
return diags
|
||||
}
|
||||
|
||||
func K8SWGResourceCheckPresence(ctx context.Context, plan *models.ResourceK8SWGModel, c *decort.DecortClient) (*k8s.ItemK8SGroup, uint64, error) {
|
||||
tflog.Info(ctx, "Get info about wg with ID", map[string]any{"wg_id": plan.Id.ValueString()})
|
||||
|
||||
var wgId int
|
||||
var k8sId int
|
||||
var err error
|
||||
|
||||
ids := strings.Split(plan.Id.ValueString(), "#")
|
||||
if len(ids) == 2 {
|
||||
k8sId, err = strconv.Atoi(ids[0])
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
wgId, err = strconv.Atoi(ids[1])
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
} else {
|
||||
wgId, err = strconv.Atoi(plan.Id.ValueString())
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
k8sId = int(plan.K8SID.ValueInt64())
|
||||
}
|
||||
|
||||
cluster, err := c.CloudAPI().K8S().Get(ctx, k8s.GetRequest{K8SID: uint64(k8sId)})
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("cannot get info about cluster with error: %w", err)
|
||||
}
|
||||
|
||||
for _, wg := range cluster.K8SGroups.Workers {
|
||||
if wg.ID == uint64(wgId) {
|
||||
tflog.Info(ctx, "Getting info about wg successfully", map[string]any{"wg_id": plan.Id.ValueString()})
|
||||
return &wg, cluster.ID, nil
|
||||
}
|
||||
}
|
||||
|
||||
tflog.Error(ctx, fmt.Sprintf("Getting info about wg end with error - %s", err.Error()))
|
||||
return nil, 0, fmt.Errorf("not found wg with id: %d in k8s cluster: %d", wgId, cluster.ID)
|
||||
}
|
||||
|
||||
func K8SWGUpdateCloudInit(ctx context.Context, plan, state *models.ResourceK8SWGModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Update cloud init in wg with id", map[string]any{"wg_id": state.WorkerGroupId.ValueInt64(), "k8s_id": state.K8SID.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
req := k8s.UpdateWorkerNodesMetaDataRequest{
|
||||
K8SID: uint64(state.K8SID.ValueInt64()),
|
||||
WorkersGroupID: uint64(state.WorkerGroupId.ValueInt64()),
|
||||
UserData: plan.CloudInit.ValueString(),
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().K8S().UpdateWorkerNodesMetaData(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot update cloud init in wg with id: %d", state.WorkerGroupId.ValueInt64()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Update cloud init successfully in wg with id", map[string]any{"wg_id": state.WorkerGroupId.ValueInt64(), "k8s_id": state.K8SID.ValueInt64()})
|
||||
return diags
|
||||
}
|
||||
|
||||
func K8SWGUpdateNumWorkers(ctx context.Context, plan, state *models.ResourceK8SWGModel, c *decort.DecortClient) diag.Diagnostics {
|
||||
tflog.Info(ctx, "Update num workers in wg with id", map[string]any{"wg_id": state.WorkerGroupId.ValueInt64(), "k8s_id": state.K8SID.ValueInt64()})
|
||||
|
||||
diags := diag.Diagnostics{}
|
||||
|
||||
wg, k8sId, err := K8SWGResourceCheckPresence(ctx, plan, c)
|
||||
if err != nil {
|
||||
diags.AddError("Cannot get info about wg ", err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
if newNum := plan.Num.ValueInt64(); uint64(newNum) > wg.Num {
|
||||
req := k8s.WorkerAddRequest{
|
||||
K8SID: k8sId,
|
||||
WorkersGroupID: wg.ID,
|
||||
Num: uint64(newNum) - wg.Num,
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Add workers in wg with id", map[string]any{"wg_id": state.WorkerGroupId.ValueInt64(), "k8s_id": state.K8SID.ValueInt64()})
|
||||
|
||||
_, err := c.CloudAPI().K8S().WorkerAdd(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot add workers in wg with id: %d", state.WorkerGroupId.ValueInt64()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Add workers successfully in wg with id", map[string]any{"wg_id": state.WorkerGroupId.ValueInt64(), "k8s_id": state.K8SID.ValueInt64()})
|
||||
} else {
|
||||
for i := int64(wg.Num) - 1; i >= newNum; i-- {
|
||||
req := k8s.DeleteWorkerFromGroupRequest{
|
||||
K8SID: k8sId,
|
||||
WorkersGroupID: wg.ID,
|
||||
WorkerID: wg.DetailedInfo[i].ID,
|
||||
}
|
||||
tflog.Info(ctx, "Start delete worker in wg with id", map[string]any{"worker_id": wg.DetailedInfo[i].ID, "wg_id": state.WorkerGroupId.ValueInt64(), "k8s_id": state.K8SID.ValueInt64()})
|
||||
|
||||
_, err := c.CloudAPI().K8S().DeleteWorkerFromGroup(ctx, req)
|
||||
if err != nil {
|
||||
diags.AddError(fmt.Sprintf("Cannot delete worker from wg with id: %d", state.WorkerGroupId.ValueInt64()), err.Error())
|
||||
return diags
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "End delete worker successfully in wg with id", map[string]any{"worker_id": wg.DetailedInfo[i].ID, "wg_id": state.WorkerGroupId.ValueInt64(), "k8s_id": state.K8SID.ValueInt64()})
|
||||
}
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Update num workers successfully in wg with id", map[string]any{"wg_id": state.WorkerGroupId.ValueInt64(), "k8s_id": state.K8SID.ValueInt64()})
|
||||
return diags
|
||||
}
|
||||
Reference in New Issue
Block a user