example_resource.go (6206B)
1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package provider 5 6 import ( 7 "context" 8 "fmt" 9 "net/http" 10 11 "github.com/hashicorp/terraform-plugin-framework/path" 12 "github.com/hashicorp/terraform-plugin-framework/resource" 13 "github.com/hashicorp/terraform-plugin-framework/resource/schema" 14 "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" 15 "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" 16 "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" 17 "github.com/hashicorp/terraform-plugin-framework/types" 18 "github.com/hashicorp/terraform-plugin-log/tflog" 19 ) 20 21 // Ensure provider defined types fully satisfy framework interfaces. 22 var _ resource.Resource = &ExampleResource{} 23 var _ resource.ResourceWithImportState = &ExampleResource{} 24 25 func NewExampleResource() resource.Resource { 26 return &ExampleResource{} 27 } 28 29 // ExampleResource defines the resource implementation. 30 type ExampleResource struct { 31 client *http.Client 32 } 33 34 // ExampleResourceModel describes the resource data model. 35 type ExampleResourceModel struct { 36 ConfigurableAttribute types.String `tfsdk:"configurable_attribute"` 37 Defaulted types.String `tfsdk:"defaulted"` 38 Id types.String `tfsdk:"id"` 39 } 40 41 func (r *ExampleResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { 42 resp.TypeName = req.ProviderTypeName + "_example" 43 } 44 45 func (r *ExampleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { 46 resp.Schema = schema.Schema{ 47 // This description is used by the documentation generator and the language server. 48 MarkdownDescription: "Example resource", 49 50 Attributes: map[string]schema.Attribute{ 51 "configurable_attribute": schema.StringAttribute{ 52 MarkdownDescription: "Example configurable attribute", 53 Optional: true, 54 }, 55 "defaulted": schema.StringAttribute{ 56 MarkdownDescription: "Example configurable attribute with default value", 57 Optional: true, 58 Computed: true, 59 Default: stringdefault.StaticString("example value when not configured"), 60 }, 61 "id": schema.StringAttribute{ 62 Computed: true, 63 MarkdownDescription: "Example identifier", 64 PlanModifiers: []planmodifier.String{ 65 stringplanmodifier.UseStateForUnknown(), 66 }, 67 }, 68 }, 69 } 70 } 71 72 func (r *ExampleResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { 73 // Prevent panic if the provider has not been configured. 74 if req.ProviderData == nil { 75 return 76 } 77 78 client, ok := req.ProviderData.(*http.Client) 79 80 if !ok { 81 resp.Diagnostics.AddError( 82 "Unexpected Resource Configure Type", 83 fmt.Sprintf("Expected *http.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 84 ) 85 86 return 87 } 88 89 r.client = client 90 } 91 92 func (r *ExampleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { 93 var data ExampleResourceModel 94 95 // Read Terraform plan data into the model 96 resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 97 98 if resp.Diagnostics.HasError() { 99 return 100 } 101 102 // If applicable, this is a great opportunity to initialize any necessary 103 // provider client data and make a call using it. 104 // httpResp, err := r.client.Do(httpReq) 105 // if err != nil { 106 // resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create example, got error: %s", err)) 107 // return 108 // } 109 110 // For the purposes of this example code, hardcoding a response value to 111 // save into the Terraform state. 112 data.Id = types.StringValue("example-id") 113 114 // Write logs using the tflog package 115 // Documentation: https://terraform.io/plugin/log 116 tflog.Trace(ctx, "created a resource") 117 118 // Save data into Terraform state 119 resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 120 } 121 122 func (r *ExampleResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { 123 var data ExampleResourceModel 124 125 // Read Terraform prior state data into the model 126 resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 127 128 if resp.Diagnostics.HasError() { 129 return 130 } 131 132 // If applicable, this is a great opportunity to initialize any necessary 133 // provider client data and make a call using it. 134 // httpResp, err := r.client.Do(httpReq) 135 // if err != nil { 136 // resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read example, got error: %s", err)) 137 // return 138 // } 139 140 // Save updated data into Terraform state 141 resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 142 } 143 144 func (r *ExampleResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { 145 var data ExampleResourceModel 146 147 // Read Terraform plan data into the model 148 resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 149 150 if resp.Diagnostics.HasError() { 151 return 152 } 153 154 // If applicable, this is a great opportunity to initialize any necessary 155 // provider client data and make a call using it. 156 // httpResp, err := r.client.Do(httpReq) 157 // if err != nil { 158 // resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update example, got error: %s", err)) 159 // return 160 // } 161 162 // Save updated data into Terraform state 163 resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 164 } 165 166 func (r *ExampleResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { 167 var data ExampleResourceModel 168 169 // Read Terraform prior state data into the model 170 resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 171 172 if resp.Diagnostics.HasError() { 173 return 174 } 175 176 // If applicable, this is a great opportunity to initialize any necessary 177 // provider client data and make a call using it. 178 // httpResp, err := r.client.Do(httpReq) 179 // if err != nil { 180 // resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete example, got error: %s", err)) 181 // return 182 // } 183 } 184 185 func (r *ExampleResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { 186 resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) 187 }