Skip to content

Commit 4b9f71c

Browse files
Validate that there's exactly one SM check setting (#329)
* Validate that there's exactly one SM check setting Fixes #326 * Add doc in the settings attribute
1 parent 7209614 commit 4b9f71c

File tree

3 files changed

+100
-2
lines changed

3 files changed

+100
-2
lines changed

docs/resources/synthetic_monitoring_check.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ resource "grafana_synthetic_monitoring_check" "traceroute" {
413413

414414
- **job** (String) Name used for job label.
415415
- **probes** (Set of Number) List of probe location IDs where this target will be checked from.
416-
- **settings** (Block Set, Min: 1, Max: 1) Check settings. (see [below for nested schema](#nestedblock--settings))
416+
- **settings** (Block Set, Min: 1, Max: 1) Check settings. Should contain exactly one nested block. (see [below for nested schema](#nestedblock--settings))
417417
- **target** (String) Hostname to ping.
418418

419419
### Optional

grafana/resource_synthetic_monitoring_check.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package grafana
22

33
import (
44
"context"
5+
"fmt"
56
"strconv"
67

78
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -446,6 +447,7 @@ multiple checks for a single endpoint to check different capabilities.
446447
Importer: &schema.ResourceImporter{
447448
StateContext: schema.ImportStatePassthroughContext,
448449
},
450+
CustomizeDiff: resourceSyntheticMonitoringCheckCustomizeDiff,
449451

450452
Schema: map[string]*schema.Schema{
451453
"id": {
@@ -521,7 +523,7 @@ multiple checks for a single endpoint to check different capabilities.
521523
},
522524
},
523525
"settings": {
524-
Description: "Check settings.",
526+
Description: "Check settings. Should contain exactly one nested block.",
525527
Type: schema.TypeSet,
526528
Required: true,
527529
MaxItems: 1,
@@ -955,3 +957,26 @@ func makeCheckSettings(settings map[string]interface{}) sm.CheckSettings {
955957

956958
return cs
957959
}
960+
961+
// Check if the user provider exactly one setting
962+
// Ideally, we'd use `ExactlyOneOf` here but it doesn't support TypeSet.
963+
// Also, TypeSet doesn't support ValidateFunc.
964+
// To maintain backwards compatibility, we do a custom validation in the CustomizeDiff function.
965+
func resourceSyntheticMonitoringCheckCustomizeDiff(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error {
966+
settingsList := diff.Get("settings").(*schema.Set).List()
967+
if len(settingsList) == 0 {
968+
return fmt.Errorf("at least one check setting must be defined")
969+
}
970+
settings := settingsList[0].(map[string]interface{})
971+
972+
count := 0
973+
for k := range syntheticMonitoringCheckSettings.Schema {
974+
count += len(settings[k].(*schema.Set).List())
975+
}
976+
977+
if count != 1 {
978+
return fmt.Errorf("exactly one check setting must be defined, got %d", count)
979+
}
980+
981+
return nil
982+
}

grafana/resource_synthetic_monitoring_check_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,76 @@ func TestAccResourceSyntheticMonitoringCheck_traceroute(t *testing.T) {
239239
},
240240
})
241241
}
242+
243+
func TestAccResourceSyntheticMonitoringCheck_noSettings(t *testing.T) {
244+
CheckCloudTestsEnabled(t)
245+
246+
resource.Test(t, resource.TestCase{
247+
PreCheck: func() { testAccPreCheckCloud(t) },
248+
ProviderFactories: testAccProviderFactories,
249+
Steps: []resource.TestStep{
250+
{
251+
Config: testAccResourceSyntheticMonitoringCheck_noSettings,
252+
PlanOnly: true,
253+
ExpectError: regexp.MustCompile("at least one check setting must be defined"),
254+
},
255+
},
256+
})
257+
}
258+
259+
func TestAccResourceSyntheticMonitoringCheck_multiple(t *testing.T) {
260+
CheckCloudTestsEnabled(t)
261+
262+
resource.Test(t, resource.TestCase{
263+
PreCheck: func() { testAccPreCheckCloud(t) },
264+
ProviderFactories: testAccProviderFactories,
265+
Steps: []resource.TestStep{
266+
{
267+
Config: testAccResourceSyntheticMonitoringCheck_multiple,
268+
PlanOnly: true,
269+
ExpectError: regexp.MustCompile("exactly one check setting must be defined, got 2"),
270+
},
271+
},
272+
})
273+
}
274+
275+
const testAccResourceSyntheticMonitoringCheck_noSettings = `
276+
data "grafana_synthetic_monitoring_probes" "main" {}
277+
278+
resource "grafana_synthetic_monitoring_check" "no_settings" {
279+
job = "No Settings"
280+
target = "grafana.com"
281+
enabled = false
282+
frequency = 120000
283+
timeout = 30000
284+
probes = [
285+
data.grafana_synthetic_monitoring_probes.main.probes.Atlanta,
286+
]
287+
labels = {
288+
foo = "bar"
289+
}
290+
settings {
291+
292+
}
293+
}`
294+
295+
const testAccResourceSyntheticMonitoringCheck_multiple = `
296+
data "grafana_synthetic_monitoring_probes" "main" {}
297+
298+
resource "grafana_synthetic_monitoring_check" "multiple" {
299+
job = "No Settings"
300+
target = "grafana.com"
301+
enabled = false
302+
frequency = 120000
303+
timeout = 30000
304+
probes = [
305+
data.grafana_synthetic_monitoring_probes.main.probes.Atlanta,
306+
]
307+
labels = {
308+
foo = "bar"
309+
}
310+
settings {
311+
traceroute {}
312+
http {}
313+
}
314+
}`

0 commit comments

Comments
 (0)