Skip to content

Commit e520ff7

Browse files
[datadog_synthetics_test] Add support for grpc subtype (#1500)
* add grpc subtype * add basic grpc test * update docs
1 parent 82e497b commit e520ff7

File tree

5 files changed

+243
-0
lines changed

5 files changed

+243
-0
lines changed

datadog/resource_datadog_synthetics_test_.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ func syntheticsTestRequest() *schema.Resource {
196196
Type: schema.TypeString,
197197
Optional: true,
198198
},
199+
"service": {
200+
Description: "For gRPC tests, service to target for healthcheck.",
201+
Type: schema.TypeString,
202+
Optional: true,
203+
},
199204
},
200205
}
201206
}
@@ -1159,6 +1164,7 @@ func isTargetOfTypeInt(assertionType datadogV1.SyntheticsAssertionType, assertio
11591164
datadogV1.SYNTHETICSASSERTIONTYPE_PACKET_LOSS_PERCENTAGE,
11601165
datadogV1.SYNTHETICSASSERTIONTYPE_PACKETS_RECEIVED,
11611166
datadogV1.SYNTHETICSASSERTIONTYPE_NETWORK_HOP,
1167+
datadogV1.SYNTHETICSASSERTIONTYPE_GRPC_HEALTHCHECK_STATUS,
11621168
} {
11631169
if assertionType == intTargetAssertionType {
11641170
return true
@@ -1229,6 +1235,9 @@ func buildSyntheticsAPITestStruct(d *schema.ResourceData) *datadogV1.SyntheticsA
12291235
if attr, ok := k.GetOkWith("message"); ok {
12301236
request.SetMessage(attr.(string))
12311237
}
1238+
if attr, ok := k.GetOkWith("service"); ok {
1239+
request.SetService(attr.(string))
1240+
}
12321241
k.Remove(parts)
12331242

12341243
request = completeSyntheticsTestRequest(request, d.Get("request_headers").(map[string]interface{}), d.Get("request_query").(map[string]interface{}), d.Get("request_basicauth").([]interface{}), d.Get("request_client_certificate").([]interface{}), d.Get("request_proxy").([]interface{}))
@@ -1992,6 +2001,9 @@ func buildLocalRequest(request datadogV1.SyntheticsTestRequest) map[string]inter
19922001
if request.HasMessage() {
19932002
localRequest["message"] = request.GetMessage()
19942003
}
2004+
if request.HasService() {
2005+
localRequest["service"] = request.GetService()
2006+
}
19952007

19962008
return localRequest
19972009
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2022-07-22T16:51:23.267258+02:00
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
---
2+
version: 1
3+
interactions:
4+
- request:
5+
body: |
6+
{"config":{"assertions":[{"operator":"lessThan","target":2000,"type":"responseTime"},{"operator":"is","target":1,"type":"grpcHealthcheckStatus"}],"configVariables":[],"request":{"host":"google.com","method":"GET","port":50050,"service":"Hello","timeout":60}},"locations":["aws:eu-central-1"],"message":"Notify @datadog.user","name":"tf-TestAccDatadogSyntheticsGRPCTest_Basic-local-1658501483","options":{"min_location_failed":1,"tick_every":60},"status":"paused","subtype":"grpc","tags":["foo:bar","baz"],"type":"api"}
7+
form: {}
8+
headers:
9+
Accept:
10+
- application/json
11+
Content-Type:
12+
- application/json
13+
url: https://api.datadoghq.com/api/v1/synthetics/tests/api
14+
method: POST
15+
response:
16+
body: '{"status":"paused","public_id":"p7z-xup-ykk","tags":["foo:bar","baz"],"org_id":321813,"locations":["aws:eu-central-1"],"message":"Notify @datadog.user","deleted_at":null,"name":"tf-TestAccDatadogSyntheticsGRPCTest_Basic-local-1658501483","monitor_id":77932425,"type":"api","created_at":"2022-07-22T14:51:37.522437+00:00","modified_at":"2022-07-22T14:51:37.522437+00:00","subtype":"grpc","config":{"request":{"host":"google.com","service":"Hello","method":"GET","timeout":60,"port":50050},"assertions":[{"operator":"lessThan","type":"responseTime","target":2000},{"operator":"is","type":"grpcHealthcheckStatus","target":1}],"configVariables":[]},"options":{"min_location_failed":1,"tick_every":60}}'
17+
headers:
18+
Content-Type:
19+
- application/json
20+
status: 200 OK
21+
code: 200
22+
duration: ""
23+
- request:
24+
body: ""
25+
form: {}
26+
headers:
27+
Accept:
28+
- application/json
29+
url: https://api.datadoghq.com/api/v1/synthetics/tests/api/p7z-xup-ykk
30+
method: GET
31+
response:
32+
body: '{"status":"paused","public_id":"p7z-xup-ykk","tags":["foo:bar","baz"],"locations":["aws:eu-central-1"],"message":"Notify @datadog.user","name":"tf-TestAccDatadogSyntheticsGRPCTest_Basic-local-1658501483","monitor_id":77932425,"type":"api","created_at":"2022-07-22T14:51:37.522437+00:00","creator":{"handle":"[email protected]","name":null,"email":"[email protected]"},"modified_at":"2022-07-22T14:51:37.522437+00:00","subtype":"grpc","config":{"request":{"host":"google.com","service":"Hello","method":"GET","timeout":60,"port":50050},"assertions":[{"operator":"lessThan","type":"responseTime","target":2000},{"operator":"is","type":"grpcHealthcheckStatus","target":1}],"configVariables":[]},"options":{"min_location_failed":1,"tick_every":60}}'
33+
headers:
34+
Content-Type:
35+
- application/json
36+
status: 200 OK
37+
code: 200
38+
duration: ""
39+
- request:
40+
body: ""
41+
form: {}
42+
headers:
43+
Accept:
44+
- application/json
45+
url: https://api.datadoghq.com/api/v1/synthetics/tests/p7z-xup-ykk
46+
method: GET
47+
response:
48+
body: '{"status":"paused","public_id":"p7z-xup-ykk","tags":["foo:bar","baz"],"locations":["aws:eu-central-1"],"message":"Notify @datadog.user","name":"tf-TestAccDatadogSyntheticsGRPCTest_Basic-local-1658501483","monitor_id":77932425,"type":"api","created_at":"2022-07-22T14:51:37.522437+00:00","creator":{"handle":"[email protected]","name":null,"email":"[email protected]"},"modified_at":"2022-07-22T14:51:37.522437+00:00","subtype":"grpc","config":{"request":{"host":"google.com","service":"Hello","method":"GET","timeout":60,"port":50050},"assertions":[{"operator":"lessThan","type":"responseTime","target":2000},{"operator":"is","type":"grpcHealthcheckStatus","target":1}],"configVariables":[]},"options":{"min_location_failed":1,"tick_every":60}}'
49+
headers:
50+
Content-Type:
51+
- application/json
52+
status: 200 OK
53+
code: 200
54+
duration: ""
55+
- request:
56+
body: ""
57+
form: {}
58+
headers:
59+
Accept:
60+
- application/json
61+
url: https://api.datadoghq.com/api/v1/synthetics/tests/p7z-xup-ykk
62+
method: GET
63+
response:
64+
body: '{"status":"paused","public_id":"p7z-xup-ykk","tags":["foo:bar","baz"],"locations":["aws:eu-central-1"],"message":"Notify @datadog.user","name":"tf-TestAccDatadogSyntheticsGRPCTest_Basic-local-1658501483","monitor_id":77932425,"type":"api","created_at":"2022-07-22T14:51:37.522437+00:00","creator":{"handle":"[email protected]","name":null,"email":"[email protected]"},"modified_at":"2022-07-22T14:51:37.522437+00:00","subtype":"grpc","config":{"request":{"host":"google.com","service":"Hello","method":"GET","timeout":60,"port":50050},"assertions":[{"operator":"lessThan","type":"responseTime","target":2000},{"operator":"is","type":"grpcHealthcheckStatus","target":1}],"configVariables":[]},"options":{"min_location_failed":1,"tick_every":60}}'
65+
headers:
66+
Content-Type:
67+
- application/json
68+
status: 200 OK
69+
code: 200
70+
duration: ""
71+
- request:
72+
body: ""
73+
form: {}
74+
headers:
75+
Accept:
76+
- application/json
77+
url: https://api.datadoghq.com/api/v1/synthetics/tests/api/p7z-xup-ykk
78+
method: GET
79+
response:
80+
body: '{"status":"paused","public_id":"p7z-xup-ykk","tags":["foo:bar","baz"],"locations":["aws:eu-central-1"],"message":"Notify @datadog.user","name":"tf-TestAccDatadogSyntheticsGRPCTest_Basic-local-1658501483","monitor_id":77932425,"type":"api","created_at":"2022-07-22T14:51:37.522437+00:00","creator":{"handle":"[email protected]","name":null,"email":"[email protected]"},"modified_at":"2022-07-22T14:51:37.522437+00:00","subtype":"grpc","config":{"request":{"host":"google.com","service":"Hello","method":"GET","timeout":60,"port":50050},"assertions":[{"operator":"lessThan","type":"responseTime","target":2000},{"operator":"is","type":"grpcHealthcheckStatus","target":1}],"configVariables":[]},"options":{"min_location_failed":1,"tick_every":60}}'
81+
headers:
82+
Content-Type:
83+
- application/json
84+
status: 200 OK
85+
code: 200
86+
duration: ""
87+
- request:
88+
body: |
89+
{"public_ids":["p7z-xup-ykk"]}
90+
form: {}
91+
headers:
92+
Accept:
93+
- application/json
94+
Content-Type:
95+
- application/json
96+
url: https://api.datadoghq.com/api/v1/synthetics/tests/delete
97+
method: POST
98+
response:
99+
body: '{"deleted_tests":[{"deleted_at":"2022-07-22T14:52:08.865182+00:00","public_id":"p7z-xup-ykk"}]}'
100+
headers:
101+
Content-Type:
102+
- application/json
103+
status: 200 OK
104+
code: 200
105+
duration: ""
106+
- request:
107+
body: ""
108+
form: {}
109+
headers:
110+
Accept:
111+
- application/json
112+
url: https://api.datadoghq.com/api/v1/synthetics/tests/p7z-xup-ykk
113+
method: GET
114+
response:
115+
body: '{"errors": ["Synthetics test not found"]}'
116+
headers:
117+
Content-Type:
118+
- application/json
119+
status: 404 Not Found
120+
code: 404
121+
duration: ""

datadog/tests/resource_datadog_synthetics_test_test.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,21 @@ func TestAccDatadogSyntheticsWebsocketTest_Basic(t *testing.T) {
346346
})
347347
}
348348

