From f63ff642b11c15a3ee7eef28eaf1fcf68cbb989a Mon Sep 17 00:00:00 2001 From: Sherzod Karimov Date: Tue, 26 Nov 2024 08:41:40 -0500 Subject: [PATCH 1/6] renames --- .../resource_datadog_aws_account_v2.go | 169 ++++++------------ 1 file changed, 57 insertions(+), 112 deletions(-) diff --git a/datadog/fwprovider/resource_datadog_aws_account_v2.go b/datadog/fwprovider/resource_datadog_aws_account_v2.go index 22c8c94a97..5d69d8487d 100644 --- a/datadog/fwprovider/resource_datadog_aws_account_v2.go +++ b/datadog/fwprovider/resource_datadog_aws_account_v2.go @@ -52,13 +52,7 @@ type awsAuthConfigRoleModel struct { } type awsRegionsModel struct { - AwsRegionsIncludeAll *awsRegionsIncludeAllModel `tfsdk:"aws_regions_include_all"` - AwsRegionsIncludeOnly *awsRegionsIncludeOnlyModel `tfsdk:"aws_regions_include_only"` -} -type awsRegionsIncludeAllModel struct { - IncludeAll types.Bool `tfsdk:"include_all"` -} -type awsRegionsIncludeOnlyModel struct { + IncludeAll types.Bool `tfsdk:"include_all"` IncludeOnly types.List `tfsdk:"include_only"` } @@ -84,13 +78,7 @@ type tagFiltersModel struct { } type namespaceFiltersModel struct { - AwsNamespaceFiltersExcludeOnly *awsNamespaceFiltersExcludeOnlyModel `tfsdk:"aws_namespace_filters_exclude_only"` - AwsNamespaceFiltersIncludeOnly *awsNamespaceFiltersIncludeOnlyModel `tfsdk:"aws_namespace_filters_include_only"` -} -type awsNamespaceFiltersExcludeOnlyModel struct { ExcludeOnly types.List `tfsdk:"exclude_only"` -} -type awsNamespaceFiltersIncludeOnlyModel struct { IncludeOnly types.List `tfsdk:"include_only"` } @@ -103,13 +91,7 @@ type tracesConfigModel struct { XrayServices *xrayServicesModel `tfsdk:"xray_services"` } type xrayServicesModel struct { - XRayServicesIncludeAll *xRayServicesIncludeAllModel `tfsdk:"x_ray_services_include_all"` - XRayServicesIncludeOnly *xRayServicesIncludeOnlyModel `tfsdk:"x_ray_services_include_only"` -} -type xRayServicesIncludeAllModel struct { - IncludeAll types.Bool `tfsdk:"include_all"` -} -type xRayServicesIncludeOnlyModel struct { + IncludeAll types.Bool `tfsdk:"include_all"` IncludeOnly types.List `tfsdk:"include_only"` } @@ -134,16 +116,16 @@ func (r *awsAccountV2Resource) ConfigValidators(ctx context.Context) []resource. path.MatchRoot("auth_config").AtName("aws_auth_config_role"), ), resourcevalidator.ExactlyOneOf( - path.MatchRoot("traces_config").AtName("xray_services").AtName("x_ray_services_include_all"), - path.MatchRoot("traces_config").AtName("xray_services").AtName("x_ray_services_include_only"), + path.MatchRoot("traces_config").AtName("xray_services").AtName("include_all"), + path.MatchRoot("traces_config").AtName("xray_services").AtName("nclude_only"), ), resourcevalidator.ExactlyOneOf( - path.MatchRoot("metrics_config").AtName("namespace_filters").AtName("aws_namespace_filters_include_only"), - path.MatchRoot("metrics_config").AtName("namespace_filters").AtName("aws_namespace_filters_exclude_only"), + path.MatchRoot("metrics_config").AtName("include_only"), + path.MatchRoot("metrics_config").AtName("exclude_only"), ), resourcevalidator.ExactlyOneOf( - path.MatchRoot("aws_regions").AtName("aws_regions_include_all"), - path.MatchRoot("aws_regions").AtName("aws_regions_include_only"), + path.MatchRoot("aws_regions").AtName("include_all"), + path.MatchRoot("aws_regions").AtName("include_only"), ), resourcevalidator.RequiredTogether( path.MatchRoot("auth_config").AtName("aws_auth_config_keys").AtName("access_key_id"), @@ -208,26 +190,17 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques }, }, "aws_regions": schema.SingleNestedBlock{ - Attributes: map[string]schema.Attribute{}, - Blocks: map[string]schema.Block{ - "aws_regions_include_all": schema.SingleNestedBlock{ - Attributes: map[string]schema.Attribute{ - "include_all": schema.BoolAttribute{ - Optional: true, - Computed: true, - Description: "Include all regions", - }, - }, + Attributes: map[string]schema.Attribute{ + "include_all": schema.BoolAttribute{ + Optional: true, + Computed: true, + Description: "Include all regions", }, - "aws_regions_include_only": schema.SingleNestedBlock{ - Attributes: map[string]schema.Attribute{ - "include_only": schema.ListAttribute{ - Optional: true, - Computed: true, - Description: "Include only these regions", - ElementType: types.StringType, - }, - }, + "include_only": schema.ListAttribute{ + Optional: true, + Computed: true, + Description: "Include only these regions", + ElementType: types.StringType, }, }, }, @@ -289,27 +262,18 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques }, }, "namespace_filters": schema.SingleNestedBlock{ - Attributes: map[string]schema.Attribute{}, - Blocks: map[string]schema.Block{ - "aws_namespace_filters_exclude_only": schema.SingleNestedBlock{ - Attributes: map[string]schema.Attribute{ - "exclude_only": schema.ListAttribute{ - Optional: true, - Computed: true, - Description: "Exclude only these namespaces", - ElementType: types.StringType, - }, - }, + Attributes: map[string]schema.Attribute{ + "exclude_only": schema.ListAttribute{ + Optional: true, + Computed: true, + Description: "Exclude only these namespaces", + ElementType: types.StringType, }, - "aws_namespace_filters_include_only": schema.SingleNestedBlock{ - Attributes: map[string]schema.Attribute{ - "include_only": schema.ListAttribute{ - Optional: true, - Computed: true, - Description: "Include only these namespaces", - ElementType: types.StringType, - }, - }, + "include_only": schema.ListAttribute{ + Optional: true, + Computed: true, + Description: "Include only these namespaces", + ElementType: types.StringType, }, }, }, @@ -331,26 +295,17 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Attributes: map[string]schema.Attribute{}, Blocks: map[string]schema.Block{ "xray_services": schema.SingleNestedBlock{ - Attributes: map[string]schema.Attribute{}, - Blocks: map[string]schema.Block{ - "x_ray_services_include_all": schema.SingleNestedBlock{ - Attributes: map[string]schema.Attribute{ - "include_all": schema.BoolAttribute{ - Optional: true, - Computed: true, - Description: "Include all services", - }, - }, + Attributes: map[string]schema.Attribute{ + "include_all": schema.BoolAttribute{ + Optional: true, + Computed: true, + Description: "Include all services", }, - "x_ray_services_include_only": schema.SingleNestedBlock{ - Attributes: map[string]schema.Attribute{ - "include_only": schema.ListAttribute{ - Optional: true, - Computed: true, - Description: "Include only these services", - ElementType: types.StringType, - }, - }, + "include_only": schema.ListAttribute{ + Optional: true, + Computed: true, + Description: "Include only these services", + ElementType: types.StringType, }, }, }, @@ -512,14 +467,10 @@ func buildStateAwsRegions(ctx context.Context, attributes datadogV2.AWSAccountRe awsRegionsTf := awsRegionsModel{} if awsRegions.AWSRegionsIncludeAll != nil { - awsRegionsTf.AwsRegionsIncludeAll = &awsRegionsIncludeAllModel{ - IncludeAll: types.BoolValue(awsRegions.AWSRegionsIncludeAll.GetIncludeAll()), - } + awsRegionsTf.IncludeAll = types.BoolValue(awsRegions.AWSRegionsIncludeAll.GetIncludeAll()) } else if awsRegions.AWSRegionsIncludeOnly != nil { includeOnly, d := types.ListValueFrom(ctx, types.StringType, awsRegions.AWSRegionsIncludeOnly.GetIncludeOnly()) - awsRegionsTf.AwsRegionsIncludeOnly = &awsRegionsIncludeOnlyModel{ - IncludeOnly: includeOnly, - } + awsRegionsTf.IncludeOnly = includeOnly diags.Append(d...) } @@ -562,14 +513,12 @@ func buildStateMetricsConfig(ctx context.Context, attributes datadogV2.AWSAccoun if namespaceFilters, ok := metricsConfig.GetNamespaceFiltersOk(); ok { nsFiltersTf := namespaceFiltersModel{} if namespaceFilters.AWSNamespaceFiltersExcludeOnly != nil { - nsFiltersTf.AwsNamespaceFiltersExcludeOnly = &awsNamespaceFiltersExcludeOnlyModel{} excludeOnly, _ := types.ListValueFrom(ctx, types.StringType, namespaceFilters.AWSNamespaceFiltersExcludeOnly.GetExcludeOnly()) - nsFiltersTf.AwsNamespaceFiltersExcludeOnly.ExcludeOnly = excludeOnly + nsFiltersTf.ExcludeOnly = excludeOnly } if namespaceFilters.AWSNamespaceFiltersIncludeOnly != nil { - nsFiltersTf.AwsNamespaceFiltersIncludeOnly = &awsNamespaceFiltersIncludeOnlyModel{} includeOnly, _ := types.ListValueFrom(ctx, types.StringType, namespaceFilters.AWSNamespaceFiltersIncludeOnly.GetIncludeOnly()) - nsFiltersTf.AwsNamespaceFiltersIncludeOnly.IncludeOnly = includeOnly + nsFiltersTf.IncludeOnly = includeOnly } metricsConfigTf.NamespaceFilters = &nsFiltersTf @@ -593,14 +542,10 @@ func buildStateTracesConfig(ctx context.Context, attributes datadogV2.AWSAccount if xrayServices, ok := tracesConfig.GetXrayServicesOk(); ok { xrayServicesTf := xrayServicesModel{} if xrayServices.XRayServicesIncludeAll != nil { - xrayServicesTf.XRayServicesIncludeAll = &xRayServicesIncludeAllModel{ - IncludeAll: types.BoolValue(xrayServices.XRayServicesIncludeAll.GetIncludeAll()), - } + xrayServicesTf.IncludeAll = types.BoolValue(xrayServices.XRayServicesIncludeAll.GetIncludeAll()) } else if xrayServices.XRayServicesIncludeOnly != nil { includeOnly, d := types.ListValueFrom(ctx, types.StringType, xrayServices.XRayServicesIncludeOnly.GetIncludeOnly()) - xrayServicesTf.XRayServicesIncludeOnly = &xRayServicesIncludeOnlyModel{ - IncludeOnly: includeOnly, - } + xrayServicesTf.IncludeOnly = includeOnly diags.Append(d...) } tracesConfigTf.XrayServices = &xrayServicesTf @@ -659,14 +604,14 @@ func (r *awsAccountV2Resource) buildAwsAccountV2RequestBody(ctx context.Context, func buildRequestAwsRegions(ctx context.Context, state *awsAccountV2Model, diags diag.Diagnostics) datadogV2.AWSRegions { regions := datadogV2.AWSRegions{} - if state.AwsRegions.AwsRegionsIncludeAll != nil { + if state.AwsRegions.IncludeAll.IsUnknown() { regions.AWSRegionsIncludeAll = datadogV2.NewAWSRegionsIncludeAllWithDefaults() - regions.AWSRegionsIncludeAll.IncludeAll = state.AwsRegions.AwsRegionsIncludeAll.IncludeAll.ValueBool() + regions.AWSRegionsIncludeAll.IncludeAll = state.AwsRegions.IncludeAll.ValueBool() } - if state.AwsRegions.AwsRegionsIncludeOnly != nil { + if state.AwsRegions.IncludeOnly.IsUnknown() { regions.AWSRegionsIncludeOnly = datadogV2.NewAWSRegionsIncludeOnlyWithDefaults() var includeOnly []string - diags.Append(state.AwsRegions.AwsRegionsIncludeOnly.IncludeOnly.ElementsAs(ctx, &includeOnly, false)...) + diags.Append(state.AwsRegions.IncludeOnly.ElementsAs(ctx, &includeOnly, false)...) regions.AWSRegionsIncludeOnly.IncludeOnly = includeOnly } return regions @@ -761,15 +706,15 @@ func buildRequestMetricsConfig(ctx context.Context, state *awsAccountV2Model, di namespaceFiltersDD := datadogV2.AWSNamespaceFilters{} nsFiltersTf := state.MetricsConfig.NamespaceFilters - if nsFiltersTf.AwsNamespaceFiltersExcludeOnly != nil { + if !nsFiltersTf.ExcludeOnly.IsUnknown() { var excludeOnly []string namespaceFiltersDD.AWSNamespaceFiltersExcludeOnly = datadogV2.NewAWSNamespaceFiltersExcludeOnlyWithDefaults() - diags.Append(nsFiltersTf.AwsNamespaceFiltersExcludeOnly.ExcludeOnly.ElementsAs(ctx, &excludeOnly, false)...) + diags.Append(nsFiltersTf.ExcludeOnly.ElementsAs(ctx, &excludeOnly, false)...) namespaceFiltersDD.AWSNamespaceFiltersExcludeOnly.SetExcludeOnly(excludeOnly) - } else if nsFiltersTf.AwsNamespaceFiltersIncludeOnly != nil { + } else if !nsFiltersTf.ExcludeOnly.IsUnknown() { var includeOnly []string namespaceFiltersDD.AWSNamespaceFiltersIncludeOnly = datadogV2.NewAWSNamespaceFiltersIncludeOnlyWithDefaults() - diags.Append(nsFiltersTf.AwsNamespaceFiltersIncludeOnly.IncludeOnly.ElementsAs(ctx, &includeOnly, false)...) + diags.Append(nsFiltersTf.IncludeOnly.ElementsAs(ctx, &includeOnly, false)...) namespaceFiltersDD.AWSNamespaceFiltersIncludeOnly.SetIncludeOnly(includeOnly) } metricsConfig.SetNamespaceFilters(namespaceFiltersDD) @@ -797,11 +742,11 @@ func buildRequestTracesConfig(ctx context.Context, state *awsAccountV2Model, dia if state.TracesConfig.XrayServices != nil { var ddXRayServiceList datadogV2.XRayServicesList - if state.TracesConfig.XrayServices.XRayServicesIncludeAll != nil { - includeAll := state.TracesConfig.XrayServices.XRayServicesIncludeAll.IncludeAll.ValueBool() + if !state.TracesConfig.XrayServices.IncludeAll.IsUnknown() { + includeAll := state.TracesConfig.XrayServices.IncludeAll.ValueBool() ddXRayServiceList = datadogV2.XRayServicesIncludeAllAsXRayServicesList(&datadogV2.XRayServicesIncludeAll{IncludeAll: includeAll}) - } else if state.TracesConfig.XrayServices.XRayServicesIncludeOnly != nil { - includeOnlyTf := state.TracesConfig.XrayServices.XRayServicesIncludeOnly.IncludeOnly + } else if !state.TracesConfig.XrayServices.IncludeOnly.IsUnknown() { + includeOnlyTf := state.TracesConfig.XrayServices.IncludeOnly var ddIncludeOnly []string diags.Append(includeOnlyTf.ElementsAs(ctx, &ddIncludeOnly, false)...) ddXRayServiceList = datadogV2.XRayServicesIncludeOnlyAsXRayServicesList(&datadogV2.XRayServicesIncludeOnly{IncludeOnly: ddIncludeOnly}) From d45ae70ed4224ef7c116eeea8cffe37395e068c1 Mon Sep 17 00:00:00 2001 From: Sherzod Karimov Date: Tue, 26 Nov 2024 09:21:19 -0500 Subject: [PATCH 2/6] type changes --- .../fwprovider/resource_datadog_aws_account_v2.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/datadog/fwprovider/resource_datadog_aws_account_v2.go b/datadog/fwprovider/resource_datadog_aws_account_v2.go index 5d69d8487d..e8642b47d2 100644 --- a/datadog/fwprovider/resource_datadog_aws_account_v2.go +++ b/datadog/fwprovider/resource_datadog_aws_account_v2.go @@ -117,11 +117,11 @@ func (r *awsAccountV2Resource) ConfigValidators(ctx context.Context) []resource. ), resourcevalidator.ExactlyOneOf( path.MatchRoot("traces_config").AtName("xray_services").AtName("include_all"), - path.MatchRoot("traces_config").AtName("xray_services").AtName("nclude_only"), + path.MatchRoot("traces_config").AtName("xray_services").AtName("include_only"), ), resourcevalidator.ExactlyOneOf( - path.MatchRoot("metrics_config").AtName("include_only"), - path.MatchRoot("metrics_config").AtName("exclude_only"), + path.MatchRoot("metrics_config").AtName("namespace_filters").AtName("include_only"), + path.MatchRoot("metrics_config").AtName("namespace_filters").AtName("exclude_only"), ), resourcevalidator.ExactlyOneOf( path.MatchRoot("aws_regions").AtName("include_all"), @@ -162,12 +162,10 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Attributes: map[string]schema.Attribute{ "access_key_id": schema.StringAttribute{ Optional: true, - Computed: true, Description: "AWS Access Key ID", }, "secret_access_key": schema.StringAttribute{ Optional: true, - Computed: true, Sensitive: true, Description: "AWS Secret Access Key", }, @@ -182,7 +180,6 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques }, "role_name": schema.StringAttribute{ Optional: true, - Computed: true, Description: "AWS IAM Role name", }, }, @@ -604,11 +601,11 @@ func (r *awsAccountV2Resource) buildAwsAccountV2RequestBody(ctx context.Context, func buildRequestAwsRegions(ctx context.Context, state *awsAccountV2Model, diags diag.Diagnostics) datadogV2.AWSRegions { regions := datadogV2.AWSRegions{} - if state.AwsRegions.IncludeAll.IsUnknown() { + if !state.AwsRegions.IncludeAll.IsUnknown() { regions.AWSRegionsIncludeAll = datadogV2.NewAWSRegionsIncludeAllWithDefaults() regions.AWSRegionsIncludeAll.IncludeAll = state.AwsRegions.IncludeAll.ValueBool() } - if state.AwsRegions.IncludeOnly.IsUnknown() { + if !state.AwsRegions.IncludeOnly.IsUnknown() { regions.AWSRegionsIncludeOnly = datadogV2.NewAWSRegionsIncludeOnlyWithDefaults() var includeOnly []string diags.Append(state.AwsRegions.IncludeOnly.ElementsAs(ctx, &includeOnly, false)...) From cd81d91b1a6e5cab18a2a2ae4f1276195c333340 Mon Sep 17 00:00:00 2001 From: Sherzod Karimov Date: Tue, 26 Nov 2024 09:50:59 -0500 Subject: [PATCH 3/6] remove bunch of computed --- .../resource_datadog_aws_account_v2.go | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/datadog/fwprovider/resource_datadog_aws_account_v2.go b/datadog/fwprovider/resource_datadog_aws_account_v2.go index e8642b47d2..5c268982b3 100644 --- a/datadog/fwprovider/resource_datadog_aws_account_v2.go +++ b/datadog/fwprovider/resource_datadog_aws_account_v2.go @@ -10,6 +10,8 @@ import ( frameworkPath "github.com/hashicorp/terraform-plugin-framework/path" "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-datadog/datadog/internal/utils" @@ -177,6 +179,9 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Optional: true, Computed: true, Description: "AWS IAM External ID for associated role", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, "role_name": schema.StringAttribute{ Optional: true, @@ -190,12 +195,10 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Attributes: map[string]schema.Attribute{ "include_all": schema.BoolAttribute{ Optional: true, - Computed: true, Description: "Include all regions", }, "include_only": schema.ListAttribute{ Optional: true, - Computed: true, Description: "Include only these regions", ElementType: types.StringType, }, @@ -208,13 +211,11 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Attributes: map[string]schema.Attribute{ "lambdas": schema.ListAttribute{ Optional: true, - Computed: true, Description: "List of Datadog Lambda Log Forwarder ARNs", ElementType: types.StringType, }, "sources": schema.ListAttribute{ Optional: true, - Computed: true, Description: "List of AWS services that will send logs to the Datadog Lambda Log Forwarder", ElementType: types.StringType, }, @@ -251,7 +252,6 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques }, "tags": schema.ListAttribute{ Optional: true, - Computed: true, Description: "The tags to filter based on", ElementType: types.StringType, }, @@ -262,13 +262,11 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Attributes: map[string]schema.Attribute{ "exclude_only": schema.ListAttribute{ Optional: true, - Computed: true, Description: "Exclude only these namespaces", ElementType: types.StringType, }, "include_only": schema.ListAttribute{ Optional: true, - Computed: true, Description: "Include only these namespaces", ElementType: types.StringType, }, @@ -295,12 +293,10 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Attributes: map[string]schema.Attribute{ "include_all": schema.BoolAttribute{ Optional: true, - Computed: true, Description: "Include all services", }, "include_only": schema.ListAttribute{ Optional: true, - Computed: true, Description: "Include only these services", ElementType: types.StringType, }, @@ -461,8 +457,11 @@ func buildStateLogsConfig(ctx context.Context, attributes datadogV2.AWSAccountRe func buildStateAwsRegions(ctx context.Context, attributes datadogV2.AWSAccountResponseAttributes, diags diag.Diagnostics) *awsRegionsModel { awsRegions := attributes.GetAwsRegions() + awsRegionsTf := awsRegionsModel{ + IncludeAll: types.BoolNull(), + IncludeOnly: types.ListNull(types.StringType), + } - awsRegionsTf := awsRegionsModel{} if awsRegions.AWSRegionsIncludeAll != nil { awsRegionsTf.IncludeAll = types.BoolValue(awsRegions.AWSRegionsIncludeAll.GetIncludeAll()) } else if awsRegions.AWSRegionsIncludeOnly != nil { @@ -508,7 +507,10 @@ func buildStateMetricsConfig(ctx context.Context, attributes datadogV2.AWSAccoun } if namespaceFilters, ok := metricsConfig.GetNamespaceFiltersOk(); ok { - nsFiltersTf := namespaceFiltersModel{} + nsFiltersTf := namespaceFiltersModel{ + ExcludeOnly: types.ListNull(types.StringType), + IncludeOnly: types.ListNull(types.StringType), + } if namespaceFilters.AWSNamespaceFiltersExcludeOnly != nil { excludeOnly, _ := types.ListValueFrom(ctx, types.StringType, namespaceFilters.AWSNamespaceFiltersExcludeOnly.GetExcludeOnly()) nsFiltersTf.ExcludeOnly = excludeOnly @@ -535,9 +537,12 @@ func buildStateResourcesConfig(attributes datadogV2.AWSAccountResponseAttributes func buildStateTracesConfig(ctx context.Context, attributes datadogV2.AWSAccountResponseAttributes, diags diag.Diagnostics) *tracesConfigModel { tracesConfig := attributes.GetTracesConfig() tracesConfigTf := tracesConfigModel{} + xrayServicesTf := xrayServicesModel{ + IncludeAll: types.BoolNull(), + IncludeOnly: types.ListNull(types.StringType), + } if xrayServices, ok := tracesConfig.GetXrayServicesOk(); ok { - xrayServicesTf := xrayServicesModel{} if xrayServices.XRayServicesIncludeAll != nil { xrayServicesTf.IncludeAll = types.BoolValue(xrayServices.XRayServicesIncludeAll.GetIncludeAll()) } else if xrayServices.XRayServicesIncludeOnly != nil { @@ -601,11 +606,11 @@ func (r *awsAccountV2Resource) buildAwsAccountV2RequestBody(ctx context.Context, func buildRequestAwsRegions(ctx context.Context, state *awsAccountV2Model, diags diag.Diagnostics) datadogV2.AWSRegions { regions := datadogV2.AWSRegions{} - if !state.AwsRegions.IncludeAll.IsUnknown() { + if !state.AwsRegions.IncludeAll.IsNull() { regions.AWSRegionsIncludeAll = datadogV2.NewAWSRegionsIncludeAllWithDefaults() regions.AWSRegionsIncludeAll.IncludeAll = state.AwsRegions.IncludeAll.ValueBool() } - if !state.AwsRegions.IncludeOnly.IsUnknown() { + if !state.AwsRegions.IncludeOnly.IsNull() { regions.AWSRegionsIncludeOnly = datadogV2.NewAWSRegionsIncludeOnlyWithDefaults() var includeOnly []string diags.Append(state.AwsRegions.IncludeOnly.ElementsAs(ctx, &includeOnly, false)...) @@ -628,7 +633,7 @@ func buildRequestAuthConfig(state *awsAccountV2Model) datadogV2.AWSAuthConfig { if state.AuthConfig.AwsAuthConfigRole != nil { authConfig.AWSAuthConfigRole = datadogV2.NewAWSAuthConfigRoleWithDefaults() - if !state.AuthConfig.AwsAuthConfigRole.ExternalId.IsNull() { + if !state.AuthConfig.AwsAuthConfigRole.ExternalId.IsUnknown() { authConfig.AWSAuthConfigRole.SetExternalId(state.AuthConfig.AwsAuthConfigRole.ExternalId.ValueString()) } if !state.AuthConfig.AwsAuthConfigRole.RoleName.IsNull() { @@ -701,20 +706,24 @@ func buildRequestMetricsConfig(ctx context.Context, state *awsAccountV2Model, di } metricsConfig.SetTagFilters(tagFilters) - namespaceFiltersDD := datadogV2.AWSNamespaceFilters{} + var namespaceFiltersDD *datadogV2.AWSNamespaceFilters nsFiltersTf := state.MetricsConfig.NamespaceFilters - if !nsFiltersTf.ExcludeOnly.IsUnknown() { + if !nsFiltersTf.ExcludeOnly.IsNull() { var excludeOnly []string + namespaceFiltersDD = &datadogV2.AWSNamespaceFilters{} namespaceFiltersDD.AWSNamespaceFiltersExcludeOnly = datadogV2.NewAWSNamespaceFiltersExcludeOnlyWithDefaults() diags.Append(nsFiltersTf.ExcludeOnly.ElementsAs(ctx, &excludeOnly, false)...) namespaceFiltersDD.AWSNamespaceFiltersExcludeOnly.SetExcludeOnly(excludeOnly) - } else if !nsFiltersTf.ExcludeOnly.IsUnknown() { + } else if !nsFiltersTf.IncludeOnly.IsNull() { var includeOnly []string + namespaceFiltersDD = &datadogV2.AWSNamespaceFilters{} namespaceFiltersDD.AWSNamespaceFiltersIncludeOnly = datadogV2.NewAWSNamespaceFiltersIncludeOnlyWithDefaults() diags.Append(nsFiltersTf.IncludeOnly.ElementsAs(ctx, &includeOnly, false)...) namespaceFiltersDD.AWSNamespaceFiltersIncludeOnly.SetIncludeOnly(includeOnly) } - metricsConfig.SetNamespaceFilters(namespaceFiltersDD) + if namespaceFiltersDD != nil { + metricsConfig.SetNamespaceFilters(*namespaceFiltersDD) + } return metricsConfig } @@ -739,10 +748,10 @@ func buildRequestTracesConfig(ctx context.Context, state *awsAccountV2Model, dia if state.TracesConfig.XrayServices != nil { var ddXRayServiceList datadogV2.XRayServicesList - if !state.TracesConfig.XrayServices.IncludeAll.IsUnknown() { + if !state.TracesConfig.XrayServices.IncludeAll.IsNull() { includeAll := state.TracesConfig.XrayServices.IncludeAll.ValueBool() ddXRayServiceList = datadogV2.XRayServicesIncludeAllAsXRayServicesList(&datadogV2.XRayServicesIncludeAll{IncludeAll: includeAll}) - } else if !state.TracesConfig.XrayServices.IncludeOnly.IsUnknown() { + } else if !state.TracesConfig.XrayServices.IncludeOnly.IsNull() { includeOnlyTf := state.TracesConfig.XrayServices.IncludeOnly var ddIncludeOnly []string diags.Append(includeOnlyTf.ElementsAs(ctx, &ddIncludeOnly, false)...) From 2de5a4aea74cf4d5d02b7f4e23fc89a2e9590987 Mon Sep 17 00:00:00 2001 From: Sherzod Karimov Date: Tue, 26 Nov 2024 14:40:26 -0500 Subject: [PATCH 4/6] handle some top level --- .../resource_datadog_aws_account_v2.go | 123 ++++++++++++++---- 1 file changed, 96 insertions(+), 27 deletions(-) diff --git a/datadog/fwprovider/resource_datadog_aws_account_v2.go b/datadog/fwprovider/resource_datadog_aws_account_v2.go index 5c268982b3..56292ab103 100644 --- a/datadog/fwprovider/resource_datadog_aws_account_v2.go +++ b/datadog/fwprovider/resource_datadog_aws_account_v2.go @@ -5,6 +5,7 @@ import ( "github.com/DataDog/datadog-api-client-go/v2/api/datadogV2" "github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" frameworkPath "github.com/hashicorp/terraform-plugin-framework/path" @@ -22,6 +23,13 @@ var ( _ resource.ResourceWithImportState = &awsAccountV2Resource{} ) +var ( + namespaceFiltersPath = path.MatchRoot("metrics_config").AtName("namespace_filters") + awsRegionsPath = path.MatchRoot("aws_regions") + authConfigPath = path.MatchRoot("auth_config") + tracesConfigPath = path.MatchRoot("traces_config") +) + type awsAccountV2Resource struct { Api *datadogV2.AWSIntegrationApi Auth context.Context @@ -44,10 +52,12 @@ type authConfigModel struct { AwsAuthConfigKeys *awsAuthConfigKeysModel `tfsdk:"aws_auth_config_keys"` AwsAuthConfigRole *awsAuthConfigRoleModel `tfsdk:"aws_auth_config_role"` } + type awsAuthConfigKeysModel struct { AccessKeyId types.String `tfsdk:"access_key_id"` SecretAccessKey types.String `tfsdk:"secret_access_key"` } + type awsAuthConfigRoleModel struct { ExternalId types.String `tfsdk:"external_id"` RoleName types.String `tfsdk:"role_name"` @@ -61,6 +71,7 @@ type awsRegionsModel struct { type logsConfigModel struct { LambdaForwarder *lambdaForwarderModel `tfsdk:"lambda_forwarder"` } + type lambdaForwarderModel struct { Lambdas types.List `tfsdk:"lambdas"` Sources types.List `tfsdk:"sources"` @@ -74,6 +85,7 @@ type metricsConfigModel struct { TagFilters []*tagFiltersModel `tfsdk:"tag_filters"` NamespaceFilters *namespaceFiltersModel `tfsdk:"namespace_filters"` } + type tagFiltersModel struct { Namespace types.String `tfsdk:"namespace"` Tags types.List `tfsdk:"tags"` @@ -92,6 +104,7 @@ type resourcesConfigModel struct { type tracesConfigModel struct { XrayServices *xrayServicesModel `tfsdk:"xray_services"` } + type xrayServicesModel struct { IncludeAll types.Bool `tfsdk:"include_all"` IncludeOnly types.List `tfsdk:"include_only"` @@ -114,28 +127,59 @@ func (r *awsAccountV2Resource) Metadata(_ context.Context, request resource.Meta func (r *awsAccountV2Resource) ConfigValidators(ctx context.Context) []resource.ConfigValidator { return []resource.ConfigValidator{ resourcevalidator.ExactlyOneOf( - path.MatchRoot("auth_config").AtName("aws_auth_config_keys"), - path.MatchRoot("auth_config").AtName("aws_auth_config_role"), + authConfigPath.AtName("aws_auth_config_keys"), + authConfigPath.AtName("aws_auth_config_role"), ), - resourcevalidator.ExactlyOneOf( - path.MatchRoot("traces_config").AtName("xray_services").AtName("include_all"), - path.MatchRoot("traces_config").AtName("xray_services").AtName("include_only"), + resourcevalidator.Conflicting( + tracesConfigPath.AtName("xray_services").AtName("include_all"), + tracesConfigPath.AtName("xray_services").AtName("include_only"), ), - resourcevalidator.ExactlyOneOf( - path.MatchRoot("metrics_config").AtName("namespace_filters").AtName("include_only"), - path.MatchRoot("metrics_config").AtName("namespace_filters").AtName("exclude_only"), + resourcevalidator.AtLeastOneOf( + namespaceFiltersPath, ), - resourcevalidator.ExactlyOneOf( - path.MatchRoot("aws_regions").AtName("include_all"), - path.MatchRoot("aws_regions").AtName("include_only"), + resourcevalidator.Conflicting( + namespaceFiltersPath.AtName("include_only"), + namespaceFiltersPath.AtName("exclude_only"), + ), + resourcevalidator.AtLeastOneOf( + awsRegionsPath, + ), + resourcevalidator.Conflicting( + awsRegionsPath.AtName("include_all"), + awsRegionsPath.AtName("include_only"), ), resourcevalidator.RequiredTogether( - path.MatchRoot("auth_config").AtName("aws_auth_config_keys").AtName("access_key_id"), - path.MatchRoot("auth_config").AtName("aws_auth_config_keys").AtName("secret_access_key"), + authConfigPath.AtName("aws_auth_config_keys").AtName("access_key_id"), + authConfigPath.AtName("aws_auth_config_keys").AtName("secret_access_key"), ), } } +func (r *awsAccountV2Resource) ModifyPlan(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse) { + // Add defaults to namespace_filters + excludeOnlyDefaultValue, _ := types.ListValueFrom(ctx, types.StringType, []string{"AWS/SQS", "AWS/ElasticMapReduce"}) + r.defaultIfNotSet( + ctx, + request, + response, + namespaceFiltersPath.AtName("include_only"), + namespaceFiltersPath.AtName("exclude_only"), + namespaceFiltersPath.AtName("exclude_only"), + excludeOnlyDefaultValue, + ) + + // Add defaults to aws_regions + r.defaultIfNotSet( + ctx, + request, + response, + awsRegionsPath.AtName("include_all"), + awsRegionsPath.AtName("include_only"), + awsRegionsPath.AtName("include_all"), + types.BoolValue(true), + ) +} + func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaRequest, response *resource.SchemaResponse) { response.Schema = schema.Schema{ Description: "Provides a Datadog AwsAccountV2 resource. This can be used to create and manage Datadog aws_account_v2.", @@ -195,6 +239,7 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Attributes: map[string]schema.Attribute{ "include_all": schema.BoolAttribute{ Optional: true, + Computed: true, Description: "Include all regions", }, "include_only": schema.ListAttribute{ @@ -262,6 +307,7 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Attributes: map[string]schema.Attribute{ "exclude_only": schema.ListAttribute{ Optional: true, + Computed: true, Description: "Exclude only these namespaces", ElementType: types.StringType, }, @@ -606,15 +652,14 @@ func (r *awsAccountV2Resource) buildAwsAccountV2RequestBody(ctx context.Context, func buildRequestAwsRegions(ctx context.Context, state *awsAccountV2Model, diags diag.Diagnostics) datadogV2.AWSRegions { regions := datadogV2.AWSRegions{} - if !state.AwsRegions.IncludeAll.IsNull() { - regions.AWSRegionsIncludeAll = datadogV2.NewAWSRegionsIncludeAllWithDefaults() - regions.AWSRegionsIncludeAll.IncludeAll = state.AwsRegions.IncludeAll.ValueBool() - } if !state.AwsRegions.IncludeOnly.IsNull() { regions.AWSRegionsIncludeOnly = datadogV2.NewAWSRegionsIncludeOnlyWithDefaults() var includeOnly []string diags.Append(state.AwsRegions.IncludeOnly.ElementsAs(ctx, &includeOnly, false)...) regions.AWSRegionsIncludeOnly.IncludeOnly = includeOnly + } else { + regions.AWSRegionsIncludeAll = datadogV2.NewAWSRegionsIncludeAllWithDefaults() + regions.AWSRegionsIncludeAll.IncludeAll = state.AwsRegions.IncludeAll.ValueBool() } return regions } @@ -708,23 +753,22 @@ func buildRequestMetricsConfig(ctx context.Context, state *awsAccountV2Model, di var namespaceFiltersDD *datadogV2.AWSNamespaceFilters nsFiltersTf := state.MetricsConfig.NamespaceFilters - if !nsFiltersTf.ExcludeOnly.IsNull() { - var excludeOnly []string - namespaceFiltersDD = &datadogV2.AWSNamespaceFilters{} - namespaceFiltersDD.AWSNamespaceFiltersExcludeOnly = datadogV2.NewAWSNamespaceFiltersExcludeOnlyWithDefaults() - diags.Append(nsFiltersTf.ExcludeOnly.ElementsAs(ctx, &excludeOnly, false)...) - namespaceFiltersDD.AWSNamespaceFiltersExcludeOnly.SetExcludeOnly(excludeOnly) - } else if !nsFiltersTf.IncludeOnly.IsNull() { + if !nsFiltersTf.IncludeOnly.IsNull() { var includeOnly []string namespaceFiltersDD = &datadogV2.AWSNamespaceFilters{} namespaceFiltersDD.AWSNamespaceFiltersIncludeOnly = datadogV2.NewAWSNamespaceFiltersIncludeOnlyWithDefaults() diags.Append(nsFiltersTf.IncludeOnly.ElementsAs(ctx, &includeOnly, false)...) namespaceFiltersDD.AWSNamespaceFiltersIncludeOnly.SetIncludeOnly(includeOnly) - } - if namespaceFiltersDD != nil { - metricsConfig.SetNamespaceFilters(*namespaceFiltersDD) + } else { + var excludeOnly []string + namespaceFiltersDD = &datadogV2.AWSNamespaceFilters{} + namespaceFiltersDD.AWSNamespaceFiltersExcludeOnly = datadogV2.NewAWSNamespaceFiltersExcludeOnlyWithDefaults() + diags.Append(nsFiltersTf.ExcludeOnly.ElementsAs(ctx, &excludeOnly, false)...) + namespaceFiltersDD.AWSNamespaceFiltersExcludeOnly.SetExcludeOnly(excludeOnly) } + metricsConfig.SetNamespaceFilters(*namespaceFiltersDD) + return metricsConfig } @@ -784,3 +828,28 @@ func (r *awsAccountV2Resource) buildAwsAccountV2UpdateRequestBody(ctx context.Co return req, diags } + +func (r *awsAccountV2Resource) defaultIfNotSet(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse, firstPath path.Expression, secondPath path.Expression, defaultPath path.Expression, defaultVal interface{}) { + var firstValue attr.Value + var isFirstValueUnknownOrNull bool + var secondValue attr.Value + var isSecondValueUnknownOrNull bool + + firstPathMatches, _ := request.Config.PathMatches(ctx, firstPath) + secondPathMatches, _ := request.Config.PathMatches(ctx, secondPath) + + request.Config.GetAttribute(ctx, firstPathMatches[0], &firstValue) + request.Config.GetAttribute(ctx, secondPathMatches[0], &secondValue) + + if firstValue.IsNull() || firstValue.IsUnknown() { + isFirstValueUnknownOrNull = true + } + if secondValue.IsNull() || secondValue.IsUnknown() { + isSecondValueUnknownOrNull = true + } + + if isFirstValueUnknownOrNull && isSecondValueUnknownOrNull { + defaultPathMatches, _ := request.Config.PathMatches(ctx, defaultPath) + response.Plan.SetAttribute(ctx, defaultPathMatches[0], defaultVal) + } +} From 31c258f3544c2ce00b7fec51c4298a8e3e7f90b7 Mon Sep 17 00:00:00 2001 From: Sherzod Karimov Date: Wed, 27 Nov 2024 08:17:39 -0500 Subject: [PATCH 5/6] few more defaults --- datadog/fwprovider/resource_datadog_aws_account_v2.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/datadog/fwprovider/resource_datadog_aws_account_v2.go b/datadog/fwprovider/resource_datadog_aws_account_v2.go index 56292ab103..58f85cf5ce 100644 --- a/datadog/fwprovider/resource_datadog_aws_account_v2.go +++ b/datadog/fwprovider/resource_datadog_aws_account_v2.go @@ -11,6 +11,7 @@ import ( frameworkPath "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/listdefault" "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" @@ -28,6 +29,7 @@ var ( awsRegionsPath = path.MatchRoot("aws_regions") authConfigPath = path.MatchRoot("auth_config") tracesConfigPath = path.MatchRoot("traces_config") + logsConfigPath = path.MatchRoot("logs_config") ) type awsAccountV2Resource struct { @@ -152,6 +154,9 @@ func (r *awsAccountV2Resource) ConfigValidators(ctx context.Context) []resource. authConfigPath.AtName("aws_auth_config_keys").AtName("access_key_id"), authConfigPath.AtName("aws_auth_config_keys").AtName("secret_access_key"), ), + resourcevalidator.AtLeastOneOf( + logsConfigPath.AtName("lambda_forwarder"), + ), } } @@ -256,13 +261,17 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Attributes: map[string]schema.Attribute{ "lambdas": schema.ListAttribute{ Optional: true, + Computed: true, Description: "List of Datadog Lambda Log Forwarder ARNs", ElementType: types.StringType, + Default: listdefault.StaticValue(types.ListValueMust(types.StringType, []attr.Value{})), }, "sources": schema.ListAttribute{ Optional: true, + Computed: true, Description: "List of AWS services that will send logs to the Datadog Lambda Log Forwarder", ElementType: types.StringType, + Default: listdefault.StaticValue(types.ListValueMust(types.StringType, []attr.Value{})), }, }, }, From c4555cb68f95cce47154a79f6a954611e3234a56 Mon Sep 17 00:00:00 2001 From: Sherzod Karimov Date: Wed, 27 Nov 2024 09:23:25 -0500 Subject: [PATCH 6/6] add helper func to remove defaults when in oneOF --- .../resource_datadog_aws_account_v2.go | 63 +++++-------------- datadog/internal/fwutils/modify_plan.go | 62 ++++++++++++++++++ 2 files changed, 76 insertions(+), 49 deletions(-) create mode 100644 datadog/internal/fwutils/modify_plan.go diff --git a/datadog/fwprovider/resource_datadog_aws_account_v2.go b/datadog/fwprovider/resource_datadog_aws_account_v2.go index 58f85cf5ce..9b01b62ac5 100644 --- a/datadog/fwprovider/resource_datadog_aws_account_v2.go +++ b/datadog/fwprovider/resource_datadog_aws_account_v2.go @@ -11,11 +11,13 @@ import ( frameworkPath "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "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/listdefault" "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-datadog/datadog/internal/fwutils" "github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" ) @@ -161,28 +163,10 @@ func (r *awsAccountV2Resource) ConfigValidators(ctx context.Context) []resource. } func (r *awsAccountV2Resource) ModifyPlan(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse) { - // Add defaults to namespace_filters - excludeOnlyDefaultValue, _ := types.ListValueFrom(ctx, types.StringType, []string{"AWS/SQS", "AWS/ElasticMapReduce"}) - r.defaultIfNotSet( - ctx, - request, - response, - namespaceFiltersPath.AtName("include_only"), - namespaceFiltersPath.AtName("exclude_only"), - namespaceFiltersPath.AtName("exclude_only"), - excludeOnlyDefaultValue, - ) - - // Add defaults to aws_regions - r.defaultIfNotSet( - ctx, - request, - response, - awsRegionsPath.AtName("include_all"), - awsRegionsPath.AtName("include_only"), - awsRegionsPath.AtName("include_all"), - types.BoolValue(true), - ) + // Remove exclude_only default if namespace_filters is set. + fwutils.RemoveDefaultIfConflictingSet(ctx, request, response, namespaceFiltersPath.AtName("exclude_only"), namespaceFiltersPath.AtName("include_only")) + // Remove aws_config default if `include_only` is set. + fwutils.RemoveDefaultIfConflictingSet(ctx, request, response, awsRegionsPath.AtName("include_all"), awsRegionsPath.AtName("include_only")) } func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaRequest, response *resource.SchemaResponse) { @@ -245,6 +229,7 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques "include_all": schema.BoolAttribute{ Optional: true, Computed: true, + Default: booldefault.StaticBool(true), Description: "Include all regions", }, "include_only": schema.ListAttribute{ @@ -319,6 +304,12 @@ func (r *awsAccountV2Resource) Schema(_ context.Context, _ resource.SchemaReques Computed: true, Description: "Exclude only these namespaces", ElementType: types.StringType, + Default: listdefault.StaticValue(types.ListValueMust( + types.StringType, []attr.Value{ + types.StringValue("AWS/SQS"), + types.StringValue("AWS/ElasticMapReduce"), + }), + ), }, "include_only": schema.ListAttribute{ Optional: true, @@ -569,8 +560,7 @@ func buildStateMetricsConfig(ctx context.Context, attributes datadogV2.AWSAccoun if namespaceFilters.AWSNamespaceFiltersExcludeOnly != nil { excludeOnly, _ := types.ListValueFrom(ctx, types.StringType, namespaceFilters.AWSNamespaceFiltersExcludeOnly.GetExcludeOnly()) nsFiltersTf.ExcludeOnly = excludeOnly - } - if namespaceFilters.AWSNamespaceFiltersIncludeOnly != nil { + } else if namespaceFilters.AWSNamespaceFiltersIncludeOnly != nil { includeOnly, _ := types.ListValueFrom(ctx, types.StringType, namespaceFilters.AWSNamespaceFiltersIncludeOnly.GetIncludeOnly()) nsFiltersTf.IncludeOnly = includeOnly } @@ -837,28 +827,3 @@ func (r *awsAccountV2Resource) buildAwsAccountV2UpdateRequestBody(ctx context.Co return req, diags } - -func (r *awsAccountV2Resource) defaultIfNotSet(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse, firstPath path.Expression, secondPath path.Expression, defaultPath path.Expression, defaultVal interface{}) { - var firstValue attr.Value - var isFirstValueUnknownOrNull bool - var secondValue attr.Value - var isSecondValueUnknownOrNull bool - - firstPathMatches, _ := request.Config.PathMatches(ctx, firstPath) - secondPathMatches, _ := request.Config.PathMatches(ctx, secondPath) - - request.Config.GetAttribute(ctx, firstPathMatches[0], &firstValue) - request.Config.GetAttribute(ctx, secondPathMatches[0], &secondValue) - - if firstValue.IsNull() || firstValue.IsUnknown() { - isFirstValueUnknownOrNull = true - } - if secondValue.IsNull() || secondValue.IsUnknown() { - isSecondValueUnknownOrNull = true - } - - if isFirstValueUnknownOrNull && isSecondValueUnknownOrNull { - defaultPathMatches, _ := request.Config.PathMatches(ctx, defaultPath) - response.Plan.SetAttribute(ctx, defaultPathMatches[0], defaultVal) - } -} diff --git a/datadog/internal/fwutils/modify_plan.go b/datadog/internal/fwutils/modify_plan.go new file mode 100644 index 0000000000..db372a98ec --- /dev/null +++ b/datadog/internal/fwutils/modify_plan.go @@ -0,0 +1,62 @@ +package fwutils + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// RemoveDefaultIfConflictingSet remove default value from attr if conflicting paths are set +// explicitly sets the default value to null if any of the conflicting paths are set. +// This is useful for nested blocks which have oneOf attributes. +func RemoveDefaultIfConflictingSet(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse, defaultPath path.Expression, conflictingPaths ...path.Expression) { + isConflictingSet := false + for _, conflictingPath := range conflictingPaths { + conflictingPathMatches, _ := request.Config.PathMatches(ctx, conflictingPath) + var conflictingValue attr.Value + request.Config.GetAttribute(ctx, conflictingPathMatches[0], &conflictingValue) + schema, _ := request.Config.Schema.AttributeAtPath(ctx, conflictingPathMatches[0]) + if (schema.IsComputed() && !conflictingValue.IsUnknown()) || (!schema.IsComputed() && !conflictingValue.IsNull()) { + isConflictingSet = true + break + } + } + + if isConflictingSet { + defaultPathMatches, _ := request.Config.PathMatches(ctx, defaultPath) + schema, _ := request.Config.Schema.AttributeAtPath(ctx, defaultPathMatches[0]) + var defaultValue interface{} + switch schema.GetType() { + case types.StringType: + defaultValue = types.StringNull() + case types.BoolType: + defaultValue = types.BoolNull() + case types.NumberType: + defaultValue = types.NumberNull() + case types.Float64Type: + defaultValue = types.Float64Null() + case types.Int64Type: + defaultValue = types.Int64Null() + case types.ListType{ElemType: types.StringType}: + defaultValue = types.ListNull(types.StringType) + case types.ListType{ElemType: types.BoolType}: + defaultValue = types.ListNull(types.BoolType) + case types.ListType{ElemType: types.NumberType}: + defaultValue = types.ListNull(types.NumberType) + case types.ListType{ElemType: types.Float64Type}: + defaultValue = types.ListNull(types.Float64Type) + case types.ListType{ElemType: types.Int64Type}: + defaultValue = types.ListNull(types.Int64Type) + default: + response.Diagnostics.AddError("unsupported type for default value", fmt.Sprintf("Unsupported type: %s", defaultPathMatches[0].String())) + return + } + + response.Plan.SetAttribute(ctx, defaultPathMatches[0], defaultValue) + } + +}