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

[Backport 2.x] Alerts in Correlations Part 2 #1069

Merged
merged 1 commit into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
Expand Up @@ -57,10 +57,12 @@
import org.opensearch.securityanalytics.action.AckAlertsAction;
import org.opensearch.securityanalytics.action.CreateIndexMappingsAction;
import org.opensearch.securityanalytics.action.CorrelatedFindingAction;
import org.opensearch.securityanalytics.action.AckCorrelationAlertsAction;
import org.opensearch.securityanalytics.action.DeleteCustomLogTypeAction;
import org.opensearch.securityanalytics.action.DeleteDetectorAction;
import org.opensearch.securityanalytics.action.DeleteRuleAction;
import org.opensearch.securityanalytics.action.GetAllRuleCategoriesAction;
import org.opensearch.securityanalytics.action.GetCorrelationAlertsAction;
import org.opensearch.securityanalytics.action.GetDetectorAction;
import org.opensearch.securityanalytics.action.GetFindingsAction;
import org.opensearch.securityanalytics.action.GetIndexMappingsAction;
Expand Down Expand Up @@ -131,6 +133,8 @@ public class SecurityAnalyticsPlugin extends Plugin implements ActionPlugin, Map
public static final String CORRELATION_RULES_BASE_URI = PLUGINS_BASE_URI + "/correlation/rules";

public static final String CUSTOM_LOG_TYPE_URI = PLUGINS_BASE_URI + "/logtype";

public static final String CORRELATIONS_ALERTS_BASE_URI = PLUGINS_BASE_URI + "/correlationAlerts";
public static final String JOB_INDEX_NAME = ".opensearch-sap--job";
public static final Map<String, Object> TIF_JOB_INDEX_SETTING = Map.of(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1, IndexMetadata.SETTING_AUTO_EXPAND_REPLICAS, "0-all", IndexMetadata.SETTING_INDEX_HIDDEN, true);

Expand Down Expand Up @@ -238,7 +242,9 @@ public List<RestHandler> getRestHandlers(Settings settings,
new RestSearchCorrelationRuleAction(),
new RestIndexCustomLogTypeAction(),
new RestSearchCustomLogTypeAction(),
new RestDeleteCustomLogTypeAction()
new RestDeleteCustomLogTypeAction(),
new RestGetCorrelationsAlertsAction(),
new RestAcknowledgeCorrelationAlertsAction()
);
}

Expand Down Expand Up @@ -359,7 +365,9 @@ public List<Setting<?>> getSettings() {
new ActionHandler<>(IndexCustomLogTypeAction.INSTANCE, TransportIndexCustomLogTypeAction.class),
new ActionHandler<>(SearchCustomLogTypeAction.INSTANCE, TransportSearchCustomLogTypeAction.class),
new ActionHandler<>(DeleteCustomLogTypeAction.INSTANCE, TransportDeleteCustomLogTypeAction.class),
new ActionHandler<>(PutTIFJobAction.INSTANCE, TransportPutTIFJobAction.class)
new ActionHandler<>(PutTIFJobAction.INSTANCE, TransportPutTIFJobAction.class),
new ActionPlugin.ActionHandler<>(GetCorrelationAlertsAction.INSTANCE, TransportGetCorrelationAlertsAction.class),
new ActionPlugin.ActionHandler<>(AckCorrelationAlertsAction.INSTANCE, TransportAckCorrelationAlertsAction.class)
);
}

Expand Down
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
@@ -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";

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
Loading