Skip to content

Commit

Permalink
adds ml rule preview and fixes refresh error
Browse files Browse the repository at this point in the history
  • Loading branch information
dplumlee committed Dec 6, 2021
1 parent a4e2aff commit 75fd94c
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ export class RuleDataClient implements IRuleDataClient {
return this.options.indexInfo.kibanaVersion;
}

public indexNameWithNamespace(namespace: string): string {
return this.options.indexInfo.getPrimaryAlias(namespace);
}

private get writeEnabled(): boolean {
return this._isWriteEnabled;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { TechnicalRuleDataFieldName } from '../../common/technical_rule_data_fie

export interface IRuleDataClient {
indexName: string;
indexNameWithNamespace(namespace: string): string;
kibanaVersion: string;
isWriteEnabled(): boolean;
getReader(options?: { namespace?: string }): IRuleDataReader;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,15 @@ export const getIsRulePreviewDisabled = ({
index,
threatIndex,
threatMapping,
machineLearningJobId,
}: {
ruleType: Type;
isQueryBarValid: boolean;
isThreatQueryBarValid: boolean;
index: string[];
threatIndex: string[];
threatMapping: ThreatMapping;
machineLearningJobId: string[];
}) => {
if (!isQueryBarValid || index.length === 0) return true;
if (ruleType === 'threat_match') {
Expand All @@ -227,5 +229,8 @@ export const getIsRulePreviewDisabled = ({
)
return true;
}
if (ruleType === 'machine_learning') {
return machineLearningJobId.length === 0;
}
return false;
};
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export interface RulePreviewProps {
threatMapping: ThreatMapping;
threatQuery: FieldValueQueryBar;
threshold: FieldValueThreshold;
machineLearningJobId: string[];
anomalyThreshold: number;
}

const Select = styled(EuiSelect)`
Expand All @@ -57,6 +59,8 @@ const RulePreviewComponent: React.FC<RulePreviewProps> = ({
threatQuery,
threatMapping,
threshold,
machineLearningJobId,
anomalyThreshold,
}) => {
const { spaces } = useKibana().services;
const [spaceId, setSpaceId] = useState('');
Expand Down Expand Up @@ -84,6 +88,8 @@ const RulePreviewComponent: React.FC<RulePreviewProps> = ({
ruleType,
threatMapping,
threshold,
machineLearningJobId,
anomalyThreshold,
});

// Resets the timeFrame to default when rule type is changed because not all time frames are supported by all rule types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const PreviewHistogram = ({
threshold: isThresholdRule ? threshold : undefined,
query,
index,
ruleType,
});

const previousPreviewId = usePrevious(previewId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/
import { useMemo } from 'react';
import { Type } from '@kbn/securitysolution-io-ts-alerting-types';
import { useMatrixHistogram } from '../../../../common/containers/matrix_histogram';
import { MatrixHistogramType } from '../../../../../common/search_strategy';
import { convertToBuildEsQuery } from '../../../../common/lib/keury';
Expand All @@ -23,6 +24,7 @@ interface PreviewHistogramParams {
threshold?: FieldValueThreshold;
query: FieldValueQueryBar;
index: string[];
ruleType: Type;
}

export const usePreviewHistogram = ({
Expand All @@ -33,6 +35,7 @@ export const usePreviewHistogram = ({
threshold,
query,
index,
ruleType,
}: PreviewHistogramParams) => {
const { uiSettings } = useKibana().services;
const {
Expand All @@ -53,20 +56,25 @@ export const usePreviewHistogram = ({
filters,
});

const stackByField = useMemo(() => {
const stackByDefault = ruleType === 'machine_learning' ? 'host.name' : 'event.category';
return threshold?.field[0] ?? stackByDefault;
}, [threshold, ruleType]);

const matrixHistogramRequest = useMemo(() => {
return {
endDate,
errorMessage: QUERY_PREVIEW_ERROR,
filterQuery,
histogramType: MatrixHistogramType.preview,
indexNames: [`${DEFAULT_PREVIEW_INDEX}-${spaceId}`],
stackByField: threshold?.field[0] ?? 'event.category',
stackByField,
startDate,
threshold,
includeMissingData: false,
skip: error != null,
};
}, [startDate, endDate, filterQuery, spaceId, error, threshold]);
}, [startDate, endDate, filterQuery, spaceId, error, threshold, stackByField]);

return useMatrixHistogram(matrixHistogramRequest);
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ interface PreviewRouteParams {
timeFrame: Unit;
threatMapping: ThreatMapping;
threshold: FieldValueThreshold;
machineLearningJobId: string[];
anomalyThreshold: number;
}

export const usePreviewRoute = ({
Expand All @@ -36,6 +38,8 @@ export const usePreviewRoute = ({
ruleType,
threatMapping,
threshold,
machineLearningJobId,
anomalyThreshold,
}: PreviewRouteParams) => {
const [isRequestTriggered, setIsRequestTriggered] = useState(false);

Expand Down Expand Up @@ -70,6 +74,8 @@ export const usePreviewRoute = ({
ruleType,
threatMapping,
threshold,
machineLearningJobId,
anomalyThreshold,
]);

useEffect(() => {
Expand All @@ -84,6 +90,8 @@ export const usePreviewRoute = ({
threatQuery,
timeFrame,
threshold,
machineLearningJobId,
anomalyThreshold,
})
);
}
Expand All @@ -99,6 +107,8 @@ export const usePreviewRoute = ({
threatQuery,
timeFrame,
threshold,
machineLearningJobId,
anomalyThreshold,
]);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
threatQueryBar: formThreatQuery,
threshold: formThreshold,
threatMapping: formThreatMapping,
machineLearningJobId: formMachineLearningJobId,
anomalyThreshold: formAnomalyThreshold,
},
] = useFormData<DefineStepRule>({
form,
Expand All @@ -176,18 +178,19 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
'threshold.cardinality.value',
'threatIndex',
'threatMapping',
'machineLearningJobId',
'anomalyThreshold',
],
});

const [isQueryBarValid, setIsQueryBarValid] = useState(false);
const [isThreatQueryBarValid, setIsThreatQueryBarValid] = useState(false);
const index = formIndex || initialState.index;
const threatIndex = formThreatIndex || initialState.threatIndex;
const machineLearningJobId = formMachineLearningJobId ?? initialState.machineLearningJobId;
const anomalyThreshold = formAnomalyThreshold ?? initialState.anomalyThreshold;
const ruleType = formRuleType || initialState.ruleType;
const isPreviewRouteEnabled = useMemo(
() => ruleType !== 'machine_learning' && ruleType !== 'threat_match',
[ruleType]
);
const isPreviewRouteEnabled = useMemo(() => ruleType !== 'threat_match', [ruleType]);
const [indexPatternsLoading, { browserFields, indexPatterns }] = useFetchIndex(index);
const aggregatableFields = Object.entries(browserFields).reduce<BrowserFields>(
(groupAcc, [groupName, groupValue]) => {
Expand Down Expand Up @@ -513,13 +516,16 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
index,
threatIndex,
threatMapping: formThreatMapping,
machineLearningJobId,
})}
query={formQuery}
ruleType={ruleType}
threatIndex={threatIndex}
threatQuery={formThreatQuery}
threatMapping={formThreatMapping}
threshold={formThreshold}
machineLearningJobId={machineLearningJobId}
anomalyThreshold={anomalyThreshold}
/>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,8 @@ export const formatPreviewRule = ({
threatMapping,
timeFrame,
threshold,
machineLearningJobId,
anomalyThreshold,
}: {
index: string[];
threatIndex: string[];
Expand All @@ -412,6 +414,8 @@ export const formatPreviewRule = ({
threatMapping: ThreatMapping;
timeFrame: Unit;
threshold: FieldValueThreshold;
machineLearningJobId: string[];
anomalyThreshold: number;
}): CreateRulesSchema => {
const defineStepData = {
...stepDefineDefaultValue,
Expand All @@ -422,6 +426,8 @@ export const formatPreviewRule = ({
threatQueryBar: threatQuery,
threatMapping,
threshold,
machineLearningJobId,
anomalyThreshold,
};
const aboutStepData = {
...stepAboutDefaultValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const previewRulesRoute = async (
return response.ok({ body: { errors: ['Invalid invocation count'] } });
}

if (request.body.type === 'threat_match' || request.body.type === 'machine_learning') {
if (request.body.type === 'threat_match') {
return response.ok({ body: { errors: ['Preview for rule type not supported'] } });
}

Expand Down Expand Up @@ -261,6 +261,11 @@ export const previewRulesRoute = async (
)
.map((item) => item.message);

// Refreshes alias to ensure index is able to be read before returning
await context.core.elasticsearch.client.asInternalUser.indices.refresh({
index: previewRuleDataClient.indexNameWithNamespace(spaceId),
});

return response.ok({
body: {
previewId,
Expand Down

0 comments on commit 75fd94c

Please sign in to comment.