Skip to content

Commit 33be267

Browse files
update csm_threats_agent_rule resource and data_source
1 parent e91f8b1 commit 33be267

5 files changed

+123
-84
lines changed

datadog/fwprovider/data_source_datadog_csm_threats_agent_rule.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (r *csmThreatsAgentRulesDataSource) Configure(_ context.Context, request da
6262
r.auth = providerData.Auth
6363
}
6464

65-
func (r *csmThreatsAgentRulesDataSource) Metadata(_ context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) {
65+
func (*csmThreatsAgentRulesDataSource) Metadata(_ context.Context, _ datasource.MetadataRequest, response *datasource.MetadataResponse) {
6666
response.TypeName = "csm_threats_agent_rules"
6767
}
6868

datadog/fwprovider/resource_datadog_csm_threats_agent_rule.go

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import (
1313
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
1414
"github.com/hashicorp/terraform-plugin-framework/types"
1515

16+
"net/http"
17+
1618
"github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils"
1719
)
1820

@@ -57,7 +59,7 @@ func (r *csmThreatsAgentRuleResource) Schema(_ context.Context, _ resource.Schem
5759
Attributes: map[string]schema.Attribute{
5860
"id": utils.ResourceIDAttribute(),
5961
"policy_id": schema.StringAttribute{
60-
Required: true,
62+
Optional: true,
6163
Description: "The ID of the agent policy in which the rule is saved",
6264
},
6365
"name": schema.StringAttribute{
@@ -73,15 +75,13 @@ func (r *csmThreatsAgentRuleResource) Schema(_ context.Context, _ resource.Schem
7375
Computed: true,
7476
},
7577
"enabled": schema.BoolAttribute{
76-
Required: true,
77-
Description: "Indicates Whether the Agent rule is enabled.",
78+
Optional: true,
79+
Description: "Indicates whether the Agent rule is enabled. Must not be used without policy_id.",
80+
Computed: true,
7881
},
7982
"expression": schema.StringAttribute{
8083
Required: true,
8184
Description: "The SECL expression of the Agent rule",
82-
PlanModifiers: []planmodifier.String{
83-
stringplanmodifier.RequiresReplace(),
84-
},
8585
},
8686
"product_tags": schema.SetAttribute{
8787
Optional: true,
@@ -95,13 +95,15 @@ func (r *csmThreatsAgentRuleResource) Schema(_ context.Context, _ resource.Schem
9595

9696
func (r *csmThreatsAgentRuleResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) {
9797
result := strings.SplitN(request.ID, ":", 2)
98-
if len(result) != 2 {
99-
response.Diagnostics.AddError("error retrieving policy_id or rule_id from given ID", "")
100-
return
101-
}
10298

103-
response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root("policy_id"), result[0])...)
104-
response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root("id"), result[1])...)
99+
if len(result) == 2 {
100+
response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root("policy_id"), result[0])...)
101+
response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root("id"), result[1])...)
102+
} else if len(result) == 1 {
103+
response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root("id"), result[0])...)
104+
} else {
105+
response.Diagnostics.AddError("unexpected import format", "expected '<policy_id>:<rule_id>' or '<rule_id>'")
106+
}
105107
}
106108

