-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Fleet] Enable per policy outputs (#126692)
- Loading branch information
Showing
19 changed files
with
651 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
181 changes: 181 additions & 0 deletions
181
...ations/fleet/sections/agent_policy/components/agent_policy_advanced_fields/hooks.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { createFleetTestRendererMock } from '../../../../../../mock'; | ||
import type { MockedFleetStartServices } from '../../../../../../mock'; | ||
import { useLicense } from '../../../../../../hooks/use_license'; | ||
import type { LicenseService } from '../../../../services'; | ||
|
||
import { useOutputOptions } from './hooks'; | ||
|
||
jest.mock('../../../../../../hooks/use_license'); | ||
|
||
const mockedUseLicence = useLicense as jest.MockedFunction<typeof useLicense>; | ||
|
||
function defaultHttpClientGetImplementation(path: any) { | ||
if (typeof path !== 'string') { | ||
throw new Error('Invalid request'); | ||
} | ||
const err = new Error(`API [GET ${path}] is not MOCKED!`); | ||
// eslint-disable-next-line no-console | ||
console.log(err); | ||
throw err; | ||
} | ||
|
||
const mockApiCallsWithOutputs = (http: MockedFleetStartServices['http']) => { | ||
http.get.mockImplementation(async (path) => { | ||
if (typeof path !== 'string') { | ||
throw new Error('Invalid request'); | ||
} | ||
if (path === '/api/fleet/outputs') { | ||
return { | ||
data: { | ||
items: [ | ||
{ | ||
id: 'output1', | ||
name: 'Output 1', | ||
is_default: true, | ||
is_default_monitoring: true, | ||
}, | ||
{ | ||
id: 'output2', | ||
name: 'Output 2', | ||
is_default: true, | ||
is_default_monitoring: true, | ||
}, | ||
{ | ||
id: 'output3', | ||
name: 'Output 3', | ||
is_default: true, | ||
is_default_monitoring: true, | ||
}, | ||
], | ||
}, | ||
}; | ||
} | ||
|
||
return defaultHttpClientGetImplementation(path); | ||
}); | ||
}; | ||
|
||
describe('useOutputOptions', () => { | ||
it('should generate enabled options if the licence is platinium', async () => { | ||
const testRenderer = createFleetTestRendererMock(); | ||
mockedUseLicence.mockReturnValue({ | ||
hasAtLeast: () => true, | ||
} as unknown as LicenseService); | ||
mockApiCallsWithOutputs(testRenderer.startServices.http); | ||
const { result, waitForNextUpdate } = testRenderer.renderHook(() => useOutputOptions()); | ||
expect(result.current.isLoading).toBeTruthy(); | ||
|
||
await waitForNextUpdate(); | ||
expect(result.current.dataOutputOptions).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"inputDisplay": "Default (currently Output 1)", | ||
"value": "@@##DEFAULT_OUTPUT_VALUE##@@", | ||
}, | ||
Object { | ||
"disabled": false, | ||
"inputDisplay": "Output 1", | ||
"value": "output1", | ||
}, | ||
Object { | ||
"disabled": false, | ||
"inputDisplay": "Output 2", | ||
"value": "output2", | ||
}, | ||
Object { | ||
"disabled": false, | ||
"inputDisplay": "Output 3", | ||
"value": "output3", | ||
}, | ||
] | ||
`); | ||
expect(result.current.monitoringOutputOptions).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"inputDisplay": "Default (currently Output 1)", | ||
"value": "@@##DEFAULT_OUTPUT_VALUE##@@", | ||
}, | ||
Object { | ||
"disabled": false, | ||
"inputDisplay": "Output 1", | ||
"value": "output1", | ||
}, | ||
Object { | ||
"disabled": false, | ||
"inputDisplay": "Output 2", | ||
"value": "output2", | ||
}, | ||
Object { | ||
"disabled": false, | ||
"inputDisplay": "Output 3", | ||
"value": "output3", | ||
}, | ||
] | ||
`); | ||
}); | ||
|
||
it('should only enable the default options if the licence is not platinium', async () => { | ||
const testRenderer = createFleetTestRendererMock(); | ||
mockedUseLicence.mockReturnValue({ | ||
hasAtLeast: () => false, | ||
} as unknown as LicenseService); | ||
mockApiCallsWithOutputs(testRenderer.startServices.http); | ||
const { result, waitForNextUpdate } = testRenderer.renderHook(() => useOutputOptions()); | ||
expect(result.current.isLoading).toBeTruthy(); | ||
|
||
await waitForNextUpdate(); | ||
expect(result.current.dataOutputOptions).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"inputDisplay": "Default (currently Output 1)", | ||
"value": "@@##DEFAULT_OUTPUT_VALUE##@@", | ||
}, | ||
Object { | ||
"disabled": true, | ||
"inputDisplay": "Output 1", | ||
"value": "output1", | ||
}, | ||
Object { | ||
"disabled": true, | ||
"inputDisplay": "Output 2", | ||
"value": "output2", | ||
}, | ||
Object { | ||
"disabled": true, | ||
"inputDisplay": "Output 3", | ||
"value": "output3", | ||
}, | ||
] | ||
`); | ||
expect(result.current.monitoringOutputOptions).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"inputDisplay": "Default (currently Output 1)", | ||
"value": "@@##DEFAULT_OUTPUT_VALUE##@@", | ||
}, | ||
Object { | ||
"disabled": true, | ||
"inputDisplay": "Output 1", | ||
"value": "output1", | ||
}, | ||
Object { | ||
"disabled": true, | ||
"inputDisplay": "Output 2", | ||
"value": "output2", | ||
}, | ||
Object { | ||
"disabled": true, | ||
"inputDisplay": "Output 3", | ||
"value": "output3", | ||
}, | ||
] | ||
`); | ||
}); | ||
}); |
74 changes: 74 additions & 0 deletions
74
...pplications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/hooks.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { useMemo } from 'react'; | ||
import { i18n } from '@kbn/i18n'; | ||
import type { EuiSuperSelectOption } from '@elastic/eui'; | ||
|
||
import { useGetOutputs, useLicense } from '../../../../hooks'; | ||
import { LICENCE_FOR_PER_POLICY_OUTPUT } from '../../../../../../../common'; | ||
|
||
// The super select component do not support null or '' as a value | ||
export const DEFAULT_OUTPUT_VALUE = '@@##DEFAULT_OUTPUT_VALUE##@@'; | ||
|
||
function getDefaultOutput(defaultOutputName?: string) { | ||
return { | ||
inputDisplay: i18n.translate('xpack.fleet.agentPolicy.outputOptions.defaultOutputText', { | ||
defaultMessage: 'Default (currently {defaultOutputName})', | ||
values: { defaultOutputName }, | ||
}), | ||
value: DEFAULT_OUTPUT_VALUE, | ||
}; | ||
} | ||
|
||
export function useOutputOptions() { | ||
const outputsRequest = useGetOutputs(); | ||
const licenseService = useLicense(); | ||
|
||
const isLicenceAllowingPolicyPerOutput = licenseService.hasAtLeast(LICENCE_FOR_PER_POLICY_OUTPUT); | ||
|
||
const outputOptions: Array<EuiSuperSelectOption<string>> = useMemo(() => { | ||
if (outputsRequest.isLoading || !outputsRequest.data) { | ||
return []; | ||
} | ||
|
||
return outputsRequest.data.items.map((item) => ({ | ||
value: item.id, | ||
inputDisplay: item.name, | ||
disabled: !isLicenceAllowingPolicyPerOutput, | ||
})); | ||
}, [outputsRequest, isLicenceAllowingPolicyPerOutput]); | ||
|
||
const dataOutputOptions = useMemo(() => { | ||
if (outputsRequest.isLoading || !outputsRequest.data) { | ||
return []; | ||
} | ||
|
||
const defaultOutputName = outputsRequest.data.items.find((item) => item.is_default)?.name; | ||
return [getDefaultOutput(defaultOutputName), ...outputOptions]; | ||
}, [outputsRequest, outputOptions]); | ||
|
||
const monitoringOutputOptions = useMemo(() => { | ||
if (outputsRequest.isLoading || !outputsRequest.data) { | ||
return []; | ||
} | ||
|
||
const defaultOutputName = outputsRequest.data.items.find( | ||
(item) => item.is_default_monitoring | ||
)?.name; | ||
return [getDefaultOutput(defaultOutputName), ...outputOptions]; | ||
}, [outputsRequest, outputOptions]); | ||
|
||
return useMemo( | ||
() => ({ | ||
dataOutputOptions, | ||
monitoringOutputOptions, | ||
isLoading: outputsRequest.isLoading, | ||
}), | ||
[dataOutputOptions, monitoringOutputOptions, outputsRequest.isLoading] | ||
); | ||
} |
Oops, something went wrong.