Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UII] Support integration-level outputs #189125

Merged
merged 43 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
f4c1aa7
Update schemas to include `output_id` for package policies
jen-huang Jul 22, 2024
04821c3
Adjust create/edit package policy APIs to allow output_id and gate it…
jen-huang Jul 22, 2024
d11b8d8
Adjust API gating to include check for allowed output type based on t…
jen-huang Jul 22, 2024
06aba09
Compile output permissions correctly
jen-huang Jul 23, 2024
3cf6b71
Fix update handler, add tests
jen-huang Jul 23, 2024
4358b9b
Remove output from package policies when it is deleted
jen-huang Jul 23, 2024
7739f10
Merge remote-tracking branch 'upstream/main' into feat/output-per-int…
jen-huang Jul 23, 2024
a5fbc22
Fix output preconfiguration test mock
jen-huang Jul 23, 2024
bb776fa
Fix truncation and wrapping issues with agent policy name + descripti…
jen-huang Jul 23, 2024
9ce8a8c
Add Output column to integration policies table
jen-huang Jul 23, 2024
ccc4702
Make output_id nullable in api schemas
jen-huang Jul 24, 2024
93bf7e5
Move license const
jen-huang Jul 24, 2024
d071843
Add Output select field to create/edit package policy form
jen-huang Jul 24, 2024
9e2b219
Merge remote-tracking branch 'upstream/main' into feat/output-per-int…
jen-huang Jul 24, 2024
5d15a12
Fix typos, clean up unused agent count code
jen-huang Jul 24, 2024
cca9d2f
Fix agent policy and agent count in edit output confirm modal
jen-huang Jul 24, 2024
e964831
Fix output id not being set on creation w/ non-simplified request
jen-huang Jul 24, 2024
1a43c5c
Fix query for retrieving an output's related agent policies
jen-huang Jul 25, 2024
8c1f570
Fix test failures
jen-huang Jul 26, 2024
fc4ff97
Merge remote-tracking branch 'upstream/main' into feat/output-per-int…
jen-huang Jul 26, 2024
b760c92
Merge remote-tracking branch 'upstream/main' into feat/output-per-int…
jen-huang Jul 30, 2024
2be5ddd
Merge remote-tracking branch 'upstream/main' into feat/output-per-int…
jen-huang Aug 1, 2024
f97e138
Merge remote-tracking branch 'upstream/main' into feat/output-per-int…
jen-huang Aug 5, 2024
5be583a
Fix mocks
jen-huang Aug 6, 2024
700e0b9
Make outputs service search across all spaces when retrieving policy …
jen-huang Aug 6, 2024
a52ed50
Update openapi spec
jen-huang Aug 6, 2024
d0154c3
Merge remote-tracking branch 'upstream/main' into feat/output-per-int…
jen-huang Aug 6, 2024
eef7592
Fix types
jen-huang Aug 6, 2024
7953757
Add new version for package policy SO
jen-huang Aug 6, 2024
7ca5a4f
Return promise in pMap
jen-huang Aug 6, 2024
1cbc17d
[CI] Auto-commit changed files from 'node scripts/check_mappings_upda…
kibanamachine Aug 6, 2024
12023f0
Update SO hash
jen-huang Aug 7, 2024
9019534
Merge remote-tracking branch 'upstream/main' into feat/output-per-int…
jen-huang Aug 7, 2024
43f2eea
Add api integration tests
jen-huang Aug 7, 2024
7d092ba
Merge branch 'main' into feat/output-per-integration
jen-huang Aug 7, 2024
f59c5ca
Fix default output ID
jen-huang Aug 7, 2024
bd713b7
Merge branch 'feat/output-per-integration' of github.com:jen-huang/ki…
jen-huang Aug 7, 2024
476971f
Remove unnecessary cleanup
jen-huang Aug 12, 2024
e2e7a99
Move validation of multiple agent policies and outputs to package pol…
jen-huang Aug 12, 2024
560b078
Move tests
jen-huang Aug 12, 2024
0b0dfa6
Merge remote-tracking branch 'upstream/main' into feat/output-per-int…
jen-huang Aug 12, 2024
0802091
Fix bad merge
jen-huang Aug 12, 2024
617c3d9
Fix types
jen-huang Aug 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@
"is_managed",
"name",
"namespace",
"output_id",
"overrides",
"package",
"package.name",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2097,6 +2097,9 @@
"namespace": {
"type": "keyword"
},
"output_id": {
"type": "keyword"
},
"overrides": {
"index": false,
"type": "flattened"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
"ingest-agent-policies": "90625b4a5ded9d4867358fcccc14a57c0454fcee",
"ingest-download-sources": "279a68147e62e4d8858c09ad1cf03bd5551ce58d",
"ingest-outputs": "daafff49255ab700e07491376fe89f04fc998b91",
"ingest-package-policies": "2c0f7c72d211bb7d3076ce2fc0bd368f9c16d274",
"ingest-package-policies": "53a94064674835fdb35e5186233bcd7052eabd22",
"ingest_manager_settings": "91445219e7115ff0c45d1dabd5d614a80b421797",
"inventory-view": "b8683c8e352a286b4aca1ab21003115a4800af83",
"kql-telemetry": "93c1d16c1a0dfca9c8842062cf5ef8f62ae401ad",
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/fleet/common/constants/mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

/**
* ATTENTION: Mappings for Fleet are defined in the ElasticSearch repo.
* ATTENTION: Mappings for Fleet are defined in the Elasticsearch repo.
*
* The following mappings declared here closely mirror them
* But they are only used to perform validation on the endpoints using ListWithKuery
Expand Down Expand Up @@ -54,6 +54,7 @@ export const PACKAGE_POLICIES_MAPPINGS = {
is_managed: { type: 'boolean' },
policy_id: { type: 'keyword' },
policy_ids: { type: 'keyword' },
output_id: { type: 'keyword' },
package: {
properties: {
name: { type: 'keyword' },
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/fleet/common/constants/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const DEFAULT_OUTPUT: NewOutput = {
export const SERVERLESS_DEFAULT_OUTPUT_ID = 'es-default-output';

export const LICENCE_FOR_PER_POLICY_OUTPUT = 'platinum';
export const LICENCE_FOR_OUTPUT_PER_INTEGRATION = 'enterprise';
jen-huang marked this conversation as resolved.
Show resolved Hide resolved

/**
* Kafka constants
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/fleet/common/constants/package_policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ export const inputsFormat = {
Simplified: 'simplified',
Legacy: 'legacy',
} as const;

export const LICENCE_FOR_MULTIPLE_AGENT_POLICIES = 'enterprise';
3 changes: 1 addition & 2 deletions x-pack/plugins/fleet/common/openapi/bundled.json
Original file line number Diff line number Diff line change
Expand Up @@ -7484,8 +7484,7 @@
"type": "string"
},
"output_id": {
"type": "string",
"deprecated": true
"type": "string"
},
"inputs": {
"type": "array",
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/fleet/common/openapi/bundled.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4804,7 +4804,6 @@ components:
type: string
output_id:
type: string
deprecated: true
inputs:
type: array
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ properties:
type: string
output_id:
type: string
deprecated: true
inputs:
type: array
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ properties:
type: string
output_id:
type: string
description: Not supported output can be set at the agent policy level only
deprecated: true
inputs:
type: array
items:
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ describe('toPackagePolicy', () => {
namespace: 'default',
policy_id: 'policy123',
policy_ids: ['policy123'],
output_id: 'output123',
description: 'Test description',
inputs: {
'nginx-logfile': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export interface SimplifiedPackagePolicy {
id?: string;
policy_id?: string;
policy_ids: string[];
output_id?: string;
namespace: string;
name: string;
description?: string;
Expand Down Expand Up @@ -147,6 +148,7 @@ export function simplifiedPackagePolicytoNewPackagePolicy(
const {
policy_id: policyId,
policy_ids: policyIds,
output_id: outputId,
namespace,
name,
description,
Expand All @@ -161,6 +163,10 @@ export function simplifiedPackagePolicytoNewPackagePolicy(
description
);

if (outputId) {
packagePolicy.output_id = outputId;
}

if (packagePolicy.package && options?.experimental_data_stream_features) {
packagePolicy.package.experimental_data_stream_features =
options.experimental_data_stream_features;
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/fleet/common/types/models/package_policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ export interface NewPackagePolicy {
/** @deprecated */
policy_id?: string;
policy_ids: string[];
// Nullable to allow user to reset to default outputs
output_id?: string | null;
package?: PackagePolicyPackage;
inputs: NewPackagePolicyInput[];
vars?: PackagePolicyConfigRecord;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export type PostDeletePackagePoliciesResponse = Array<{
package?: PackagePolicyPackage;
policy_id?: string;
policy_ids?: string[];
output_id?: string;
// Support generic errors
statusCode?: number;
body?: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import { useMemo } from 'react';
import { useHistory } from 'react-router-dom';

import { LICENCE_FOR_OUTPUT_PER_INTEGRATION } from '../../../../../../../../../common/constants';
import { getAllowedOutputTypesForIntegration } from '../../../../../../../../../common/services/output_helpers';
import { useGetOutputs, useLicense } from '../../../../../../hooks';

export function useDataStreamId() {
const history = useHistory();

Expand All @@ -16,3 +20,21 @@ export function useDataStreamId() {
return searchParams.get('datastreamId') ?? undefined;
}, [history.location.search]);
}

export function useOutputs(packageName: string) {
const licenseService = useLicense();
const canUseOutputPerIntegration = licenseService.hasAtLeast(LICENCE_FOR_OUTPUT_PER_INTEGRATION);
const { data: outputsData, isLoading } = useGetOutputs();
const allowedOutputTypes = getAllowedOutputTypesForIntegration(packageName);
const allowedOutputs = useMemo(() => {
if (!outputsData || !canUseOutputPerIntegration) {
return [];
}
return outputsData.items.filter((output) => allowedOutputTypes.includes(output.type));
}, [allowedOutputTypes, canUseOutputPerIntegration, outputsData]);
return {
isLoading,
canUseOutputPerIntegration,
allowedOutputs,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
EuiLink,
EuiCallOut,
EuiSpacer,
EuiSelect,
} from '@elastic/eui';

import styled from 'styled-components';
Expand All @@ -32,6 +33,7 @@ import { isAdvancedVar } from '../../services';
import type { PackagePolicyValidationResults } from '../../services';

import { PackagePolicyInputVarField } from './components';
import { useOutputs } from './components/hooks';

// on smaller screens, fields should be displayed in one column
const FormGroupResponsiveFields = styled(EuiDescribedFormGroup)`
Expand Down Expand Up @@ -81,6 +83,14 @@ export const StepDefinePackagePolicy: React.FunctionComponent<{
});
}

// Outputs
const {
isLoading: isOutputsLoading,
canUseOutputPerIntegration,
allowedOutputs,
} = useOutputs(packageInfo.name);

// Managed policy
const isManaged = packagePolicy.is_managed;

return validationResults ? (
Expand Down Expand Up @@ -245,6 +255,7 @@ export const StepDefinePackagePolicy: React.FunctionComponent<{
{isShowingAdvanced ? (
<EuiFlexItem>
<EuiFlexGroup direction="column" gutterSize="m">
{/* Namespace */}
<EuiFlexItem>
<EuiFormRow
isInvalid={!!validationResults.namespace}
Expand All @@ -264,7 +275,7 @@ export const StepDefinePackagePolicy: React.FunctionComponent<{
) : (
<FormattedMessage
id="xpack.fleet.createPackagePolicy.stepConfigure.packagePolicyNamespaceHelpLabel"
defaultMessage="Change the default namespace inherited from the selected Agent policy. This setting changes the name of the integration's data stream. {learnMore}."
defaultMessage="Change the default namespace inherited from the parent agent policy. This setting changes the name of the integration's data stream. {learnMore}."
values={{
learnMore: (
<EuiLink
Expand Down Expand Up @@ -304,6 +315,49 @@ export const StepDefinePackagePolicy: React.FunctionComponent<{
/>
</EuiFormRow>
</EuiFlexItem>

{/* Output */}
{canUseOutputPerIntegration && (
<EuiFlexItem>
<EuiFormRow
label={
<FormattedMessage
id="xpack.fleet.createPackagePolicy.stepConfigure.packagePolicyOutputInputLabel"
defaultMessage="Output"
/>
}
helpText={
<FormattedMessage
id="xpack.fleet.createPackagePolicy.stepConfigure.packagePolicyOutputHelpLabel"
defaultMessage="Change the default output inherited from the parent agent policy. This setting changes where the integration's data is sent."
/>
}
>
<EuiSelect
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use a super select like we do for the agent policy output selector? the default value looks more explicit to me
Currently
Screenshot 2024-08-12 at 10 13 11 AM
Agent policy output selector
Screenshot 2024-08-12 at 10 13 30 AM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can address this in a follow up PR

data-test-subj="packagePolicyOutputInput"
isLoading={isOutputsLoading}
options={[
{
value: '',
text: '',
},
...allowedOutputs.map((output) => ({
value: output.id,
text: output.name,
})),
]}
value={packagePolicy.output_id || ''}
onChange={(e) => {
updatePackagePolicy({
output_id: e.target.value.trim() || null,
});
}}
/>
</EuiFormRow>
</EuiFlexItem>
)}

{/* Data retention settings info */}
<EuiFlexItem>
<EuiFormRow
label={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import {
usePermissionCheck,
useStartServices,
useMultipleAgentPolicies,
useGetOutputs,
useDefaultOutput,
} from '../../../../../hooks';
import { pkgKeyFromPackageInfo } from '../../../../../services';

Expand Down Expand Up @@ -106,6 +108,16 @@ export const PackagePoliciesTable: React.FunctionComponent<Props> = ({
return packagePolicy.policy_ids.length || 0;
}, []);

const { data: outputsData, isLoading: isOutputsLoading } = useGetOutputs();
const { output: defaultOutputData } = useDefaultOutput();
const outputNamesById = useMemo(() => {
const outputs = outputsData?.items ?? [];
return outputs.reduce<Record<string, string>>((acc, output) => {
acc[output.id] = output.name;
return acc;
}, {});
}, [outputsData]);

const columns = useMemo(
(): EuiInMemoryTableProps<InMemoryPackagePolicy>['columns'] => [
{
Expand All @@ -115,6 +127,7 @@ export const PackagePoliciesTable: React.FunctionComponent<Props> = ({
name: i18n.translate('xpack.fleet.policyDetails.packagePoliciesTable.nameColumnTitle', {
defaultMessage: 'Integration policy',
}),
width: '35%',
render: (value: string, packagePolicy: InMemoryPackagePolicy) => (
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexItem data-test-subj="PackagePoliciesTableName" grow={false}>
Expand Down Expand Up @@ -278,10 +291,67 @@ export const PackagePoliciesTable: React.FunctionComponent<Props> = ({
);
},
},
{
field: 'output_id',
name: i18n.translate('xpack.fleet.policyDetails.packagePoliciesTable.outputColumnTitle', {
defaultMessage: 'Output',
}),
render: (outputId: InMemoryPackagePolicy['output_id']) => {
if (isOutputsLoading) {
return null;
}
if (outputId) {
return <EuiBadge color="hollow">{outputNamesById[outputId] || outputId}</EuiBadge>;
}
if (agentPolicy.data_output_id) {
return (
<>
<EuiBadge color="default">
{outputNamesById[agentPolicy.data_output_id] || agentPolicy.data_output_id}
</EuiBadge>
&nbsp;
<EuiIconTip
content={i18n.translate(
'xpack.fleet.policyDetails.packagePoliciesTable.outputFromParentPolicyText',
{
defaultMessage: 'Output defined in parent agent policy',
}
)}
position="right"
type="iInCircle"
color="subdued"
/>
</>
);
}
if (defaultOutputData) {
return (
<>
<EuiBadge color="default">
{outputNamesById[defaultOutputData.id] || defaultOutputData.id}
</EuiBadge>
&nbsp;
<EuiIconTip
content={i18n.translate(
'xpack.fleet.policyDetails.packagePoliciesTable.outputFromFleetSettingsText',
{
defaultMessage: 'Output defined in Fleet settings',
}
)}
position="right"
type="iInCircle"
color="subdued"
/>
</>
);
}
},
},
{
name: i18n.translate('xpack.fleet.policyDetails.packagePoliciesTable.actionsColumnTitle', {
defaultMessage: 'Actions',
}),
width: '70px',
actions: [
{
render: (packagePolicy: InMemoryPackagePolicy) => {
Expand Down Expand Up @@ -309,8 +379,11 @@ export const PackagePoliciesTable: React.FunctionComponent<Props> = ({
agentPolicy,
canUseMultipleAgentPolicies,
canReadAgentPolicies,
canWriteIntegrationPolicies,
getSharedPoliciesNumber,
canWriteIntegrationPolicies,
isOutputsLoading,
defaultOutputData,
outputNamesById,
]
);

Expand Down
Loading
Loading