Skip to content

Commit

Permalink
[SIEM] Fixes index substring incorrectly matching configured indices …
Browse files Browse the repository at this point in the history
…and failing to install ML job (#43409)

## Summary

As described in elastic/siem-team#441, when checking which ML ConfigTemplates are valid to install, a substring of a configured index would match and the job would fail to install. This fixes this by ensuring the complete index name matches.
  • Loading branch information
spong authored Aug 17, 2019
1 parent 9b92f84 commit 0d635d8
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 25 deletions.
20 changes: 9 additions & 11 deletions x-pack/legacy/plugins/siem/public/components/ml_popover/api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
throwIfErrorAttachedToSetup,
} from '../ml/api/throw_if_not_ok';

const emptyIndexPattern: string = '';
const emptyIndexPattern: string[] = [];

/**
* Fetches ML Groups Data
Expand Down Expand Up @@ -196,7 +196,7 @@ export const jobsSummary = async (
*/
export const getIndexPatterns = async (
headers: Record<string, string | undefined>
): Promise<string> => {
): Promise<string[]> => {
const response = await fetch(
`${chrome.getBasePath()}/api/saved_objects/_find?type=index-pattern&fields=title&fields=type&per_page=10000`,
{
Expand All @@ -214,15 +214,13 @@ export const getIndexPatterns = async (
const results: IndexPatternResponse = await response.json();

if (results.saved_objects && Array.isArray(results.saved_objects)) {
return results.saved_objects
.reduce(
(acc: string[], v) => [
...acc,
...(v.attributes && v.attributes.title ? [v.attributes.title] : []),
],
[]
)
.join(', ');
return results.saved_objects.reduce(
(acc: string[], v) => [
...acc,
...(v.attributes && v.attributes.title ? [v.attributes.title] : []),
],
[]
);
} else {
return emptyIndexPattern;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('helpers', () => {
const configTemplatesToInstall = getConfigTemplatesToInstall(
mockConfigTemplates,
[],
'auditbeat-*, winlogbeat-*'
['auditbeat-*', 'winlogbeat-*']
);
expect(configTemplatesToInstall.length).toEqual(2);
});
Expand All @@ -43,7 +43,7 @@ describe('helpers', () => {
const configTemplatesToInstall = getConfigTemplatesToInstall(
mockConfigTemplates,
[],
'auditbeat-*, spongbeat-*'
['auditbeat-*', 'spongbeat-*']
);
expect(configTemplatesToInstall.length).toEqual(1);
});
Expand All @@ -52,10 +52,19 @@ describe('helpers', () => {
const configTemplatesToInstall = getConfigTemplatesToInstall(
mockConfigTemplates,
mockInstalledJobIds,
'auditbeat-*, winlogbeat-*'
['auditbeat-*', 'winlogbeat-*']
);
expect(configTemplatesToInstall.length).toEqual(2);
});

test('returns no configTemplates if index is substring of indexPatterns', () => {
const configTemplatesToInstall = getConfigTemplatesToInstall(
mockConfigTemplates,
mockInstalledJobIds,
['winlogbeat-**']
);
expect(configTemplatesToInstall.length).toEqual(0);
});
});

describe('getJobsToDisplay', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ export const getJobsToInstall = (templates: ConfigTemplate[]): string[] =>
*
* @param templates ConfigTemplates as provided by ML Team
* @param installedJobIds list of installed JobIds
* @param indexPattern Comma separated string of the user's currently configured IndexPattern
* @param indexPatterns list of the user's currently configured IndexPatterns
*/
export const getConfigTemplatesToInstall = (
templates: ConfigTemplate[],
installedJobIds: string[],
indexPattern: string
indexPatterns: string[]
): ConfigTemplate[] =>
templates
.filter(ct => !ct.jobs.every(ctJobId => installedJobIds.includes(ctJobId)))
.filter(ct => indexPattern.indexOf(ct.defaultIndexPattern) >= 0);
.filter(ct => indexPatterns.includes(ct.defaultIndexPattern));

/**
* Returns a filtered array of Jobs that based on filterGroup selection (Elastic vs Custom Jobs) and any user provided filterQuery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import { errorToToaster } from '../../ml/api/error_to_toaster';

import * as i18n from './translations';

type Return = [boolean, string];
type Return = [boolean, string[]];

export const useIndexPatterns = (refreshToggle = false): Return => {
const [indexPattern, setIndexPattern] = useState<string>('');
const [indexPatterns, setIndexPatterns] = useState<string[]>([]);
const [isLoading, setIsLoading] = useState(true);
const config = useContext(KibanaConfigContext);
const [, dispatchToaster] = useStateToaster();
Expand All @@ -26,7 +26,7 @@ export const useIndexPatterns = (refreshToggle = false): Return => {
'kbn-version': config.kbnVersion,
});

setIndexPattern(data);
setIndexPatterns(data);
setIsLoading(false);
} catch (error) {
errorToToaster({ title: i18n.INDEX_PATTERN_FETCH_FAILURE, error, dispatchToaster });
Expand All @@ -39,5 +39,5 @@ export const useIndexPatterns = (refreshToggle = false): Return => {
fetchFunc();
}, [refreshToggle]);

return [isLoading, indexPattern];
return [isLoading, indexPatterns];
};
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export const MlPopover = React.memo(() => {
const [filterQuery, setFilterQuery] = useState('');
const [, dispatchToaster] = useStateToaster();

const [, configuredIndexPattern] = useIndexPatterns(refreshToggle);
const [, configuredIndexPatterns] = useIndexPatterns(refreshToggle);
const config = useContext(KibanaConfigContext);
const capabilities = useContext(MlCapabilitiesContext);
const headers = { 'kbn-version': config.kbnVersion };
Expand Down Expand Up @@ -136,7 +136,7 @@ export const MlPopover = React.memo(() => {
const configTemplatesToInstall = getConfigTemplatesToInstall(
configTemplates,
installedJobIds,
configuredIndexPattern || ''
configuredIndexPatterns || []
);

// Filter installed job to show all 'siem' group jobs or just embedded
Expand All @@ -152,7 +152,7 @@ export const MlPopover = React.memo(() => {
useEffect(() => {
if (
jobSummaryData != null &&
configuredIndexPattern !== '' &&
configuredIndexPatterns.length > 0 &&
configTemplatesToInstall.length > 0
) {
const setupJobs = async () => {
Expand All @@ -178,7 +178,7 @@ export const MlPopover = React.memo(() => {
};
setupJobs();
}
}, [jobSummaryData, configuredIndexPattern]);
}, [jobSummaryData, configuredIndexPatterns]);

if (!capabilities.isPlatinumOrTrialLicense) {
// If the user does not have platinum show upgrade UI
Expand Down

0 comments on commit 0d635d8

Please sign in to comment.