Skip to content

Commit

Permalink
[FEATURE] Deleting detectors should delete all related dashboards (in…
Browse files Browse the repository at this point in the history
…cluding index-patterns and visualisations) opensearch-project#509

Signed-off-by: Jovan Cvetkovic <[email protected]>
  • Loading branch information
jovancvetkovic3006 committed Apr 12, 2023
1 parent 5f2e4d0 commit 3ecdd08
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,14 @@ export const AlertTriggerView: React.FC<AlertTriggerViewProps> = ({
<h5>If any detection rule matches</h5>
</EuiTitle>
<EuiSpacer size={'m'} />
{createTextDetailsGroup(
[
{ label: 'Log type', content: `${types[0]}` || DEFAULT_EMPTY_DATA },
{ label: 'Rule names', content: conditionRuleNames.join('\n') || DEFAULT_EMPTY_DATA },
],
3
)}
{createTextDetailsGroup(
[
{ label: 'Rule severities', content: sev_levels.join('\n') || DEFAULT_EMPTY_DATA },
{ label: 'Tags', content: tags.join('\n') || DEFAULT_EMPTY_DATA },
],
3
)}
{createTextDetailsGroup([
{ label: 'Log type', content: `${types[0]}` || DEFAULT_EMPTY_DATA },
{ label: 'Rule names', content: conditionRuleNames.join('\n') || DEFAULT_EMPTY_DATA },
])}
{createTextDetailsGroup([
{ label: 'Rule severities', content: sev_levels.join('\n') || DEFAULT_EMPTY_DATA },
{ label: 'Tags', content: tags.join('\n') || DEFAULT_EMPTY_DATA },
])}
<EuiSpacer size="xl" />

<EuiTitle size="s">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const DetectorBasicDetailsView: React.FC<DetectorBasicDetailsViewProps> =
<EuiIcon type={'popout'} />
</EuiLink>
) : (
'Not available for this log type'
'-'
)) as any,
},
];
Expand All @@ -68,16 +68,13 @@ export const DetectorBasicDetailsView: React.FC<DetectorBasicDetailsViewProps> =
}
>
<EuiSpacer size={'l'} />
{createTextDetailsGroup(firstTextDetailsGroupEntries, 4)}
{createTextDetailsGroup(
[
{ label: 'Description', content: inputs[0].detector_input.description },
{ label: 'Detector schedule', content: detectorSchedule },
{ label: 'Created at', content: createdAt || DEFAULT_EMPTY_DATA },
{ label: 'Last updated time', content: lastUpdated || DEFAULT_EMPTY_DATA },
],
4
)}
{createTextDetailsGroup(firstTextDetailsGroupEntries)}
{createTextDetailsGroup([
{ label: 'Description', content: inputs[0].detector_input.description },
{ label: 'Detector schedule', content: detectorSchedule },
{ label: 'Created at', content: createdAt || DEFAULT_EMPTY_DATA },
{ label: 'Last updated time', content: lastUpdated || DEFAULT_EMPTY_DATA },
])}
{rulesCanFold ? children : null}
</ContentPanel>
);
Expand Down
26 changes: 25 additions & 1 deletion public/pages/Detectors/containers/Detector/DetectorDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { DetectorDetailsView } from '../DetectorDetailsView/DetectorDetailsView'
import { FieldMappingsView } from '../../components/FieldMappingsView/FieldMappingsView';
import { AlertTriggersView } from '../AlertTriggersView/AlertTriggersView';
import { RuleItem } from '../../../CreateDetector/components/DefineDetector/components/DetectionRules/types/interfaces';
import { DetectorsService } from '../../../../services';
import { DetectorsService, IndexPatternsService } from '../../../../services';
import { errorNotificationToast } from '../../../../utils/helpers';
import { NotificationsStart, SimpleSavedObject } from 'opensearch-dashboards/public';
import { ISavedObjectsService, ServerResponse } from '../../../../../types';
Expand All @@ -47,6 +47,7 @@ export interface DetectorDetailsProps
detectorService: DetectorsService;
notifications: NotificationsStart;
savedObjectsService: ISavedObjectsService;
indexPatternsService: IndexPatternsService;
}

export interface DetectorDetailsState {
Expand Down Expand Up @@ -257,6 +258,11 @@ export class DetectorDetails extends React.Component<DetectorDetailsProps, Detec
BREADCRUMBS.DETECTORS,
BREADCRUMBS.DETECTORS_DETAILS(detector._source.name, detector._id),
]);

const dashboard = await this.props.savedObjectsService.getDashboard(detectorId);
if (dashboard?.id) {
this.setState({ dashboardId: dashboard.id });
}
} else {
errorNotificationToast(notifications, 'retrieve', 'detector', response.error);
}
Expand All @@ -282,10 +288,28 @@ export class DetectorDetails extends React.Component<DetectorDetailsProps, Detec
const { detectorService, notifications } = this.props;
const detectorId = this.detectorHit._id;
try {
const dashboard = await this.props.savedObjectsService.getDashboard(detectorId);
if (dashboard) {
// delete dashboard
dashboard.references?.map(async (ref) => {
if (ref.type === 'visualization') {
await this.props.savedObjectsService.deleteVisualization(ref.id);
}
});
await this.props.savedObjectsService.deleteDashboard(dashboard.id);
}

const index = await this.props.indexPatternsService.getIndexPattern(detectorId);
if (index) {
await this.props.indexPatternsService.deleteIndexPattern(index.id);
}

const deleteRes = await detectorService.deleteDetector(detectorId);
if (!deleteRes.ok) {
errorNotificationToast(notifications, 'delete', 'detector', deleteRes.error);
} else {
DataStore.detectors.deleteState();
DataStore.detectors.clearNotifications();
this.props.history.push(ROUTES.DETECTORS);
}
} catch (e: any) {
Expand Down
1 change: 1 addition & 0 deletions public/pages/Main/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ export default class Main extends Component<MainProps, MainState> {
<DetectorDetails
detectorService={services.detectorsService}
savedObjectsService={services.savedObjectsService}
indexPatternsService={services.indexPatternsService}
{...props}
notifications={core?.notifications}
/>
Expand Down
31 changes: 31 additions & 0 deletions public/services/IndexPatternsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
IndexPatternSpec,
IndexPatternsService as CoreIndexPatternsService,
} from '../../../../src/plugins/data/common/index_patterns';
import { IndexPatternSavedObjectAttrs } from '../../../../src/plugins/data/common/index_patterns/index_patterns';
import { SavedObject } from '../../../../src/plugins/data/common';

export default class IndexPatternsService {
constructor(private coreIndexPatternsService: CoreIndexPatternsService) {}
Expand All @@ -19,4 +21,33 @@ export default class IndexPatternsService {
async createAndSave(spec: IndexPatternSpec, override = false, skipFetchFields = false) {
return this.coreIndexPatternsService.createAndSave(spec, override, skipFetchFields);
}

public getIndexPatterns = async (): Promise<
SavedObject<IndexPatternSavedObjectAttrs>[] | null | undefined
> => {
const indexPatterns = await this.coreIndexPatternsService.getCache();

return Promise.resolve(indexPatterns);
};

public getIndexPattern = async (
detectorId: string
): Promise<Promise<SavedObject<IndexPatternSavedObjectAttrs>> | Promise<undefined>> => {
let indexPattern;
const indexPatterns = await this.getIndexPatterns();
console.log('indexPatterns', indexPatterns);
indexPatterns?.some((indexRef) => {
if (indexRef.references.findIndex((reference) => reference.id === detectorId) > -1) {
indexPattern = indexRef;
return true;
}

return false;
});

return indexPattern;
};

public deleteIndexPattern = async (indexPatternId: string) =>
await this.coreIndexPatternsService.delete(indexPatternId);
}
33 changes: 32 additions & 1 deletion public/services/SavedObjectService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,17 @@ export default class SavedObjectService implements ISavedObjectsService {
},
};
});
const createAliasRes = await this.indexService.updateAliases({
await this.indexService.updateAliases({
actions: indexActions,
});

const detectorReferences = [
{
id: detectorId,
name: name,
type: 'detector-SA',
},
];
const indexPattern = await this.savedObjectsClient.create(
savedObjectConfig['index-pattern'].type,
{
Expand All @@ -51,6 +58,7 @@ export default class SavedObjectService implements ISavedObjectsService {
},
{
...savedObjectConfig['index-pattern'],
references: detectorReferences,
}
);

Expand Down Expand Up @@ -130,6 +138,23 @@ export default class SavedObjectService implements ISavedObjectsService {
return Promise.resolve(dashboards);
};

public getDashboard = async (
detectorId: string
): Promise<Promise<SimpleSavedObject<SavedObjectReference>> | Promise<undefined>> => {
let dashboard;
const dashboards = await this.getDashboards();
dashboards?.some((dashRef) => {
if (dashRef.references.findIndex((reference) => reference.id === detectorId) > -1) {
dashboard = dashRef;
return true;
}

return false;
});

return dashboard;
};

public async getIndexPatterns(): Promise<SimpleSavedObject<{ title: string }>[]> {
const indexPatterns = await this.savedObjectsClient
.find<{ title: string }>({
Expand All @@ -141,4 +166,10 @@ export default class SavedObjectService implements ISavedObjectsService {

return Promise.resolve(indexPatterns);
}

public deleteDashboard = async (dashboardId: string) =>
await this.savedObjectsClient.delete('dashboard', dashboardId);

public deleteVisualization = async (visualizationId: string) =>
await this.savedObjectsClient.delete('visualization', visualizationId);
}
19 changes: 10 additions & 9 deletions public/store/DetectorsStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ export class DetectorsStore implements IDetectorsStore {
delete this.state;
};

public clearNotifications = (): void => {
this.hideCallout();
this.toasts = [];
this.showToastCallback([]);
};

private showNotification = (
title: string,
message?: string,
Expand Down Expand Up @@ -258,15 +264,10 @@ export class DetectorsStore implements IDetectorsStore {
if (dashboardResponse && dashboardResponse.ok) {
dashboardId = dashboardResponse.response.id;
} else {
const dashboards = await this.savedObjectsService.getDashboards();
dashboards.some((dashboard) => {
if (dashboard.references.findIndex((reference) => reference.id === detectorId) > -1) {
dashboardId = dashboard.id;
return true;
}

return false;
});
const dashboard = await this.savedObjectsService.getDashboard(detectorId);
if (dashboard) {
dashboardId = dashboard.id;
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions types/services/ISavedObjectsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ export interface ISavedObjectsService {
getDashboards(): Promise<
SimpleSavedObject<{ references: SavedObjectReference[]; id?: string }>[]
>;
getDashboard(
detectorId: string
): Promise<Promise<SimpleSavedObject<SavedObjectReference>> | Promise<undefined>>;
deleteDashboard(detectorId: string): Promise<any>;
deleteVisualization(detectorId: string): Promise<any>;
}

0 comments on commit 3ecdd08

Please sign in to comment.