Skip to content

Commit 02f68d7

Browse files
regenerate policy tests
1 parent 35f356f commit 02f68d7

File tree

1 file changed

+199
-70
lines changed

1 file changed

+199
-70
lines changed

packages/crowdstrike/data_stream/host/_dev/test/policy/test-default.expected

Lines changed: 199 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -15,88 +15,214 @@ inputs:
1515
dataset: crowdstrike.host
1616
interval: 24h
1717
program: |-
18-
state.with(
19-
(
20-
state.?want_more.orValue(false) ?
21-
state.start_time
22-
:
23-
state.?cursor.last_timestamp.orValue(
24-
(now - duration(state.initial_interval)).format(time_layout.RFC3339)
25-
)
26-
).as(start_time,
27-
request(
28-
"GET",
29-
state.url.trim_right("/") + "/devices/combined/devices/v1?" + {
30-
?"offset": state.?next.page_token.optMap(v, [v]),
31-
"limit": [string(state.batch_size)],
32-
"sort": ["modified_timestamp|asc"],
33-
"filter": [
34-
[
35-
"modified_timestamp:>'" + start_time + "'",
36-
?state.?query.optMap(q, "(" + q + ")"),
37-
].join("+"),
38-
],
39-
?"fields": state.?select_fields.optMap(v, [v.trim_right(",")+",modified_timestamp"]),
40-
}.format_query()
41-
).do_request().as(resp, (resp.StatusCode == 200) ?
42-
resp.Body.decode_json().as(body,
43-
(size(body.?errors.orValue([])) > 0) ?
44-
{
45-
"events": body.errors.map(error,
18+
// This logic determines which CrowdStrike devices endpoint to call. The
19+
// "/devices/combined/devices/v1" endpoint is not supported in GovCloud
20+
// environments, so we must fall back to the "/devices/entities/devices/v2"
21+
// endpoint when running in GovCloud.
22+
//
23+
// The selection works in two stages:
24+
// 1. If the "gov_cloud" flag is explicitly enabled in the data stream manifest,
25+
// we always use the "/devices/entities/devices/v2" endpoint.
26+
//
27+
// 2. If the flag is disabled, the program inspects the base URL to infer
28+
// whether the integration is pointed at a GovCloud environment. If the
29+
// URL matches a known GovCloud domain, we avoid calling the unsupported
30+
// combined endpoint and instead use "/devices/entities/devices/v2".
31+
//
32+
// This dual-check mechanism ensures that GovCloud users do not encounter errors
33+
// even if they forget to enable the "gov_cloud" flag in the manifest.
34+
(
35+
state.gov_cloud || state.url.trim_right("/") in ["https://api.laggar.gcw.crowdstrike.com", "https://api.us-gov-2.crowdstrike.mil"] ?
36+
(
37+
state.want_more ?
38+
state.?page.start
39+
:
40+
optional.of(state.?cursor.last_timestamp.orValue((now - duration(state.initial_interval)).format(time_layout.RFC3339)))
41+
).as(filter,
42+
state.with(
43+
get_request(
44+
state.url.trim_right("/") + "/devices/queries/devices/v1?" + {
45+
"sort": ["modified_timestamp.asc"],
46+
"offset": [string(state.offset)],
47+
"limit": [string(state.batch_size)],
48+
?"filter": (filter.hasValue() || state.?query.orValue("") != "") ?
49+
optional.of(
50+
[
51+
[
52+
?filter.optMap(f, "modified_timestamp:>\"" + f + "\""),
53+
?state.?query.optMap(q, "(" + q + ")"),
54+
].join("+"),
55+
]
56+
)
57+
:
58+
optional.none(),
59+
}.format_query()
60+
).do_request().as(get_resp, (get_resp.StatusCode == 200) ?
61+
bytes(get_resp.Body).decode_json().as(body,
62+
(int(state.offset) + body.resources.size() < body.meta.pagination.total).as(want_more,
4663
{
47-
"error": {
48-
"code": string(error.code),
49-
"message": string(error.message),
64+
"next": {
65+
?"resources": (body.resources.size() > 0) ? optional.of(body.resources) : optional.none(),
5066
},
67+
"filter": filter,
68+
"events": [],
69+
"offset": want_more ? (int(state.offset) + body.resources.size()) : 0,
70+
"want_more": want_more,
5171
}
52-
),
53-
"next": {},
54-
"want_more": false,
55-
}
72+
)
73+
)
5674
:
5775
{
58-
"events": has(body.resources) ?
59-
body.resources.map(e,
76+
"events": {
77+
"error": {
78+
"code": string(get_resp.StatusCode),
79+
"id": string(get_resp.Status),
80+
"message": "GET:" + (
81+
(size(get_resp.Body) != 0) ?
82+
string(get_resp.Body)
83+
:
84+
string(get_resp.Status) + " (" + string(get_resp.StatusCode) + ")"
85+
),
86+
},
87+
},
88+
"want_more": false,
89+
"next": {},
90+
}
91+
)
92+
).as(state,
93+
state.with(
94+
!has(state.?next.resources) ? // Exit early due to GET failure or no resources to collect.
95+
state
96+
:
97+
post_request(
98+
state.url + "/devices/entities/devices/v2",
99+
"application/json",
100+
{"ids": state.next.resources}.encode_json()
101+
).do_request().as(post_resp, (post_resp.StatusCode == 200) ?
102+
bytes(post_resp.Body).decode_json().as(inner_body,
60103
{
61-
"message": e.encode_json(),
104+
"events": inner_body.resources.map(e,
105+
{
106+
"message": e.encode_json(),
107+
}
108+
),
109+
"cursor": {
110+
?"last_timestamp": (has(inner_body.resources) && inner_body.resources.size() > 0) ?
111+
optional.of(inner_body.resources.map(e, timestamp(e.modified_timestamp)).max().format(time_layout.RFC3339))
112+
:
113+
state.?cursor.last_timestamp,
114+
},
115+
"page": {
116+
"start": state.filter,
117+
},
118+
"next": {},
62119
}
63120
)
64121
:
65-
[],
66-
"start_time": start_time,
67-
"next": {
68-
?"page_token": body.?meta.pagination.next,
69-
},
70-
"cursor": {
71-
// The records are sorted in ascending order, based on value of modified_timestamp.
72-
// In the next interval we start from the last event (newest) time.
73-
?"last_timestamp": (has(body.resources) && body.resources.size() > 0) ?
74-
optional.of(timestamp(body.resources[size(body.resources) - 1].modified_timestamp).format(time_layout.RFC3339))
75-
:
76-
state.?cursor.last_timestamp,
122+
{
123+
"events": {
124+
"error": {
125+
"code": string(post_resp.StatusCode),
126+
"id": string(post_resp.Status),
127+
"message": "POST:" + (
128+
(size(post_resp.Body) != 0) ?
129+
string(post_resp.Body)
130+
:
131+
string(post_resp.Status) + " (" + string(post_resp.StatusCode) + ")"
132+
),
133+
},
134+
},
135+
"want_more": false,
136+
"next": {},
137+
}
138+
)
139+
)
140+
)
141+
)
142+
:
143+
state.with(
144+
(
145+
state.?want_more.orValue(false) ?
146+
state.start_time
147+
:
148+
state.?cursor.last_timestamp.orValue(
149+
(now - duration(state.initial_interval)).format(time_layout.RFC3339)
150+
)
151+
).as(start_time,
152+
request(
153+
"GET",
154+
state.url.trim_right("/") + "/devices/combined/devices/v1?" + {
155+
?"offset": state.?next.page_token.optMap(v, [v]),
156+
"limit": [string(state.batch_size)],
157+
"sort": ["modified_timestamp|asc"],
158+
"filter": [
159+
[
160+
"modified_timestamp:>'" + start_time + "'",
161+
?state.?query.optMap(q, "(" + q + ")"),
162+
].join("+"),
163+
],
164+
?"fields": state.?select_fields.optMap(v, [v.trim_right(",")+",modified_timestamp"]),
165+
}.format_query()
166+
).do_request().as(resp, (resp.StatusCode == 200) ?
167+
resp.Body.decode_json().as(body,
168+
(size(body.?errors.orValue([])) > 0) ?
169+
{
170+
"events": body.errors.map(error,
171+
{
172+
"error": {
173+
"code": string(error.code),
174+
"message": string(error.message),
175+
},
176+
}
177+
),
178+
"next": {},
179+
"want_more": false,
180+
}
181+
:
182+
{
183+
"events": has(body.resources) ?
184+
body.resources.map(e,
185+
{
186+
"message": e.encode_json(),
187+
}
188+
)
189+
:
190+
[],
191+
"start_time": start_time,
192+
"next": {
193+
?"page_token": body.?meta.pagination.next,
194+
},
195+
"cursor": {
196+
// The records are sorted in ascending order, based on value of modified_timestamp.
197+
// In the next interval we start from the last event (newest) time.
198+
?"last_timestamp": (has(body.resources) && body.resources.size() > 0) ?
199+
optional.of(timestamp(body.resources[size(body.resources) - 1].modified_timestamp).format(time_layout.RFC3339))
200+
:
201+
state.?cursor.last_timestamp,
202+
},
203+
"want_more": has(body.?meta.pagination.next),
204+
}
205+
)
206+
:
207+
{
208+
"events": {
209+
"error": {
210+
"code": string(resp.StatusCode),
211+
"id": string(resp.Status),
212+
"message": "GET " + state.url.trim_right("/") + "/devices/combined/devices/v1:" + (
213+
(size(resp.Body) != 0) ?
214+
string(resp.Body)
215+
:
216+
string(resp.Status) + " (" + string(resp.StatusCode) + ")"
217+
),
218+
},
77219
},
78-
"want_more": has(body.?meta.pagination.next),
220+
"next": {},
221+
"want_more": false,
79222
}
223+
)
80224
)
81-
:
82-
{
83-
"events": {
84-
"error": {
85-
"code": string(resp.StatusCode),
86-
"id": string(resp.Status),
87-
"message": "GET " + state.url.trim_right("/") + "/devices/combined/devices/v1:" + (
88-
(size(resp.Body) != 0) ?
89-
string(resp.Body)
90-
:
91-
string(resp.Status) + " (" + string(resp.StatusCode) + ")"
92-
),
93-
},
94-
},
95-
"next": {},
96-
"want_more": false,
97-
}
98225
)
99-
)
100226
)
101227
publisher_pipeline.disable_host: true
102228
redact:
@@ -109,9 +235,12 @@ inputs:
109235
maxbackups: 5
110236
resource.url: http://host.tld
111237
state:
112-
batch_size: 10000
238+
batch_size: 5000
239+
gov_cloud: false
113240
initial_interval: 24h
241+
offset: 0
114242
select_fields: null
243+
want_more: false
115244
tags:
116245
- preserve_original_event
117246
- preserve_duplicate_custom_fields

0 commit comments

Comments
 (0)