Skip to content

Commit 4833231

Browse files
Nil check on oncall integration templates (#1185)
* Nil check on oncall integration templates If a user defines an empty templates block, it currently panics An empty block should be functionally equivalent to not defining the block at all * Set an empty templates in the tests * oops * Add test for all three cases - no templates block - empty templates block - non-empty templates block + fix all cases
1 parent 9f1896a commit 4833231

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

docs/resources/oncall_integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ resource "grafana_oncall_integration" "integration_with_templates" {
5656
### Optional
5757

5858
- `team_id` (String) The ID of the OnCall team. To get one, create a team in Grafana, and navigate to the OnCall plugin (to sync the team with OnCall). You can then get the ID using the `grafana_oncall_team` datasource.
59-
- `templates` (Block List, Max: 1) Jinja2 templates for Alert payload. (see [below for nested schema](#nestedblock--templates))
59+
- `templates` (Block List, Max: 1) Jinja2 templates for Alert payload. An empty templates block will be ignored. (see [below for nested schema](#nestedblock--templates))
6060

6161
### Read-Only
6262

internal/resources/oncall/resource_integration.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,28 @@ func ResourceIntegration() *schema.Resource {
202202
},
203203
},
204204
MaxItems: 1,
205-
Description: "Jinja2 templates for Alert payload.",
205+
Description: "Jinja2 templates for Alert payload. An empty templates block will be ignored.",
206+
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
207+
oldTemplate, newTemplate := d.GetChange("templates")
208+
209+
getTemplatesOrEmpty := func(template interface{}) map[string]interface{} {
210+
list := template.([]interface{})
211+
if len(list) > 0 && list[0] != nil {
212+
return list[0].(map[string]interface{})
213+
}
214+
return map[string]interface{}{}
215+
}
216+
oldTemplateMap, newTemplateMap := getTemplatesOrEmpty(oldTemplate), getTemplatesOrEmpty(newTemplate)
217+
if len(oldTemplateMap) != len(newTemplateMap) {
218+
return false
219+
}
220+
for k, v := range oldTemplateMap {
221+
if newTemplateMap[k] != v {
222+
return false
223+
}
224+
}
225+
return true
226+
},
206227
},
207228
},
208229
}
@@ -575,6 +596,10 @@ func expandTemplates(input []interface{}) *onCallAPI.Templates {
575596
templates := onCallAPI.Templates{}
576597

577598
for _, r := range input {
599+
if r == nil {
600+
continue
601+
}
602+
578603
inputMap := r.(map[string]interface{})
579604
if inputMap["grouping_key"] != "" {
580605
gk := inputMap["grouping_key"].(string)

internal/resources/oncall/resource_integration_test.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,35 @@ func TestAccOnCallIntegration_basic(t *testing.T) {
2323
CheckDestroy: testAccCheckOnCallIntegrationResourceDestroy,
2424
Steps: []resource.TestStep{
2525
{
26-
Config: testAccOnCallIntegrationConfig(rName, rType),
26+
Config: testAccOnCallIntegrationConfig(rName, rType, ``),
2727
Check: resource.ComposeTestCheckFunc(
2828
testAccCheckOnCallIntegrationResourceExists("grafana_oncall_integration.test-acc-integration"),
2929
resource.TestCheckResourceAttr("grafana_oncall_integration.test-acc-integration", "name", rName),
3030
resource.TestCheckResourceAttr("grafana_oncall_integration.test-acc-integration", "type", rType),
3131
resource.TestCheckResourceAttrSet("grafana_oncall_integration.test-acc-integration", "link"),
3232
),
3333
},
34+
{
35+
Config: testAccOnCallIntegrationConfig(rName, rType, `templates {}`),
36+
Check: resource.ComposeTestCheckFunc(
37+
testAccCheckOnCallIntegrationResourceExists("grafana_oncall_integration.test-acc-integration"),
38+
resource.TestCheckResourceAttr("grafana_oncall_integration.test-acc-integration", "name", rName),
39+
resource.TestCheckResourceAttr("grafana_oncall_integration.test-acc-integration", "type", rType),
40+
resource.TestCheckResourceAttrSet("grafana_oncall_integration.test-acc-integration", "link"),
41+
),
42+
},
43+
{
44+
Config: testAccOnCallIntegrationConfig(rName, rType, `templates {
45+
grouping_key = "test"
46+
}`),
47+
Check: resource.ComposeTestCheckFunc(
48+
testAccCheckOnCallIntegrationResourceExists("grafana_oncall_integration.test-acc-integration"),
49+
resource.TestCheckResourceAttr("grafana_oncall_integration.test-acc-integration", "name", rName),
50+
resource.TestCheckResourceAttr("grafana_oncall_integration.test-acc-integration", "type", rType),
51+
resource.TestCheckResourceAttrSet("grafana_oncall_integration.test-acc-integration", "link"),
52+
resource.TestCheckResourceAttr("grafana_oncall_integration.test-acc-integration", "templates.0.grouping_key", "test"),
53+
),
54+
},
3455
},
3556
})
3657
}
@@ -49,7 +70,7 @@ func testAccCheckOnCallIntegrationResourceDestroy(s *terraform.State) error {
4970
return nil
5071
}
5172

52-
func testAccOnCallIntegrationConfig(rName, rType string) string {
73+
func testAccOnCallIntegrationConfig(rName, rType, additionalConfigs string) string {
5374
return fmt.Sprintf(`
5475
resource "grafana_oncall_integration" "test-acc-integration" {
5576
name = "%s"
@@ -62,8 +83,10 @@ resource "grafana_oncall_integration" "test-acc-integration" {
6283
enabled = false
6384
}
6485
}
86+
87+
%s
6588
}
66-
`, rName, rType)
89+
`, rName, rType, additionalConfigs)
6790
}
6891

6992
func testAccCheckOnCallIntegrationResourceExists(name string) resource.TestCheckFunc {

0 commit comments

Comments
 (0)