From 028dbd3715ff2ded33e158b47b1e5020e4ab98d3 Mon Sep 17 00:00:00 2001 From: Reinoldo Krause Junior Date: Thu, 19 Sep 2024 12:34:20 -0300 Subject: [PATCH] feat: Adding substitions input to replace values on files --- examples/README.md | 2 +- .../substitution_example/resource.tf | 8 +++ internal/provider/fhir_resource.go | 68 +++++++++++++++++-- 3 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 examples/resources/substitution_example/resource.tf diff --git a/examples/README.md b/examples/README.md index 026c42c..8e48c91 100644 --- a/examples/README.md +++ b/examples/README.md @@ -6,4 +6,4 @@ The document generation tool looks for files in the following locations by defau * **provider/provider.tf** example file for the provider index page * **data-sources/`full data source name`/data-source.tf** example file for the named data source page -* **resources/`full resource name`/resource.tf** example file for the named data source page +* **resources/`full resource name`/resource.tf** examples files for the named data source page diff --git a/examples/resources/substitution_example/resource.tf b/examples/resources/substitution_example/resource.tf new file mode 100644 index 0000000..9e38042 --- /dev/null +++ b/examples/resources/substitution_example/resource.tf @@ -0,0 +1,8 @@ +resource "fhirrest_fhir_resource" "patient" { + file_path = "${path.cwd}/patient.json" + file_sha256 = sha256(file("${path.cwd}/patient.json")) + substitutions = { + "name" = "John Doe", + "TENANT_PLACEHOLDER" = "my-tenant", + } +} diff --git a/internal/provider/fhir_resource.go b/internal/provider/fhir_resource.go index eb9dc4c..2d7bf8e 100644 --- a/internal/provider/fhir_resource.go +++ b/internal/provider/fhir_resource.go @@ -20,6 +20,7 @@ import ( "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-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-log/tflog" ) @@ -40,13 +41,15 @@ type FhirResource struct { type FhirResourceSettings struct { FhirResourceFilePath string FhirBaseUrl *string + Substitutions map[string]string } type FhirResourceModel struct { // from model - FilePath types.String `tfsdk:"file_path"` - FileSha256 types.String `tfsdk:"file_sha256"` - FhirBaseUrl types.String `tfsdk:"fhir_base_url"` + FilePath types.String `tfsdk:"file_path"` + FileSha256 types.String `tfsdk:"file_sha256"` + FhirBaseUrl types.String `tfsdk:"fhir_base_url"` + Substitutions types.Map `tfsdk:"substitutions"` //actual state ResourceId types.String `tfsdk:"resource_id"` @@ -83,6 +86,33 @@ func (r *FhirResource) Schema(ctx context.Context, req resource.SchemaRequest, r MarkdownDescription: "The sha256 of the response of the fhir server.", Computed: true, }, + "substitutions": schema.MapAttribute{ + ElementType: basetypes.StringType{}, + MarkdownDescription: `A map of substitutions to be applied to the file content before sending it to the server. + The key is the string to be replaced, and the value is the string to replace it with. + + ### Example: + Given a FHIR resource file with content: + + { + "resourceType": "Questionnaire", + "url": "https://system.com/R4/Questionnaire/{{Tenant.GUID}}/DiagnosticTests" + } + + And the following substitutions: + + substitutions = { + "{{Tenant.GUID}}" = "12345" + } + + The final content sent to the server will be: + + { + "resourceType": "Questionnaire", + "url": "https://system.com/R4/Questionnaire/12345/DiagnosticTests" + }`, + Optional: true, + }, }, } } @@ -112,7 +142,7 @@ func (r *FhirResource) Create(ctx context.Context, req resource.CreateRequest, r // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - r.fhirResourceSettings = FhirResourceSettings{FhirResourceFilePath: data.FilePath.ValueString(), FhirBaseUrl: data.FhirBaseUrl.ValueStringPointer()} + r.fhirResourceSettings = NewFhirResourceSettings(data, ctx) if resp.Diagnostics.HasError() { return @@ -139,6 +169,8 @@ func persistFhirResource(ctx context.Context, fhirResource *FhirResource, resour return nil, nil, nil } + fileContent = replaceValues(fileContent, fhirResource.fhirResourceSettings.Substitutions) + var fileContentJson map[string]interface{} if err := json.Unmarshal(fileContent, &fileContentJson); err != nil { diag.AddError(fmt.Sprintf("failed to unmarshal JSON file %s", fhirResource.fhirResourceSettings.FhirResourceFilePath), err.Error()) @@ -223,7 +255,7 @@ func (r *FhirResource) Read(ctx context.Context, req resource.ReadRequest, resp return } - r.fhirResourceSettings = FhirResourceSettings{FhirResourceFilePath: data.FilePath.ValueString(), FhirBaseUrl: data.FhirBaseUrl.ValueStringPointer()} + r.fhirResourceSettings = NewFhirResourceSettings(data, ctx) body, shouldReturn := ReadFhirResource(r.providerSettings, r.fhirResourceSettings.FhirBaseUrl, data.ResourceId.ValueString(), &resp.Diagnostics) if shouldReturn { @@ -262,7 +294,7 @@ func (r *FhirResource) Update(ctx context.Context, req resource.UpdateRequest, r return } - r.fhirResourceSettings = FhirResourceSettings{FhirResourceFilePath: data.FilePath.ValueString(), FhirBaseUrl: data.FhirBaseUrl.ValueStringPointer()} + r.fhirResourceSettings = NewFhirResourceSettings(data, ctx) body, responseJson, resourceType := persistFhirResource(ctx, r, state.ResourceId.ValueStringPointer(), &resp.Diagnostics) if responseJson == nil { @@ -277,6 +309,7 @@ func (r *FhirResource) Update(ctx context.Context, req resource.UpdateRequest, r state.ResponseSha256 = types.StringValue(hashString) state.FilePath = data.FilePath state.FileSha256 = data.FileSha256 + state.Substitutions = data.Substitutions // Save updated data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) @@ -292,7 +325,7 @@ func (r *FhirResource) Delete(ctx context.Context, req resource.DeleteRequest, r return } - r.fhirResourceSettings = FhirResourceSettings{FhirResourceFilePath: data.FilePath.ValueString(), FhirBaseUrl: data.FhirBaseUrl.ValueStringPointer()} + r.fhirResourceSettings = NewFhirResourceSettings(data, ctx) baseUrl := r.providerSettings.FhirBaseUrl if r.fhirResourceSettings.FhirBaseUrl != nil { @@ -326,3 +359,24 @@ func (r *FhirResource) Delete(ctx context.Context, req resource.DeleteRequest, r func (r *FhirResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { resource.ImportStatePassthroughID(ctx, path.Root("resource_id"), req, resp) } + +func NewFhirResourceSettings(data FhirResourceModel, ctx context.Context) FhirResourceSettings { + substitutions := make(map[string]string) + data.Substitutions.ElementsAs(ctx, &substitutions, true) + + return FhirResourceSettings{ + FhirResourceFilePath: data.FilePath.ValueString(), + FhirBaseUrl: data.FhirBaseUrl.ValueStringPointer(), + Substitutions: substitutions, + } +} + +func replaceValues(content []byte, substitutions map[string]string) []byte { + contentStr := string(content) + + for key, value := range substitutions { + contentStr = strings.ReplaceAll(contentStr, key, value) + } + + return []byte(contentStr) +}