Archived
Validate domain resource and extend DNS record typed fields
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"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/stringplanmodifier"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/dynu/terraform-provider-dynu/internal/dynuclient"
|
||||
)
|
||||
|
||||
var (
|
||||
_ resource.Resource = &domainResource{}
|
||||
_ resource.ResourceWithConfigure = &domainResource{}
|
||||
_ resource.ResourceWithImportState = &domainResource{}
|
||||
)
|
||||
|
||||
type domainResource struct{ clientProvider *providerData }
|
||||
|
||||
type domainResourceModel struct {
|
||||
ID types.Int64 `tfsdk:"id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
IPv4Address types.String `tfsdk:"ipv4_address"`
|
||||
IPv6Address types.String `tfsdk:"ipv6_address"`
|
||||
TTL types.Int64 `tfsdk:"ttl"`
|
||||
Group types.String `tfsdk:"group"`
|
||||
State types.String `tfsdk:"state"`
|
||||
Token types.String `tfsdk:"token"`
|
||||
}
|
||||
|
||||
func NewDomainResource() resource.Resource { return &domainResource{} }
|
||||
func (r *domainResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_domain"
|
||||
}
|
||||
func (r *domainResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{Description: "Manages a Dynu DNS domain.", Attributes: map[string]schema.Attribute{
|
||||
"id": schema.Int64Attribute{Computed: true},
|
||||
"name": schema.StringAttribute{Required: true, PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
|
||||
"ipv4_address": schema.StringAttribute{Optional: true, Computed: true},
|
||||
"ipv6_address": schema.StringAttribute{Optional: true, Computed: true},
|
||||
"ttl": schema.Int64Attribute{Optional: true, Computed: true},
|
||||
"group": schema.StringAttribute{Optional: true, Computed: true},
|
||||
"state": schema.StringAttribute{Computed: true},
|
||||
"token": schema.StringAttribute{Computed: true, Sensitive: true},
|
||||
}}
|
||||
}
|
||||
func (r *domainResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
|
||||
if req.ProviderData == nil {
|
||||
return
|
||||
}
|
||||
providerData, ok := req.ProviderData.(*providerData)
|
||||
if !ok {
|
||||
resp.Diagnostics.AddError("Unexpected resource configure type", fmt.Sprintf("Expected *providerData, got %T", req.ProviderData))
|
||||
return
|
||||
}
|
||||
r.clientProvider = providerData
|
||||
}
|
||||
func (r *domainResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var plan domainResourceModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
domain, err := r.clientProvider.client.CreateDomain(ctx, dynuclient.CreateDomainRequest{Name: plan.Name.ValueString(), IPv4Address: stringFromOptional(plan.IPv4Address), IPv6Address: stringFromOptional(plan.IPv6Address), TTL: int64FromOptional(plan.TTL), Group: stringFromOptional(plan.Group)})
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError(diagnosticSummary("Unable to create Dynu domain", err), err.Error())
|
||||
return
|
||||
}
|
||||
state := mapDomainResource(*domain)
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
func (r *domainResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state domainResourceModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
domain, err := r.clientProvider.client.GetDomainByID(ctx, state.ID.ValueInt64())
|
||||
if err != nil {
|
||||
var apiErr *dynuclient.APIError
|
||||
if errors.As(err, &apiErr) && apiErr.StatusCode == 404 {
|
||||
resp.State.RemoveResource(ctx)
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.AddError(diagnosticSummary("Unable to read Dynu domain", err), err.Error())
|
||||
return
|
||||
}
|
||||
next := mapDomainResource(*domain)
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &next)...)
|
||||
}
|
||||
func (r *domainResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan domainResourceModel
|
||||
var state domainResourceModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
domain, err := r.clientProvider.client.UpdateDomain(ctx, state.ID.ValueInt64(), dynuclient.UpdateDomainRequest{Name: plan.Name.ValueString(), IPv4Address: stringFromOptional(plan.IPv4Address), IPv6Address: stringFromOptional(plan.IPv6Address), TTL: int64FromOptional(plan.TTL), Group: stringFromOptional(plan.Group)})
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError(diagnosticSummary("Unable to update Dynu domain", err), err.Error())
|
||||
return
|
||||
}
|
||||
next := mapDomainResource(*domain)
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &next)...)
|
||||
}
|
||||
func (r *domainResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state domainResourceModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
err := r.clientProvider.client.DeleteDomain(ctx, state.ID.ValueInt64())
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
var apiErr *dynuclient.APIError
|
||||
if errors.As(err, &apiErr) && apiErr.StatusCode == 404 {
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.AddError(diagnosticSummary("Unable to delete Dynu domain", err), err.Error())
|
||||
}
|
||||
func (r *domainResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
id, err := strconv.ParseInt(strings.TrimSpace(req.ID), 10, 64)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Invalid domain import ID", "Use the Dynu numeric domain ID.")
|
||||
return
|
||||
}
|
||||
state := domainResourceModel{ID: types.Int64Value(id)}
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
func mapDomainResource(domain dynuclient.Domain) domainResourceModel {
|
||||
return domainResourceModel{ID: types.Int64Value(domain.ID), Name: types.StringValue(strings.TrimSpace(domain.Name)), IPv4Address: mapString(domain.IPv4Address), IPv6Address: mapString(domain.IPv6Address), TTL: types.Int64Value(domain.TTL), Group: mapString(domain.Group), State: mapString(domain.State), Token: mapString(domain.Token)}
|
||||
}
|
||||
Reference in New Issue
Block a user