blob: 75e0167b99b92d3d8289e8ff1d3d1d67ce0a6163 [file] [log] [blame] [edit]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"fmt"
"github.com/hashicorp/go-uuid"
"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/terraform-providers/terraform-provider-random/internal/diagnostics"
mapplanmodifiers "github.com/terraform-providers/terraform-provider-random/internal/planmodifiers/map"
)
var (
_ resource.Resource = (*uuidResource)(nil)
_ resource.ResourceWithImportState = (*uuidResource)(nil)
)
func NewUuidResource() resource.Resource {
return &uuidResource{}
}
type uuidResource struct{}
func (r *uuidResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_uuid"
}
func (r *uuidResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "The resource `random_uuid` generates a random uuid string that is intended to be " +
"used as a unique identifier for other resources.\n" +
"\n" +
"This resource uses [hashicorp/go-uuid](https://github.com/hashicorp/go-uuid) to generate a " +
"UUID-formatted string for use with services needing a unique string identifier.",
Attributes: map[string]schema.Attribute{
"keepers": schema.MapAttribute{
Description: "Arbitrary map of values that, when changed, will trigger recreation of " +
"resource. See [the main provider documentation](../index.html) for more information.",
ElementType: types.StringType,
Optional: true,
PlanModifiers: []planmodifier.Map{
mapplanmodifiers.RequiresReplaceIfValuesNotNull(),
},
},
"result": schema.StringAttribute{
Description: "The generated uuid presented in string format.",
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"id": schema.StringAttribute{
Description: "The generated uuid presented in string format.",
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
},
}
}
func (r *uuidResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
result, err := uuid.GenerateUUID()
if err != nil {
resp.Diagnostics.AddError(
"Create Random UUID error",
"There was an error during generation of a UUID.\n\n"+
diagnostics.RetryMsg+
fmt.Sprintf("Original Error: %s", err),
)
return
}
var plan uuidModelV0
diags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
u := &uuidModelV0{
ID: types.StringValue(result),
Result: types.StringValue(result),
Keepers: plan.Keepers,
}
diags = resp.State.Set(ctx, u)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
// Read does not need to perform any operations as the state in ReadResourceResponse is already populated.
func (r *uuidResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
}
// Update ensures the plan value is copied to the state to complete the update.
func (r *uuidResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var model uuidModelV0
resp.Diagnostics.Append(req.Plan.Get(ctx, &model)...)
if resp.Diagnostics.HasError() {
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, &model)...)
}
// Delete does not need to explicitly call resp.State.RemoveResource() as this is automatically handled by the
// [framework](https://github.com/hashicorp/terraform-plugin-framework/pull/301).
func (r *uuidResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
}
func (r *uuidResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
bytes, err := uuid.ParseUUID(req.ID)
if err != nil {
resp.Diagnostics.AddError(
"Import Random UUID Error",
"There was an error during the parsing of the UUID.\n\n"+
diagnostics.RetryMsg+
fmt.Sprintf("Original Error: %s", err),
)
return
}
result, err := uuid.FormatUUID(bytes)
if err != nil {
resp.Diagnostics.AddError(
"Import Random UUID Error",
"There was an error during the formatting of the UUID.\n\n"+
diagnostics.RetryMsg+
fmt.Sprintf("Original Error: %s", err),
)
return
}
var state uuidModelV0
state.ID = types.StringValue(result)
state.Result = types.StringValue(result)
state.Keepers = types.MapValueMust(types.StringType, nil)
diags := resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
type uuidModelV0 struct {
ID types.String `tfsdk:"id"`
Keepers types.Map `tfsdk:"keepers"`
Result types.String `tfsdk:"result"`
}