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

Allow deletion of custom log type if custom rule index is missing (#767) #780

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 @@ -26,26 +26,26 @@
import org.opensearch.common.settings.Settings;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.commons.authuser.User;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.index.IndexNotFoundException;
import org.opensearch.index.query.QueryBuilder;
import org.opensearch.index.query.QueryBuilders;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.search.builder.SearchSourceBuilder;
import org.opensearch.securityanalytics.action.DeleteCustomLogTypeAction;
import org.opensearch.securityanalytics.action.DeleteCustomLogTypeRequest;
import org.opensearch.securityanalytics.action.DeleteCustomLogTypeResponse;
import org.opensearch.securityanalytics.logtype.LogTypeService;
import org.opensearch.securityanalytics.model.CustomLogType;
import org.opensearch.securityanalytics.model.Detector;
import org.opensearch.securityanalytics.model.Rule;
import org.opensearch.securityanalytics.settings.SecurityAnalyticsSettings;
import org.opensearch.securityanalytics.util.CustomLogTypeIndices;
import org.opensearch.securityanalytics.util.DetectorIndices;
import org.opensearch.securityanalytics.util.RuleIndices;
import org.opensearch.securityanalytics.util.SecurityAnalyticsException;
import org.opensearch.tasks.Task;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.TransportService;

import java.io.IOException;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
Expand All @@ -65,6 +65,8 @@

private final DetectorIndices detectorIndices;

private final RuleIndices ruleIndices;

private final CustomLogTypeIndices customLogTypeIndices;

private volatile Boolean filterByEnabled;
Expand All @@ -77,6 +79,7 @@
ActionFilters actionFilters,
ClusterService clusterService,
DetectorIndices detectorIndices,
RuleIndices ruleIndices,
CustomLogTypeIndices customLogTypeIndices,
Settings settings,
ThreadPool threadPool) {
Expand All @@ -86,6 +89,7 @@
this.threadPool = threadPool;
this.settings = settings;
this.detectorIndices = detectorIndices;
this.ruleIndices = ruleIndices;

Check warning on line 92 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L92

Added line #L92 was not covered by tests
this.customLogTypeIndices = customLogTypeIndices;
this.filterByEnabled = SecurityAnalyticsSettings.FILTER_BY_BACKEND_ROLES.get(this.settings);
this.indexTimeout = SecurityAnalyticsSettings.INDEX_TIMEOUT.get(this.settings);
Expand Down Expand Up @@ -166,15 +170,17 @@

private void onGetResponse(CustomLogType logType) {
if (logType.getSource().equals("Sigma")) {
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(), "Log Type with id %s cannot be deleted because source is sigma", logType.getId()), RestStatus.BAD_REQUEST));
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(),
"Log Type with id %s cannot be deleted because source is sigma", logType.getId()), RestStatus.BAD_REQUEST));

Check warning on line 174 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L173-L174

Added lines #L173 - L174 were not covered by tests
}

if (detectorIndices.detectorIndexExists()) {
searchDetectors(logType.getName(), new ActionListener<>() {
@Override
public void onResponse(SearchResponse response) {
if (response.isTimedOut()) {
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(), "Search request timed out. Log Type with id %s cannot be deleted", logType.getId()), RestStatus.REQUEST_TIMEOUT));
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(),
"Search request timed out. Log Type with id %s cannot be deleted", logType.getId()), RestStatus.REQUEST_TIMEOUT));

Check warning on line 183 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L182-L183

Added lines #L182 - L183 were not covered by tests
return;
}

Expand All @@ -183,44 +189,7 @@
return;
}

searchRules(logType.getName(), new ActionListener<>() {
@Override
public void onResponse(SearchResponse response) {
if (response.isTimedOut()) {
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(), "Search request timed out. Log Type with id %s cannot be deleted", logType.getId()), RestStatus.REQUEST_TIMEOUT));
return;
}

if (response.getHits().getTotalHits().value > 0) {
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(), "Log Type with id %s cannot be deleted because active rules exist", logType.getId()), RestStatus.BAD_REQUEST));
return;
}

DeleteRequest deleteRequest = new DeleteRequest(LogTypeService.LOG_TYPE_INDEX, logType.getId())
.setRefreshPolicy(request.getRefreshPolicy())
.timeout(indexTimeout);

client.delete(deleteRequest, new ActionListener<>() {
@Override
public void onResponse(DeleteResponse response) {
if (response.status() != RestStatus.OK) {
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(), "Log Type with id %s cannot be deleted", logType.getId()), RestStatus.INTERNAL_SERVER_ERROR));
}
onOperation(response);
}

@Override
public void onFailure(Exception e) {
onFailures(e);
}
});
}

@Override
public void onFailure(Exception e) {
onFailures(e);
}
});
checkRuleIndexAndDeleteLogType(logType);

Check warning on line 192 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L192

Added line #L192 was not covered by tests
}

@Override
Expand All @@ -229,25 +198,62 @@
}
});
} else {
DeleteRequest deleteRequest = new DeleteRequest(LogTypeService.LOG_TYPE_INDEX, logType.getId())
.setRefreshPolicy(request.getRefreshPolicy())
.timeout(indexTimeout);
checkRuleIndexAndDeleteLogType(logType);

Check warning on line 201 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L201

Added line #L201 was not covered by tests
}
}

