diff --git a/internal/provider/helpers/marshal.go b/internal/provider/helpers/marshal.go new file mode 100644 index 00000000..627112b7 --- /dev/null +++ b/internal/provider/helpers/marshal.go @@ -0,0 +1,19 @@ +package helpers + +import ( + "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// SafeUnmarshal is a helper function for safely unmarshalling a JSON object by checking if +// it is null before attempting to unmarshal it. This should always be used for optional attributes. +func SafeUnmarshal(attribute jsontypes.Normalized) (map[string]interface{}, diag.Diagnostics) { + var diags diag.Diagnostics + + result := map[string]interface{}{} + if !attribute.IsNull() { + diags = attribute.Unmarshal(&result) + } + + return result, diags +} diff --git a/internal/provider/resources/deployment.go b/internal/provider/resources/deployment.go index 207db7b9..34499c87 100644 --- a/internal/provider/resources/deployment.go +++ b/internal/provider/resources/deployment.go @@ -307,20 +307,20 @@ func (r *DeploymentResource) Create(ctx context.Context, req resource.CreateRequ return } - var parameters map[string]interface{} - resp.Diagnostics.Append(plan.Parameters.Unmarshal(¶meters)...) + parameters, diags := helpers.SafeUnmarshal(plan.Parameters) + resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } - var jobVariables map[string]interface{} - resp.Diagnostics.Append(plan.JobVariables.Unmarshal(&jobVariables)...) + jobVariables, diags := helpers.SafeUnmarshal(plan.JobVariables) + resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } - var parameterOpenAPISchema map[string]interface{} - resp.Diagnostics.Append(plan.ParameterOpenAPISchema.Unmarshal(¶meterOpenAPISchema)...) + parameterOpenAPISchema, diags := helpers.SafeUnmarshal(plan.ParameterOpenAPISchema) + resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } @@ -473,15 +473,19 @@ func (r *DeploymentResource) Update(ctx context.Context, req resource.UpdateRequ } var parameters map[string]interface{} - resp.Diagnostics.Append(model.Parameters.Unmarshal(¶meters)...) - if resp.Diagnostics.HasError() { - return + if !model.Parameters.IsNull() { + resp.Diagnostics.Append(model.Parameters.Unmarshal(¶meters)...) + if resp.Diagnostics.HasError() { + return + } } var jobVariables map[string]interface{} - resp.Diagnostics.Append(model.JobVariables.Unmarshal(&jobVariables)...) - if resp.Diagnostics.HasError() { - return + if !model.JobVariables.IsNull() { + resp.Diagnostics.Append(model.JobVariables.Unmarshal(&jobVariables)...) + if resp.Diagnostics.HasError() { + return + } } payload := api.DeploymentUpdate{ diff --git a/internal/provider/resources/work_pool.go b/internal/provider/resources/work_pool.go index 190b80d1..d8351c72 100644 --- a/internal/provider/resources/work_pool.go +++ b/internal/provider/resources/work_pool.go @@ -198,8 +198,8 @@ func (r *WorkPoolResource) Create(ctx context.Context, req resource.CreateReques return } - baseJobTemplate := map[string]interface{}{} - resp.Diagnostics.Append(plan.BaseJobTemplate.Unmarshal(&baseJobTemplate)...) + baseJobTemplate, diag := helpers.SafeUnmarshal(plan.BaseJobTemplate) + resp.Diagnostics.Append(diag...) if resp.Diagnostics.HasError() { return } @@ -277,8 +277,8 @@ func (r *WorkPoolResource) Update(ctx context.Context, req resource.UpdateReques return } - baseJobTemplate := map[string]interface{}{} - resp.Diagnostics.Append(plan.BaseJobTemplate.Unmarshal(&baseJobTemplate)...) + baseJobTemplate, diag := helpers.SafeUnmarshal(plan.BaseJobTemplate) + resp.Diagnostics.Append(diag...) if resp.Diagnostics.HasError() { return }