@@ -13,6 +13,8 @@ import (
13
13
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
14
14
"github.com/hashicorp/terraform-plugin-framework/types"
15
15
16
+ "net/http"
17
+
16
18
"github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils"
17
19
)
18
20
@@ -57,7 +59,7 @@ func (r *csmThreatsAgentRuleResource) Schema(_ context.Context, _ resource.Schem
57
59
Attributes : map [string ]schema.Attribute {
58
60
"id" : utils .ResourceIDAttribute (),
59
61
"policy_id" : schema.StringAttribute {
60
- Required : true ,
62
+ Optional : true ,
61
63
Description : "The ID of the agent policy in which the rule is saved" ,
62
64
},
63
65
"name" : schema.StringAttribute {
@@ -70,38 +72,35 @@ func (r *csmThreatsAgentRuleResource) Schema(_ context.Context, _ resource.Schem
70
72
"description" : schema.StringAttribute {
71
73
Optional : true ,
72
74
Description : "A description for the Agent rule." ,
73
- Computed : true ,
74
75
},
75
76
"enabled" : schema.BoolAttribute {
76
- Required : true ,
77
- Description : "Indicates Whether the Agent rule is enabled." ,
77
+ Optional : true ,
78
+ Description : "Indicates whether the Agent rule is enabled. Must not be used without policy_id ." ,
78
79
},
79
80
"expression" : schema.StringAttribute {
80
81
Required : true ,
81
82
Description : "The SECL expression of the Agent rule" ,
82
- PlanModifiers : []planmodifier.String {
83
- stringplanmodifier .RequiresReplace (),
84
- },
85
83
},
86
84
"product_tags" : schema.SetAttribute {
87
85
Optional : true ,
88
86
ElementType : types .StringType ,
89
87
Description : "The list of product tags associated with the rule" ,
90
- Computed : true ,
91
88
},
92
89
},
93
90
}
94
91
}
95
92
96
93
func (r * csmThreatsAgentRuleResource ) ImportState (ctx context.Context , request resource.ImportStateRequest , response * resource.ImportStateResponse ) {
97
94
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
- }
102
95
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 ])... )
96
+ if len (result ) == 2 {
97
+ response .Diagnostics .Append (response .State .SetAttribute (ctx , path .Root ("policy_id" ), result [0 ])... )
98
+ response .Diagnostics .Append (response .State .SetAttribute (ctx , path .Root ("id" ), result [1 ])... )
99
+ } else if len (result ) == 1 {
100
+ response .Diagnostics .Append (response .State .SetAttribute (ctx , path .Root ("id" ), result [0 ])... )
101
+ } else {
102
+ response .Diagnostics .AddError ("unexpected import format" , "expected '<policy_id>:<rule_id>' or '<rule_id>'" )
103
+ }
105
104
}
106
105
107
106
func (r * csmThreatsAgentRuleResource ) Create (ctx context.Context , request resource.CreateRequest , response * resource.CreateResponse ) {
@@ -111,6 +110,9 @@ func (r *csmThreatsAgentRuleResource) Create(ctx context.Context, request resour
111
110
return
112
111
}
113
112
113
+ csmThreatsMutex .Lock ()
114
+ defer csmThreatsMutex .Unlock ()
115
+
114
116
agentRulePayload , err := r .buildCreateCSMThreatsAgentRulePayload (& state )
115
117
if err != nil {
116
118
response .Diagnostics .AddError ("error while parsing resource" , err .Error ())
@@ -137,11 +139,23 @@ func (r *csmThreatsAgentRuleResource) Read(ctx context.Context, request resource
137
139
return
138
140
}
139
141
142
+ csmThreatsMutex .Lock ()
143
+ defer csmThreatsMutex .Unlock ()
144
+
140
145
agentRuleId := state .Id .ValueString ()
141
- policyId := state .PolicyId .ValueString ()
142
- res , httpResponse , err := r .api .GetCSMThreatsAgentRule (r .auth , agentRuleId , * datadogV2 .NewGetCSMThreatsAgentRuleOptionalParameters ().WithPolicyId (policyId ))
146
+
147
+ var res datadogV2.CloudWorkloadSecurityAgentRuleResponse
148
+ var httpResp * http.Response
149
+ var err error
150
+ if ! state .PolicyId .IsNull () && ! state .PolicyId .IsUnknown () {
151
+ policyId := state .PolicyId .ValueString ()
152
+ res , httpResp , err = r .api .GetCSMThreatsAgentRule (r .auth , agentRuleId , * datadogV2 .NewGetCSMThreatsAgentRuleOptionalParameters ().WithPolicyId (policyId ))
153
+ } else {
154
+ res , httpResp , err = r .api .GetCSMThreatsAgentRule (r .auth , agentRuleId )
155
+ }
156
+
143
157
if err != nil {
144
- if httpResponse != nil && httpResponse .StatusCode == 404 {
158
+ if httpResp .StatusCode == 404 {
145
159
response .State .RemoveResource (ctx )
146
160
return
147
161
}
@@ -164,9 +178,13 @@ func (r *csmThreatsAgentRuleResource) Update(ctx context.Context, request resour
164
178
return
165
179
}
166
180
181
+ csmThreatsMutex .Lock ()
182
+ defer csmThreatsMutex .Unlock ()
183
+
167
184
agentRulePayload , err := r .buildUpdateCSMThreatsAgentRulePayload (& state )
168
185
if err != nil {
169
186
response .Diagnostics .AddError ("error while parsing resource" , err .Error ())
187
+ return
170
188
}
171
189
172
190
res , _ , err := r .api .UpdateCSMThreatsAgentRule (r .auth , state .Id .ValueString (), * agentRulePayload )
@@ -190,11 +208,22 @@ func (r *csmThreatsAgentRuleResource) Delete(ctx context.Context, request resour
190
208
return
191
209
}
192
210
211
+ csmThreatsMutex .Lock ()
212
+ defer csmThreatsMutex .Unlock ()
213
+
193
214
id := state .Id .ValueString ()
194
- policyId := state .PolicyId .ValueString ()
195
- httpResp , err := r .api .DeleteCSMThreatsAgentRule (r .auth , id , * datadogV2 .NewDeleteCSMThreatsAgentRuleOptionalParameters ().WithPolicyId (policyId ))
215
+
216
+ var httpResp * http.Response
217
+ var err error
218
+ if ! state .PolicyId .IsNull () && ! state .PolicyId .IsUnknown () {
219
+ policyId := state .PolicyId .ValueString ()
220
+ httpResp , err = r .api .DeleteCSMThreatsAgentRule (r .auth , id , * datadogV2 .NewDeleteCSMThreatsAgentRuleOptionalParameters ().WithPolicyId (policyId ))
221
+ } else {
222
+ httpResp , err = r .api .DeleteCSMThreatsAgentRule (r .auth , id )
223
+ }
224
+
196
225
if err != nil {
197
- if httpResp != nil && httpResp .StatusCode == 404 {
226
+ if httpResp .StatusCode == 404 {
198
227
return
199
228
}
200
229
response .Diagnostics .Append (utils .FrameworkErrorDiag (err , "error deleting agent rule" ))
@@ -210,32 +239,39 @@ func (r *csmThreatsAgentRuleResource) buildCreateCSMThreatsAgentRulePayload(stat
210
239
attributes .Name = name
211
240
attributes .Description = description
212
241
attributes .Enabled = & enabled
213
- attributes .PolicyId = & policyId
242
+ attributes .PolicyId = policyId
214
243
attributes .ProductTags = productTags
215
244
216
245
data := datadogV2 .NewCloudWorkloadSecurityAgentRuleCreateData (attributes , datadogV2 .CLOUDWORKLOADSECURITYAGENTRULETYPE_AGENT_RULE )
217
246
return datadogV2 .NewCloudWorkloadSecurityAgentRuleCreateRequest (* data ), nil
218
247
}
219
248
220
249
func (r * csmThreatsAgentRuleResource ) buildUpdateCSMThreatsAgentRulePayload (state * csmThreatsAgentRuleModel ) (* datadogV2.CloudWorkloadSecurityAgentRuleUpdateRequest , error ) {
221
- agentRuleId , policyId , _ , description , enabled , _ , productTags := r .extractAgentRuleAttributesFromResource (state )
250
+ agentRuleId , policyId , _ , description , enabled , expression , productTags := r .extractAgentRuleAttributesFromResource (state )
222
251
223
252
attributes := datadogV2.CloudWorkloadSecurityAgentRuleUpdateAttributes {}
253
+ attributes .Expression = & expression
224
254
attributes .Description = description
225
255
attributes .Enabled = & enabled
226
- attributes .PolicyId = & policyId
256
+ attributes .PolicyId = policyId
227
257
attributes .ProductTags = productTags
228
258
229
259
data := datadogV2 .NewCloudWorkloadSecurityAgentRuleUpdateData (attributes , datadogV2 .CLOUDWORKLOADSECURITYAGENTRULETYPE_AGENT_RULE )
230
260
data .Id = & agentRuleId
231
261
return datadogV2 .NewCloudWorkloadSecurityAgentRuleUpdateRequest (* data ), nil
232
262
}
233
263
234
- func (r * csmThreatsAgentRuleResource ) extractAgentRuleAttributesFromResource (state * csmThreatsAgentRuleModel ) (string , string , string , * string , bool , string , []string ) {
264
+ func (r * csmThreatsAgentRuleResource ) extractAgentRuleAttributesFromResource (state * csmThreatsAgentRuleModel ) (string , * string , string , * string , bool , string , []string ) {
235
265
// Mandatory fields
236
266
id := state .Id .ValueString ()
237
- policyId := state .PolicyId .ValueString ()
238
267
name := state .Name .ValueString ()
268
+
269
+ // Optional fields
270
+ var policyId * string
271
+ if ! state .PolicyId .IsNull () && ! state .PolicyId .IsUnknown () {
272
+ val := state .PolicyId .ValueString ()
273
+ policyId = & val
274
+ }
239
275
enabled := state .Enabled .ValueBool ()
240
276
expression := state .Expression .ValueString ()
241
277
description := state .Description .ValueStringPointer ()
@@ -244,7 +280,7 @@ func (r *csmThreatsAgentRuleResource) extractAgentRuleAttributesFromResource(sta
244
280
for _ , tag := range state .ProductTags .Elements () {
245
281
tagStr , ok := tag .(types.String )
246
282
if ! ok {
247
- return "" , "" , "" , nil , false , "" , nil
283
+ return "" , nil , "" , nil , false , "" , nil
248
284
}
249
285
productTags = append (productTags , tagStr .ValueString ())
250
286
}
0 commit comments