From 11d3079e7ea45fb2d9cb61a02118063cd39abc97 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 24 Apr 2024 13:06:42 +0200 Subject: [PATCH] fix mapping issues --- internal/common/cluster_bindings.go | 12 ++-- internal/common/map.go | 12 ++++ .../resource/infrastructure_stack_model.go | 70 ++++++++++--------- .../resource/infrastructure_stack_schema.go | 10 --- 4 files changed, 57 insertions(+), 47 deletions(-) diff --git a/internal/common/cluster_bindings.go b/internal/common/cluster_bindings.go index ceac7f1..14e1180 100644 --- a/internal/common/cluster_bindings.go +++ b/internal/common/cluster_bindings.go @@ -56,13 +56,15 @@ func (cb *ClusterBindings) From(readBindings []*console.PolicyBindingFragment, w return } - cb.Read = clusterBindingsFrom(readBindings, ctx, d) - cb.Write = clusterBindingsFrom(writeBindings, ctx, d) + cb.Read = clusterBindingsFrom(readBindings, cb.Read, ctx, d) + cb.Write = clusterBindingsFrom(writeBindings, cb.Write, ctx, d) } -func clusterBindingsFrom(bindings []*console.PolicyBindingFragment, ctx context.Context, d diag.Diagnostics) types.Set { - if bindings == nil { - return types.SetNull(basetypes.ObjectType{AttrTypes: ClusterPolicyBindingAttrTypes}) +func clusterBindingsFrom(bindings []*console.PolicyBindingFragment, config types.Set, ctx context.Context, d diag.Diagnostics) types.Set { + if len(bindings) == 0 { + // Rewriting config to state to avoid inconsistent result errors. + // This could happen, for example, when sending "nil" to API and "[]" is returned as a result. + return config } values := make([]attr.Value, len(bindings)) diff --git a/internal/common/map.go b/internal/common/map.go index 8e11724..86d2049 100644 --- a/internal/common/map.go +++ b/internal/common/map.go @@ -16,3 +16,15 @@ func MapFrom(values map[string]any, ctx context.Context, d diag.Diagnostics) typ d.Append(diags...) return mapValue } + +func MapFromWithConfig(values map[string]any, config types.Map, ctx context.Context, d diag.Diagnostics) types.Map { + if len(values) == 0 { + // Rewriting config to state to avoid inconsistent result errors. + // This could happen, for example, when sending "nil" to API and "[]" is returned as a result. + return config + } + + mapValue, diags := types.MapValueFrom(ctx, types.StringType, values) + d.Append(diags...) + return mapValue +} diff --git a/internal/resource/infrastructure_stack_model.go b/internal/resource/infrastructure_stack_model.go index be33ac8..e4cf801 100644 --- a/internal/resource/infrastructure_stack_model.go +++ b/internal/resource/infrastructure_stack_model.go @@ -89,15 +89,17 @@ func (is *infrastructureStack) From(stack *gqlclient.InfrastructureStackFragment is.ClusterId = types.StringValue(stack.Cluster.ID) is.Repository.From(stack.Repository, stack.Git) is.Configuration.From(stack.Configuration) - is.Files = infrastructureStackFilesFrom(stack.Files, d) - is.Environment = infrastructureStackEnvironmentsFrom(stack.Environment, ctx, d) + is.Files = infrastructureStackFilesFrom(stack.Files, is.Files, d) + is.Environment = infrastructureStackEnvironmentsFrom(stack.Environment, is.Environment, ctx, d) is.Bindings.From(stack.ReadBindings, stack.WriteBindings, ctx, d) is.JobSpec.From(stack.JobSpec, ctx, d) } -func infrastructureStackFilesFrom(files []*gqlclient.StackFileFragment, d diag.Diagnostics) basetypes.MapValue { - if files == nil { - return types.MapNull(types.StringType) +func infrastructureStackFilesFrom(files []*gqlclient.StackFileFragment, config types.Map, d diag.Diagnostics) types.Map { + if len(files) == 0 { + // Rewriting config to state to avoid inconsistent result errors. + // This could happen, for example, when sending "nil" to API and "[]" is returned as a result. + return config } resultMap := make(map[string]attr.Value, len(files)) @@ -111,6 +113,29 @@ func infrastructureStackFilesFrom(files []*gqlclient.StackFileFragment, d diag.D return result } +func infrastructureStackEnvironmentsFrom(envs []*gqlclient.StackEnvironmentFragment, config types.Set, ctx context.Context, d diag.Diagnostics) types.Set { + if len(envs) == 0 { + // Rewriting config to state to avoid inconsistent result errors. + // This could happen, for example, when sending "nil" to API and "[]" is returned as a result. + return config + } + + values := make([]attr.Value, len(envs)) + for i, file := range envs { + objValue, diags := types.ObjectValueFrom(ctx, InfrastructureStackEnvironmentAttrTypes, InfrastructureStackEnvironment{ + Name: types.StringValue(file.Name), + Value: types.StringValue(file.Value), + Secret: types.BoolPointerValue(file.Secret), + }) + values[i] = objValue + d.Append(diags...) + } + + setValue, diags := types.SetValue(basetypes.ObjectType{AttrTypes: InfrastructureStackEnvironmentAttrTypes}, values) + d.Append(diags...) + return setValue +} + type InfrastructureStackRepository struct { Id types.String `tfsdk:"id"` Ref types.String `tfsdk:"ref"` @@ -180,27 +205,6 @@ var InfrastructureStackEnvironmentAttrTypes = map[string]attr.Type{ "secret": types.BoolType, } -func infrastructureStackEnvironmentsFrom(envs []*gqlclient.StackEnvironmentFragment, ctx context.Context, d diag.Diagnostics) types.Set { - if envs == nil { - return types.SetNull(basetypes.ObjectType{AttrTypes: InfrastructureStackEnvironmentAttrTypes}) - } - - values := make([]attr.Value, len(envs)) - for i, file := range envs { - objValue, diags := types.ObjectValueFrom(ctx, InfrastructureStackEnvironmentAttrTypes, InfrastructureStackEnvironment{ - Name: types.StringValue(file.Name), - Value: types.StringValue(file.Value), - Secret: types.BoolPointerValue(file.Secret), - }) - values[i] = objValue - d.Append(diags...) - } - - setValue, diags := types.SetValue(basetypes.ObjectType{AttrTypes: InfrastructureStackEnvironmentAttrTypes}, values) - d.Append(diags...) - return setValue -} - type InfrastructureStackBindings struct { Read []*InfrastructureStackPolicyBinding `tfsdk:"read"` Write []*InfrastructureStackPolicyBinding `tfsdk:"write"` @@ -279,15 +283,17 @@ func (isjs *InfrastructureStackJobSpec) From(spec *gqlclient.JobGateSpecFragment isjs.Namespace = types.StringValue(spec.Namespace) isjs.Raw = types.StringPointerValue(spec.Raw) - isjs.Containers = infrastructureStackJobSpecContainersFrom(spec.Containers, ctx, d) - isjs.Labels = common.MapFrom(spec.Labels, ctx, d) - isjs.Annotations = common.MapFrom(spec.Annotations, ctx, d) + isjs.Containers = infrastructureStackJobSpecContainersFrom(spec.Containers, isjs.Containers, ctx, d) + isjs.Labels = common.MapFromWithConfig(spec.Labels, isjs.Labels, ctx, d) + isjs.Annotations = common.MapFromWithConfig(spec.Annotations, isjs.Annotations, ctx, d) isjs.ServiceAccount = types.StringPointerValue(spec.ServiceAccount) } -func infrastructureStackJobSpecContainersFrom(containers []*gqlclient.ContainerSpecFragment, ctx context.Context, d diag.Diagnostics) types.Set { - if containers == nil { - return types.SetNull(basetypes.ObjectType{AttrTypes: InfrastructureStackContainerSpecAttrTypes}) +func infrastructureStackJobSpecContainersFrom(containers []*gqlclient.ContainerSpecFragment, config types.Set, ctx context.Context, d diag.Diagnostics) types.Set { + if len(containers) == 0 { + // Rewriting config to state to avoid inconsistent result errors. + // This could happen, for example, when sending "nil" to API and "[]" is returned as a result. + return config } values := make([]attr.Value, len(containers)) diff --git a/internal/resource/infrastructure_stack_schema.go b/internal/resource/infrastructure_stack_schema.go index a5ce790..49577bc 100644 --- a/internal/resource/infrastructure_stack_schema.go +++ b/internal/resource/infrastructure_stack_schema.go @@ -6,11 +6,9 @@ import ( "github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/mapdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" @@ -108,7 +106,6 @@ func (r *InfrastructureStackResource) schema() schema.Schema { Description: "Defines environment variables for the stack.", MarkdownDescription: "Defines environment variables for the stack.", Optional: true, - Computed: true, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ "name": schema.StringAttribute{ @@ -155,8 +152,6 @@ func (r *InfrastructureStackResource) schema() schema.Schema { MarkdownDescription: "Kubernetes labels applied to the job.", ElementType: types.StringType, Optional: true, - Computed: true, - Default: mapdefault.StaticValue(types.MapValueMust(types.StringType, map[string]attr.Value{})), Validators: []validator.Map{mapvalidator.ConflictsWith(path.MatchRelative().AtParent().AtName("raw"))}, }, "annotations": schema.MapAttribute{ @@ -164,8 +159,6 @@ func (r *InfrastructureStackResource) schema() schema.Schema { MarkdownDescription: "Kubernetes annotations applied to the job.", ElementType: types.StringType, Optional: true, - Computed: true, - Default: mapdefault.StaticValue(types.MapValueMust(types.StringType, map[string]attr.Value{})), Validators: []validator.Map{mapvalidator.ConflictsWith(path.MatchRelative().AtParent().AtName("raw"))}, }, "service_account": schema.StringAttribute{ @@ -176,7 +169,6 @@ func (r *InfrastructureStackResource) schema() schema.Schema { }, "containers": schema.SetNestedAttribute{ Optional: true, - Computed: true, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ "image": schema.StringAttribute{ @@ -226,7 +218,6 @@ func (r *InfrastructureStackResource) schema() schema.Schema { Description: "Read policies of this stack.", MarkdownDescription: "Read policies of this stack.", Optional: true, - Computed: true, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ "group_id": schema.StringAttribute{ @@ -245,7 +236,6 @@ func (r *InfrastructureStackResource) schema() schema.Schema { Description: "Write policies of this stack.", MarkdownDescription: "Write policies of this stack.", Optional: true, - Computed: true, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ "group_id": schema.StringAttribute{