diff --git a/src/main/java/org/opensearch/securityanalytics/threatIntel/transport/monitor/TransportIndexThreatIntelMonitorAction.java b/src/main/java/org/opensearch/securityanalytics/threatIntel/transport/monitor/TransportIndexThreatIntelMonitorAction.java index 2fd5b1ebb..2d6a5bf30 100644 --- a/src/main/java/org/opensearch/securityanalytics/threatIntel/transport/monitor/TransportIndexThreatIntelMonitorAction.java +++ b/src/main/java/org/opensearch/securityanalytics/threatIntel/transport/monitor/TransportIndexThreatIntelMonitorAction.java @@ -106,7 +106,12 @@ protected void doExecute(Task task, IndexThreatIntelMonitorRequest request, Acti listener.onFailure(SecurityAnalyticsException.wrap(new OpenSearchStatusException(validateBackendRoleMessage, RestStatus.FORBIDDEN))); return; } - //fetch monitors and search + if(request.getMethod().equals(RestRequest.Method.PUT)) { + indexMonitor(request, listener, user); + return; + } + + //fetch monitors and search to ensure only one threat intel monitor can be created SearchRequest threatIntelMonitorsSearchRequest = new SearchRequest(); threatIntelMonitorsSearchRequest.indices(".opendistro-alerting-config"); BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); @@ -118,7 +123,7 @@ protected void doExecute(Task task, IndexThreatIntelMonitorRequest request, Acti List monitorIds = searchResponse.getHits() == null || searchResponse.getHits().getHits() == null ? new ArrayList<>() : Arrays.stream(searchResponse.getHits().getHits()).map(SearchHit::getId).collect(Collectors.toList()); if (monitorIds.isEmpty()) { - createMonitor(request, listener, user); + indexMonitor(request, listener, user); } else listener.onFailure(new ResourceAlreadyExistsException(String.format("Threat intel monitor %s already exists.", monitorIds.get(0)))); }, @@ -126,7 +131,7 @@ protected void doExecute(Task task, IndexThreatIntelMonitorRequest request, Acti e -> { if (e instanceof IndexNotFoundException || e.getMessage().contains("Configured indices are not found")) { try { - createMonitor(request, listener, user); + indexMonitor(request, listener, user); return; } catch (IOException ex) { log.error(() -> new ParameterizedMessage("Unexpected failure while indexing threat intel monitor {} named {}", request.getId(), request.getMonitor().getName())); @@ -145,7 +150,7 @@ protected void doExecute(Task task, IndexThreatIntelMonitorRequest request, Acti } } - private void createMonitor(IndexThreatIntelMonitorRequest request, ActionListener listener, User user) throws IOException { + private void indexMonitor(IndexThreatIntelMonitorRequest request, ActionListener listener, User user) throws IOException { IndexMonitorRequest indexMonitorRequest = buildIndexMonitorRequest(request); AlertingPluginInterface.INSTANCE.indexMonitor((NodeClient) client, indexMonitorRequest, namedWriteableRegistry, ActionListener.wrap( r -> { diff --git a/src/test/java/org/opensearch/securityanalytics/resthandler/ThreatIntelMonitorRestApiIT.java b/src/test/java/org/opensearch/securityanalytics/resthandler/ThreatIntelMonitorRestApiIT.java index 8496b1238..6cef20cab 100644 --- a/src/test/java/org/opensearch/securityanalytics/resthandler/ThreatIntelMonitorRestApiIT.java +++ b/src/test/java/org/opensearch/securityanalytics/resthandler/ThreatIntelMonitorRestApiIT.java @@ -9,12 +9,14 @@ import org.opensearch.common.xcontent.XContentFactory; import org.opensearch.commons.alerting.model.IntervalSchedule; import org.opensearch.commons.alerting.model.Monitor; +import org.opensearch.commons.alerting.model.Schedule; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.search.SearchHit; import org.opensearch.securityanalytics.SecurityAnalyticsPlugin; import org.opensearch.securityanalytics.SecurityAnalyticsRestTestCase; import org.opensearch.securityanalytics.commons.model.IOCType; import org.opensearch.securityanalytics.model.STIX2IOC; +import org.opensearch.securityanalytics.model.threatintel.ThreatIntelAlert; import org.opensearch.securityanalytics.threatIntel.common.RefreshType; import org.opensearch.securityanalytics.threatIntel.common.SourceConfigType; import org.opensearch.securityanalytics.threatIntel.common.TIFJobState; @@ -186,6 +188,24 @@ public void testCreateThreatIntelMonitor() throws IOException { Response getAlertsResponse = makeRequest(client(), "GET", SecurityAnalyticsPlugin.THREAT_INTEL_ALERTS_URI, params, null); Map getAlertsBody = asMap(getAlertsResponse); Assert.assertEquals(4, getAlertsBody.get("total_alerts")); + + + ThreatIntelMonitorDto updateMonitorDto = new ThreatIntelMonitorDto( + monitorId, + iocScanMonitor.getName() + "update", + iocScanMonitor.getPerIocTypeScanInputList(), + new IntervalSchedule(5, ChronoUnit.MINUTES, Instant.now()), + false, + null, + List.of(iocScanMonitor.getTriggers().get(0), iocScanMonitor.getTriggers().get(1)) + ); + //update monitor + response = makeRequest(client(), "PUT", SecurityAnalyticsPlugin.THREAT_INTEL_MONITOR_URI + "/" + monitorId, Collections.emptyMap(), toHttpEntity(updateMonitorDto)); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + responseBody = asMap(response); + assertEquals(responseBody.get("id").toString(), monitorId); + assertEquals(((HashMap) responseBody.get("monitor")).get("name").toString(), iocScanMonitor.getName() + "update"); + //delete Response delete = makeRequest(client(), "DELETE", SecurityAnalyticsPlugin.THREAT_INTEL_MONITOR_URI + "/" + monitorId, Collections.emptyMap(), null); Assert.assertEquals(200, delete.getStatusLine().getStatusCode());