Skip to content

Commit

Permalink
fixed acknowledge button
Browse files Browse the repository at this point in the history
Signed-off-by: Riya Saxena <[email protected]>
  • Loading branch information
riysaxen-amzn committed Jun 18, 2024
1 parent 07a8559 commit 0ce266b
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
import { parseAlertSeverityToOption } from '../../../CreateDetector/components/ConfigureAlerts/utils/helpers';
import { NotificationsStart } from 'opensearch-dashboards/public';
import { DataStore } from '../../../../store/DataStore';
import { CorrelationAlertItem, Detector, Finding } from '../../../../../types';
import { CorrelationAlertItem, Finding } from '../../../../../types';

export interface CorrelationAlertFlyoutProps {
alertItem: CorrelationAlertItem;
Expand Down Expand Up @@ -147,7 +147,7 @@ import {
onClick={() => {
const ruleId = finding.queries[0]?.id; // Assuming you retrieve rule ID from finding
const rule: RuleSource | undefined = rules[ruleId];

DataStore.findings.openFlyout(
{
...finding,
Expand Down Expand Up @@ -177,10 +177,7 @@ import {
sortable: true,
dataType: 'string',
render: (finding: any) => {
const ruleId = finding.queries[0]?.id; // Retrieve rule ID from the first query of the finding
const rule: RuleSource | undefined = rules[ruleId];

return formatRuleType(rule?.category || ''); // Pass category from rule as string, default to empty string if rule is undefined
return formatRuleType(finding[0]?.tags[1]); // Pass category from rule as string, default to empty string if rule is undefined
},
},
];
Expand Down
90 changes: 57 additions & 33 deletions public/pages/Alerts/containers/Alerts/Alerts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export interface AlertsState {
timeUnit: TimeUnit;
dateFormat: string;
widgetEmptyMessage: React.ReactNode | undefined;
widgetEmptyCorrelationMessage: React.ReactNode | undefined;
tab: string;
}

Expand Down Expand Up @@ -131,6 +132,7 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
timeUnit: timeUnits.timeUnit,
dateFormat: timeUnits.dateFormat,
widgetEmptyMessage: undefined,
widgetEmptyCorrelationMessage: undefined,
tab: 'findings'
};
}
Expand All @@ -154,22 +156,17 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
prevState.correlationAlerts !== this.state.correlationAlerts ||
prevState.correlationAlerts.length !== this.state.correlationAlerts.length;

if (prevState.tab != this.state.tab) {
if (this.state.tab == "findings") {
renderVisualization(this.generateVisualizationSpec(this.state.filteredAlerts), 'alerts-view');
} else {
renderVisualization(this.generateCorrelationVisualizationSpec(this.state.filteredCorrelationAlerts), 'alerts-view');
}
if (prevState.tab !== this.state.tab) {
this.onRefresh();
}
if (this.props.dataSource !== prevProps.dataSource) {
this.onRefresh();
} else if (alertsChanged) {
this.filterAlerts();
} else if (correlationAlertsChanged) {
this.filterCorrelationAlerts();
}
else if (this.state.groupBy !== prevState.groupBy) {
renderVisualization(this.generateVisualizationSpec(this.state.filteredAlerts), 'alerts-view');
} else if (this.state.groupBy !== prevState.groupBy) {
this.renderVisAsPerTab();
}
}

Expand Down Expand Up @@ -219,7 +216,7 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
this.setState({
alertsFiltered: true,
filteredCorrelationAlerts: filteredCorrelationAlerts,
widgetEmptyMessage: filteredCorrelationAlerts.length ? undefined : (
widgetEmptyCorrelationMessage: filteredCorrelationAlerts.length ? undefined : (
<EuiEmptyPrompt
body={
<p>
Expand All @@ -233,6 +230,25 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
renderVisualization(this.generateCorrelationVisualizationSpec(filteredCorrelationAlerts), 'alerts-view');
};

private renderVisAsPerTab() {
if (this.state.tab === "findings") {
renderVisualization(this.generateVisualizationSpec(this.state.filteredAlerts), 'alerts-view');
} else {
renderVisualization(this.generateCorrelationVisualizationSpec(this.state.filteredCorrelationAlerts), 'alerts-view');
}
}

private getAlertsAsPerTab() {
if (this.state.tab === "findings") {
this.abortPendingGetAlerts();
const abortController = new AbortController();
this.abortControllers.push(abortController);
this.getAlerts(abortController.signal);
} else {
this.getCorrelationAlerts();
}
}

getColumns(): EuiBasicTableColumn<AlertItem>[] {
return [
{
Expand Down Expand Up @@ -481,10 +497,9 @@ export class Alerts extends Component<AlertsProps, AlertsState> {

async getCorrelationAlerts() {
this.setState({ loading: true, correlationAlerts: [] });
const { correlationService, notifications, dateTimeFilter } = this.props;
const { correlationService, notifications } = this.props;
try {
const correlationRes = await correlationService.getCorrelationAlerts();
const duration = getDuration(dateTimeFilter);
if (correlationRes.ok) {
this.setState({ correlationAlerts: correlationRes.response.correlationAlerts });
} else {
Expand Down Expand Up @@ -549,6 +564,19 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
);
}

createAcknowledgeControlForCorrelations() {
const { correlatedItems } = this.state;
return (
<EuiButton
disabled={!correlatedItems.length}
onClick={() => this.onAcknowledgeCorrelationAlert(correlatedItems)}
data-test-subj={'acknowledge-button'}
>
Acknowledge
</EuiButton>
);
}

onTimeChange = ({ start, end }: { start: string; end: string }) => {
let { recentlyUsedRanges } = this.state;
recentlyUsedRanges = recentlyUsedRanges.filter(
Expand Down Expand Up @@ -578,13 +606,8 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
}

onRefresh = async () => {
this.abortPendingGetAlerts();
const abortController = new AbortController();
this.abortControllers.push(abortController);
this.getAlerts(abortController.signal);
this.getCorrelationAlerts();
renderVisualization(this.generateVisualizationSpec(this.state.filteredAlerts), 'alerts-view');
renderVisualization(this.generateCorrelationVisualizationSpec(this.state.filteredCorrelationAlerts), 'alerts-view');
this.getAlertsAsPerTab();
this.renderVisAsPerTab();
};

onSelectionChange = (selectedItems: AlertItem[]) => {
Expand Down Expand Up @@ -638,21 +661,17 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
let successCount = 0;
try {
// Separating the selected items by detector ID, and adding all selected alert IDs to an array for that detector ID.
const correlations: { [key: string]: string[] } = {};
const alertIds: string[] = [];
selectedItems.forEach((item) => {
if (!correlations[item.correlation_rule_id]) correlations[item.correlation_rule_id] = [item.id];
else correlations[item.correlation_rule_id].push(item.id);
alertIds.push(item.id);
});

for (let corrId of Object.keys(correlations)) {
const alertIds = correlations[corrId];
if (alertIds.length > 0) {
const response = await correlationService.acknowledgeCorrelationAlerts(alertIds);
if (response.ok) {
successCount += alertIds.length;
} else {
errorNotificationToast(notifications, 'acknowledge', 'alerts', response.error);
}
if (alertIds.length > 0) {
const response = await correlationService.acknowledgeCorrelationAlerts(alertIds);
if (response.ok) {
successCount += alertIds.length;
} else {
errorNotificationToast(notifications, 'acknowledge', 'alerts', response.error);
}
}
} catch (e: any) {
Expand All @@ -677,6 +696,7 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
loading,
recentlyUsedRanges,
widgetEmptyMessage,
widgetEmptyCorrelationMessage,
} = this.state;

const {
Expand Down Expand Up @@ -851,7 +871,11 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
<EuiSpacer size="xxl" />
</EuiFlexItem>
<EuiFlexItem>
<ContentPanel title={'Alerts'} actions={[this.createAcknowledgeControl()]}>
<ContentPanel title={'Alerts'} actions={[
this.state.tab === 'findings'
? this.createAcknowledgeControl()
: this.createAcknowledgeControlForCorrelations()
]}>
<EuiTabs>
<EuiTab onClick={() => this.setState({ tab: 'findings' })} isSelected={this.state.tab === 'findings'}>
Findings
Expand Down Expand Up @@ -886,7 +910,7 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
sorting={sorting}
selection={correlationSelection}
loading={loading}
message={widgetEmptyMessage}
message={widgetEmptyCorrelationMessage}
/>
)}
</ContentPanel>
Expand Down
37 changes: 17 additions & 20 deletions public/pages/Correlations/containers/CreateCorrelationRule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,29 @@ export const CreateCorrelationRule: React.FC<CreateCorrelationRuleProps> = (
}, [props.dataSource]);

useEffect(() => {
const alertCondition = initialValues.trigger;
if (alertCondition && alertCondition.actions) {
if (alertCondition.actions.length == 0)
alertCondition.actions = getEmptyAlertCondition().actions;

const channelId = alertCondition?.actions[0].destination_id;
const selectedNotificationChannelOption: NotificationChannelOption[] = [];
if (channelId) {
notificationChannels.forEach((typeOption) => {
const matchingChannel = typeOption.options.find((option) => option.value === channelId);
if (matchingChannel) selectedNotificationChannelOption.push(matchingChannel);
});
}
setSelectedNotificationChannelOption(selectedNotificationChannelOption);
}
setPeriod(parseTime(initialValues.time_window));
setGroupByEnabled(initialValues.queries.some((q) => !!q.field));
setDataFilterEnabled(initialValues.queries.some((q) => q.conditions.length > 0));

initialValues.queries.forEach(({ index }) => {
updateLogFieldsForIndex(index);
});
}, [initialValues]);
}, [initialValues, notificationChannels]);


const onNotificationChannelsChange = (selectedOptions: EuiComboBoxOptionOption<string>[]) => {
Expand Down Expand Up @@ -823,24 +838,6 @@ export const CreateCorrelationRule: React.FC<CreateCorrelationRuleProps> = (
);
};

useEffect(() => {
const alertCondition = initialValues.trigger;
if (alertCondition && alertCondition.actions) {
if (alertCondition.actions.length == 0)
alertCondition.actions = getEmptyAlertCondition().actions;

const channelId = alertCondition?.actions[0].destination_id;
const selectedNotificationChannelOption: NotificationChannelOption[] = [];
if (channelId) {
notificationChannels.forEach((typeOption) => {
const matchingChannel = typeOption.options.find((option) => option.value === channelId);
if (matchingChannel) selectedNotificationChannelOption.push(matchingChannel);
});
}
setSelectedNotificationChannelOption(selectedNotificationChannelOption);
}
}, [initialValues, notificationChannels]);

useEffect(() => {
context?.chrome.setBreadcrumbs([
BREADCRUMBS.SECURITY_ANALYTICS,
Expand Down Expand Up @@ -1041,7 +1038,7 @@ export const CreateCorrelationRule: React.FC<CreateCorrelationRuleProps> = (
value={trigger?.name}
onChange={(e) => {
const triggerName = e.target.value || '';
props.handleChange('trigger?.name')(triggerName);
props.setFieldValue('trigger?.name', triggerName)
onNameChange(triggerName);
}}
data-test-subj="alert-condition-name"
Expand Down
2 changes: 1 addition & 1 deletion public/services/CorrelationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default class CorrelationService implements ICorrelationsService {
const url = `..${API.ACK_CORRELATION_ALERTS}`;

return (await this.httpClient.post(url, {
body: JSON.stringify(body),
body: JSON.stringify({alertIds: body}),
query: {
dataSourceId: dataSourceInfo.activeDataSource.id,
},
Expand Down
2 changes: 1 addition & 1 deletion server/routes/FindingsRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function setupFindingsRoutes(services: NodeServices, router: IRouter) {
detectionType: schema.maybe(schema.string()),
severity: schema.maybe(schema.string()),
searchString: schema.maybe(schema.string()),
findingIds: schema.string(),
findingIds: schema.maybe(schema.string()),
startTime: schema.maybe(schema.number()),
endTime: schema.maybe(schema.number())
}),
Expand Down

0 comments on commit 0ce266b

Please sign in to comment.