Check warning on line 203 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L203

Added line #L203 was not covered by tests

client.delete(deleteRequest, new ActionListener<>() {
void checkRuleIndexAndDeleteLogType(CustomLogType logType) {
if(ruleIndices.ruleIndexExists(false)) {
ruleIndices.searchRules(logType.getName(), new ActionListener<>() {

Check warning on line 207 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L207

Added line #L207 was not covered by tests
@Override
public void onResponse(DeleteResponse response) {
if (response.status() != RestStatus.OK) {
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(), "Log Type with id %s cannot be deleted", logType.getId()), RestStatus.INTERNAL_SERVER_ERROR));
public void onResponse(SearchResponse response) {
if (response.isTimedOut()) {
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(), "Search request timed out. Log Type with id %s cannot be deleted", logType.getId()), RestStatus.REQUEST_TIMEOUT));
return;

Check warning on line 212 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L211-L212

Added lines #L211 - L212 were not covered by tests
}
onOperation(response);

if (response.getHits().getTotalHits().value > 0) {
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(), "Log Type with id %s cannot be deleted because active rules exist", logType.getId()), RestStatus.BAD_REQUEST));
return;

Check warning on line 217 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L216-L217

Added lines #L216 - L217 were not covered by tests
}
deleteLogType(logType);

Check warning on line 219 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L219

Added line #L219 was not covered by tests
}

@Override
public void onFailure(Exception e) {
onFailures(e);
if (e instanceof IndexNotFoundException) {
// let log type deletion to go through if the rule index is missing
deleteLogType(logType);

Check warning on line 226 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L226

Added line #L226 was not covered by tests
} else {
onFailures(e);

Check warning on line 228 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L228

Added line #L228 was not covered by tests
}
}
});
} else {
log.warn("Custom rule index missing, allowing deletion of custom log type {} to go through", logType.getId());
deleteLogType(logType);

Check warning on line 234 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L233-L234

Added lines #L233 - L234 were not covered by tests
}
}

Check warning on line 236 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L236

Added line #L236 was not covered by tests

private void deleteLogType(CustomLogType logType) {
DeleteRequest deleteRequest = new DeleteRequest(LogTypeService.LOG_TYPE_INDEX, logType.getId())
.setRefreshPolicy(request.getRefreshPolicy())
.timeout(indexTimeout);

Check warning on line 241 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L239-L241

Added lines #L239 - L241 were not covered by tests

client.delete(deleteRequest, new ActionListener<>() {

Check warning on line 243 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L243

Added line #L243 was not covered by tests
@Override
public void onResponse(DeleteResponse response) {
if (response.status() != RestStatus.OK) {
onFailures(new OpenSearchStatusException(String.format(Locale.getDefault(), "Log Type with id %s cannot be deleted", logType.getId()), RestStatus.INTERNAL_SERVER_ERROR));

Check warning on line 247 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L247

Added line #L247 was not covered by tests
}
onOperation(response);
}

Check warning on line 250 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L249-L250

Added lines #L249 - L250 were not covered by tests

@Override
public void onFailure(Exception e) {
onFailures(e);
}

Check warning on line 255 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L254-L255

Added lines #L254 - L255 were not covered by tests
});
}

private void searchDetectors(String logTypeName, ActionListener<SearchResponse> listener) {
Expand All @@ -267,23 +273,6 @@
client.search(searchRequest, listener);
}

private void searchRules(String logTypeName, ActionListener<SearchResponse> listener) {
QueryBuilder queryBuilder =
QueryBuilders.nestedQuery("rule",
QueryBuilders.boolQuery().must(
QueryBuilders.matchQuery("rule.category", logTypeName)
), ScoreMode.Avg);

SearchRequest searchRequest = new SearchRequest(Rule.CUSTOM_RULES_INDEX)
.source(new SearchSourceBuilder()
.seqNoAndPrimaryTerm(true)
.version(true)
.query(queryBuilder)
.size(0));

client.search(searchRequest, listener);
}

private void onOperation(DeleteResponse response) {
this.response.set(response);
if (counter.compareAndSet(false, true)) {
Expand All @@ -292,7 +281,7 @@
}

private void onFailures(Exception t) {
log.error(String.format(Locale.ROOT, "Failed to delete detector"));
log.error(String.format(Locale.ROOT, "Failed to delete log type"), t);

Check warning on line 284 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteCustomLogTypeAction.java#L284

Added line #L284 was not covered by tests
if (counter.compareAndSet(false, true)) {
finishHim(null, t);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@
new DeleteByQueryRequestBuilder(client, DeleteByQueryAction.INSTANCE)
.source(Rule.CUSTOM_RULES_INDEX)
.filter(QueryBuilders.matchQuery("_id", ruleId))
.refresh(true)

Check warning on line 230 in src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteRuleAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/transport/TransportDeleteRuleAction.java#L230

Added line #L230 was not covered by tests
.execute(new ActionListener<>() {
@Override
public void onResponse(BulkByScrollResponse response) {
Expand Down
Loading
Loading