107109
func (r *csmThreatsAgentRuleResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) {
@@ -111,6 +113,9 @@ func (r *csmThreatsAgentRuleResource) Create(ctx context.Context, request resour
111113
return
112114
}
113115

116+
csmThreatsMutex.Lock()
117+
defer csmThreatsMutex.Unlock()
118+
114119
agentRulePayload, err := r.buildCreateCSMThreatsAgentRulePayload(&state)
115120
if err != nil {
116121
response.Diagnostics.AddError("error while parsing resource", err.Error())
@@ -137,11 +142,23 @@ func (r *csmThreatsAgentRuleResource) Read(ctx context.Context, request resource
137142
return
138143
}
139144

145+
csmThreatsMutex.Lock()
146+
defer csmThreatsMutex.Unlock()
147+
140148
agentRuleId := state.Id.ValueString()
141-
policyId := state.PolicyId.ValueString()
142-
res, httpResponse, err := r.api.GetCSMThreatsAgentRule(r.auth, agentRuleId, *datadogV2.NewGetCSMThreatsAgentRuleOptionalParameters().WithPolicyId(policyId))
149+
150+
var res datadogV2.CloudWorkloadSecurityAgentRuleResponse
151+
var httpResp *http.Response
152+
var err error
153+
if !state.PolicyId.IsNull() && !state.PolicyId.IsUnknown() {
154+
policyId := state.PolicyId.ValueString()
155+
res, httpResp, err = r.api.GetCSMThreatsAgentRule(r.auth, agentRuleId, *datadogV2.NewGetCSMThreatsAgentRuleOptionalParameters().WithPolicyId(policyId))
156+
} else {
157+
res, httpResp, err = r.api.GetCSMThreatsAgentRule(r.auth, agentRuleId)
158+
}
159+
143160
if err != nil {
144-
if httpResponse != nil && httpResponse.StatusCode == 404 {
161+
if httpResp.StatusCode == 404 {
145162
response.State.RemoveResource(ctx)
146163
return
147164
}
@@ -164,9 +181,13 @@ func (r *csmThreatsAgentRuleResource) Update(ctx context.Context, request resour
164181
return
165182
}
166183

184+
csmThreatsMutex.Lock()
185+
defer csmThreatsMutex.Unlock()
186+
167187
agentRulePayload, err := r.buildUpdateCSMThreatsAgentRulePayload(&state)
168188
if err != nil {
169189
response.Diagnostics.AddError("error while parsing resource", err.Error())
190+
return
170191
}
171192

172193
res, _, err := r.api.UpdateCSMThreatsAgentRule(r.auth, state.Id.ValueString(), *agentRulePayload)
@@ -190,11 +211,22 @@ func (r *csmThreatsAgentRuleResource) Delete(ctx context.Context, request resour
190211
return
191212
}
192213

214+
csmThreatsMutex.Lock()
215+
defer csmThreatsMutex.Unlock()
216+
193217
id := state.Id.ValueString()
194-
policyId := state.PolicyId.ValueString()
195-
httpResp, err := r.api.DeleteCSMThreatsAgentRule(r.auth, id, *datadogV2.NewDeleteCSMThreatsAgentRuleOptionalParameters().WithPolicyId(policyId))
218+
219+
var httpResp *http.Response
220+
var err error
221+
if !state.PolicyId.IsNull() && !state.PolicyId.IsUnknown() {
222+
policyId := state.PolicyId.ValueString()
223+
httpResp, err = r.api.DeleteCSMThreatsAgentRule(r.auth, id, *datadogV2.NewDeleteCSMThreatsAgentRuleOptionalParameters().WithPolicyId(policyId))
224+
} else {
225+
httpResp, err = r.api.DeleteCSMThreatsAgentRule(r.auth, id)
226+
}
227+
196228
if err != nil {
197-
if httpResp != nil && httpResp.StatusCode == 404 {
229+
if httpResp.StatusCode == 404 {
198230
return
199231
}
200232
response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error deleting agent rule"))
@@ -210,32 +242,39 @@ func (r *csmThreatsAgentRuleResource) buildCreateCSMThreatsAgentRulePayload(stat
210242
attributes.Name = name
211243
attributes.Description = description
212244
attributes.Enabled = &enabled
213-
attributes.PolicyId = &policyId
245+
attributes.PolicyId = policyId
214246
attributes.ProductTags = productTags
215247

216248
data := datadogV2.NewCloudWorkloadSecurityAgentRuleCreateData(attributes, datadogV2.CLOUDWORKLOADSECURITYAGENTRULETYPE_AGENT_RULE)
217249
return datadogV2.NewCloudWorkloadSecurityAgentRuleCreateRequest(*data), nil
218250
}
219251

220252
func (r *csmThreatsAgentRuleResource) buildUpdateCSMThreatsAgentRulePayload(state *csmThreatsAgentRuleModel) (*datadogV2.CloudWorkloadSecurityAgentRuleUpdateRequest, error) {
221-
agentRuleId, policyId, _, description, enabled, _, productTags := r.extractAgentRuleAttributesFromResource(state)
253+
agentRuleId, policyId, _, description, enabled, expression, productTags := r.extractAgentRuleAttributesFromResource(state)
222254

223255
attributes := datadogV2.CloudWorkloadSecurityAgentRuleUpdateAttributes{}
256+
attributes.Expression = &expression
224257
attributes.Description = description
225258
attributes.Enabled = &enabled
226-
attributes.PolicyId = &policyId
259+
attributes.PolicyId = policyId
227260
attributes.ProductTags = productTags
228261

229262
data := datadogV2.NewCloudWorkloadSecurityAgentRuleUpdateData(attributes, datadogV2.CLOUDWORKLOADSECURITYAGENTRULETYPE_AGENT_RULE)
230263
data.Id = &agentRuleId
231264
return datadogV2.NewCloudWorkloadSecurityAgentRuleUpdateRequest(*data), nil
232265
}
233266

234-
func (r *csmThreatsAgentRuleResource) extractAgentRuleAttributesFromResource(state *csmThreatsAgentRuleModel) (string, string, string, *string, bool, string, []string) {
267+
func (r *csmThreatsAgentRuleResource) extractAgentRuleAttributesFromResource(state *csmThreatsAgentRuleModel) (string, *string, string, *string, bool, string, []string) {
235268
// Mandatory fields
236269
id := state.Id.ValueString()
237-
policyId := state.PolicyId.ValueString()
238270
name := state.Name.ValueString()
271+
272+
// Optional fields
273+
var policyId *string
274+
if !state.PolicyId.IsNull() && !state.PolicyId.IsUnknown() {
275+
val := state.PolicyId.ValueString()
276+
policyId = &val
277+
}
239278
enabled := state.Enabled.ValueBool()
240279
expression := state.Expression.ValueString()
241280
description := state.Description.ValueStringPointer()
@@ -244,7 +283,7 @@ func (r *csmThreatsAgentRuleResource) extractAgentRuleAttributesFromResource(sta
244283
for _, tag := range state.ProductTags.Elements() {
245284
tagStr, ok := tag.(types.String)
246285
if !ok {
247-
return "", "", "", nil, false, "", nil
286+
return "", nil, "", nil, false, "", nil
248287
}
249288
productTags = append(productTags, tagStr.ValueString())
250289
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2025-05-22T10:38:29.722541+02:00
1+
2025-06-02T15:24:08.619998+02:00

0 commit comments

Comments
 (0)