Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Threat intel monitor implementation #1092

Merged
merged 15 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## Version 2.15.0.0 2024-06-10

Compatible with OpenSearch 2.15.0

### Features
* Alerts in correlations [Experminental] ([#1040](https://github.com/opensearch-project/security-analytics/pull/1040))
* Alerts in Correlations Part 2 ([#1062](https://github.com/opensearch-project/security-analytics/pull/1062))

### Maintenance
* Increment version to 2.15.0-SNAPSHOT. ([#1055](https://github.com/opensearch-project/security-analytics/pull/1055))
* Fix codecov calculation ([#1021](https://github.com/opensearch-project/security-analytics/pull/1021))
* Stabilize integ tests ([#1014](https://github.com/opensearch-project/security-analytics/pull/1014))

### Bug Fixes
* Fix chained findings monitor logic in update detector flow ([#1019](https://github.com/opensearch-project/security-analytics/pull/1019))
* Change default filter to time based fields ([#1030](https://github.com/opensearch-project/security-analytics/pull/1030))

### Documentation
* Added 2.15.0 release notes. ([#1061](https://github.com/opensearch-project/security-analytics/pull/1061))

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.securityanalytics.action;

import org.opensearch.action.ActionType;

/**
* Acknowledge Correlation Alert Action
*/
public class AckCorrelationAlertsAction extends ActionType<AckCorrelationAlertsResponse> {
public static final String NAME = "cluster:admin/opensearch/securityanalytics/correlationAlerts/ack";
public static final AckCorrelationAlertsAction INSTANCE = new AckCorrelationAlertsAction();

public AckCorrelationAlertsAction() {
super(NAME, AckCorrelationAlertsResponse::new);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.securityanalytics.action;

import org.opensearch.action.ActionRequest;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.action.ValidateActions;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;
import org.opensearch.core.xcontent.ToXContent;
import org.opensearch.core.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

public class AckCorrelationAlertsRequest extends ActionRequest {
private final List<String> correlationAlertIds;

public AckCorrelationAlertsRequest(List<String> correlationAlertIds) {
this.correlationAlertIds = correlationAlertIds;
}

public AckCorrelationAlertsRequest(StreamInput in) throws IOException {
correlationAlertIds = Collections.unmodifiableList(in.readStringList());
}

@Override
public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = null;
if(correlationAlertIds == null || correlationAlertIds.isEmpty()) {
validationException = ValidateActions.addValidationError("alert ids list cannot be empty", validationException);
}
return validationException;
}

public void writeTo(StreamOutput out) throws IOException {
out.writeStringCollection(this.correlationAlertIds);
}

public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
return builder.startObject()
.field("correlation_alert_ids", correlationAlertIds)
.endObject();
}

public static AckAlertsRequest readFrom(StreamInput sin) throws IOException {
return new AckAlertsRequest(sin);
}

public List<String> getCorrelationAlertIds() {
return correlationAlertIds;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.securityanalytics.action;

import org.opensearch.commons.alerting.model.CorrelationAlert;
import org.opensearch.core.action.ActionResponse;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

public class AckCorrelationAlertsResponse extends ActionResponse implements ToXContentObject {

private final List<CorrelationAlert> acknowledged;
private final List<CorrelationAlert> failed;

public AckCorrelationAlertsResponse(List<CorrelationAlert> acknowledged, List<CorrelationAlert> failed) {
this.acknowledged = acknowledged;
this.failed = failed;
}

public AckCorrelationAlertsResponse(StreamInput sin) throws IOException {
this(
Collections.unmodifiableList(sin.readList(CorrelationAlert::new)),
Collections.unmodifiableList(sin.readList(CorrelationAlert::new))
);
}

@Override
public void writeTo(StreamOutput streamOutput) throws IOException {
streamOutput.writeList(this.acknowledged);
streamOutput.writeList(this.failed);
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject()
.field("acknowledged",this.acknowledged)
.field("failed",this.failed);
return builder.endObject();
}

public List<CorrelationAlert> getAcknowledged() {
return acknowledged;
}

public List<CorrelationAlert> getFailed() {
return failed;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ public class GetAlertsAction extends ActionType<GetAlertsResponse> {
public GetAlertsAction() {
super(NAME, GetAlertsResponse::new);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.securityanalytics.action;

import org.opensearch.action.ActionType;

public class GetCorrelationAlertsAction extends ActionType<GetCorrelationAlertsResponse> {

public static final GetCorrelationAlertsAction INSTANCE = new GetCorrelationAlertsAction();
public static final String NAME = "cluster:admin/opensearch/securityanalytics/correlationAlerts/get";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Should correlationAlerts be all lowercase like securityanalytics?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not from my PR
merged main branch


public GetCorrelationAlertsAction() {
super(NAME, GetCorrelationAlertsResponse::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.securityanalytics.action;

import org.opensearch.action.ActionRequest;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.commons.alerting.model.Table;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;

import java.io.IOException;
import java.time.Instant;
import java.util.Locale;

import static org.opensearch.action.ValidateActions.addValidationError;

public class GetCorrelationAlertsRequest extends ActionRequest {
private String correlationRuleId;
private String correlationRuleName;
private Table table;
private String severityLevel;
private String alertState;

private Instant startTime;

private Instant endTime;

public static final String CORRELATION_RULE_ID = "correlation_rule_id";

public GetCorrelationAlertsRequest(
String correlationRuleId,
String correlationRuleName,
Table table,
String severityLevel,
String alertState,
Instant startTime,
Instant endTime
) {
super();
this.correlationRuleId = correlationRuleId;
this.correlationRuleName = correlationRuleName;
this.table = table;
this.severityLevel = severityLevel;
this.alertState = alertState;
this.startTime = startTime;
this.endTime = endTime;
}
public GetCorrelationAlertsRequest(StreamInput sin) throws IOException {
this(
sin.readOptionalString(),
sin.readOptionalString(),
Table.readFrom(sin),
sin.readString(),
sin.readString(),
sin.readOptionalInstant(),
sin.readOptionalInstant()
);
}

@Override
public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = null;
if ((correlationRuleId != null && correlationRuleId.isEmpty())) {
validationException = addValidationError(String.format(Locale.getDefault(),
"Correlation ruleId is empty or not valid", CORRELATION_RULE_ID),
validationException);
}
return validationException;
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeOptionalString(correlationRuleId);
out.writeOptionalString(correlationRuleName);
table.writeTo(out);
out.writeString(severityLevel);
out.writeString(alertState);
out.writeOptionalInstant(startTime);
out.writeOptionalInstant(endTime);
}

public String getCorrelationRuleId() {
return correlationRuleId;
}

public Table getTable() {
return table;
}

public String getSeverityLevel() {
return severityLevel;
}

public String getAlertState() {
return alertState;
}

public String getCorrelationRuleName() {
return correlationRuleName;
}

public Instant getStartTime() {
return startTime;
}

public Instant getEndTime() {
return endTime;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.securityanalytics.action;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.opensearch.commons.alerting.model.CorrelationAlert;
import org.opensearch.core.action.ActionResponse;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.Collections;
import java.util.List;

public class GetCorrelationAlertsResponse extends ActionResponse implements ToXContentObject {

private static final Logger log = LogManager.getLogger(GetCorrelationAlertsResponse.class);
private static final String CORRELATION_ALERTS_FIELD = "correlationAlerts";
private static final String TOTAL_ALERTS_FIELD = "total_alerts";

private List<CorrelationAlert> alerts;
private Integer totalAlerts;

public GetCorrelationAlertsResponse(List<CorrelationAlert> alerts, Integer totalAlerts) {
super();
this.alerts = alerts;
this.totalAlerts = totalAlerts;
}

public GetCorrelationAlertsResponse(StreamInput sin) throws IOException {
this(
Collections.unmodifiableList(sin.readList(CorrelationAlert::new)),
sin.readInt()
);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeCollection(this.alerts);
out.writeInt(this.totalAlerts);
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject()
.field(CORRELATION_ALERTS_FIELD, this.alerts)
.field(TOTAL_ALERTS_FIELD, this.totalAlerts);
return builder.endObject();
}
}
Loading