Skip to content

Commit fb90fc3

Browse files
committed
added secure rest test to verify that monitor clean up works when create request by user without delete permission fails partially
Signed-off-by: Surya Sashank Nistala <[email protected]>
1 parent 3178347 commit fb90fc3

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

alerting/src/test/kotlin/org/opensearch/alerting/MonitorDataSourcesIT.kt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.opensearch.alerting.action.SearchMonitorAction
2424
import org.opensearch.alerting.action.SearchMonitorRequest
2525
import org.opensearch.alerting.alerts.AlertIndices
2626
import org.opensearch.alerting.core.ScheduledJobIndices
27+
import org.opensearch.alerting.model.DocumentLevelTriggerRunResult
2728
import org.opensearch.alerting.transport.AlertingSingleNodeTestCase
2829
import org.opensearch.alerting.util.DocLevelMonitorQueries
2930
import org.opensearch.alerting.util.DocLevelMonitorQueries.Companion.INDEX_PATTERN_SUFFIX
@@ -808,6 +809,47 @@ class MonitorDataSourcesIT : AlertingSingleNodeTestCase() {
808809
}
809810
}
810811

812+
fun `test execute monitor without create when no monitors exists`() {
813+
val docQuery = DocLevelQuery(query = "test_field:\"us-west-2\"", name = "3")
814+
val docLevelInput = DocLevelMonitorInput("description", listOf(index), listOf(docQuery))
815+
val trigger = randomDocumentLevelTrigger(condition = ALWAYS_RUN)
816+
val customQueryIndex = "custom_alerts_index"
817+
val analyzer = "whitespace"
818+
var monitor = randomDocumentLevelMonitor(
819+
inputs = listOf(docLevelInput),
820+
triggers = listOf(trigger),
821+
dataSources = DataSources(
822+
queryIndex = customQueryIndex,
823+
queryIndexMappingsByType = mapOf(Pair("text", mapOf(Pair("analyzer", analyzer)))),
824+
)
825+
)
826+
var executeMonitorResponse = executeMonitor(monitor, null)
827+
val testTime = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().truncatedTo(MILLIS))
828+
val testDoc = """{
829+
"message" : "This is an error from IAD region",
830+
"test_strict_date_time" : "$testTime",
831+
"test_field" : "us-west-2"
832+
}"""
833+
834+
assertIndexNotExists(SCHEDULED_JOBS_INDEX)
835+
836+
val createMonitorResponse = createMonitor(monitor)
837+
838+
assertIndexExists(SCHEDULED_JOBS_INDEX)
839+
840+
indexDoc(index, "1", testDoc)
841+
842+
executeMonitorResponse = executeMonitor(monitor, createMonitorResponse?.id, dryRun = false)
843+
844+
Assert.assertEquals(executeMonitorResponse!!.monitorRunResult.monitorName, monitor.name)
845+
Assert.assertEquals(executeMonitorResponse.monitorRunResult.triggerResults.size, 1)
846+
Assert.assertEquals(
847+
(executeMonitorResponse.monitorRunResult.triggerResults.iterator().next().value as DocumentLevelTriggerRunResult)
848+
.triggeredDocs.size,
849+
1
850+
)
851+
}
852+
811853
fun `test execute monitor with custom query index and custom field mappings`() {
812854
val docQuery = DocLevelQuery(query = "test_field:\"us-west-2\"", name = "3")
813855
val docLevelInput = DocLevelMonitorInput("description", listOf(index), listOf(docQuery))

alerting/src/test/kotlin/org/opensearch/alerting/resthandler/SecureMonitorRestApiIT.kt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import org.opensearch.alerting.randomTemplateScript
4545
import org.opensearch.client.Response
4646
import org.opensearch.client.ResponseException
4747
import org.opensearch.client.RestClient
48+
import org.opensearch.common.settings.Settings
4849
import org.opensearch.common.xcontent.LoggingDeprecationHandler
4950
import org.opensearch.common.xcontent.XContentType
5051
import org.opensearch.common.xcontent.json.JsonXContent
@@ -1155,6 +1156,51 @@ class SecureMonitorRestApiIT : AlertingRestTestCase() {
11551156
}
11561157
}
11571158

1159+
/**
1160+
* We want to verify that user roles/permissions do not affect clean up of monitors during partial monitor creation failure
1161+
*/
1162+
fun `test create monitor failure clean up with a user without delete monitor access`() {
1163+
createUserWithTestDataAndCustomRole(
1164+
user,
1165+
TEST_HR_INDEX,
1166+
TEST_HR_ROLE,
1167+
listOf(TEST_HR_BACKEND_ROLE),
1168+
getClusterPermissionsFromCustomRole(ALERTING_NO_ACCESS_ROLE)
1169+
)
1170+
1171+
val refresh = true
1172+
val docLevelQueryIndex = ".opensearch-alerting-queries-000001"
1173+
createIndex(
1174+
docLevelQueryIndex, Settings.EMPTY,
1175+
"""
1176+
"properties" : {
1177+
"query": { "type": "percolator_ext" },
1178+
"monitor_id": { "type" : "text" },
1179+
"index": { "type": "text" }
1180+
}
1181+
""".trimIndent(),
1182+
".opensearch-alerting-queries"
1183+
)
1184+
closeIndex(docLevelQueryIndex) // close index to simulate doc level query indexing failure
1185+
try {
1186+
createRandomDocumentMonitor(true)
1187+
fail("Monitor creation should have failed due to error in indexing doc level queries")
1188+
} catch (e: ResponseException) {
1189+
val search = SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).toString()
1190+
val searchResponse = client().makeRequest(
1191+
"GET", "$ALERTING_BASE_URI/_search",
1192+
emptyMap(),
1193+
StringEntity(search, ContentType.APPLICATION_JSON)
1194+
)
1195+
val xcp = createParser(XContentType.JSON.xContent(), searchResponse.entity.content)
1196+
val hits = xcp.map()["hits"]!! as Map<String, Map<String, Any>>
1197+
val numberDocsFound = hits["total"]?.get("value")
1198+
assertEquals("Monitors found. Clean up unsuccessful", 0, numberDocsFound)
1199+
} finally {
1200+
deleteRoleAndRoleMapping(TEST_HR_ROLE)
1201+
}
1202+
}
1203+
11581204
fun `test query all alerts in all states with disabled filter by`() {
11591205

11601206
disableFilterBy()

0 commit comments

Comments
 (0)