349+
func TestAccDatadogSyntheticsGRPCTest_Basic(t *testing.T) {
350+
t.Parallel()
351+
ctx, accProviders := testAccProviders(context.Background(), t)
352+
accProvider := testAccProvider(t, accProviders)
353+
354+
resource.Test(t, resource.TestCase{
355+
PreCheck: func() { testAccPreCheck(t) },
356+
ProviderFactories: accProviders,
357+
CheckDestroy: testSyntheticsTestIsDestroyed(accProvider),
358+
Steps: []resource.TestStep{
359+
createSyntheticsGRPCTestStep(ctx, accProvider, t),
360+
},
361+
})
362+
}
363+
349364
func TestAccDatadogSyntheticsBrowserTest_Basic(t *testing.T) {
350365
t.Parallel()
351366
ctx, accProviders := testAccProviders(context.Background(), t)
@@ -1989,6 +2004,98 @@ resource "datadog_synthetics_test" "websocket" {
19892004
}`, uniq)
19902005
}
19912006

2007+
func createSyntheticsGRPCTestStep(ctx context.Context, accProvider func() (*schema.Provider, error), t *testing.T) resource.TestStep {
2008+
testName := uniqueEntityName(ctx, t)
2009+
return resource.TestStep{
2010+
Config: createSyntheticsGRPCTestConfig(testName),
2011+
Check: resource.ComposeTestCheckFunc(
2012+
testSyntheticsTestExists(accProvider),
2013+
resource.TestCheckResourceAttr(
2014+
"datadog_synthetics_test.grpc", "type", "api"),
2015+
resource.TestCheckResourceAttr(
2016+
"datadog_synthetics_test.grpc", "subtype", "grpc"),
2017+
resource.TestCheckResourceAttr(
2018+
"datadog_synthetics_test.grpc", "request_definition.0.host", "google.com"),
2019+
resource.TestCheckResourceAttr(
2020+
"datadog_synthetics_test.grpc", "request_definition.0.port", "50050"),
2021+
resource.TestCheckResourceAttr(
2022+
"datadog_synthetics_test.grpc", "request_definition.0.service", "Hello"),
2023+
resource.TestCheckResourceAttr(
2024+
"datadog_synthetics_test.grpc", "assertion.#", "2"),
2025+
resource.TestCheckResourceAttr(
2026+
"datadog_synthetics_test.grpc", "assertion.0.type", "responseTime"),
2027+
resource.TestCheckResourceAttr(
2028+
"datadog_synthetics_test.grpc", "assertion.0.operator", "lessThan"),
2029+
resource.TestCheckResourceAttr(
2030+
"datadog_synthetics_test.grpc", "assertion.0.target", "2000"),
2031+
resource.TestCheckResourceAttr(
2032+
"datadog_synthetics_test.grpc", "assertion.1.type", "grpcHealthcheckStatus"),
2033+
resource.TestCheckResourceAttr(
2034+
"datadog_synthetics_test.grpc", "assertion.1.operator", "is"),
2035+
resource.TestCheckResourceAttr(
2036+
"datadog_synthetics_test.grpc", "assertion.1.target", "1"),
2037+
resource.TestCheckResourceAttr(
2038+
"datadog_synthetics_test.grpc", "locations.#", "1"),
2039+
resource.TestCheckTypeSetElemAttr(
2040+
"datadog_synthetics_test.grpc", "locations.*", "aws:eu-central-1"),
2041+
resource.TestCheckResourceAttr(
2042+
"datadog_synthetics_test.grpc", "options_list.0.tick_every", "60"),
2043+
resource.TestCheckResourceAttr(
2044+
"datadog_synthetics_test.grpc", "name", testName),
2045+
resource.TestCheckResourceAttr(
2046+
"datadog_synthetics_test.grpc", "message", "Notify @datadog.user"),
2047+
resource.TestCheckResourceAttr(
2048+
"datadog_synthetics_test.grpc", "tags.#", "2"),
2049+
resource.TestCheckResourceAttr(
2050+
"datadog_synthetics_test.grpc", "tags.0", "foo:bar"),
2051+
resource.TestCheckResourceAttr(
2052+
"datadog_synthetics_test.grpc", "tags.1", "baz"),
2053+
resource.TestCheckResourceAttr(
2054+
"datadog_synthetics_test.grpc", "status", "paused"),
2055+
resource.TestCheckResourceAttrSet(
2056+
"datadog_synthetics_test.grpc", "monitor_id"),
2057+
),
2058+
}
2059+
}
2060+
2061+
func createSyntheticsGRPCTestConfig(uniq string) string {
2062+
return fmt.Sprintf(`
2063+
resource "datadog_synthetics_test" "grpc" {
2064+
type = "api"
2065+
subtype = "grpc"
2066+
2067+
request_definition {
2068+
method = "GET"
2069+
host = "google.com"
2070+
port = 50050
2071+
service = "Hello"
2072+
}
2073+
2074+
assertion {
2075+
type = "responseTime"
2076+
operator = "lessThan"
2077+
target = "2000"
2078+
}
2079+
2080+
assertion {
2081+
operator = "is"
2082+
type = "grpcHealthcheckStatus"
2083+
target = 1
2084+
}
2085+
2086+
locations = [ "aws:eu-central-1" ]
2087+
options_list {
2088+
tick_every = 60
2089+
}
2090+
2091+
name = "%s"
2092+
message = "Notify @datadog.user"
2093+
tags = ["foo:bar", "baz"]
2094+
2095+
status = "paused"
2096+
}`, uniq)
2097+
}
2098+
19922099
func createSyntheticsBrowserTestStep(ctx context.Context, accProvider func() (*schema.Provider, error), t *testing.T) resource.TestStep {
19932100
testName := uniqueEntityName(ctx, t)
19942101
return resource.TestStep{

docs/resources/synthetics_test.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ Optional:
446446
- `number_of_packets` (Number) Number of pings to use per test for ICMP tests (`subtype = "icmp"`) between 0 and 10.
447447
- `port` (Number) Port to use when performing the test.
448448
- `servername` (String) For SSL tests, it specifies on which server you want to initiate the TLS handshake, allowing the server to present one of multiple possible certificates on the same IP address and TCP port number.
449+
- `service` (String) For gRPC tests, service to target for healthcheck.
449450
- `should_track_hops` (Boolean) This will turn on a traceroute probe to discover all gateways along the path to the host destination. For ICMP tests (`subtype = "icmp"`).
450451
- `timeout` (Number) Timeout in seconds for the test. Defaults to `60`.
451452
- `url` (String) The URL to send the request to.
@@ -732,6 +733,7 @@ Optional:
732733
- `number_of_packets` (Number) Number of pings to use per test for ICMP tests (`subtype = "icmp"`) between 0 and 10.
733734
- `port` (Number) Port to use when performing the test.
734735
- `servername` (String) For SSL tests, it specifies on which server you want to initiate the TLS handshake, allowing the server to present one of multiple possible certificates on the same IP address and TCP port number.
736+
- `service` (String) For gRPC tests, service to target for healthcheck.
735737
- `should_track_hops` (Boolean) This will turn on a traceroute probe to discover all gateways along the path to the host destination. For ICMP tests (`subtype = "icmp"`).
736738
- `timeout` (Number) Timeout in seconds for the test. Defaults to `60`.
737739
- `url` (String) The URL to send the request to.

0 commit comments

Comments
 (0)