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/cloudapi/k8s/resource_k8s_wg.go

270 lines
9.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package k8s
import (
"context"
"time"
"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"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s"
"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/k8s/flattens"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s/models"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s/schemas"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s/utilities"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ resource.Resource = &resourceK8SWG{}
_ resource.ResourceWithImportState = &resourceK8SWG{}
)
// NewResourceK8S_WG is a helper function to simplify the provider implementation.
func NewResourceK8SWG() resource.Resource {
return &resourceK8SWG{}
}
// resourceK8S_WG is the resource implementation.
type resourceK8SWG struct {
client *client.Client
}
// Create the resource and sets the initial Terraform state.
func (r *resourceK8SWG) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var plan models.ResourceK8SWGModel
// Get plan for create cluster
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error receiving the plan")
return
}
tflog.Info(ctx, "Start create k8s_wg", map[string]any{"name": plan.Name.ValueString(), "k8s_id": plan.K8SID.ValueInt64()})
// Set timeouts
createTimeout, diags := plan.Timeouts.Create(ctx, constants.Timeout20m)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error set timeout")
return
}
ctx, cancel := context.WithTimeout(ctx, createTimeout)
defer cancel()
// Сhecking for values in the platform
resp.Diagnostics.Append(utilities.CheckParamsExistenceWG(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error check input values")
return
}
// Create k8s_wg and validated
resp.Diagnostics.Append(utilities.ResourceK8SWGCreate(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error create k8s_wg")
return
}
// Map response body to schema
resp.Diagnostics.Append(flattens.K8SWGResource(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error flatten k8s_wg")
return
}
// Set state to fully populated data
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error set state")
return
}
tflog.Info(ctx, "End create k8s_wg cluster", map[string]any{"k8s_id": plan.K8SID.ValueInt64(), "wg_id": plan.Id.ValueString()})
}
// Read refreshes the Terraform state with the latest data.
func (r *resourceK8SWG) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var state models.ResourceK8SWGModel
// Get current state
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error get state")
return
}
tflog.Info(ctx, "Start read k8s_wg", map[string]any{"wg_id": state.Id.ValueString()})
// Set timeouts
readTimeout, diags := state.Timeouts.Read(ctx, constants.Timeout20m)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error set timeout")
return
}
ctx, cancel := context.WithTimeout(ctx, readTimeout)
defer cancel()
// Overwrite items with refreshed state
resp.Diagnostics.Append(flattens.K8SWGResource(ctx, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error flatten k8s_wg")
return
}
// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error set state")
return
}
tflog.Info(ctx, "End read k8s_wg", map[string]any{"wg_id": state.Id.ValueString()})
}
// Update updates the resource and sets the updated Terraform state on success.
func (r *resourceK8SWG) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var plan models.ResourceK8SWGModel
var state models.ResourceK8SWGModel
// Retrieve values from plan
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error receiving the plan")
return
}
// Retrieve values from state
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error receiving the state")
return
}
tflog.Info(ctx, "Start update k8s_wg", map[string]any{"k8s_id": plan.K8SID.ValueInt64(), "wg_id": plan.WorkerGroupId.ValueInt64()})
// Set timeouts
updateTimeout, diags := plan.Timeouts.Update(ctx, constants.Timeout20m)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error set timeout")
return
}
ctx, cancel := context.WithTimeout(ctx, updateTimeout)
defer cancel()
// Сhecking for values in the platform
resp.Diagnostics.Append(utilities.CheckParamsExistenceWG(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error check input values")
return
}
// Update cloud init
if !plan.CloudInit.Equal(state.CloudInit) {
resp.Diagnostics.Append(utilities.K8SWGUpdateCloudInit(ctx, &plan, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error update cloud init")
return
}
}
// Update num workers
if !plan.Num.Equal(state.Num) {
resp.Diagnostics.Append(utilities.K8SWGUpdateNumWorkers(ctx, &plan, &state, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error update num workers")
return
}
}
// Map response body to schema
resp.Diagnostics.Append(flattens.K8SWGResource(ctx, &plan, r.client)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error flatten k8s_wg")
return
}
// Set data last update
plan.LastUpdated = types.StringValue(time.Now().Format(time.RFC850))
// Set state to fully populated data
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error set state")
return
}
tflog.Info(ctx, "End update k8s_wg", map[string]any{"k8s_id": plan.K8SID.ValueInt64(), "wg_id": plan.WorkerGroupId.ValueInt64()})
}
// Delete deletes the resource and removes the Terraform state on success.
func (r *resourceK8SWG) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
// Get current state
var state models.ResourceK8SWGModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error get state")
return
}
tflog.Info(ctx, "Start delete k8s_wg", map[string]any{"k8s_id": state.K8SID.ValueInt64(), "wg_id": state.WorkerGroupId.ValueInt64()})
// Set timeouts
deleteTimeout, diags := state.Timeouts.Delete(ctx, constants.Timeout20m)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
tflog.Error(ctx, "Error set timeout")
return
}
ctx, cancel := context.WithTimeout(ctx, deleteTimeout)
defer cancel()
// Delete existing k8s_wg
_, err := r.client.CloudAPI().K8S().WorkersGroupDelete(ctx, k8s.WorkersGroupDeleteRequest{K8SID: uint64(state.K8SID.ValueInt64()), WorkersGroupID: uint64(state.WorkerGroupId.ValueInt64())})
if err != nil {
resp.Diagnostics.AddError("Error deleting k8s_wg with error: ", err.Error())
return
}
tflog.Info(ctx, "End delete k8s_wg", map[string]any{"k8s_id": state.K8SID.ValueInt64(), "wg_id": state.WorkerGroupId.ValueInt64()})
}
// Schema defines the schema for the resource.
func (r *resourceK8SWG) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: schemas.MakeSchemaResourceK8SWG(),
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx, timeouts.Opts{Create: true, Read: true, Update: true, Delete: true}),
},
Version: 1,
}
}
// Metadata returns the resource type name.
func (r *resourceK8SWG) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_k8s_wg"
}
// Configure adds the provider configured client to the resource.
func (r *resourceK8SWG) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
tflog.Info(ctx, "Get configure resource")
r.client = client.Resource(ctx, &req, resp)
tflog.Info(ctx, "Getting configure resource successfully")
}
func (r *resourceK8SWG) 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)
}