Skip to content

Commit

Permalink
add workflowIds param in rest get alerts action
Browse files Browse the repository at this point in the history
Signed-off-by: Surya Sashank Nistala <[email protected]>
  • Loading branch information
eirsep committed Jul 13, 2023
1 parent 96fcb31 commit f3aa825
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ class RestGetAlertsAction : BaseRestHandler() {
val severityLevel = request.param("severityLevel", "ALL")
val alertState = request.param("alertState", "ALL")
val monitorId: String? = request.param("monitorId")
val workflowId: String? = request.param("workflowIds")
val workflowIds = mutableListOf<String>()
if (workflowId.isNullOrEmpty() == false) {
workflowIds.add(workflowId)
}
val table = Table(
sortOrder,
sortString,
Expand All @@ -66,7 +71,7 @@ class RestGetAlertsAction : BaseRestHandler() {
searchString
)

val getAlertsRequest = GetAlertsRequest(table, severityLevel, alertState, monitorId, null)
val getAlertsRequest = GetAlertsRequest(table, severityLevel, alertState, monitorId, null, workflowIds = workflowIds)
return RestChannelConsumer {
channel ->
client.execute(AlertingActions.GET_ALERTS_ACTION_TYPE, getAlertsRequest, RestToXContentListener(channel))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,65 @@ class MonitorDataSourcesIT : AlertingSingleNodeTestCase() {
assertEquals("Findings saved for test monitor", 4, findings.size)
}

fun `test execute monitor without triggers`() {
val docQuery = DocLevelQuery(query = "eventType:\"login\"", name = "3")

val docLevelInput = DocLevelMonitorInput(
"description", listOf(index), listOf(docQuery)
)
val customFindingsIndex = "custom_findings_index"
val customFindingsIndexPattern = "custom_findings_index-1"
val customQueryIndex = "custom_alerts_index"
var monitor = randomDocumentLevelMonitor(
inputs = listOf(docLevelInput),
triggers = listOf(),
dataSources = DataSources(
queryIndex = customQueryIndex,
findingsIndex = customFindingsIndex,
findingsIndexPattern = customFindingsIndexPattern
)
)
val monitorResponse = createMonitor(monitor)
assertFalse(monitorResponse?.id.isNullOrEmpty())

val testDoc = """{
"eventType" : "login"
}"""
indexDoc(index, "1", testDoc)

monitor = monitorResponse!!.monitor
val id = monitorResponse.id
// Execute dry run first and expect no alerts or findings
var executeMonitorResponse = executeMonitor(monitor, id, true)
Assert.assertEquals(executeMonitorResponse!!.monitorRunResult.monitorName, monitor.name)
Assert.assertEquals(executeMonitorResponse.monitorRunResult.triggerResults.size, 0)
searchAlerts(id)
var table = Table("asc", "id", null, 1, 0, "")
var getAlertsResponse = client()
.execute(AlertingActions.GET_ALERTS_ACTION_TYPE, GetAlertsRequest(table, "ALL", "ALL", null, null))
.get()
Assert.assertTrue(getAlertsResponse != null)
Assert.assertTrue(getAlertsResponse.alerts.isEmpty())
var findings = searchFindings(id, customFindingsIndex)
assertEquals("Findings saved for test monitor", 0, findings.size)

// Execute real run - expect findings, but no alerts
executeMonitorResponse = executeMonitor(monitor, id, false)

searchAlerts(id)
table = Table("asc", "id", null, 1, 0, "")
getAlertsResponse = client()
.execute(AlertingActions.GET_ALERTS_ACTION_TYPE, GetAlertsRequest(table, "ALL", "ALL", null, null))
.get()
Assert.assertTrue(getAlertsResponse != null)
Assert.assertTrue(getAlertsResponse.alerts.isEmpty())

findings = searchFindings(id, customFindingsIndex)
assertEquals("Findings saved for test monitor", 1, findings.size)
assertTrue("Findings saved for test monitor", findings[0].relatedDocIds.contains("1"))
assertEquals("Didn't match query", 1, findings[0].docLevelQueries.size)
}

fun `test execute monitor with custom query index`() {
val q1 = DocLevelQuery(query = "source.ip.v6.v1:12345", name = "3")
val q2 = DocLevelQuery(query = "source.ip.v6.v2:16645", name = "4")
Expand Down Expand Up @@ -1393,6 +1452,78 @@ class MonitorDataSourcesIT : AlertingSingleNodeTestCase() {
Assert.assertEquals(searchMonitorResponse.hits.hits.size, 1)
}

fun `test execute pre-existing monitor without triggers`() {
val request = CreateIndexRequest(SCHEDULED_JOBS_INDEX).mapping(ScheduledJobIndices.scheduledJobMappings())
.settings(Settings.builder().put("index.hidden", true).build())
client().admin().indices().create(request)
val monitorStringWithoutName = """
{
"monitor": {
"type": "monitor",
"schema_version": 0,
"name": "UayEuXpZtb",
"monitor_type": "doc_level_monitor",
"user": {
"name": "",
"backend_roles": [],
"roles": [],
"custom_attribute_names": [],
"user_requested_tenant": null
},
"enabled": true,
"enabled_time": 1662753436791,
"schedule": {
"period": {
"interval": 5,
"unit": "MINUTES"
}
},
"inputs": [{
"doc_level_input": {
"description": "description",
"indices": [
"$index"
],
"queries": [{
"id": "63efdcce-b5a1-49f4-a25f-6b5f9496a755",
"name": "3",
"query": "test_field:\"us-west-2\"",
"tags": []
}]
}
}],
"triggers": [],
"last_update_time": 1662753436791
}
}
""".trimIndent()
val monitorId = "abc"
indexDoc(SCHEDULED_JOBS_INDEX, monitorId, monitorStringWithoutName)
val getMonitorResponse = getMonitorResponse(monitorId)
Assert.assertNotNull(getMonitorResponse)
Assert.assertNotNull(getMonitorResponse.monitor)
val monitor = getMonitorResponse.monitor

val testTime = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().truncatedTo(MILLIS))
val testDoc = """{
"message" : "This is an error from IAD region",
"test_strict_date_time" : "$testTime",
"test_field" : "us-west-2"
}"""
indexDoc(index, "1", testDoc)
var executeMonitorResponse = executeMonitor(monitor!!, monitorId, false)
Assert.assertNotNull(executeMonitorResponse)
if (executeMonitorResponse != null) {
Assert.assertNotNull(executeMonitorResponse.monitorRunResult.monitorName)
}
val alerts = searchAlerts(monitorId)
assertEquals(0, alerts.size)

val findings = searchFindings(monitorId)
assertEquals("Findings saved for test monitor", 1, findings.size)
assertTrue("Findings saved for test monitor", findings[0].relatedDocIds.contains("1"))
}

fun `test execute monitor with empty source index`() {
val docQuery = DocLevelQuery(query = "test_field:\"us-west-2\"", name = "3")
val docLevelInput = DocLevelMonitorInput("description", listOf(index), listOf(docQuery))
Expand Down Expand Up @@ -5441,4 +5572,72 @@ class MonitorDataSourcesIT : AlertingSingleNodeTestCase() {
}
Assert.assertTrue(alerts.stream().anyMatch { it.state == Alert.State.DELETED && chainedAlerts[0].id == it.id })
}

fun `test postDelete on workflow deletion`() {
val docQuery1 = DocLevelQuery(query = "test_field_1:\"us-west-2\"", name = "3")
val docLevelInput1 = DocLevelMonitorInput("description", listOf(index), listOf(docQuery1))
val trigger1 = randomDocumentLevelTrigger(condition = ALWAYS_RUN)
var monitor1 = randomDocumentLevelMonitor(
inputs = listOf(docLevelInput1),
triggers = listOf(trigger1)
)
var monitor2 = randomDocumentLevelMonitor(
inputs = listOf(docLevelInput1),
triggers = listOf(trigger1)
)
val monitorResponse = createMonitor(monitor1)!!
val monitorResponse2 = createMonitor(monitor2)!!

val andTrigger = randomChainedAlertTrigger(
name = "1And2",
condition = Script("monitor[id=${monitorResponse.id}] && monitor[id=${monitorResponse2.id}]")
)
val notTrigger = randomChainedAlertTrigger(
name = "Not1OrNot2",
condition = Script("!monitor[id=${monitorResponse.id}] || !monitor[id=${monitorResponse2.id}]")
)
var workflow = randomWorkflow(
monitorIds = listOf(monitorResponse.id, monitorResponse2.id),
triggers = listOf(andTrigger)
)
val workflowResponse = upsertWorkflow(workflow)!!
val workflowById = searchWorkflow(workflowResponse.id)
val testTime = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().truncatedTo(MILLIS))
val testDoc1 = """{
"message" : "This is an error from IAD region",
"source.ip.v6.v2" : 16644,
"test_strict_date_time" : "$testTime",
"test_field_1" : "us-west-2"
}"""
indexDoc(index, "1", testDoc1)
val workflowId = workflowById!!.id
var executeWorkflowResponse = executeWorkflow(workflowById, workflowId, false)!!
var res = getWorkflowAlerts(
workflowId,
)
var chainedAlerts = res.alerts
Assert.assertTrue(chainedAlerts.size == 1)
val deleteRes = deleteWorkflow(workflowId, false)
logger.info(deleteRes)
OpenSearchTestCase.waitUntil({
val searchRequest = SearchRequest(AlertIndices.ALERT_HISTORY_ALL)
val sr = client().search(searchRequest).get()
sr.hits.hits.size == 3
}, 5, TimeUnit.MINUTES)
val searchRequest = SearchRequest(AlertIndices.ALERT_HISTORY_ALL)
val sr = client().search(searchRequest).get()
Assert.assertTrue(sr.hits.hits.size == 3)
val alerts = sr.hits.map { hit ->
val xcp = XContentHelper.createParser(
xContentRegistry(),
LoggingDeprecationHandler.INSTANCE,
hit.sourceRef,
XContentType.JSON
)
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, xcp.nextToken(), xcp)
val alert = Alert.parse(xcp, hit.id, hit.version)
alert
}
Assert.assertTrue(alerts.stream().anyMatch { it.state == Alert.State.DELETED && chainedAlerts[0].id == it.id })
}
}

0 comments on commit f3aa825

Please sign in to comment.