mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Fleet] Disallow some egress-specific inputs for agentless integrations (#206074)
Closes https://github.com/elastic/kibana/issues/202091 ## Summary Disallow some egress-specific inputs for agentless integrations. - In the policy editor, when Setup technology dropdown is set to Agentless, hide the rendering of configuration for inputs that have type matching the blocklist and ensure that these inputs are set to `enabled: false` - `tcp, udp, winlog, http_endpoint, filestream` should be disabled when `supports_agentless: true` - At the API level, throw an error if attempting to enable a disallowed input type ### Testing Simulate agentless env with following setup in `kibana.dev.yml`: ``` xpack.cloud.id: 'anything-to-pass-cloud-validation-checks' xpack.fleet.agentless.enabled: true xpack.fleet.agentless.api.url: 'https://localhost:8443' xpack.fleet.agentless.api.tls.certificate: './config/certs/ess-client.crt' xpack.fleet.agentless.api.tls.key: './config/certs/ess-client.key' xpack.fleet.agentless.api.tls.ca: './config/certs/ca.crt' ``` -Apply [this patch](https://gist.github.com/jen-huang/dfc3e02ceb63976ad54bd1f50c524cb4) to prevent attempt to create agentless pod (the agentless policy creation fails without the patch) - Install the following test integration, that has a bunch of different inputs to simulate this specific case and is enabled for agentless (it shows the setup technology as well) [agentless_package_links-0.0.2.zip](https://github.com/user-attachments/files/18425895/agentless_package_links-0.0.2.zip) ``` curl -XPOST -H 'content-type: application/zip' -H 'kbn-xsrf: true' http://localhost:5601/YOUR_PATH/api/fleet/epm/packages -u elastic:changeme --data-binary @agentless_package_links-0.0.2.zip ``` - Navigate to the integrations page, find the above integration and test that switching between agent-based/agentless the enabled inputs change as follows: <img width="1288" alt="Screenshot 2025-01-15 at 15 30 28" src="https://github.com/user-attachments/assets/6abd45d7-1bd8-465a-af29-4c34940b32e3" /> <img width="1072" alt="Screenshot 2025-01-15 at 15 31 18" src="https://github.com/user-attachments/assets/6957562f-08a6-403a-8725-1a654e443537" /> - Verify that the preview flyout has the correct inputs based on the selected deployment mode <img width="863" alt="Screenshot 2025-01-15 at 15 32 19" src="https://github.com/user-attachments/assets/ceca1f5d-249c-4ee1-9295-6f01ae21fdb4" /> <img width="862" alt="Screenshot 2025-01-15 at 15 33 33" src="https://github.com/user-attachments/assets/f43562d7-633e-4f0a-bfc1-19e89aef7659" /> - Verify that the api throws an error when attempting to enable any of the disallowed types <img width="1774" alt="Screenshot 2025-01-15 at 15 36 03" src="https://github.com/user-attachments/assets/2b4d24a3-5adc-4ab2-bbad-83b44d348763" /> ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
d8e5cbf67f
commit
59e81ee2be
13 changed files with 293 additions and 68 deletions
|
@ -12,3 +12,6 @@ export const AGENTLESS_AGENT_POLICY_MONITORING: MonitoringType = ['logs', 'metri
|
|||
export const AGENTLESS_GLOBAL_TAG_NAME_ORGANIZATION = 'organization';
|
||||
export const AGENTLESS_GLOBAL_TAG_NAME_DIVISION = 'division';
|
||||
export const AGENTLESS_GLOBAL_TAG_NAME_TEAM = 'team';
|
||||
|
||||
// Input types to disable for agentless integrations
|
||||
export const AGENTLESS_DISABLED_INPUTS = ['tcp', 'udp', 'filestream', 'http_endpoint', 'winlog'];
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { PackageInfo, RegistryPolicyTemplate } from '../types';
|
||||
import { AGENTLESS_DISABLED_INPUTS } from '../constants';
|
||||
import { PackagePolicyValidationError } from '../errors';
|
||||
import type { NewPackagePolicyInput, PackageInfo, RegistryPolicyTemplate } from '../types';
|
||||
|
||||
import type { SimplifiedInputs } from './simplified_package_policy_helper';
|
||||
|
||||
export const isAgentlessIntegration = (
|
||||
packageInfo: Pick<PackageInfo, 'policy_templates'> | undefined
|
||||
|
@ -49,3 +53,45 @@ export const isOnlyAgentlessPolicyTemplate = (policyTemplate: RegistryPolicyTemp
|
|||
policyTemplate.deployment_modes.default.enabled === false)
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
* Check if the package policy inputs is not allowed in agentless
|
||||
*/
|
||||
export function inputNotAllowedInAgentless(inputType: string, supportsAgentless?: boolean | null) {
|
||||
return supportsAgentless === true && AGENTLESS_DISABLED_INPUTS.includes(inputType);
|
||||
}
|
||||
|
||||
/*
|
||||
* Throw error if trying to enabling an input that is not allowed in agentless
|
||||
*/
|
||||
export function validateAgentlessInputs(
|
||||
packagePolicyInputs: NewPackagePolicyInput[] | SimplifiedInputs,
|
||||
supportsAgentless?: boolean | null
|
||||
) {
|
||||
if (Array.isArray(packagePolicyInputs)) {
|
||||
return packagePolicyInputs.forEach((input) => {
|
||||
throwIfInputNotAllowed(input.type, input.enabled, supportsAgentless);
|
||||
});
|
||||
} else {
|
||||
Object.keys(packagePolicyInputs).forEach((inputName) => {
|
||||
const input = packagePolicyInputs[inputName];
|
||||
const match = inputName.match(/\-(\w*)$/);
|
||||
const inputType = match && match.length > 0 ? match[1] : '';
|
||||
throwIfInputNotAllowed(inputType, input?.enabled ?? false, supportsAgentless);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function throwIfInputNotAllowed(
|
||||
inputType: string,
|
||||
inputEnabled: boolean,
|
||||
supportsAgentless?: boolean | null
|
||||
) {
|
||||
if (inputNotAllowedInAgentless(inputType, supportsAgentless) && inputEnabled === true) {
|
||||
throw new PackagePolicyValidationError(
|
||||
`Input ${inputType} is not allowed: types '${AGENTLESS_DISABLED_INPUTS.map(
|
||||
(name) => name
|
||||
).join(', ')}' cannot be enabled for an Agentless integration`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,11 @@ import type {
|
|||
PackageInfo,
|
||||
ExperimentalDataStreamFeature,
|
||||
} from '../types';
|
||||
import { DATASET_VAR_NAME } from '../constants';
|
||||
import { AGENTLESS_DISABLED_INPUTS, DATASET_VAR_NAME } from '../constants';
|
||||
import { PackagePolicyValidationError } from '../errors';
|
||||
|
||||
import { packageToPackagePolicy } from '.';
|
||||
import { inputNotAllowedInAgentless } from './agentless_policy_helper';
|
||||
|
||||
export type SimplifiedVars = Record<string, string | string[] | boolean | number | number[] | null>;
|
||||
|
||||
|
@ -75,14 +76,18 @@ export function generateInputId(input: NewPackagePolicyInput) {
|
|||
return `${input.policy_template ? `${input.policy_template}-` : ''}${input.type}`;
|
||||
}
|
||||
|
||||
export function formatInputs(inputs: NewPackagePolicy['inputs']) {
|
||||
export function formatInputs(inputs: NewPackagePolicy['inputs'], supportsAgentless?: boolean) {
|
||||
return inputs.reduce((acc, input) => {
|
||||
const inputId = generateInputId(input);
|
||||
if (!acc) {
|
||||
acc = {};
|
||||
}
|
||||
const enabled =
|
||||
supportsAgentless === true && AGENTLESS_DISABLED_INPUTS.includes(input.type)
|
||||
? false
|
||||
: input.enabled;
|
||||
acc[inputId] = {
|
||||
enabled: input.enabled,
|
||||
enabled,
|
||||
vars: formatVars(input.vars),
|
||||
streams: formatStreams(input.streams),
|
||||
};
|
||||
|
@ -196,7 +201,10 @@ export function simplifiedPackagePolicytoNewPackagePolicy(
|
|||
throw new PackagePolicyValidationError(`Input not found: ${inputId}`);
|
||||
}
|
||||
|
||||
if (enabled === false) {
|
||||
if (
|
||||
inputNotAllowedInAgentless(packagePolicyInput.type, packagePolicy?.supports_agentless) ||
|
||||
enabled === false
|
||||
) {
|
||||
packagePolicyInput.enabled = false;
|
||||
} else {
|
||||
packagePolicyInput.enabled = true;
|
||||
|
@ -213,7 +221,10 @@ export function simplifiedPackagePolicytoNewPackagePolicy(
|
|||
throw new PackagePolicyValidationError(`Stream not found ${inputId}: ${streamId}`);
|
||||
}
|
||||
|
||||
if (streamEnabled === false) {
|
||||
if (
|
||||
streamEnabled === false ||
|
||||
inputNotAllowedInAgentless(packagePolicyInput.type, packagePolicy?.supports_agentless)
|
||||
) {
|
||||
packagePolicyStream.enabled = false;
|
||||
} else {
|
||||
packagePolicyStream.enabled = true;
|
||||
|
|
|
@ -27,6 +27,8 @@ import { doesPackageHaveIntegrations } from '../../../../../services';
|
|||
|
||||
import type { PackagePolicyValidationResults } from '../../services';
|
||||
|
||||
import { AGENTLESS_DISABLED_INPUTS } from '../../../../../../../../common/constants';
|
||||
|
||||
import { PackagePolicyInputPanel } from './components';
|
||||
|
||||
export const StepConfigurePackagePolicy: React.FunctionComponent<{
|
||||
|
@ -38,6 +40,7 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{
|
|||
submitAttempted: boolean;
|
||||
noTopRule?: boolean;
|
||||
isEditPage?: boolean;
|
||||
isAgentlessSelected?: boolean;
|
||||
}> = ({
|
||||
packageInfo,
|
||||
showOnlyIntegration,
|
||||
|
@ -47,6 +50,7 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{
|
|||
submitAttempted,
|
||||
noTopRule = false,
|
||||
isEditPage = false,
|
||||
isAgentlessSelected = false,
|
||||
}) => {
|
||||
const hasIntegrations = useMemo(() => doesPackageHaveIntegrations(packageInfo), [packageInfo]);
|
||||
const packagePolicyTemplates = useMemo(
|
||||
|
@ -66,8 +70,9 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{
|
|||
<EuiFlexGroup direction="column" gutterSize="none">
|
||||
{packagePolicyTemplates.map((policyTemplate) => {
|
||||
const inputs = getNormalizedInputs(policyTemplate);
|
||||
const packagePolicyInputs = packagePolicy.inputs;
|
||||
return inputs.map((packageInput) => {
|
||||
const packagePolicyInput = packagePolicy.inputs.find(
|
||||
const packagePolicyInput = packagePolicyInputs.find(
|
||||
(input) =>
|
||||
input.type === packageInput.type &&
|
||||
(hasIntegrations ? input.policy_template === policyTemplate.name : true)
|
||||
|
@ -79,28 +84,35 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{
|
|||
? policyTemplate.data_streams
|
||||
: []
|
||||
);
|
||||
return packagePolicyInput ? (
|
||||
|
||||
const updatePackagePolicyInput = (updatedInput: Partial<NewPackagePolicyInput>) => {
|
||||
const indexOfUpdatedInput = packagePolicyInputs.findIndex(
|
||||
(input) =>
|
||||
input.type === packageInput.type &&
|
||||
(hasIntegrations ? input.policy_template === policyTemplate.name : true)
|
||||
);
|
||||
const newInputs = [...packagePolicyInputs];
|
||||
newInputs[indexOfUpdatedInput] = {
|
||||
...newInputs[indexOfUpdatedInput],
|
||||
...updatedInput,
|
||||
};
|
||||
updatePackagePolicy({
|
||||
inputs: newInputs,
|
||||
});
|
||||
};
|
||||
|
||||
return packagePolicyInput &&
|
||||
!(
|
||||
(isAgentlessSelected || packagePolicy.supports_agentless === true) &&
|
||||
AGENTLESS_DISABLED_INPUTS.includes(packagePolicyInput.type)
|
||||
) ? (
|
||||
<EuiFlexItem key={packageInput.type}>
|
||||
<PackagePolicyInputPanel
|
||||
packageInput={packageInput}
|
||||
packageInfo={packageInfo}
|
||||
packageInputStreams={packageInputStreams}
|
||||
packagePolicyInput={packagePolicyInput}
|
||||
updatePackagePolicyInput={(updatedInput: Partial<NewPackagePolicyInput>) => {
|
||||
const indexOfUpdatedInput = packagePolicy.inputs.findIndex(
|
||||
(input) =>
|
||||
input.type === packageInput.type &&
|
||||
(hasIntegrations ? input.policy_template === policyTemplate.name : true)
|
||||
);
|
||||
const newInputs = [...packagePolicy.inputs];
|
||||
newInputs[indexOfUpdatedInput] = {
|
||||
...newInputs[indexOfUpdatedInput],
|
||||
...updatedInput,
|
||||
};
|
||||
updatePackagePolicy({
|
||||
inputs: newInputs,
|
||||
});
|
||||
}}
|
||||
updatePackagePolicyInput={updatePackagePolicyInput}
|
||||
inputValidationResults={
|
||||
validationResults?.inputs?.[
|
||||
hasIntegrations
|
||||
|
|
|
@ -84,6 +84,8 @@ describe('useOnSubmit', () => {
|
|||
newAgentPolicy: { name: 'test', namespace: '' },
|
||||
queryParamsPolicyId: undefined,
|
||||
hasFleetAddAgentsPrivileges: true,
|
||||
setNewAgentPolicy: jest.fn(),
|
||||
setSelectedPolicyTab: jest.fn(),
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
@ -5,20 +5,21 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { load } from 'js-yaml';
|
||||
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import { useSpaceSettingsContext } from '../../../../../../../hooks/use_space_settings_context';
|
||||
import type {
|
||||
AgentPolicy,
|
||||
NewPackagePolicy,
|
||||
NewAgentPolicy,
|
||||
CreatePackagePolicyRequest,
|
||||
PackagePolicy,
|
||||
PackageInfo,
|
||||
import {
|
||||
type AgentPolicy,
|
||||
type NewPackagePolicy,
|
||||
type NewAgentPolicy,
|
||||
type CreatePackagePolicyRequest,
|
||||
type PackagePolicy,
|
||||
type PackageInfo,
|
||||
SetupTechnology,
|
||||
} from '../../../../../types';
|
||||
import {
|
||||
useStartServices,
|
||||
|
@ -49,7 +50,9 @@ import {
|
|||
getCloudShellUrlFromPackagePolicy,
|
||||
} from '../../../../../../../components/cloud_security_posture/services';
|
||||
|
||||
import { useAgentless } from './setup_technology';
|
||||
import { AGENTLESS_DISABLED_INPUTS } from '../../../../../../../../common/constants';
|
||||
|
||||
import { useAgentless, useSetupTechnology } from './setup_technology';
|
||||
|
||||
export async function createAgentPolicy({
|
||||
packagePolicy,
|
||||
|
@ -142,6 +145,8 @@ export function useOnSubmit({
|
|||
packageInfo,
|
||||
integrationToEnable,
|
||||
hasFleetAddAgentsPrivileges,
|
||||
setNewAgentPolicy,
|
||||
setSelectedPolicyTab,
|
||||
}: {
|
||||
packageInfo?: PackageInfo;
|
||||
newAgentPolicy: NewAgentPolicy;
|
||||
|
@ -151,6 +156,8 @@ export function useOnSubmit({
|
|||
queryParamsPolicyId: string | undefined;
|
||||
integrationToEnable?: string;
|
||||
hasFleetAddAgentsPrivileges: boolean;
|
||||
setNewAgentPolicy: (policy: NewAgentPolicy) => void;
|
||||
setSelectedPolicyTab: (tab: SelectedPolicyTab) => void;
|
||||
}) {
|
||||
const { notifications } = useStartServices();
|
||||
const confirmForceInstall = useConfirmForceInstall();
|
||||
|
@ -167,6 +174,11 @@ export function useOnSubmit({
|
|||
// Used to initialize the package policy once
|
||||
const isInitializedRef = useRef(false);
|
||||
|
||||
// only used to save the initial value of the package policy
|
||||
const [initialPackagePolicy, setInitialPackagePolicy] = useState<NewPackagePolicy>({
|
||||
...DEFAULT_PACKAGE_POLICY,
|
||||
});
|
||||
|
||||
const [agentPolicies, setAgentPolicies] = useState<AgentPolicy[]>([]);
|
||||
// New package policy state
|
||||
const [packagePolicy, setPackagePolicy] = useState<NewPackagePolicy>({
|
||||
|
@ -255,20 +267,27 @@ export function useOnSubmit({
|
|||
const incrementedName = getMaxPackageName(packageInfo.name, packagePolicyData?.items);
|
||||
|
||||
isInitializedRef.current = true;
|
||||
updatePackagePolicy(
|
||||
packageToPackagePolicy(
|
||||
packageInfo,
|
||||
agentPolicies.map((policy) => policy.id),
|
||||
'',
|
||||
DEFAULT_PACKAGE_POLICY.name || incrementedName,
|
||||
DEFAULT_PACKAGE_POLICY.description,
|
||||
integrationToEnable
|
||||
)
|
||||
const basePackagePolicy = packageToPackagePolicy(
|
||||
packageInfo,
|
||||
agentPolicies.map((policy) => policy.id),
|
||||
'',
|
||||
DEFAULT_PACKAGE_POLICY.name || incrementedName,
|
||||
DEFAULT_PACKAGE_POLICY.description,
|
||||
integrationToEnable
|
||||
);
|
||||
setInitialPackagePolicy(basePackagePolicy);
|
||||
updatePackagePolicy(basePackagePolicy);
|
||||
setIsInitialized(true);
|
||||
}
|
||||
init();
|
||||
}, [packageInfo, agentPolicies, updatePackagePolicy, integrationToEnable, isInitialized]);
|
||||
}, [
|
||||
packageInfo,
|
||||
agentPolicies,
|
||||
updatePackagePolicy,
|
||||
integrationToEnable,
|
||||
isInitialized,
|
||||
initialPackagePolicy,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
|
@ -284,6 +303,42 @@ export function useOnSubmit({
|
|||
}
|
||||
}, [packagePolicy, agentPolicies, updatePackagePolicy, canUseMultipleAgentPolicies]);
|
||||
|
||||
const { handleSetupTechnologyChange, selectedSetupTechnology, defaultSetupTechnology } =
|
||||
useSetupTechnology({
|
||||
newAgentPolicy,
|
||||
setNewAgentPolicy,
|
||||
updateAgentPolicies,
|
||||
updatePackagePolicy,
|
||||
setSelectedPolicyTab,
|
||||
packageInfo,
|
||||
packagePolicy,
|
||||
});
|
||||
const setupTechnologyRef = useRef<SetupTechnology | undefined>(selectedSetupTechnology);
|
||||
// sync the inputs with the agentless selector change
|
||||
useEffect(() => {
|
||||
setupTechnologyRef.current = selectedSetupTechnology;
|
||||
});
|
||||
const prevSetupTechnology = setupTechnologyRef.current;
|
||||
const isAgentlessSelected =
|
||||
isAgentlessIntegration(packageInfo) && selectedSetupTechnology === SetupTechnology.AGENTLESS;
|
||||
|
||||
const newInputs = useMemo(() => {
|
||||
return packagePolicy.inputs.map((input, i) => {
|
||||
if (isAgentlessSelected && AGENTLESS_DISABLED_INPUTS.includes(input.type)) {
|
||||
return { ...input, enabled: false };
|
||||
}
|
||||
return initialPackagePolicy.inputs[i];
|
||||
});
|
||||
}, [initialPackagePolicy?.inputs, isAgentlessSelected, packagePolicy.inputs]);
|
||||
|
||||
useEffect(() => {
|
||||
if (prevSetupTechnology !== selectedSetupTechnology) {
|
||||
updatePackagePolicy({
|
||||
inputs: newInputs,
|
||||
});
|
||||
}
|
||||
}, [newInputs, prevSetupTechnology, selectedSetupTechnology, updatePackagePolicy, packagePolicy]);
|
||||
|
||||
const onSaveNavigate = useOnSaveNavigate({
|
||||
packagePolicy,
|
||||
queryParamsPolicyId,
|
||||
|
@ -495,5 +550,9 @@ export function useOnSubmit({
|
|||
// TODO check
|
||||
navigateAddAgent,
|
||||
navigateAddAgentHelp,
|
||||
handleSetupTechnologyChange,
|
||||
selectedSetupTechnology,
|
||||
defaultSetupTechnology,
|
||||
isAgentlessSelected,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -77,13 +77,13 @@ import { generateNewAgentPolicyWithDefaults } from '../../../../../../../common/
|
|||
import { packageHasAtLeastOneSecret } from '../utils';
|
||||
|
||||
import { CreatePackagePolicySinglePageLayout, PostInstallAddAgentModal } from './components';
|
||||
import { useDevToolsRequest, useOnSubmit, useSetupTechnology } from './hooks';
|
||||
import { useDevToolsRequest, useOnSubmit } from './hooks';
|
||||
import { PostInstallCloudFormationModal } from './components/cloud_security_posture/post_install_cloud_formation_modal';
|
||||
import { PostInstallGoogleCloudShellModal } from './components/cloud_security_posture/post_install_google_cloud_shell_modal';
|
||||
import { PostInstallAzureArmTemplateModal } from './components/cloud_security_posture/post_install_azure_arm_template_modal';
|
||||
import { RootPrivilegesCallout } from './root_callout';
|
||||
import { useAgentless } from './hooks/setup_technology';
|
||||
import { SetupTechnologySelector } from './components/setup_technology_selector';
|
||||
import { useAgentless } from './hooks/setup_technology';
|
||||
|
||||
export const StepsWithLessPadding = styled(EuiSteps)`
|
||||
.euiStep__content {
|
||||
|
@ -176,6 +176,10 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
|||
validationResults,
|
||||
hasAgentPolicyError,
|
||||
isInitialized,
|
||||
handleSetupTechnologyChange,
|
||||
selectedSetupTechnology,
|
||||
defaultSetupTechnology,
|
||||
isAgentlessSelected,
|
||||
} = useOnSubmit({
|
||||
agentCount,
|
||||
packageInfo,
|
||||
|
@ -185,6 +189,8 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
|||
queryParamsPolicyId,
|
||||
integrationToEnable: integrationInfo?.name,
|
||||
hasFleetAddAgentsPrivileges,
|
||||
setNewAgentPolicy,
|
||||
setSelectedPolicyTab,
|
||||
});
|
||||
|
||||
const setPolicyValidation = useCallback(
|
||||
|
@ -341,7 +347,7 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
|||
() =>
|
||||
pliAuthBlockView?.Component && !isPackageInfoLoading
|
||||
? pliAuthBlockView.Component
|
||||
: ({ children }) => <>{children}</>, // when no UI Extension is registered, render children
|
||||
: ({ children }: { children?: React.ReactNode }) => <>{children}</>, // when no UI Extension is registered, render children
|
||||
[isPackageInfoLoading, pliAuthBlockView?.Component]
|
||||
);
|
||||
|
||||
|
@ -351,16 +357,6 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
|||
);
|
||||
}
|
||||
const { isAgentlessIntegration } = useAgentless();
|
||||
const { handleSetupTechnologyChange, selectedSetupTechnology, defaultSetupTechnology } =
|
||||
useSetupTechnology({
|
||||
newAgentPolicy,
|
||||
setNewAgentPolicy,
|
||||
updateAgentPolicies,
|
||||
updatePackagePolicy,
|
||||
setSelectedPolicyTab,
|
||||
packageInfo,
|
||||
packagePolicy,
|
||||
});
|
||||
|
||||
const replaceStepConfigurePackagePolicy =
|
||||
replaceDefineStepView && packageInfo?.name ? (
|
||||
|
@ -423,6 +419,7 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
|||
updatePackagePolicy={updatePackagePolicy}
|
||||
validationResults={validationResults}
|
||||
submitAttempted={formState === 'INVALID'}
|
||||
isAgentlessSelected={isAgentlessSelected}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
@ -440,21 +437,22 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
|||
<div />
|
||||
),
|
||||
[
|
||||
isInitialized,
|
||||
isPackageInfoLoading,
|
||||
agentPolicies,
|
||||
isInitialized,
|
||||
packageInfo,
|
||||
agentPolicies,
|
||||
spaceSettings?.allowedNamespacePrefixes,
|
||||
packagePolicy,
|
||||
updatePackagePolicy,
|
||||
validationResults,
|
||||
formState,
|
||||
integrationInfo?.name,
|
||||
extensionView,
|
||||
handleExtensionViewOnChange,
|
||||
spaceSettings?.allowedNamespacePrefixes,
|
||||
handleSetupTechnologyChange,
|
||||
isAgentlessIntegration,
|
||||
selectedSetupTechnology,
|
||||
integrationInfo?.name,
|
||||
isAgentlessSelected,
|
||||
handleExtensionViewOnChange,
|
||||
handleSetupTechnologyChange,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ export function generateUpdatePackagePolicyDevToolsRequest(
|
|||
{
|
||||
package: formatPackage(packagePolicy.package),
|
||||
...omit(packagePolicy, 'version', 'package', 'enabled', 'secret_references'),
|
||||
inputs: formatInputs(packagePolicy.inputs),
|
||||
inputs: formatInputs(packagePolicy.inputs, packagePolicy?.supports_agentless ?? false),
|
||||
vars: formatVars(packagePolicy.vars),
|
||||
}
|
||||
);
|
||||
|
|
|
@ -56,7 +56,12 @@ import {
|
|||
packagePolicyToSimplifiedPackagePolicy,
|
||||
} from '../../../common/services/simplified_package_policy_helper';
|
||||
|
||||
import type { SimplifiedPackagePolicy } from '../../../common/services/simplified_package_policy_helper';
|
||||
import type {
|
||||
SimplifiedInputs,
|
||||
SimplifiedPackagePolicy,
|
||||
} from '../../../common/services/simplified_package_policy_helper';
|
||||
|
||||
import { validateAgentlessInputs } from '../../../common/services/agentless_policy_helper';
|
||||
|
||||
import {
|
||||
isSimplifiedCreatePackagePolicyRequest,
|
||||
|
@ -339,6 +344,7 @@ export const updatePackagePolicyHandler: FleetRequestHandler<
|
|||
}
|
||||
|
||||
try {
|
||||
// simplified request
|
||||
const { force, package: pkg, ...body } = request.body;
|
||||
let newData: NewPackagePolicy;
|
||||
|
||||
|
@ -354,12 +360,18 @@ export const updatePackagePolicyHandler: FleetRequestHandler<
|
|||
pkgName: pkg.name,
|
||||
pkgVersion: pkg.version,
|
||||
});
|
||||
|
||||
newData = simplifiedPackagePolicytoNewPackagePolicy(
|
||||
body as unknown as SimplifiedPackagePolicy,
|
||||
pkgInfo,
|
||||
{ experimental_data_stream_features: pkg.experimental_data_stream_features }
|
||||
);
|
||||
validateAgentlessInputs(
|
||||
body?.inputs as SimplifiedInputs,
|
||||
body?.supports_agentless || newData.supports_agentless
|
||||
);
|
||||
} else {
|
||||
// complete request
|
||||
const { overrides, ...restOfBody } = body as TypeOf<
|
||||
typeof UpdatePackagePolicyRequestBodySchema
|
||||
>;
|
||||
|
@ -386,6 +398,10 @@ export const updatePackagePolicyHandler: FleetRequestHandler<
|
|||
newData.overrides = overrides;
|
||||
}
|
||||
}
|
||||
validateAgentlessInputs(
|
||||
newData.inputs,
|
||||
newData.supports_agentless || packagePolicy.supports_agentless
|
||||
);
|
||||
newData.inputs = alignInputsAndStreams(newData.inputs);
|
||||
|
||||
if (
|
||||
|
|
|
@ -5240,10 +5240,17 @@ describe('Package policy service', () => {
|
|||
name: 'apache-1',
|
||||
namespace: '',
|
||||
description: '',
|
||||
package: { name: 'apache', title: 'Apache', version: '1.0.0' },
|
||||
output_id: undefined,
|
||||
package: {
|
||||
name: 'apache',
|
||||
title: 'Apache',
|
||||
version: '1.0.0',
|
||||
experimental_data_stream_features: undefined,
|
||||
},
|
||||
enabled: true,
|
||||
policy_id: '1',
|
||||
policy_ids: ['1'],
|
||||
supports_agentless: undefined,
|
||||
inputs: [
|
||||
{
|
||||
enabled: false,
|
||||
|
@ -5269,6 +5276,67 @@ describe('Package policy service', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should disable inputs if supports_agentless == true if inputs are not allowed', async () => {
|
||||
const newPolicy = {
|
||||
name: 'apache-1',
|
||||
inputs: [
|
||||
{ type: 'logfile', enabled: false },
|
||||
{ type: 'tcp', enabled: true },
|
||||
],
|
||||
package: { name: 'apache', version: '0.3.3' },
|
||||
policy_id: '1',
|
||||
policy_ids: ['1'],
|
||||
supports_agentless: true,
|
||||
} as NewPackagePolicy;
|
||||
const result = await packagePolicyService.enrichPolicyWithDefaultsFromPackage(
|
||||
savedObjectsClientMock.create(),
|
||||
newPolicy
|
||||
);
|
||||
expect(result).toEqual({
|
||||
name: 'apache-1',
|
||||
namespace: '',
|
||||
description: '',
|
||||
output_id: undefined,
|
||||
package: {
|
||||
name: 'apache',
|
||||
title: 'Apache',
|
||||
version: '1.0.0',
|
||||
experimental_data_stream_features: undefined,
|
||||
},
|
||||
enabled: true,
|
||||
policy_id: '1',
|
||||
policy_ids: ['1'],
|
||||
supports_agentless: true,
|
||||
inputs: [
|
||||
{
|
||||
enabled: false,
|
||||
type: 'logfile',
|
||||
policy_template: 'log',
|
||||
streams: [
|
||||
{
|
||||
enabled: false,
|
||||
data_stream: {
|
||||
type: 'logs',
|
||||
dataset: 'apache.access',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
enabled: false,
|
||||
type: 'tcp',
|
||||
streams: undefined,
|
||||
},
|
||||
],
|
||||
vars: {
|
||||
paths: {
|
||||
value: ['/var/log/apache2/access.log*'],
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should enrich from epm with defaults using policy template', async () => {
|
||||
(packageToPackagePolicy as jest.Mock).mockReturnValueOnce({
|
||||
package: { name: 'aws', title: 'AWS', version: '1.0.0' },
|
||||
|
|
|
@ -105,6 +105,8 @@ import {
|
|||
MAX_CONCURRENT_PACKAGE_ASSETS,
|
||||
} from '../constants';
|
||||
|
||||
import { inputNotAllowedInAgentless } from '../../common/services/agentless_policy_helper';
|
||||
|
||||
import { createSoFindIterable } from './utils/create_so_find_iterable';
|
||||
|
||||
import type { FleetAuthzRouteConfig } from './security';
|
||||
|
@ -1912,17 +1914,23 @@ class PackagePolicyClientImpl implements PackagePolicyClient {
|
|||
i.type === input.type &&
|
||||
(!input.policy_template || input.policy_template === i.policy_template)
|
||||
);
|
||||
// disable some inputs in case of agentless integration
|
||||
const enabled = inputNotAllowedInAgentless(input.type, newPolicy?.supports_agentless)
|
||||
? false
|
||||
: input.enabled;
|
||||
|
||||
return {
|
||||
...defaultInput,
|
||||
enabled: input.enabled,
|
||||
enabled,
|
||||
type: input.type,
|
||||
// to propagate "enabled: false" to streams
|
||||
streams: defaultInput?.streams?.map((stream) => ({
|
||||
...stream,
|
||||
enabled: input.enabled,
|
||||
enabled,
|
||||
})),
|
||||
} as NewPackagePolicyInput;
|
||||
});
|
||||
|
||||
newPackagePolicy = {
|
||||
...newPP,
|
||||
name: newPolicy.name,
|
||||
|
|
|
@ -468,8 +468,10 @@ describe('policy preconfiguration', () => {
|
|||
],
|
||||
name: 'Test package',
|
||||
namespace: 'default',
|
||||
output_id: undefined,
|
||||
package: { name: 'test_package', title: 'test_package', version: '3.0.0' },
|
||||
policy_id: 'test-id',
|
||||
supports_agentless: undefined,
|
||||
vars: undefined,
|
||||
}),
|
||||
expect.objectContaining({ id: 'test-1' })
|
||||
|
|
|
@ -44,7 +44,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
mockApiServer.close();
|
||||
});
|
||||
|
||||
describe('Agentless CIS_GCP Single Account Launch Cloud shell', () => {
|
||||
describe.skip('Agentless CIS_GCP Single Account Launch Cloud shell', () => {
|
||||
it(`should show CIS_GCP Launch Cloud Shell button when package version is ${CLOUD_CREDENTIALS_PACKAGE_VERSION}`, async () => {
|
||||
await cisIntegration.navigateToAddIntegrationCspmWithVersionPage(
|
||||
CLOUD_CREDENTIALS_PACKAGE_VERSION
|
||||
|
@ -61,7 +61,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
});
|
||||
|
||||
describe('Agentless CIS_GCP ORG Account Launch Cloud Shell', () => {
|
||||
describe.skip('Agentless CIS_GCP ORG Account Launch Cloud Shell', () => {
|
||||
it(`should show CIS_GCP Launch Cloud Shell button when package version is ${CLOUD_CREDENTIALS_PACKAGE_VERSION}`, async () => {
|
||||
await cisIntegration.navigateToAddIntegrationCspmWithVersionPage(
|
||||
CLOUD_CREDENTIALS_PACKAGE_VERSION
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue