Skip to content

Commit c5108dd

Browse files
committed
Add metric namespace config filters to GCP V2 terraform resource
1 parent 1a35602 commit c5108dd

File tree

2 files changed

+100
-58
lines changed

2 files changed

+100
-58
lines changed

datadog/fwprovider/resource_datadog_integration_gcp_sts.go

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ var (
2626
AttrTypes: map[string]attr.Type{
2727
"id": types.StringType,
2828
"disabled": types.BoolType,
29+
"filters": types.SetType{
30+
ElemType: types.StringType,
31+
},
2932
},
3033
}
3134

@@ -47,7 +50,9 @@ type integrationGcpStsResource struct {
4750
type MetricNamespaceConfigModel struct {
4851
ID types.String `tfsdk:"id"`
4952
Disabled types.Bool `tfsdk:"disabled"`
53+
Filters types.Set `tfsdk:"filters"`
5054
}
55+
5156
type MonitoredResourceConfigModel struct {
5257
Type types.String `tfsdk:"type"`
5358
Filters types.Set `tfsdk:"filters"`
@@ -157,8 +162,7 @@ func (r *integrationGcpStsResource) Schema(_ context.Context, _ resource.SchemaR
157162
Computed: true,
158163
},
159164
"metric_namespace_configs": schema.SetAttribute{
160-
Optional: true,
161-
// if this field is not set by the user, then we will disable prometheus by default
165+
Optional: true,
162166
Computed: true,
163167
Description: "Configurations for GCP metric namespaces.",
164168
ElementType: MetricNamespaceConfigSpec,
@@ -183,6 +187,7 @@ func (r *integrationGcpStsResource) Read(ctx context.Context, request resource.R
183187
if response.Diagnostics.HasError() {
184188
return
185189
}
190+
186191
resp, httpResp, err := r.Api.ListGCPSTSAccounts(r.Auth)
187192
if err != nil {
188193
if httpResp != nil && httpResp.StatusCode == 404 {
@@ -201,7 +206,7 @@ func (r *integrationGcpStsResource) Read(ctx context.Context, request resource.R
201206
for _, account := range resp.GetData() {
202207
if account.GetId() == state.ID.ValueString() {
203208
found = true
204-
r.updateState(ctx, &state, &account)
209+
r.parseGcpStsResponseBody(ctx, &state, &account)
205210
break
206211
}
207212
}
@@ -216,12 +221,11 @@ func (r *integrationGcpStsResource) Read(ctx context.Context, request resource.R
216221
}
217222

218223
func (r *integrationGcpStsResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) {
219-
var state integrationGcpStsModel
220-
response.Diagnostics.Append(request.Plan.Get(ctx, &state)...)
224+
var plan integrationGcpStsModel
225+
response.Diagnostics.Append(request.Plan.Get(ctx, &plan)...)
221226
if response.Diagnostics.HasError() {
222227
return
223228
}
224-
225229
integrationGcpStsMutex.Lock()
226230
defer integrationGcpStsMutex.Unlock()
227231

@@ -236,11 +240,11 @@ func (r *integrationGcpStsResource) Create(ctx context.Context, request resource
236240
return
237241
}
238242
delegateEmail := delegateResponse.Data.Attributes.GetDelegateAccountEmail()
239-
state.DelegateAccountEmail = types.StringValue(delegateEmail)
243+
plan.DelegateAccountEmail = types.StringValue(delegateEmail)
240244

241-
attributes, diags := r.buildIntegrationGcpStsRequestBody(ctx, &state)
242-
if !state.ClientEmail.IsNull() {
243-
attributes.SetClientEmail(state.ClientEmail.ValueString())
245+
attributes, diags := r.buildGcpStsRequestBody(ctx, &plan)
246+
if !plan.ClientEmail.IsNull() {
247+
attributes.SetClientEmail(plan.ClientEmail.ValueString())
244248
}
245249

246250
body := datadogV2.NewGCPSTSServiceAccountCreateRequestWithDefaults()
@@ -260,26 +264,26 @@ func (r *integrationGcpStsResource) Create(ctx context.Context, request resource
260264
response.Diagnostics.AddError("response contains unparsedObject", err.Error())
261265
return
262266
}
263-
r.updateState(ctx, &state, resp.Data)
267+
268+
r.parseGcpStsResponseBody(ctx, &plan, resp.Data)
264269

265270
// Save data into Terraform state
266-
response.Diagnostics.Append(response.State.Set(ctx, &state)...)
271+
response.Diagnostics.Append(response.State.Set(ctx, &plan)...)
267272
}
268273

269274
func (r *integrationGcpStsResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) {
270-
var state integrationGcpStsModel
271-
272-
response.Diagnostics.Append(request.Plan.Get(ctx, &state)...)
275+
var plan integrationGcpStsModel
276+
response.Diagnostics.Append(request.Plan.Get(ctx, &plan)...)
273277
if response.Diagnostics.HasError() {
274278
return
275279
}
276280

277281
integrationGcpStsMutex.Lock()
278282
defer integrationGcpStsMutex.Unlock()
279283

280-
id := state.ID.ValueString()
284+
id := plan.ID.ValueString()
281285

282-
attributes, diags := r.buildIntegrationGcpStsRequestBody(ctx, &state)
286+
attributes, diags := r.buildGcpStsRequestBody(ctx, &plan)
283287
body := datadogV2.NewGCPSTSServiceAccountUpdateRequestWithDefaults()
284288
body.Data = datadogV2.NewGCPSTSServiceAccountUpdateRequestDataWithDefaults()
285289
body.Data.SetAttributes(attributes)
@@ -294,14 +298,16 @@ func (r *integrationGcpStsResource) Update(ctx context.Context, request resource
294298
response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error retrieving Integration Gcp Sts"))
295299
return
296300
}
301+
297302
if err := utils.CheckForUnparsed(resp); err != nil {
298303
response.Diagnostics.AddError("response contains unparsedObject", err.Error())
299304
return
300305
}
301-
r.updateState(ctx, &state, resp.Data)
306+
307+
r.parseGcpStsResponseBody(ctx, &plan, resp.Data)
302308

303309
// Save data into Terraform state
304-
response.Diagnostics.Append(response.State.Set(ctx, &state)...)
310+
response.Diagnostics.Append(response.State.Set(ctx, &plan)...)
305311
}
306312

307313
func (r *integrationGcpStsResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) {
@@ -326,99 +332,101 @@ func (r *integrationGcpStsResource) Delete(ctx context.Context, request resource
326332
}
327333
}
328334

329-
func (r *integrationGcpStsResource) updateState(ctx context.Context, state *integrationGcpStsModel, resp *datadogV2.GCPSTSServiceAccount) {
330-
state.ID = types.StringValue(resp.GetId())
335+
func (r *integrationGcpStsResource) parseGcpStsResponseBody(ctx context.Context, model *integrationGcpStsModel, resp *datadogV2.GCPSTSServiceAccount) {
336+
model.ID = types.StringValue(resp.GetId())
331337

332338
attributes := resp.GetAttributes()
333339
if automute, ok := attributes.GetAutomuteOk(); ok {
334-
state.Automute = types.BoolValue(*automute)
340+
model.Automute = types.BoolValue(*automute)
335341
}
336342
if clientEmail, ok := attributes.GetClientEmailOk(); ok {
337-
state.ClientEmail = types.StringValue(*clientEmail)
343+
model.ClientEmail = types.StringValue(*clientEmail)
338344
}
339345
if isCspmEnabled, ok := attributes.GetIsCspmEnabledOk(); ok {
340-
state.IsCspmEnabled = types.BoolValue(*isCspmEnabled)
346+
model.IsCspmEnabled = types.BoolValue(*isCspmEnabled)
341347
}
342348
if isSecurityCommandCenterEnabled, ok := attributes.GetIsSecurityCommandCenterEnabledOk(); ok {
343-
state.IsSecurityCommandCenterEnabled = types.BoolValue(*isSecurityCommandCenterEnabled)
349+
model.IsSecurityCommandCenterEnabled = types.BoolValue(*isSecurityCommandCenterEnabled)
344350
}
345351
if isResourceChangeCollectionEnabled, ok := attributes.GetIsResourceChangeCollectionEnabledOk(); ok {
346-
state.IsResourceChangeCollectionEnabled = types.BoolValue(*isResourceChangeCollectionEnabled)
352+
model.IsResourceChangeCollectionEnabled = types.BoolValue(*isResourceChangeCollectionEnabled)
347353
}
348354
if isPerProjectQuotaEnabled, ok := attributes.GetIsPerProjectQuotaEnabledOk(); ok {
349-
state.IsPerProjectQuotaEnabled = types.BoolValue(*isPerProjectQuotaEnabled)
355+
model.IsPerProjectQuotaEnabled = types.BoolValue(*isPerProjectQuotaEnabled)
350356
}
351357
if resourceCollectionEnabled, ok := attributes.GetResourceCollectionEnabledOk(); ok {
352-
state.ResourceCollectionEnabled = types.BoolValue(*resourceCollectionEnabled)
358+
model.ResourceCollectionEnabled = types.BoolValue(*resourceCollectionEnabled)
353359
}
354360

355361
if accountTags := attributes.GetAccountTags(); len(accountTags) > 0 {
356-
state.AccountTags, _ = types.SetValueFrom(ctx, types.StringType, accountTags)
362+
model.AccountTags, _ = types.SetValueFrom(ctx, types.StringType, accountTags)
357363
}
358364

359365
mncs := make([]*MetricNamespaceConfigModel, 0)
360-
for _, mnc := range attributes.GetMetricNamespaceConfigs() {
361-
mncs = append(mncs, &MetricNamespaceConfigModel{
362-
ID: types.StringValue(mnc.GetId()),
363-
Disabled: types.BoolValue(mnc.GetDisabled()),
364-
})
366+
for _, cfg := range attributes.GetMetricNamespaceConfigs() {
367+
var mdl MetricNamespaceConfigModel
368+
mdl.ID = types.StringValue(cfg.GetId())
369+
mdl.Disabled = types.BoolValue(cfg.GetDisabled())
370+
mdl.Filters, _ = types.SetValueFrom(ctx, types.StringType, cfg.GetFilters())
371+
mncs = append(mncs, &mdl)
365372
}
366-
state.MetricNamespaceConfigs, _ = types.SetValueFrom(ctx, MetricNamespaceConfigSpec, mncs)
373+
model.MetricNamespaceConfigs, _ = types.SetValueFrom(ctx, MetricNamespaceConfigSpec, mncs)
367374

368-
state.HostFilters, _ = types.SetValueFrom(ctx, types.StringType, attributes.GetHostFilters())
369-
state.CloudRunRevisionFilters, _ = types.SetValueFrom(ctx, types.StringType, attributes.GetCloudRunRevisionFilters())
375+
model.HostFilters, _ = types.SetValueFrom(ctx, types.StringType, attributes.GetHostFilters())
376+
model.CloudRunRevisionFilters, _ = types.SetValueFrom(ctx, types.StringType, attributes.GetCloudRunRevisionFilters())
370377
mrcs := make([]*MonitoredResourceConfigModel, 0)
371378
for _, mrc := range attributes.GetMonitoredResourceConfigs() {
372379
var mdl MonitoredResourceConfigModel
373380
mdl.Type = types.StringValue(string(mrc.GetType()))
374381
mdl.Filters, _ = types.SetValueFrom(ctx, types.StringType, mrc.GetFilters())
375382
mrcs = append(mrcs, &mdl)
376383
}
377-
state.MonitoredResourceConfigs, _ = types.SetValueFrom(ctx, MonitoredResourceConfigSpec, mrcs)
384+
model.MonitoredResourceConfigs, _ = types.SetValueFrom(ctx, MonitoredResourceConfigSpec, mrcs)
378385
}
379386

380-
func (r *integrationGcpStsResource) buildIntegrationGcpStsRequestBody(ctx context.Context, state *integrationGcpStsModel) (datadogV2.GCPSTSServiceAccountAttributes, diag.Diagnostics) {
387+
func (r *integrationGcpStsResource) buildGcpStsRequestBody(ctx context.Context, model *integrationGcpStsModel) (datadogV2.GCPSTSServiceAccountAttributes, diag.Diagnostics) {
381388
diags := diag.Diagnostics{}
382389
attributes := datadogV2.GCPSTSServiceAccountAttributes{}
383390

384-
if !state.Automute.IsNull() {
385-
attributes.SetAutomute(state.Automute.ValueBool())
391+
if !model.Automute.IsNull() {
392+
attributes.SetAutomute(model.Automute.ValueBool())
386393
}
387-
if !state.IsCspmEnabled.IsNull() {
388-
attributes.SetIsCspmEnabled(state.IsCspmEnabled.ValueBool())
394+
if !model.IsCspmEnabled.IsNull() {
395+
attributes.SetIsCspmEnabled(model.IsCspmEnabled.ValueBool())
389396
}
390-
if !state.IsSecurityCommandCenterEnabled.IsUnknown() {
391-
attributes.SetIsSecurityCommandCenterEnabled(state.IsSecurityCommandCenterEnabled.ValueBool())
397+
if !model.IsSecurityCommandCenterEnabled.IsUnknown() {
398+
attributes.SetIsSecurityCommandCenterEnabled(model.IsSecurityCommandCenterEnabled.ValueBool())
392399
}
393-
if !state.IsResourceChangeCollectionEnabled.IsUnknown() {
394-
attributes.SetIsResourceChangeCollectionEnabled(state.IsResourceChangeCollectionEnabled.ValueBool())
400+
if !model.IsResourceChangeCollectionEnabled.IsUnknown() {
401+
attributes.SetIsResourceChangeCollectionEnabled(model.IsResourceChangeCollectionEnabled.ValueBool())
395402
}
396-
if !state.ResourceCollectionEnabled.IsUnknown() {
397-
attributes.SetResourceCollectionEnabled(state.ResourceCollectionEnabled.ValueBool())
403+
if !model.ResourceCollectionEnabled.IsUnknown() {
404+
attributes.SetResourceCollectionEnabled(model.ResourceCollectionEnabled.ValueBool())
398405
}
399-
if !state.IsPerProjectQuotaEnabled.IsUnknown() {
400-
attributes.SetIsPerProjectQuotaEnabled(state.IsPerProjectQuotaEnabled.ValueBool())
406+
if !model.IsPerProjectQuotaEnabled.IsUnknown() {
407+
attributes.SetIsPerProjectQuotaEnabled(model.IsPerProjectQuotaEnabled.ValueBool())
401408
}
402409

403-
attributes.SetAccountTags(tfCollectionToSlice[string](ctx, diags, state.AccountTags))
410+
attributes.SetAccountTags(tfCollectionToSlice[string](ctx, diags, model.AccountTags))
404411

405412
// only set this field if the user explicitly sets the field
406413
// otherwise we want to omit it so that the API server can populate defaults when applicable
407-
if cfgs := state.MetricNamespaceConfigs; !cfgs.IsUnknown() {
414+
if cfgs := model.MetricNamespaceConfigs; !cfgs.IsUnknown() {
408415
mncs := make([]datadogV2.GCPMetricNamespaceConfig, 0)
409416
for _, mnc := range tfCollectionToSlice[*MetricNamespaceConfigModel](ctx, diags, cfgs) {
410417
mncs = append(mncs, datadogV2.GCPMetricNamespaceConfig{
411418
Id: mnc.ID.ValueStringPointer(),
412419
Disabled: mnc.Disabled.ValueBoolPointer(),
420+
Filters: tfCollectionToSlice[string](ctx, diags, mnc.Filters),
413421
})
414422
}
415423
attributes.SetMetricNamespaceConfigs(mncs)
416424
}
417425

418-
attributes.SetHostFilters(tfCollectionToSlice[string](ctx, diags, state.HostFilters))
419-
attributes.SetCloudRunRevisionFilters(tfCollectionToSlice[string](ctx, diags, state.CloudRunRevisionFilters))
426+
attributes.SetHostFilters(tfCollectionToSlice[string](ctx, diags, model.HostFilters))
427+
attributes.SetCloudRunRevisionFilters(tfCollectionToSlice[string](ctx, diags, model.CloudRunRevisionFilters))
420428
mrcs := make([]datadogV2.GCPMonitoredResourceConfig, 0)
421-
for _, mrc := range tfCollectionToSlice[*MonitoredResourceConfigModel](ctx, diags, state.MonitoredResourceConfigs) {
429+
for _, mrc := range tfCollectionToSlice[*MonitoredResourceConfigModel](ctx, diags, model.MonitoredResourceConfigs) {
422430
mrcs = append(mrcs, datadogV2.GCPMonitoredResourceConfig{
423431
Type: ptrTo(datadogV2.GCPMonitoredResourceConfigType(mrc.Type.ValueString())),
424432
Filters: tfCollectionToSlice[string](ctx, diags, mrc.Filters),

datadog/tests/resource_datadog_integration_gcp_sts_test.go

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func TestAccIntGcpStsMetricNamespaceConfigs(t *testing.T) {
3636
knownvalue.ObjectExact(map[string]knownvalue.Check{
3737
"id": knownvalue.StringExact("prometheus"),
3838
"disabled": knownvalue.Bool(true),
39+
"filters": knownvalue.SetExact(nil),
3940
}),
4041
})),
4142
},
@@ -52,6 +53,7 @@ func TestAccIntGcpStsMetricNamespaceConfigs(t *testing.T) {
5253
knownvalue.ObjectExact(map[string]knownvalue.Check{
5354
"id": knownvalue.StringExact("prometheus"),
5455
"disabled": knownvalue.Bool(true),
56+
"filters": knownvalue.SetExact(nil),
5557
}),
5658
})),
5759
},
@@ -76,6 +78,7 @@ func TestAccIntGcpStsMetricNamespaceConfigs(t *testing.T) {
7678
knownvalue.ObjectExact(map[string]knownvalue.Check{
7779
"id": knownvalue.StringExact("prometheus"),
7880
"disabled": knownvalue.Bool(true),
81+
"filters": knownvalue.SetExact(nil),
7982
}),
8083
})),
8184
},
@@ -88,6 +91,7 @@ func TestAccIntGcpStsMetricNamespaceConfigs(t *testing.T) {
8891
{
8992
id = "aiplatform",
9093
disabled = true
94+
filters = []
9195
}
9296
]
9397
}`, uniq),
@@ -97,6 +101,7 @@ func TestAccIntGcpStsMetricNamespaceConfigs(t *testing.T) {
97101
knownvalue.ObjectExact(map[string]knownvalue.Check{
98102
"id": knownvalue.StringExact("aiplatform"),
99103
"disabled": knownvalue.Bool(true),
104+
"filters": knownvalue.SetExact(nil),
100105
}),
101106
})),
102107
},
@@ -118,6 +123,7 @@ func TestAccIntGcpStsMetricNamespaceConfigs(t *testing.T) {
118123
{
119124
id = "aiplatform",
120125
disabled = true
126+
filters = []
121127
}
122128
]
123129
}`, uniq),
@@ -127,6 +133,7 @@ func TestAccIntGcpStsMetricNamespaceConfigs(t *testing.T) {
127133
knownvalue.ObjectExact(map[string]knownvalue.Check{
128134
"id": knownvalue.StringExact("aiplatform"),
129135
"disabled": knownvalue.Bool(true),
136+
"filters": knownvalue.SetExact(nil),
130137
}),
131138
})),
132139
},
@@ -142,6 +149,7 @@ func TestAccIntGcpStsMetricNamespaceConfigs(t *testing.T) {
142149
knownvalue.ObjectExact(map[string]knownvalue.Check{
143150
"id": knownvalue.StringExact("aiplatform"),
144151
"disabled": knownvalue.Bool(true),
152+
"filters": knownvalue.SetExact(nil),
145153
}),
146154
})),
147155
},
@@ -185,6 +193,12 @@ func TestAccIntegrationGcpStsBasic(t *testing.T) {
185193
{
186194
id = "aiplatform",
187195
disabled = true
196+
filters = []
197+
},
198+
{
199+
id = "pubsub",
200+
disabled = false
201+
filters = ["snapshot.*", "!*_by_region"]
188202
}
189203
]
190204
cloud_run_revision_filters = ["rev:one", "rev:two"]
@@ -208,6 +222,15 @@ func TestAccIntegrationGcpStsBasic(t *testing.T) {
208222
knownvalue.ObjectExact(map[string]knownvalue.Check{
209223
"id": knownvalue.StringExact("aiplatform"),
210224
"disabled": knownvalue.Bool(true),
225+
"filters": knownvalue.SetExact(nil),
226+
}),
227+
knownvalue.ObjectExact(map[string]knownvalue.Check{
228+
"id": knownvalue.StringExact("pubsub"),
229+
"disabled": knownvalue.Bool(false),
230+
"filters": knownvalue.SetExact([]knownvalue.Check{
231+
knownvalue.StringExact("snapshot.*"),
232+
knownvalue.StringExact("!*_by_region"),
233+
}),
211234
}),
212235
})),
213236
statecheck.ExpectKnownValue("datadog_integration_gcp_sts.foo", tfjsonpath.New("cloud_run_revision_filters"), cloudRunRevisionFilters),
@@ -234,6 +257,13 @@ func TestAccIntegrationGcpStsBasic(t *testing.T) {
234257
is_security_command_center_enabled = "true"
235258
is_resource_change_collection_enabled = "true"
236259
is_per_project_quota_enabled = "true"
260+
metric_namespace_configs = [
261+
{
262+
id = "appengine",
263+
disabled = false
264+
filters = ["flex.autoscaler.*"]
265+
}
266+
]
237267
monitored_resource_configs = [
238268
{
239269
type = "cloud_function"
@@ -257,8 +287,11 @@ func TestAccIntegrationGcpStsBasic(t *testing.T) {
257287
statecheck.ExpectKnownValue("datadog_integration_gcp_sts.foo", tfjsonpath.New("account_tags"), knownvalue.Null()),
258288
statecheck.ExpectKnownValue("datadog_integration_gcp_sts.foo", tfjsonpath.New("metric_namespace_configs"), knownvalue.SetExact([]knownvalue.Check{
259289
knownvalue.ObjectExact(map[string]knownvalue.Check{
260-
"id": knownvalue.StringExact("aiplatform"),
261-
"disabled": knownvalue.Bool(true),
290+
"id": knownvalue.StringExact("appengine"),
291+
"disabled": knownvalue.Bool(false),
292+
"filters": knownvalue.SetExact([]knownvalue.Check{
293+
knownvalue.StringExact("flex.autoscaler.*"),
294+
}),
262295
}),
263296
})),
264297
statecheck.ExpectKnownValue("datadog_integration_gcp_sts.foo", tfjsonpath.New("cloud_run_revision_filters"), knownvalue.SetExact(nil)),
@@ -311,6 +344,7 @@ func TestAccIntegrationGcpStsDefault(t *testing.T) {
311344
knownvalue.ObjectExact(map[string]knownvalue.Check{
312345
"id": knownvalue.StringExact("prometheus"),
313346
"disabled": knownvalue.Bool(true),
347+
"filters": knownvalue.SetExact(nil),
314348
}),
315349
})),
316350
statecheck.ExpectKnownValue("datadog_integration_gcp_sts.foo", tfjsonpath.New("cloud_run_revision_filters"), knownvalue.SetExact(nil)),

0 commit comments

Comments
 (0)