@@ -83,15 +83,12 @@ func resourceDatadogSecurityMonitoringDefaultRule() *schema.Resource {
8383 },
8484 },
8585 "aggregation" : {
86- Type : schema .TypeString ,
87- ValidateDiagFunc : validators .ValidateEnumValue (datadogV2 .NewSecurityMonitoringRuleQueryAggregationFromValue ),
88- Optional : true ,
89- Computed : true ,
90- Description : "The aggregation type. For Signal Correlation rules, it must be event_count." ,
86+ Type : schema .TypeString ,
87+ Computed : true ,
88+ Description : "The aggregation type. For Signal Correlation rules, it must be event_count." ,
9189 },
9290 "distinct_fields" : {
9391 Type : schema .TypeList ,
94- Optional : true ,
9592 Computed : true ,
9693 Description : "Field for which the cardinality is measured. Sent as an array." ,
9794 Elem : & schema.Schema {
@@ -101,7 +98,6 @@ func resourceDatadogSecurityMonitoringDefaultRule() *schema.Resource {
10198 },
10299 "group_by_fields" : {
103100 Type : schema .TypeList ,
104- Optional : true ,
105101 Computed : true ,
106102 Description : "Fields to group by." ,
107103 Elem : & schema.Schema {
@@ -111,40 +107,33 @@ func resourceDatadogSecurityMonitoringDefaultRule() *schema.Resource {
111107 },
112108 "has_optional_group_by_fields" : {
113109 Type : schema .TypeBool ,
114- Optional : true ,
115110 Computed : true ,
116111 Description : "When false, events without a group-by value are ignored by the rule. When true, events with missing group-by fields are processed with `N/A`, replacing the missing values." ,
117112 },
118113 "data_source" : {
119- Type : schema .TypeString ,
120- ValidateDiagFunc : validators .ValidateEnumValue (datadogV2 .NewSecurityMonitoringStandardDataSourceFromValue ),
121- Optional : true ,
122- Computed : true ,
123- Description : "Source of events." ,
114+ Type : schema .TypeString ,
115+ Computed : true ,
116+ Description : "Source of events." ,
124117 },
125118 "metric" : {
126119 Type : schema .TypeString ,
127120 Deprecated : "Configure `metrics` instead. This attribute will be removed in the next major version of the provider." ,
128- Optional : true ,
129121 Computed : true ,
130122 Description : "The target field to aggregate over when using the `sum`, `max`, or `geo_data` aggregations." ,
131123 },
132124 "metrics" : {
133125 Type : schema .TypeList ,
134126 Computed : true ,
135- Optional : true ,
136127 Description : "Group of target fields to aggregate over when using the `sum`, `max`, `geo_data`, or `new_value` aggregations. The `sum`, `max`, and `geo_data` aggregations only accept one value in this list, whereas the `new_value` aggregation accepts up to five values." ,
137128 Elem : & schema.Schema {Type : schema .TypeString },
138129 },
139130 "name" : {
140131 Type : schema .TypeString ,
141- Optional : true ,
142132 Computed : true ,
143133 Description : "Name of the query. Not compatible with `new_value` aggregations." ,
144134 },
145135 "query" : {
146136 Type : schema .TypeString ,
147- Optional : true ,
148137 Computed : true ,
149138 Description : "Query to run on logs." ,
150139 },
@@ -506,21 +495,24 @@ func buildSecMonDefaultRuleUpdatePayload(currentState *datadogV2.SecurityMonitor
506495 v , ok = d .GetOk ("query" )
507496 if ok && v != "" {
508497 tfQueries := v .([]interface {})
509- payloadQueries := make ([]datadogV2.SecurityMonitoringRuleQuery , len (tfQueries ))
510- for idx , tfQuery := range tfQueries {
511- // For default rules, merge with existing query to preserve unspecified fields
512- var existingQuery * datadogV2.SecurityMonitoringStandardRuleQuery
513- if idx < len (currentState .GetQueries ()) {
514- existingQuery = & currentState .GetQueries ()[idx ]
498+ currentQueries := currentState .GetQueries ()
499+ payloadQueries := make ([]datadogV2.SecurityMonitoringRuleQuery , len (currentQueries ))
500+ for idx , existingQuery := range currentQueries {
501+ // Start from the current API query; only custom_query_extension is user-configurable.
502+ payloadQuery := existingQuery
503+ if idx < len (tfQueries ) {
504+ tfQuery := tfQueries [idx ].(map [string ]interface {})
505+ if v , ok := tfQuery ["custom_query_extension" ]; ok {
506+ cqe := v .(string )
507+ if cqe != existingQuery .GetCustomQueryExtension () {
508+ shouldUpdate = true
509+ }
510+ payloadQuery .SetCustomQueryExtension (cqe )
511+ }
515512 }
516- payloadQueries [idx ] = * buildUpdateDefaultRuleQuery ( tfQuery , existingQuery )
513+ payloadQueries [idx ] = datadogV2 . SecurityMonitoringStandardRuleQueryAsSecurityMonitoringRuleQuery ( & payloadQuery )
517514 }
518515 payload .SetQueries (payloadQueries )
519-
520- // Compare queries including custom_query_extension
521- if ! compareQueries (currentState .GetQueries (), payloadQueries ) {
522- shouldUpdate = true
523- }
524516 }
525517 }
526518
@@ -635,25 +627,6 @@ func buildSecMonDefaultRuleUpdatePayload(currentState *datadogV2.SecurityMonitor
635627 return & payload , shouldUpdate , nil
636628}
637629
638- // Helper function to compare queries including custom_query_extension
639- func compareQueries (currentQueries []datadogV2.SecurityMonitoringStandardRuleQuery , payloadQueries []datadogV2.SecurityMonitoringRuleQuery ) bool {
640- if len (currentQueries ) != len (payloadQueries ) {
641- return false
642- }
643-
644- // For now, we'll assume queries are different if they exist in the payload
645- // This is a simplified approach - in a more complete implementation,
646- // we would need to extract the standard query from the payload query
647- // and compare each field individually
648-
649- // Since we're building the payload from Terraform config and comparing with current state,
650- // if there are any queries in the payload, we should check if they differ from current state
651- // For simplicity, we'll return false (indicating a change) if there are queries in the payload
652- // This ensures that any query changes are detected
653-
654- return len (payloadQueries ) == 0
655- }
656-
657630// Helper function to compare filters
658631func compareFilters (currentFilters []datadogV2.SecurityMonitoringFilter , payloadFilters []datadogV2.SecurityMonitoringFilter ) bool {
659632 if len (currentFilters ) != len (payloadFilters ) {
@@ -720,132 +693,3 @@ func resourceDatadogSecurityMonitoringDefaultRuleDelete(ctx context.Context, d *
720693 // no-op
721694 return nil
722695}
723-
724- // buildUpdateDefaultRuleQuery merges Terraform configuration with existing query state
725- // to preserve fields that are not specified in the Terraform config
726- func buildUpdateDefaultRuleQuery (tfQuery interface {}, existingQuery * datadogV2.SecurityMonitoringStandardRuleQuery ) * datadogV2.SecurityMonitoringRuleQuery {
727- query := tfQuery .(map [string ]interface {})
728- payloadQuery := datadogV2.SecurityMonitoringStandardRuleQuery {}
729-
730- // Start with existing values if available
731- if existingQuery != nil {
732- // Preserve existing aggregation if not specified in TF config
733- if _ , ok := query ["aggregation" ]; ! ok {
734- if aggregation , exists := existingQuery .GetAggregationOk (); exists {
735- payloadQuery .SetAggregation (* aggregation )
736- }
737- }
738-
739- // Preserve existing group_by_fields if not specified in TF config
740- if _ , ok := query ["group_by_fields" ]; ! ok {
741- if groupByFields , exists := existingQuery .GetGroupByFieldsOk (); exists {
742- payloadQuery .SetGroupByFields (* groupByFields )
743- }
744- }
745-
746- if _ , ok := query ["has_optional_group_by_fields" ]; ! ok {
747- if hasGbf , exists := existingQuery .GetHasOptionalGroupByFieldsOk (); exists {
748- payloadQuery .SetHasOptionalGroupByFields (* hasGbf )
749- }
750- }
751-
752- // Preserve existing distinct_fields if not specified in TF config
753- if _ , ok := query ["distinct_fields" ]; ! ok {
754- if distinctFields , exists := existingQuery .GetDistinctFieldsOk (); exists {
755- payloadQuery .SetDistinctFields (* distinctFields )
756- }
757- }
758-
759- // Preserve existing data_source if not specified in TF config
760- if _ , ok := query ["data_source" ]; ! ok {
761- if dataSource , exists := existingQuery .GetDataSourceOk (); exists {
762- payloadQuery .SetDataSource (* dataSource )
763- }
764- }
765-
766- // Preserve existing metric if not specified in TF config
767- if _ , ok := query ["metric" ]; ! ok {
768- if metric , exists := existingQuery .GetMetricOk (); exists {
769- payloadQuery .SetMetric (* metric )
770- }
771- }
772-
773- // Preserve existing metrics if not specified in TF config
774- if _ , ok := query ["metrics" ]; ! ok {
775- if metrics , exists := existingQuery .GetMetricsOk (); exists {
776- payloadQuery .SetMetrics (* metrics )
777- }
778- }
779-
780- // Preserve existing name if not specified in TF config
781- if _ , ok := query ["name" ]; ! ok {
782- if name , exists := existingQuery .GetNameOk (); exists {
783- payloadQuery .SetName (* name )
784- }
785- }
786-
787- // Preserve existing query if not specified in TF config
788- if _ , ok := query ["query" ]; ! ok {
789- if existingQueryStr , exists := existingQuery .GetQueryOk (); exists {
790- payloadQuery .SetQuery (* existingQueryStr )
791- }
792- }
793-
794- // Preserve existing custom_query_extension if not specified in TF config
795- if _ , ok := query ["custom_query_extension" ]; ! ok {
796- if customQueryExtension , exists := existingQuery .GetCustomQueryExtensionOk (); exists {
797- payloadQuery .SetCustomQueryExtension (* customQueryExtension )
798- }
799- }
800- }
801-
802- // Override with values from Terraform config
803- if v , ok := query ["aggregation" ]; ok {
804- aggregation := datadogV2 .SecurityMonitoringRuleQueryAggregation (v .(string ))
805- payloadQuery .SetAggregation (aggregation )
806- }
807-
808- if v , ok := query ["group_by_fields" ]; ok {
809- payloadQuery .SetGroupByFields (parseStringArray (v .([]interface {})))
810- }
811-
812- if v , ok := query ["has_optional_group_by_fields" ]; ok {
813- payloadQuery .SetHasOptionalGroupByFields (v .(bool ))
814- }
815-
816- if v , ok := query ["distinct_fields" ]; ok {
817- payloadQuery .SetDistinctFields (parseStringArray (v .([]interface {})))
818- }
819-
820- if v , ok := query ["data_source" ]; ok {
821- dataSource := datadogV2 .SecurityMonitoringStandardDataSource (v .(string ))
822- payloadQuery .SetDataSource (dataSource )
823- }
824-
825- if v , ok := query ["metric" ]; ok {
826- metric := v .(string )
827- payloadQuery .SetMetric (metric )
828- }
829-
830- if v , ok := query ["metrics" ]; ok {
831- payloadQuery .SetMetrics (parseStringArray (v .([]interface {})))
832- }
833-
834- if v , ok := query ["name" ]; ok {
835- name := v .(string )
836- payloadQuery .SetName (name )
837- }
838-
839- if v , ok := query ["query" ]; ok {
840- queryQuery := v .(string )
841- payloadQuery .SetQuery (queryQuery )
842- }
843-
844- if v , ok := query ["custom_query_extension" ]; ok {
845- queryExtension := v .(string )
846- payloadQuery .SetCustomQueryExtension (queryExtension )
847- }
848-
849- standardRuleQuery := datadogV2 .SecurityMonitoringStandardRuleQueryAsSecurityMonitoringRuleQuery (& payloadQuery )
850- return & standardRuleQuery
851- }
0 commit comments