206 lines
6.6 KiB
Go
206 lines
6.6 KiB
Go
package resources
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
|
||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||
"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/stringdefault"
|
||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||
|
||
"terraform-provider-fission/internal/client"
|
||
)
|
||
|
||
var _ resource.Resource = &MQTriggerResource{}
|
||
|
||
// MQTriggerResource управляет MQ-триггером через K8s Deployment+Secret (sqs-consumer).
|
||
type MQTriggerResource struct {
|
||
client *client.Client
|
||
}
|
||
|
||
type mqTriggerResourceModel struct {
|
||
ID types.String `tfsdk:"id"`
|
||
Name types.String `tfsdk:"name"`
|
||
Namespace types.String `tfsdk:"namespace"`
|
||
Function types.String `tfsdk:"function"`
|
||
Queue types.String `tfsdk:"queue"`
|
||
AccessKey types.String `tfsdk:"access_key"`
|
||
SecretKey types.String `tfsdk:"secret_key"`
|
||
SQSEndpoint types.String `tfsdk:"sqs_endpoint"`
|
||
}
|
||
|
||
func NewMQTriggerResource() resource.Resource {
|
||
return &MQTriggerResource{}
|
||
}
|
||
|
||
func (r *MQTriggerResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||
resp.TypeName = req.ProviderTypeName + "_mq_trigger"
|
||
}
|
||
|
||
func (r *MQTriggerResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||
resp.Schema = schema.Schema{
|
||
Description: "MQ-триггер через K8s Deployment (sqs-consumer) + Secret с SQS credentials.",
|
||
Attributes: map[string]schema.Attribute{
|
||
"id": schema.StringAttribute{
|
||
Computed: true,
|
||
Description: "Идентификатор ресурса (namespace/name).",
|
||
},
|
||
"name": schema.StringAttribute{
|
||
Required: true,
|
||
Description: "Имя MQ trigger.",
|
||
PlanModifiers: []planmodifier.String{
|
||
stringplanmodifier.RequiresReplace(),
|
||
},
|
||
},
|
||
"namespace": schema.StringAttribute{
|
||
Optional: true,
|
||
Computed: true,
|
||
Description: "Kubernetes namespace.",
|
||
PlanModifiers: []planmodifier.String{
|
||
stringplanmodifier.RequiresReplace(),
|
||
},
|
||
},
|
||
"function": schema.StringAttribute{
|
||
Required: true,
|
||
Description: "Имя Fission Function, к которой направляются сообщения из очереди.",
|
||
},
|
||
"queue": schema.StringAttribute{
|
||
Required: true,
|
||
Description: "Имя SQS очереди.",
|
||
},
|
||
"access_key": schema.StringAttribute{
|
||
Required: true,
|
||
Sensitive: true,
|
||
Description: "SQS Access Key.",
|
||
},
|
||
"secret_key": schema.StringAttribute{
|
||
Required: true,
|
||
Sensitive: true,
|
||
Description: "SQS Secret Key.",
|
||
},
|
||
"sqs_endpoint": schema.StringAttribute{
|
||
Optional: true,
|
||
Computed: true,
|
||
Default: stringdefault.StaticString("http://shared-sqs.shared-sqs.svc.cluster.local:4100"),
|
||
Description: "SQS endpoint URL. По умолчанию — внутренний shared-sqs.",
|
||
},
|
||
},
|
||
}
|
||
}
|
||
|
||
func (r *MQTriggerResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
|
||
if req.ProviderData == nil {
|
||
return
|
||
}
|
||
c, ok := req.ProviderData.(*client.Client)
|
||
if !ok {
|
||
resp.Diagnostics.AddError("Неверный тип провайдера", fmt.Sprintf("ожидался *client.Client, получен %T", req.ProviderData))
|
||
return
|
||
}
|
||
r.client = c
|
||
}
|
||
|
||
func (r *MQTriggerResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||
var plan mqTriggerResourceModel
|
||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||
if resp.Diagnostics.HasError() {
|
||
return
|
||
}
|
||
|
||
ns := plan.Namespace.ValueString()
|
||
if ns == "" {
|
||
ns = r.client.Namespace
|
||
}
|
||
|
||
info, err := r.client.CreateMQTrigger(
|
||
ctx,
|
||
plan.Name.ValueString(),
|
||
ns,
|
||
plan.Function.ValueString(),
|
||
plan.Queue.ValueString(),
|
||
plan.SQSEndpoint.ValueString(),
|
||
plan.AccessKey.ValueString(),
|
||
plan.SecretKey.ValueString(),
|
||
)
|
||
if err != nil {
|
||
resp.Diagnostics.AddError("Ошибка создания MQ trigger", err.Error())
|
||
return
|
||
}
|
||
|
||
plan.ID = types.StringValue(ns + "/" + plan.Name.ValueString())
|
||
plan.Namespace = types.StringValue(ns)
|
||
plan.SQSEndpoint = types.StringValue(info.SQSEndpoint)
|
||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||
}
|
||
|
||
func (r *MQTriggerResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||
var state mqTriggerResourceModel
|
||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||
if resp.Diagnostics.HasError() {
|
||
return
|
||
}
|
||
|
||
ns := state.Namespace.ValueString()
|
||
info, err := r.client.GetMQTrigger(ctx, ns, state.Name.ValueString())
|
||
if err != nil {
|
||
if client.IsNotFound(err) {
|
||
resp.State.RemoveResource(ctx)
|
||
return
|
||
}
|
||
resp.Diagnostics.AddError("Ошибка чтения MQ trigger", err.Error())
|
||
return
|
||
}
|
||
|
||
state.Function = types.StringValue(info.Function)
|
||
state.Queue = types.StringValue(info.Queue)
|
||
state.SQSEndpoint = types.StringValue(info.SQSEndpoint)
|
||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||
}
|
||
|
||
func (r *MQTriggerResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||
var plan mqTriggerResourceModel
|
||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||
if resp.Diagnostics.HasError() {
|
||
return
|
||
}
|
||
|
||
ns := plan.Namespace.ValueString()
|
||
name := plan.Name.ValueString()
|
||
|
||
// Удаляем старый и создаём заново с новыми параметрами.
|
||
if err := r.client.DeleteMQTrigger(ctx, ns, name); err != nil {
|
||
resp.Diagnostics.AddError("Ошибка удаления MQ trigger при обновлении", err.Error())
|
||
return
|
||
}
|
||
info, err := r.client.CreateMQTrigger(
|
||
ctx, name, ns,
|
||
plan.Function.ValueString(),
|
||
plan.Queue.ValueString(),
|
||
plan.SQSEndpoint.ValueString(),
|
||
plan.AccessKey.ValueString(),
|
||
plan.SecretKey.ValueString(),
|
||
)
|
||
if err != nil {
|
||
resp.Diagnostics.AddError("Ошибка создания MQ trigger при обновлении", err.Error())
|
||
return
|
||
}
|
||
|
||
plan.SQSEndpoint = types.StringValue(info.SQSEndpoint)
|
||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||
}
|
||
|
||
func (r *MQTriggerResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||
var state mqTriggerResourceModel
|
||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||
if resp.Diagnostics.HasError() {
|
||
return
|
||
}
|
||
|
||
if err := r.client.DeleteMQTrigger(ctx, state.Namespace.ValueString(), state.Name.ValueString()); err != nil {
|
||
resp.Diagnostics.AddError("Ошибка удаления MQ trigger", err.Error())
|
||
}
|
||
}
|