-
Notifications
You must be signed in to change notification settings - Fork 389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[datadog_security_monitoring_rule] Add Terraform Support for Signal Correlation Rules #1593
Conversation
ad51fdf
to
02d8e5b
Compare
c2fcf70
to
89db8dc
Compare
89db8dc
to
a39d706
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 for docs
@@ -317,35 +426,78 @@ func resourceDatadogSecurityMonitoringRuleCreate(ctx context.Context, d *schema. | |||
return diag.FromErr(err) | |||
} | |||
|
|||
d.SetId(response.SecurityMonitoringStandardRuleResponse.GetId()) | |||
if response.SecurityMonitoringStandardRuleResponse != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: I think it would be better to differentiate based on wether query
or signal_query
field is set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, the next instruction is about getting the id of the response by accessing the non null field of the response. Therefore, it seems to me that this check is mandatory (and then sufficient) for assigning the id.
query := d.Get("query").([]interface{}) | ||
signalQuery := d.Get("signal_query").([]interface{}) | ||
if len(query) > 0 && len(signalQuery) > 0 { | ||
return fmt.Errorf("query list and signal query list cannot be both populated") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use TF validation schema helpers such as ConflictsWith
properties instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried but it was not working since, as stated in the documentations:
// Only absolute attribute paths, ones starting with top level attribute
// names, are supported. Attribute paths cannot be accurately declared
// for TypeList (if MaxItems is greater than 1), TypeMap, or TypeSet
// attributes. To reference an attribute under a single configuration block
// (TypeList with Elem of *Resource and MaxItems of 1), the syntax is
// "parent_block_name.0.child_attribute_name".
In our case, it is a TypeList whose MaxItems is greater than 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job 👌 There's a typo in the aggregation type description, otherwise only nits 😄
…mon methods of rules
a96195e
to
ba31583
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice 🎉 only a couple of nits
if v, ok := query["metrics"]; ok && v != nil { | ||
if tfMetrics, ok := v.([]interface{}); ok && len(tfMetrics) > 0 { | ||
metrics := make([]string, len(tfMetrics)) | ||
for i, value := range tfMetrics { | ||
metrics[i] = value.(string) | ||
} | ||
payloadQuery.SetMetrics(metrics) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code seems useless as metrics
is not defined on signal_query
.
if v, ok := query["metrics"]; ok && v != nil { | |
if tfMetrics, ok := v.([]interface{}); ok && len(tfMetrics) > 0 { | |
metrics := make([]string, len(tfMetrics)) | |
for i, value := range tfMetrics { | |
metrics[i] = value.(string) | |
} | |
payloadQuery.SetMetrics(metrics) | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ (in all places)
Optional: true, | ||
Description: "The rule type.", | ||
Default: "log_detection", | ||
}, | ||
} | ||
} | ||
|
||
// SecurityMonitoringRuleInterface Common Interface to SecurityMonitoringRuleCreateInterface and SecurityMonitoringRuleReadInterface | ||
type SecurityMonitoringRuleInterface interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these interfaces should be private, as they are utilities to factorize code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
Description
This PR updates the Terraform provider to support
Signal Correlation
rules.It replaces #1591 which was not backward compatible.
It impact the resources/data:
resource_datadog_security_monitoring_rule
data_source_datadog_security_monitoring_rules
To be backward compatible, the fields which are specific to Signal Correlation rules (i.e.,
ruleId
,defaultRuleId
,correlatedByFields
,correlatedQueryIndex
) are populated in a different sub list Schema calledsignal_query
.Since
query
is a List that could have multiple elements, it is not possible to enforce aDistinctsWith
.Since the Go struct
SecurityMonitoringRuleResponse
does not implement a common interface forSecurityMonitoringStandardRuleResponse
andSecurityMonitoringSignalRuleResponse
, most of the methods have been specialised in spite of having common code.Additionally, this PR homogenises the way the payloads are populated by using the Setters instead of directly accessing the attributes in
security_monitoring
. It addresses remarks from previous PR about wording.How do these changes impact current model
Up to now, Datadog Security Monitoring has been supporting one common type of rule whose Terraform schema is
This schema is not modified for existing rule type.
On the other hand, signal correlation rules will have a similar schema which will differ by its queries and its type:
A check was implemented in Terraform to prevent users from having two populated lists (i.e.
query
andsignal_query
).correlated_query_index
In spite of being an index (thus an integer), the Terraform Schema uses a string to represent it because this value can be empty.
Having:
correlated_query_index=0
: Means correlate on the projected attributes of the first query of the correlated rulecorrelated_query_index=""
: Means correlate on the non-projected per query attribute of the correlated rule.Since
TypeInt
object does not support anil
value as a Default value, we decided to use a string which is converted to an integer if it is not empty.