From fd1debacebc76f0868ba717b03117ca271ab3d31 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 20 Dec 2021 11:57:31 +0100 Subject: [PATCH 01/99] first draft --- .../agent_policy_advanced_fields.tsx | 320 ++++++++++++++ .../components/agent_policy_form.tsx | 415 ++---------------- .../agent_policy_general_fields.tsx | 53 +++ .../components/agent_policy_integration.tsx | 107 +++++ .../agent_policy_system_monitoring_field.tsx | 57 +++ .../components/agent_policy_validation.tsx | 46 ++ .../sections/agent_policy/components/index.ts | 4 +- .../create_package_policy_page/index.tsx | 151 ++++++- .../server/routes/agent_policy/handlers.ts | 22 +- .../fleet/server/services/epm/packages/get.ts | 4 +- .../server/services/epm/packages/install.ts | 6 +- .../fleet/server/services/package_policy.ts | 8 +- x-pack/plugins/fleet/server/services/setup.ts | 7 +- .../server/types/models/preconfiguration.ts | 11 +- 14 files changed, 788 insertions(+), 423 deletions(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_general_fields.tsx create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_system_monitoring_field.tsx create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.tsx diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx new file mode 100644 index 0000000000000..1f37b779f84d0 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx @@ -0,0 +1,320 @@ +/* + * 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 React, { useState } from 'react'; +import { + EuiDescribedFormGroup, + EuiFormRow, + EuiSpacer, + EuiText, + EuiComboBox, + EuiIconTip, + EuiCheckboxGroup, + EuiButton, + EuiLink, + EuiFieldNumber, + EuiFieldText, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; + +import { dataTypes } from '../../../../../../common'; +import type { NewAgentPolicy, AgentPolicy } from '../../../types'; +import { useStartServices } from '../../../hooks'; + +import { AgentPolicyDeleteProvider } from './agent_policy_delete_provider'; +import type { ValidationResults } from './agent_policy_validation'; + +interface Props { + agentPolicy: Partial; + updateAgentPolicy: (u: Partial) => void; + validation: ValidationResults; + isEditing?: boolean; + onDelete?: () => void; +} + +export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent = ({ + agentPolicy, + updateAgentPolicy, + validation, + isEditing = false, + onDelete = () => {}, +}) => { + const { docLinks } = useStartServices(); + const [touchedFields, setTouchedFields] = useState<{ [key: string]: boolean }>({}); + + return ( + <> + + + + } + description={ + + } + > + + updateAgentPolicy({ description: e.target.value })} + isInvalid={Boolean(touchedFields.description && validation.description)} + onBlur={() => setTouchedFields({ ...touchedFields, description: true })} + placeholder={i18n.translate('xpack.fleet.agentPolicyForm.descriptionFieldPlaceholder', { + defaultMessage: 'Optional description', + })} + /> + + + + + + } + description={ + + {i18n.translate( + 'xpack.fleet.agentPolicyForm.nameSpaceFieldDescription.fleetUserGuideLabel', + { defaultMessage: 'Learn more' } + )} + + ), + }} + /> + } + > + + { + updateAgentPolicy({ namespace: value }); + }} + onChange={(selectedOptions) => { + updateAgentPolicy({ + namespace: (selectedOptions.length ? selectedOptions[0] : '') as string, + }); + }} + isInvalid={Boolean(touchedFields.namespace && validation.namespace)} + onBlur={() => setTouchedFields({ ...touchedFields, namespace: true })} + /> + + + + + + } + description={ + + } + > + + {' '} + + + ), + }, + { + id: dataTypes.Metrics, + label: ( + <> + {' '} + + + ), + }, + ]} + idToSelectedMap={(agentPolicy.monitoring_enabled || []).reduce( + (acc: { logs: boolean; metrics: boolean }, key) => { + acc[key] = true; + return acc; + }, + { logs: false, metrics: false } + )} + onChange={(id) => { + if (id !== dataTypes.Logs && id !== dataTypes.Metrics) { + return; + } + + const hasLogs = + agentPolicy.monitoring_enabled && agentPolicy.monitoring_enabled.indexOf(id) >= 0; + + const previousValues = agentPolicy.monitoring_enabled || []; + updateAgentPolicy({ + monitoring_enabled: hasLogs + ? previousValues.filter((type) => type !== id) + : [...previousValues, id], + }); + }} + /> + + + + + } + description={ + + } + > + + { + updateAgentPolicy({ + unenroll_timeout: e.target.value ? Number(e.target.value) : 0, + }); + }} + isInvalid={Boolean(touchedFields.unenroll_timeout && validation.unenroll_timeout)} + onBlur={() => setTouchedFields({ ...touchedFields, unenroll_timeout: true })} + /> + + + {isEditing && + 'id' in agentPolicy && + !agentPolicy.is_managed && + !agentPolicy.is_default && + !agentPolicy.is_default_fleet_server ? ( + + + + } + description={ + <> + + + + {(deleteAgentPolicyPrompt) => { + return ( + deleteAgentPolicyPrompt(agentPolicy.id!, onDelete)} + > + + + ); + }} + + {agentPolicy.is_default ? ( + <> + + + + + + ) : null} + + } + /> + ) : null} + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx index fad45ba7b711b..f0e30c8814c2a 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx @@ -5,38 +5,24 @@ * 2.0. */ -import React, { useMemo, useState } from 'react'; +import React from 'react'; import { EuiAccordion, - EuiFieldText, EuiDescribedFormGroup, EuiForm, - EuiFormRow, EuiHorizontalRule, EuiSpacer, - EuiText, - EuiComboBox, - EuiIconTip, - EuiCheckbox, - EuiCheckboxGroup, - EuiButton, - EuiLink, - EuiFieldNumber, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { i18n } from '@kbn/i18n'; import styled from 'styled-components'; -import { dataTypes } from '../../../../../../common'; import type { NewAgentPolicy, AgentPolicy } from '../../../types'; import { isValidNamespace } from '../../../services'; -import { useStartServices } from '../../../hooks'; -import { AgentPolicyDeleteProvider } from './agent_policy_delete_provider'; - -interface ValidationResults { - [key: string]: Array; -} +import { AgentPolicyAdvancedOptionsContent } from './agent_policy_advanced_fields'; +import { AgentPolicyGeneralFields } from './agent_policy_general_fields'; +import { AgentPolicyFormSystemMonitoringCheckbox } from './agent_policy_system_monitoring_field'; +import type { ValidationResults } from './agent_policy_validation'; const StyledEuiAccordion = styled(EuiAccordion)` .ingest-active-button { @@ -44,37 +30,6 @@ const StyledEuiAccordion = styled(EuiAccordion)` } `; -export const agentPolicyFormValidation = ( - agentPolicy: Partial -): ValidationResults => { - const errors: ValidationResults = {}; - const namespaceValidation = isValidNamespace(agentPolicy.namespace || ''); - - if (!agentPolicy.name?.trim()) { - errors.name = [ - , - ]; - } - - if (!namespaceValidation.valid && namespaceValidation.error) { - errors.namespace = [namespaceValidation.error]; - } - - if (agentPolicy.unenroll_timeout && agentPolicy.unenroll_timeout < 0) { - errors.unenroll_timeout = [ - , - ]; - } - - return errors; -}; - interface Props { agentPolicy: Partial; updateAgentPolicy: (u: Partial) => void; @@ -94,38 +49,6 @@ export const AgentPolicyForm: React.FunctionComponent = ({ isEditing = false, onDelete = () => {}, }) => { - const { docLinks } = useStartServices(); - const [touchedFields, setTouchedFields] = useState<{ [key: string]: boolean }>({}); - const fields: Array<{ - name: 'name' | 'description' | 'namespace'; - label: JSX.Element; - placeholder: string; - }> = useMemo(() => { - return [ - { - name: 'name', - label: ( - - ), - placeholder: i18n.translate('xpack.fleet.agentPolicyForm.nameFieldPlaceholder', { - defaultMessage: 'Choose a name', - }), - }, - { - name: 'description', - label: ( - - ), - placeholder: i18n.translate('xpack.fleet.agentPolicyForm.descriptionFieldPlaceholder', { - defaultMessage: 'How will this policy be used?', - }), - }, - ]; - }, []); - const generalSettingsWrapper = (children: JSX.Element[]) => ( = ({ ); - const generalFields = fields.map(({ name, label, placeholder }) => { - return ( - - updateAgentPolicy({ [name]: e.target.value })} - isInvalid={Boolean(touchedFields[name] && validation[name])} - onBlur={() => setTouchedFields({ ...touchedFields, [name]: true })} - placeholder={placeholder} - /> - - ); - }); - - const advancedOptionsContent = ( - <> - - - - } - description={ - - {i18n.translate( - 'xpack.fleet.agentPolicyForm.nameSpaceFieldDescription.fleetUserGuideLabel', - { defaultMessage: 'Learn more' } - )} - - ), - }} - /> - } - > - - { - updateAgentPolicy({ namespace: value }); - }} - onChange={(selectedOptions) => { - updateAgentPolicy({ - namespace: (selectedOptions.length ? selectedOptions[0] : '') as string, - }); - }} - isInvalid={Boolean(touchedFields.namespace && validation.namespace)} - onBlur={() => setTouchedFields({ ...touchedFields, namespace: true })} - /> - - - - - - } - description={ - - } - > - - {' '} - - - ), - }, - { - id: dataTypes.Metrics, - label: ( - <> - {' '} - - - ), - }, - ]} - idToSelectedMap={(agentPolicy.monitoring_enabled || []).reduce( - (acc: { logs: boolean; metrics: boolean }, key) => { - acc[key] = true; - return acc; - }, - { logs: false, metrics: false } - )} - onChange={(id) => { - if (id !== dataTypes.Logs && id !== dataTypes.Metrics) { - return; - } - - const hasLogs = - agentPolicy.monitoring_enabled && agentPolicy.monitoring_enabled.indexOf(id) >= 0; - - const previousValues = agentPolicy.monitoring_enabled || []; - updateAgentPolicy({ - monitoring_enabled: hasLogs - ? previousValues.filter((type) => type !== id) - : [...previousValues, id], - }); - }} - /> - - - - - } - description={ - - } - > - - { - updateAgentPolicy({ - unenroll_timeout: e.target.value ? Number(e.target.value) : 0, - }); - }} - isInvalid={Boolean(touchedFields.unenroll_timeout && validation.unenroll_timeout)} - onBlur={() => setTouchedFields({ ...touchedFields, unenroll_timeout: true })} - /> - - - {isEditing && - 'id' in agentPolicy && - !agentPolicy.is_managed && - !agentPolicy.is_default && - !agentPolicy.is_default_fleet_server ? ( - - - - } - description={ - <> - - - - {(deleteAgentPolicyPrompt) => { - return ( - deleteAgentPolicyPrompt(agentPolicy.id!, onDelete)} - > - - - ); - }} - - {agentPolicy.is_default ? ( - <> - - - - - - ) : null} - - } - /> - ) : null} - - ); - return ( - {!isEditing ? generalFields : generalSettingsWrapper(generalFields)} {!isEditing ? ( - - } - > - - {' '} - - - } - checked={withSysMonitoring} - onChange={() => { - updateSysMonitoring(!withSysMonitoring); - }} - /> - + + ) : ( + generalSettingsWrapper([ + , + ]) + )} + {!isEditing ? ( + ) : null} {!isEditing ? ( <> @@ -459,11 +108,23 @@ export const AgentPolicyForm: React.FunctionComponent = ({ buttonClassName="ingest-active-button" > - {advancedOptionsContent} + ) : ( - advancedOptionsContent + )} ); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_general_fields.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_general_fields.tsx new file mode 100644 index 0000000000000..da157e79bc877 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_general_fields.tsx @@ -0,0 +1,53 @@ +/* + * 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 React, { useState } from 'react'; +import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; + +import type { NewAgentPolicy, AgentPolicy } from '../../../types'; + +import type { ValidationResults } from './agent_policy_validation'; + +interface Props { + agentPolicy: Partial; + updateAgentPolicy: (u: Partial) => void; + validation: ValidationResults; +} + +export const AgentPolicyGeneralFields: React.FunctionComponent = ({ + agentPolicy, + updateAgentPolicy, + validation, +}) => { + const [touchedFields, setTouchedFields] = useState<{ [key: string]: boolean }>({}); + + return ( + + } + error={touchedFields.name && validation.name ? validation.name : null} + isInvalid={Boolean(touchedFields.name && validation.name)} + > + updateAgentPolicy({ name: e.target.value })} + isInvalid={Boolean(touchedFields.name && validation.name)} + onBlur={() => setTouchedFields({ ...touchedFields, name: true })} + placeholder={i18n.translate('xpack.fleet.agentPolicyForm.nameFieldPlaceholder', { + defaultMessage: 'Choose a name', + })} + /> + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx new file mode 100644 index 0000000000000..b3a5f315de5f5 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx @@ -0,0 +1,107 @@ +/* + * 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 React from 'react'; +import { + EuiAccordion, + EuiDescribedFormGroup, + EuiForm, + EuiHorizontalRule, + EuiSpacer, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import styled from 'styled-components'; + +import type { NewAgentPolicy, AgentPolicy } from '../../../types'; + +import { AgentPolicyAdvancedOptionsContent } from './agent_policy_advanced_fields'; +import { AgentPolicyGeneralFields } from './agent_policy_general_fields'; +import { AgentPolicyFormSystemMonitoringCheckbox } from './agent_policy_system_monitoring_field'; +import type { ValidationResults } from './agent_policy_validation'; + +const StyledEuiAccordion = styled(EuiAccordion)` + .ingest-active-button { + color: ${(props) => props.theme.eui.euiColorPrimary}; + } +`; + +interface Props { + agentPolicy: Partial; + updateAgentPolicy: (u: Partial) => void; + withSysMonitoring: boolean; + updateSysMonitoring: (newValue: boolean) => void; + validation: ValidationResults; + isEditing?: boolean; + onDelete?: () => void; +} + +export const AgentPolicyIntegrationForm: React.FunctionComponent = ({ + agentPolicy, + updateAgentPolicy, + withSysMonitoring, + updateSysMonitoring, + validation, + isEditing = false, + onDelete = () => {}, +}) => { + // TODO labels different + + return ( + + + + + } + description={ + + } + > + + + + + <> + + + + } + buttonClassName="ingest-active-button" + > + + + + + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_system_monitoring_field.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_system_monitoring_field.tsx new file mode 100644 index 0000000000000..db7dba6e7907d --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_system_monitoring_field.tsx @@ -0,0 +1,57 @@ +/* + * 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 React from 'react'; +import { EuiFormRow, EuiIconTip, EuiCheckbox } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; + +interface Props { + withSysMonitoring: boolean; + updateSysMonitoring: (newValue: boolean) => void; +} + +export const AgentPolicyFormSystemMonitoringCheckbox: React.FunctionComponent = ({ + withSysMonitoring, + updateSysMonitoring, +}) => { + return ( + + } + > + + {' '} + + + } + checked={withSysMonitoring} + onChange={() => { + updateSysMonitoring(!withSysMonitoring); + }} + /> + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.tsx new file mode 100644 index 0000000000000..c75ce39fa7ff9 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.tsx @@ -0,0 +1,46 @@ +/* + * 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 React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { isValidNamespace } from '../../../services'; +import type { NewAgentPolicy, AgentPolicy } from '../../../types'; + +export interface ValidationResults { + [key: string]: Array; +} + +export const agentPolicyFormValidation = ( + agentPolicy: Partial +): ValidationResults => { + const errors: ValidationResults = {}; + const namespaceValidation = isValidNamespace(agentPolicy.namespace || ''); + + if (!agentPolicy.name?.trim()) { + errors.name = [ + , + ]; + } + + if (!namespaceValidation.valid && namespaceValidation.error) { + errors.namespace = [namespaceValidation.error]; + } + + if (agentPolicy.unenroll_timeout && agentPolicy.unenroll_timeout < 0) { + errors.unenroll_timeout = [ + , + ]; + } + + return errors; +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/index.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/index.ts index 439e474d416cb..f805ae5c3b15e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/index.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/index.ts @@ -8,9 +8,11 @@ // TODO: Does this need to be re-exported here? export { LinkedAgentCount } from '../../../components'; -export { AgentPolicyForm, agentPolicyFormValidation } from './agent_policy_form'; +export { AgentPolicyForm } from './agent_policy_form'; export { AgentPolicyCopyProvider } from './agent_policy_copy_provider'; export { AgentPolicyDeleteProvider } from './agent_policy_delete_provider'; export { AgentPolicyYamlFlyout } from './agent_policy_yaml_flyout'; export { ConfirmDeployAgentPolicyModal } from './confirm_deploy_modal'; export { AgentPolicyActionMenu } from './actions_menu'; +export { AgentPolicyIntegrationForm } from './agent_policy_integration'; +export { agentPolicyFormValidation } from './agent_policy_validation'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index c731936c775e5..d47799e8f11ee 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -24,9 +24,10 @@ import { import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; import { safeLoad } from 'js-yaml'; -import { splitPkgKey } from '../../../../../../common'; +import { dataTypes, splitPkgKey } from '../../../../../../common'; import type { AgentPolicy, + NewAgentPolicy, NewPackagePolicy, PackagePolicy, CreatePackagePolicyRouteState, @@ -40,9 +41,15 @@ import { useConfig, sendGetAgentStatus, useGetPackageInfoByKey, + sendCreateAgentPolicy, + useGetAgentPolicies, } from '../../../hooks'; import { Loading, Error } from '../../../components'; -import { ConfirmDeployAgentPolicyModal } from '../components'; +import { + AgentPolicyIntegrationForm, + agentPolicyFormValidation, + ConfirmDeployAgentPolicyModal, +} from '../components'; import { useIntraAppState, useUIExtension } from '../../../hooks'; import { ExtensionWrapper } from '../../../components'; import type { PackagePolicyEditExtensionComponentProps } from '../../../types'; @@ -116,6 +123,20 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { // Agent policy state const [agentPolicy, setAgentPolicy] = useState(); + const defaultPolicy = { + name: 'Default policy', + description: '', + namespace: 'default', + monitoring_enabled: Object.values(dataTypes), + }; + + const [newAgentPolicy, setNewAgentPolicy] = useState({ + ...defaultPolicy, + }); + + const [withSysMonitoring, setWithSysMonitoring] = useState(true); + const validation = agentPolicyFormValidation(newAgentPolicy); + // only used to store the resulting package policy once saved const [savedPackagePolicy, setSavedPackagePolicy] = useState(); @@ -139,7 +160,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { const [packagePolicy, setPackagePolicy] = useState({ name: '', description: '', - namespace: '', + namespace: 'default', policy_id: '', enabled: true, output_id: '', // TODO: Blank for now as we only support default output @@ -185,8 +206,35 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { [packageInfo, setAgentPolicy, setFormState] ); + const updateNewAgentPolicy = useCallback( + (updatedFields: Partial) => { + setNewAgentPolicy({ + ...newAgentPolicy, + ...updatedFields, + }); + }, + [setNewAgentPolicy, newAgentPolicy] + ); + const hasErrors = validationResults ? validationHasErrors(validationResults) : false; + let agentPolicies = []; + const { data: agentPoliciesData, error: err } = useGetAgentPolicies({ + page: 1, + perPage: 1000, + sortField: 'name', + sortOrder: 'asc', + full: true, + }); + if (err) { + // eslint-disable-next-line no-console + console.debug('Could not retrieve agent policies'); + } + agentPolicies = useMemo( + () => agentPoliciesData?.items.filter((policy) => !policy.is_managed) || [], + [agentPoliciesData?.items] + ); + // Update package policy validation const updatePackagePolicyValidation = useCallback( (newPackagePolicy?: NewPackagePolicy) => { @@ -268,12 +316,15 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { ); // Save package policy - const savePackagePolicy = useCallback(async () => { - setFormState('LOADING'); - const result = await sendCreatePackagePolicy(packagePolicy); - setFormState(agentCount ? 'SUBMITTED' : 'SUBMITTED_NO_AGENTS'); - return result; - }, [packagePolicy, agentCount]); + const savePackagePolicy = useCallback( + async (pkgPolicy: NewPackagePolicy) => { + setFormState('LOADING'); + const result = await sendCreatePackagePolicy(pkgPolicy); + setFormState(agentCount ? 'SUBMITTED' : 'SUBMITTED_NO_AGENTS'); + return result; + }, + [agentCount] + ); const doOnSaveNavigation = useRef(true); // Detect if user left page @@ -325,7 +376,41 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { setFormState('CONFIRM'); return; } - const { error, data } = await savePackagePolicy(); + let policyId = ''; + // save agent policy + if (!agentPolicy?.id && newAgentPolicy) { + try { + setFormState('LOADING'); + const resp = await sendCreateAgentPolicy(newAgentPolicy, { withSysMonitoring }); + setFormState('VALID'); + if (resp.error) throw resp.error; + if (resp.data) { + notifications.toasts.addSuccess( + i18n.translate('xpack.fleet.createAgentPolicy.successNotificationTitle', { + defaultMessage: "Agent policy '{name}' created", + values: { name: newAgentPolicy.name }, + }) + ); + policyId = resp.data.item.id; + setAgentPolicy(resp.data.item); + + updatePackagePolicy({ policy_id: policyId }); + } + } catch (e) { + notifications.toasts.addDanger( + i18n.translate('xpack.fleet.createAgentPolicy.errorNotificationTitle', { + defaultMessage: 'Unable to create agent policy', + }) + ); + return; + } + } + + // passing pkgPolicy with policy_id here as setPackagePolicy doesn't propagate immediately + const { error, data } = await savePackagePolicy({ + ...packagePolicy, + policy_id: packagePolicy.policy_id || policyId, + }); if (!error) { setSavedPackagePolicy(data!.item); @@ -367,7 +452,10 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { onSaveNavigate, agentPolicy, notifications.toasts, - packagePolicy.name, + newAgentPolicy, + packagePolicy, + updatePackagePolicy, + withSysMonitoring, ]); const integrationInfo = useMemo( @@ -393,16 +481,35 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { ); const stepSelectAgentPolicy = useMemo( - () => ( - - ), - [packageInfo, queryParamsPolicyId, agentPolicy, updateAgentPolicy] + () => + agentPolicies.length > 0 ? ( + + ) : ( + setWithSysMonitoring(newValue)} + validation={validation} + /> + ), + [ + packageInfo, + queryParamsPolicyId, + agentPolicy, + updateAgentPolicy, + newAgentPolicy, + updateNewAgentPolicy, + validation, + withSysMonitoring, + agentPolicies.length, + ] ); const extensionView = useUIExtension(packagePolicy.package?.name ?? '', 'package-policy-create'); @@ -472,7 +579,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { }, { title: i18n.translate('xpack.fleet.createPackagePolicy.stepSelectAgentPolicyTitle', { - defaultMessage: 'Apply to agent policy', + defaultMessage: 'Where to add this integration?', }), children: stepSelectAgentPolicy, }, diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index 57a9290d00a00..f9a7d96387b1a 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -23,7 +23,7 @@ import type { DeleteAgentPolicyRequestSchema, GetFullAgentPolicyRequestSchema, } from '../../types'; -import { FLEET_SYSTEM_PACKAGE } from '../../../common'; +import { FLEET_ELASTIC_AGENT_PACKAGE, FLEET_SYSTEM_PACKAGE } from '../../../common'; import type { GetAgentPoliciesResponse, GetAgentPoliciesResponseItem, @@ -37,6 +37,7 @@ import type { } from '../../../common'; import { defaultIngestErrorHandler } from '../../errors'; import { incrementPackageName } from '../../services/package_policy'; +import { ensureInstalledPackage } from '../../services/epm/packages'; export const getAgentPoliciesHandler: RequestHandler< undefined, @@ -108,8 +109,25 @@ export const createAgentPolicyHandler: RequestHandler< const esClient = context.core.elasticsearch.client.asInternalUser; const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined; const withSysMonitoring = request.query.sys_monitoring ?? false; - + // TODO set first default policy to is_default + // TODO installing these packages might take long (about 2 mins) which causes network timeout. this results in an error, and fails next agent policy creation request. Could this be improved by bundled default packages? try { + if (withSysMonitoring) { + // install system package if not yet installed + await ensureInstalledPackage({ + savedObjectsClient: soClient, + pkgName: FLEET_SYSTEM_PACKAGE, + esClient, + }); + } + if (request.body.monitoring_enabled?.length) { + // install elastic agent package if not yet installed + ensureInstalledPackage({ + savedObjectsClient: soClient, + pkgName: FLEET_ELASTIC_AGENT_PACKAGE, + esClient, + }); + } // eslint-disable-next-line prefer-const let [agentPolicy, newSysPackagePolicy] = await Promise.all([ agentPolicyService.create(soClient, esClient, request.body, { diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index 83bb8125e077e..755fafd8fbc7a 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -28,7 +28,7 @@ import { getEsPackage } from '../archive/storage'; import { getArchivePackage } from '../archive'; import { normalizeKuery } from '../../saved_object'; -import { createInstallableFrom, isUnremovablePackage } from './index'; +import { createInstallableFrom } from './index'; export type { SearchParams } from '../registry'; export { getFile } from '../registry'; @@ -130,7 +130,7 @@ export async function getPackageInfo(options: { latestVersion: latestPackage.version, title: packageInfo.title || nameAsTitle(packageInfo.name), assets: Registry.groupPathsByService(paths || []), - removable: !isUnremovablePackage(pkgName), + removable: true, notice: Registry.getNoticePath(paths || []), keepPoliciesUpToDate: savedObject?.attributes.keep_policies_up_to_date ?? false, }; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index 77fcc429b2084..19cc45bbad988 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -43,7 +43,7 @@ import type { ArchiveAsset } from '../kibana/assets/install'; import type { PackageUpdateEvent } from '../../upgrade_sender'; import { sendTelemetryEvents, UpdateEventType } from '../../upgrade_sender'; -import { isUnremovablePackage, getInstallation, getInstallationObject } from './index'; +import { getInstallation, getInstallationObject } from './index'; import { removeInstallation } from './remove'; import { getPackageSavedObjects } from './get'; import { _installPackage } from './_install_package'; @@ -518,7 +518,6 @@ export async function createInstallation(options: { }) { const { savedObjectsClient, packageInfo, installSource } = options; const { name: pkgName, version: pkgVersion } = packageInfo; - const removable = !isUnremovablePackage(pkgName); const toSaveESIndexPatterns = generateESIndexPatterns(packageInfo.data_streams); // For "stack-aligned" packages, default the `keep_policies_up_to_date` setting to true. For all other @@ -530,6 +529,7 @@ export async function createInstallation(options: { ? true : undefined; + // TODO cleanup removable flag and isUnremovablePackage function const created = await savedObjectsClient.create( PACKAGES_SAVED_OBJECT_TYPE, { @@ -539,7 +539,7 @@ export async function createInstallation(options: { es_index_patterns: toSaveESIndexPatterns, name: pkgName, version: pkgVersion, - removable, + removable: true, install_version: pkgVersion, install_status: 'installing', install_started_at: new Date().toISOString(), diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index e0bdda6e2449b..df1931dd52752 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -109,7 +109,9 @@ class PackagePolicyService { // Check that the name does not exist already if (existingPoliciesWithName.items.length > 0) { - throw new IngestManagerError('There is already an integration policy with the same name'); + throw new IngestManagerError( + `There is already an integration policy with the same name: ${packagePolicy.name}` + ); } } @@ -1382,7 +1384,9 @@ export async function incrementPackageName( ? packagePolicyData.items .filter((ds) => Boolean(ds.name.match(pkgPoliciesNamePattern))) .map((ds) => parseInt(ds.name.match(pkgPoliciesNamePattern)![1], 10)) - .sort() + .sort((a: number, b: number) => { + return a - b; + }) : []; return `${packageName}-${ diff --git a/x-pack/plugins/fleet/server/services/setup.ts b/x-pack/plugins/fleet/server/services/setup.ts index 18c66e8267468..5a2edbd227410 100644 --- a/x-pack/plugins/fleet/server/services/setup.ts +++ b/x-pack/plugins/fleet/server/services/setup.ts @@ -11,7 +11,7 @@ import type { ElasticsearchClient, SavedObjectsClientContract } from 'src/core/s import { AUTO_UPDATE_PACKAGES } from '../../common'; import type { DefaultPackagesInstallationError, PreconfigurationError } from '../../common'; -import { SO_SEARCH_LIMIT, DEFAULT_PACKAGES } from '../constants'; +import { SO_SEARCH_LIMIT } from '../constants'; import { appContextService } from './app_context'; import { agentPolicyService } from './agent_policy'; @@ -25,7 +25,6 @@ import { outputService } from './output'; import { generateEnrollmentAPIKey, hasEnrollementAPIKeysForPolicy } from './api_keys'; import { settingsService } from '.'; import { awaitIfPending } from './setup_utils'; -import { ensureFleetServerAgentPoliciesExists } from './agents'; import { ensureFleetFinalPipelineIsInstalled } from './epm/elasticsearch/ingest_pipeline/install'; import { ensureDefaultComponentTemplate } from './epm/elasticsearch/template/install'; import { getInstallations, installPackage } from './epm/packages'; @@ -92,7 +91,6 @@ async function createSetupSideEffects( packages = [ ...packages, - ...DEFAULT_PACKAGES.filter((pkg) => !preconfiguredPackageNames.has(pkg.name)), ...autoUpdateablePackages.filter((pkg) => !preconfiguredPackageNames.has(pkg.name)), ]; @@ -112,9 +110,6 @@ async function createSetupSideEffects( logger.debug('Setting up Fleet enrollment keys'); await ensureDefaultEnrollmentAPIKeysExists(soClient, esClient); - logger.debug('Setting up Fleet Server agent policies'); - await ensureFleetServerAgentPoliciesExists(soClient, esClient); - if (nonFatalErrors.length > 0) { logger.info('Encountered non fatal errors during Fleet setup'); formatNonFatalErrors(nonFatalErrors).forEach((error) => logger.info(JSON.stringify(error))); diff --git a/x-pack/plugins/fleet/server/types/models/preconfiguration.ts b/x-pack/plugins/fleet/server/types/models/preconfiguration.ts index 4d030e1e87ed4..1741e3d5f9e95 100644 --- a/x-pack/plugins/fleet/server/types/models/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/types/models/preconfiguration.ts @@ -8,12 +8,7 @@ import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; import semverValid from 'semver/functions/valid'; -import { - PRECONFIGURATION_LATEST_KEYWORD, - DEFAULT_AGENT_POLICY, - DEFAULT_FLEET_SERVER_AGENT_POLICY, - DEFAULT_PACKAGES, -} from '../../constants'; +import { PRECONFIGURATION_LATEST_KEYWORD } from '../../constants'; import type { PreconfiguredOutput } from '../../../common'; import { outputType } from '../../../common'; @@ -45,7 +40,7 @@ export const PreconfiguredPackagesSchema = schema.arrayOf( }), }), { - defaultValue: DEFAULT_PACKAGES, + defaultValue: [], } ); @@ -141,6 +136,6 @@ export const PreconfiguredAgentPoliciesSchema = schema.arrayOf( ), }), { - defaultValue: [DEFAULT_AGENT_POLICY, DEFAULT_FLEET_SERVER_AGENT_POLICY], + defaultValue: [], } ); From 4312eac0c2a5241e2a25013feb5103482db55cac Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 20 Dec 2021 13:25:01 +0100 Subject: [PATCH 02/99] added new text with badge --- .../agent_policy_advanced_fields.tsx | 9 +++- .../components/agent_policy_form.tsx | 1 - .../agent_policy_system_monitoring_field.tsx | 16 +++++-- .../components/agent_policy_package_badge.tsx | 48 +++++++++++++++++++ .../agent_policy_package_badges.tsx | 38 ++++----------- .../plugins/fleet/public/components/index.ts | 1 + 6 files changed, 77 insertions(+), 36 deletions(-) create mode 100644 x-pack/plugins/fleet/public/components/agent_policy_package_badge.tsx diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx index 1f37b779f84d0..a509dfacaa4ac 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx @@ -26,6 +26,8 @@ import { dataTypes } from '../../../../../../common'; import type { NewAgentPolicy, AgentPolicy } from '../../../types'; import { useStartServices } from '../../../hooks'; +import { AgentPolicyPackageBadge } from '../../../components'; + import { AgentPolicyDeleteProvider } from './agent_policy_delete_provider'; import type { ValidationResults } from './agent_policy_validation'; @@ -147,7 +149,12 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent = description={ + ), + }} /> } > diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx index f0e30c8814c2a..e4720bad5a091 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx @@ -17,7 +17,6 @@ import { FormattedMessage } from '@kbn/i18n-react'; import styled from 'styled-components'; import type { NewAgentPolicy, AgentPolicy } from '../../../types'; -import { isValidNamespace } from '../../../services'; import { AgentPolicyAdvancedOptionsContent } from './agent_policy_advanced_fields'; import { AgentPolicyGeneralFields } from './agent_policy_general_fields'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_system_monitoring_field.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_system_monitoring_field.tsx index db7dba6e7907d..4f65b64942d37 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_system_monitoring_field.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_system_monitoring_field.tsx @@ -8,7 +8,8 @@ import React from 'react'; import { EuiFormRow, EuiIconTip, EuiCheckbox } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { i18n } from '@kbn/i18n'; + +import { AgentPolicyPackageBadge } from '../../../components'; interface Props { withSysMonitoring: boolean; @@ -37,10 +38,15 @@ export const AgentPolicyFormSystemMonitoringCheckbox: React.FunctionComponent{' '} , + }} + /> + } position="right" type="iInCircle" color="subdued" diff --git a/x-pack/plugins/fleet/public/components/agent_policy_package_badge.tsx b/x-pack/plugins/fleet/public/components/agent_policy_package_badge.tsx new file mode 100644 index 0000000000000..01cd86064e6e6 --- /dev/null +++ b/x-pack/plugins/fleet/public/components/agent_policy_package_badge.tsx @@ -0,0 +1,48 @@ +/* + * 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 React from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiBadge } from '@elastic/eui'; + +import { PackageIcon } from '../components'; +import { FLEET_SERVER_PACKAGE } from '../../common/constants'; + +interface Props { + excludeFleetServer?: boolean; + pkgName: string; + pkgVersion?: string; + pkgTitle: string; +} + +export const AgentPolicyPackageBadge: React.FunctionComponent = ({ + excludeFleetServer, + pkgName, + pkgVersion, + pkgTitle, +}) => { + return ( + + + + + // this collides with some EuiText (+img) CSS from the EuiIcon component + // which makes the button large, wide, and poorly layed out + // override those styles until the bug is fixed or we find a better approach + { margin: 'unset', width: '16px' } + } + /> + + {pkgTitle} + + + ); +}; diff --git a/x-pack/plugins/fleet/public/components/agent_policy_package_badges.tsx b/x-pack/plugins/fleet/public/components/agent_policy_package_badges.tsx index b8dbe74a9f242..a6434b0c08b50 100644 --- a/x-pack/plugins/fleet/public/components/agent_policy_package_badges.tsx +++ b/x-pack/plugins/fleet/public/components/agent_policy_package_badges.tsx @@ -8,13 +8,14 @@ import React, { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiSpacer, EuiText, EuiFlexGroup, EuiFlexItem, EuiBadge, EuiCallOut } from '@elastic/eui'; +import { EuiSpacer, EuiText, EuiFlexGroup, EuiFlexItem, EuiCallOut } from '@elastic/eui'; import { FLEET_SERVER_PACKAGE } from '../../common/constants'; import type { PackagePolicy, PackagePolicyPackage } from '../types'; import { useGetOneAgentPolicy } from '../hooks'; -import { PackageIcon } from '../components'; + +import { AgentPolicyPackageBadge } from './agent_policy_package_badge'; interface Props { agentPolicyId: string; @@ -88,34 +89,13 @@ export const AgentPolicyPackageBadges: React.FunctionComponent = ({ {packages.map((pkg, idx) => { return ( - - - - - // this collides with some EuiText (+img) CSS from the EuiIcon component - // which makes the button large, wide, and poorly layed out - // override those styles until the bug is fixed or we find a better approach - { margin: 'unset', width: '16px' } - } - /> - - {pkg.title} - - + excludeFleetServer={excludeFleetServer} + pkgName={pkg.name} + pkgVersion={pkg.version} + pkgTitle={pkg.title} + /> ); })} diff --git a/x-pack/plugins/fleet/public/components/index.ts b/x-pack/plugins/fleet/public/components/index.ts index 757625d7244a3..ce6e09f33eb62 100644 --- a/x-pack/plugins/fleet/public/components/index.ts +++ b/x-pack/plugins/fleet/public/components/index.ts @@ -16,6 +16,7 @@ export { AlphaFlyout } from './alpha_flyout'; export type { HeaderProps } from './header'; export { Header } from './header'; export { NewEnrollmentTokenModal } from './new_enrollment_key_modal'; +export { AgentPolicyPackageBadge } from './agent_policy_package_badge'; export { AgentPolicyPackageBadges } from './agent_policy_package_badges'; export { DangerEuiContextMenuItem } from './danger_eui_context_menu_item'; export { PackagePolicyDeleteProvider } from './package_policy_delete_provider'; From 5f7ee9a3cb9a4a38bcc591823f437736022b1b1e Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 20 Dec 2021 14:00:21 +0100 Subject: [PATCH 03/99] updated labels --- .../components/agent_policy_general_fields.tsx | 7 ++++++- .../agent_policy/components/agent_policy_integration.tsx | 6 ++++++ .../components/agent_policy_system_monitoring_field.tsx | 9 +-------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_general_fields.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_general_fields.tsx index da157e79bc877..c71803e45aed5 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_general_fields.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_general_fields.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { ReactElement } from 'react'; import React, { useState } from 'react'; import { EuiFieldText, EuiFormRow } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -18,12 +19,14 @@ interface Props { agentPolicy: Partial; updateAgentPolicy: (u: Partial) => void; validation: ValidationResults; + nameLabel?: ReactElement; } export const AgentPolicyGeneralFields: React.FunctionComponent = ({ agentPolicy, updateAgentPolicy, validation, + nameLabel, }) => { const [touchedFields, setTouchedFields] = useState<{ [key: string]: boolean }>({}); @@ -32,7 +35,9 @@ export const AgentPolicyGeneralFields: React.FunctionComponent = ({ fullWidth key="name" label={ - + nameLabel || ( + + ) } error={touchedFields.name && validation.name ? validation.name : null} isInvalid={Boolean(touchedFields.name && validation.name)} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx index b3a5f315de5f5..c9678c6803187 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx @@ -72,6 +72,12 @@ export const AgentPolicyIntegrationForm: React.FunctionComponent = ({ agentPolicy={agentPolicy} updateAgentPolicy={updateAgentPolicy} validation={validation} + nameLabel={ + + } /> { return ( - - } - > + Date: Mon, 20 Dec 2021 15:24:22 +0100 Subject: [PATCH 04/99] added tabs --- .../components/agent_policy_integration.tsx | 2 - .../create_package_policy_page/index.tsx | 59 +++------- .../step_select_hosts.tsx | 107 ++++++++++++++++++ 3 files changed, 123 insertions(+), 45 deletions(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx index c9678c6803187..da7ca2f3e18ec 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx @@ -48,8 +48,6 @@ export const AgentPolicyIntegrationForm: React.FunctionComponent = ({ isEditing = false, onDelete = () => {}, }) => { - // TODO labels different - return ( { const hasErrors = validationResults ? validationHasErrors(validationResults) : false; - let agentPolicies = []; - const { data: agentPoliciesData, error: err } = useGetAgentPolicies({ - page: 1, - perPage: 1000, - sortField: 'name', - sortOrder: 'asc', - full: true, - }); - if (err) { - // eslint-disable-next-line no-console - console.debug('Could not retrieve agent policies'); - } - agentPolicies = useMemo( - () => agentPoliciesData?.items.filter((policy) => !policy.is_managed) || [], - [agentPoliciesData?.items] - ); - // Update package policy validation const updatePackagePolicyValidation = useCallback( (newPackagePolicy?: NewPackagePolicy) => { @@ -481,24 +459,20 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { ); const stepSelectAgentPolicy = useMemo( - () => - agentPolicies.length > 0 ? ( - - ) : ( - setWithSysMonitoring(newValue)} - validation={validation} - /> - ), + () => ( + setWithSysMonitoring(newValue)} + validation={validation} + packageInfo={packageInfo} + setHasAgentPolicyError={setHasAgentPolicyError} + defaultAgentPolicyId={queryParamsPolicyId} + /> + ), [ packageInfo, queryParamsPolicyId, @@ -508,7 +482,6 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { updateNewAgentPolicy, validation, withSysMonitoring, - agentPolicies.length, ] ); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx new file mode 100644 index 0000000000000..5aa46674d58d9 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -0,0 +1,107 @@ +/* + * 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 React, { useMemo } from 'react'; +import { EuiTabbedContent } from '@elastic/eui'; +import styled from 'styled-components'; + +import { useGetAgentPolicies } from '../../../hooks'; +import type { AgentPolicy, NewAgentPolicy, PackageInfo } from '../../../types'; +import { AgentPolicyIntegrationForm } from '../components'; +import type { ValidationResults } from '../components/agent_policy_validation'; + +import { StepSelectAgentPolicy } from './step_select_agent_policy'; + +const StyledEuiTabbedContent = styled(EuiTabbedContent)` + [role='tabpanel'] { + padding-top: ${(props) => props.theme.eui.paddingSizes.m}; + } +`; + +interface Props { + agentPolicy: AgentPolicy | undefined; + updateAgentPolicy: (u: AgentPolicy | undefined) => void; + newAgentPolicy: Partial; + updateNewAgentPolicy: (u: Partial) => void; + withSysMonitoring: boolean; + updateSysMonitoring: (newValue: boolean) => void; + validation: ValidationResults; + packageInfo?: PackageInfo; + setHasAgentPolicyError: (hasError: boolean) => void; + defaultAgentPolicyId?: string; +} + +export const StepSelectHosts: React.FunctionComponent = ({ + agentPolicy, + updateAgentPolicy, + newAgentPolicy, + updateNewAgentPolicy, + withSysMonitoring, + updateSysMonitoring, + validation, + packageInfo, + setHasAgentPolicyError, + defaultAgentPolicyId, +}) => { + let agentPolicies = []; + const { data: agentPoliciesData, error: err } = useGetAgentPolicies({ + page: 1, + perPage: 1000, + sortField: 'name', + sortOrder: 'asc', + full: true, + }); + if (err) { + // eslint-disable-next-line no-console + console.debug('Could not retrieve agent policies'); + } + agentPolicies = useMemo( + () => agentPoliciesData?.items.filter((policy) => !policy.is_managed) || [], + [agentPoliciesData?.items] + ); + + const tabs = [ + { + id: 'new', + name: 'New hosts', + content: ( + + ), + }, + { + id: 'existing', + name: 'Existing hosts', + content: ( + + ), + }, + ]; + + return agentPolicies.length > 0 ? ( + + ) : ( + + ); +}; From 8ccfe99138394b11a508915358894cccd3b45ec0 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 20 Dec 2021 15:49:28 +0100 Subject: [PATCH 05/99] fix checks --- x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - 2 files changed, 2 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 86d059f13e85c..b087a34c5b8ea 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10160,7 +10160,6 @@ "xpack.fleet.agentPolicyForm.namespaceFieldDescription": "名前空間はユーザーが構成できる任意のグループであり、データの検索とユーザーアクセス権の管理が容易になります。ポリシー名前空間は、統合のデータストリームの名前を設定するために使用されます。{fleetUserGuide}。", "xpack.fleet.agentPolicyForm.nameSpaceFieldDescription.fleetUserGuideLabel": "詳細", "xpack.fleet.agentPolicyForm.namespaceFieldLabel": "デフォルト名前空間", - "xpack.fleet.agentPolicyForm.systemMonitoringFieldLabel": "システム監視", "xpack.fleet.agentPolicyForm.systemMonitoringText": "システムログとメトリックの収集", "xpack.fleet.agentPolicyForm.systemMonitoringTooltipText": "このオプションを有効にすると、システムログとメトリックを収集する統合でポリシーをブートストラップできます。", "xpack.fleet.agentPolicyForm.unenrollmentTimeoutDescription": "任意のタイムアウト(秒)。指定されている場合、この期間が経過した後、エージェントは自動的に登録解除されます。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index b31ba78246b3f..98e309458bf65 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -10253,7 +10253,6 @@ "xpack.fleet.agentPolicyForm.namespaceFieldDescription": "命名空间是用户可配置的任意分组,使搜索数据和管理用户权限更容易。策略命名空间用于命名其集成的数据流。{fleetUserGuide}。", "xpack.fleet.agentPolicyForm.nameSpaceFieldDescription.fleetUserGuideLabel": "了解详情", "xpack.fleet.agentPolicyForm.namespaceFieldLabel": "默认命名空间", - "xpack.fleet.agentPolicyForm.systemMonitoringFieldLabel": "系统监测", "xpack.fleet.agentPolicyForm.systemMonitoringText": "收集系统日志和指标", "xpack.fleet.agentPolicyForm.systemMonitoringTooltipText": "启用此选项可使用收集系统日志和指标的集成启动您的策略。", "xpack.fleet.agentPolicyForm.unenrollmentTimeoutDescription": "可选超时(秒)。若提供,代理断开连接此段时间后,将自动注销。", From 8249dd4cc4d5be29d96d72fd6764e72b47dd6983 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 20 Dec 2021 15:50:57 +0100 Subject: [PATCH 06/99] ignore tests --- .../plugins/fleet/cypress/integration/fleet_startup.spec.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 804fe56510c1d..5938e07c115ec 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -18,13 +18,14 @@ describe('Fleet startup', () => { cy.get('.euiBadge').contains('Healthy'); }); - it('should display default agent policies on agent policies tab', () => { + // TODO update assertions + it.skip('should display default agent policies on agent policies tab', () => { cy.getBySel(AGENT_POLICIES_TAB).click(); cy.get('.euiLink').contains('Default policy'); cy.get('.euiLink').contains('Default Fleet Server policy'); }); - it('should display default tokens on enrollment tokens tab', () => { + it.skip('should display default tokens on enrollment tokens tab', () => { cy.getBySel(ENROLLMENT_TOKENS_TAB).click(); cy.get('.euiTableRow').should('have.length', 2); cy.get('.euiTableRowCell').contains('Default policy'); From 5c28e7b455b5072f0f9e9c86596b5b89051c7378 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 20 Dec 2021 17:04:56 +0100 Subject: [PATCH 07/99] fix i18n --- x-pack/plugins/translations/translations/ja-JP.json | 2 -- x-pack/plugins/translations/translations/zh-CN.json | 2 -- 2 files changed, 4 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index b087a34c5b8ea..7ca55c9a462fd 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10148,7 +10148,6 @@ "xpack.fleet.agentPolicyForm.advancedOptionsToggleLabel": "高度なオプション", "xpack.fleet.agentPolicyForm.descriptionFieldLabel": "説明", "xpack.fleet.agentPolicyForm.descriptionFieldPlaceholder": "どのようにこのポリシーを使用しますか?", - "xpack.fleet.agentPolicyForm.monitoringDescription": "パフォーマンスのデバッグと追跡のために、エージェントに関するデータを収集します。監視データは上記のデフォルト名前空間に書き込まれます。", "xpack.fleet.agentPolicyForm.monitoringLabel": "アラート監視", "xpack.fleet.agentPolicyForm.monitoringLogsFieldLabel": "エージェントログを収集", "xpack.fleet.agentPolicyForm.monitoringLogsTooltipText": "このポリシーを使用するElasticエージェントからログを収集します。", @@ -10161,7 +10160,6 @@ "xpack.fleet.agentPolicyForm.nameSpaceFieldDescription.fleetUserGuideLabel": "詳細", "xpack.fleet.agentPolicyForm.namespaceFieldLabel": "デフォルト名前空間", "xpack.fleet.agentPolicyForm.systemMonitoringText": "システムログとメトリックの収集", - "xpack.fleet.agentPolicyForm.systemMonitoringTooltipText": "このオプションを有効にすると、システムログとメトリックを収集する統合でポリシーをブートストラップできます。", "xpack.fleet.agentPolicyForm.unenrollmentTimeoutDescription": "任意のタイムアウト(秒)。指定されている場合、この期間が経過した後、エージェントは自動的に登録解除されます。", "xpack.fleet.agentPolicyForm.unenrollmentTimeoutLabel": "登録解除タイムアウト", "xpack.fleet.agentPolicyForm.unenrollTimeoutMinValueErrorMessage": "タイムアウトは0よりも大きい値でなければなりません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 98e309458bf65..6bc67a9f150de 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -10241,7 +10241,6 @@ "xpack.fleet.agentPolicyForm.advancedOptionsToggleLabel": "高级选项", "xpack.fleet.agentPolicyForm.descriptionFieldLabel": "描述", "xpack.fleet.agentPolicyForm.descriptionFieldPlaceholder": "此策略将如何使用?", - "xpack.fleet.agentPolicyForm.monitoringDescription": "收集有关代理的数据,用于调试和跟踪性能。监测数据将写入到上面指定的默认命名空间。", "xpack.fleet.agentPolicyForm.monitoringLabel": "代理监测", "xpack.fleet.agentPolicyForm.monitoringLogsFieldLabel": "收集代理日志", "xpack.fleet.agentPolicyForm.monitoringLogsTooltipText": "从使用此策略的 Elastic 代理收集日志。", @@ -10254,7 +10253,6 @@ "xpack.fleet.agentPolicyForm.nameSpaceFieldDescription.fleetUserGuideLabel": "了解详情", "xpack.fleet.agentPolicyForm.namespaceFieldLabel": "默认命名空间", "xpack.fleet.agentPolicyForm.systemMonitoringText": "收集系统日志和指标", - "xpack.fleet.agentPolicyForm.systemMonitoringTooltipText": "启用此选项可使用收集系统日志和指标的集成启动您的策略。", "xpack.fleet.agentPolicyForm.unenrollmentTimeoutDescription": "可选超时(秒)。若提供,代理断开连接此段时间后,将自动注销。", "xpack.fleet.agentPolicyForm.unenrollmentTimeoutLabel": "注销超时", "xpack.fleet.agentPolicyForm.unenrollTimeoutMinValueErrorMessage": "超时必须大于零。", From 23de22c9339065abf2bccbdf3c2ddcc51f5b55e7 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 29 Dec 2021 13:52:22 +0100 Subject: [PATCH 08/99] use max instead of sort --- .../server/services/package_policy.test.ts | 22 +++++++++++++++++++ .../fleet/server/services/package_policy.ts | 22 ++++++++----------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/package_policy.test.ts b/x-pack/plugins/fleet/server/services/package_policy.test.ts index 72f6ff49e608d..dca55d44630ce 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.test.ts @@ -49,6 +49,7 @@ import { updatePackageInputs, packagePolicyService, _applyIndexPrivileges, + incrementPackageName, } from './package_policy'; import { appContextService } from './app_context'; import { fetchInfo } from './epm/registry'; @@ -3226,4 +3227,25 @@ describe('_applyIndexPrivileges()', () => { const streamOut = _applyIndexPrivileges(packageStream, inputStream); expect(streamOut).toEqual(expectedStream); }); + + describe('increment package name', () => { + it('should return 1 if no existing policies', async () => { + packagePolicyService.list = jest.fn().mockResolvedValue(undefined); + const newName = await incrementPackageName(savedObjectsClientMock.create(), 'apache'); + expect(newName).toEqual('apache-1'); + }); + + it('should return 11 if max policy name is 10', async () => { + packagePolicyService.list = jest.fn().mockResolvedValue({ + items: [ + { name: 'apache-1' }, + { name: 'aws-11' }, + { name: 'apache-10' }, + { name: 'apache-9' }, + ], + }); + const newName = await incrementPackageName(savedObjectsClientMock.create(), 'apache'); + expect(newName).toEqual('apache-11'); + }); + }); }); diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index e725298ce6d96..5e4c6d6a71b3c 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -1374,7 +1374,7 @@ function deepMergeVars(original: any, override: any, keepOriginalValue = false): export async function incrementPackageName( soClient: SavedObjectsClientContract, packageName: string -) { +): Promise { // Fetch all packagePolicies having the package name const packagePolicyData = await packagePolicyService.list(soClient, { perPage: SO_SEARCH_LIMIT, @@ -1384,16 +1384,12 @@ export async function incrementPackageName( // Retrieve highest number appended to package policy name and increment it by one const pkgPoliciesNamePattern = new RegExp(`${packageName}-(\\d+)`); - const pkgPoliciesWithMatchingNames = packagePolicyData?.items - ? packagePolicyData.items - .filter((ds) => Boolean(ds.name.match(pkgPoliciesNamePattern))) - .map((ds) => parseInt(ds.name.match(pkgPoliciesNamePattern)![1], 10)) - .sort((a, b) => a - b) - : []; - - return `${packageName}-${ - pkgPoliciesWithMatchingNames.length - ? pkgPoliciesWithMatchingNames[pkgPoliciesWithMatchingNames.length - 1] + 1 - : 1 - }`; + const maxPkgPolicyName = Math.max( + ...(packagePolicyData?.items ?? []) + .filter((ds) => Boolean(ds.name.match(pkgPoliciesNamePattern))) + .map((ds) => parseInt(ds.name.match(pkgPoliciesNamePattern)![1], 10)), + 0 + ); + + return `${packageName}-${maxPkgPolicyName + 1}`; } From a453c20d100211c20f783a4cf12922eaf1a8c56a Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 29 Dec 2021 16:41:36 +0100 Subject: [PATCH 09/99] Add agent and Fleet server policy --- .../components/agent_policy_create_inline.tsx | 196 ++++++++++++++++++ .../sections/agent_policy/components/index.ts | 1 + .../fleet_server_on_prem_instructions.tsx | 17 ++ .../agent_enrollment_flyout/steps.tsx | 27 ++- .../server/routes/agent_policy/handlers.ts | 28 ++- .../fleet/server/types/models/agent_policy.ts | 1 + 6 files changed, 254 insertions(+), 16 deletions(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx new file mode 100644 index 0000000000000..dbe2f4084884b --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -0,0 +1,196 @@ +/* + * 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 React, { useCallback, useState } from 'react'; +import { + EuiAccordion, + EuiButton, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiForm, + EuiFormRow, + EuiLink, + EuiSpacer, + EuiText, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import styled from 'styled-components'; +import { i18n } from '@kbn/i18n'; + +import { dataTypes } from '../../../../../../common'; +import { agentPolicyFormValidation } from '../components'; + +import type { NewAgentPolicy } from '../../../types'; + +import { sendCreateAgentPolicy, useStartServices } from '../../../hooks'; + +import { AgentPolicyAdvancedOptionsContent } from './agent_policy_advanced_fields'; +import { AgentPolicyFormSystemMonitoringCheckbox } from './agent_policy_system_monitoring_field'; + +const StyledEuiAccordion = styled(EuiAccordion)` + .ingest-active-button { + color: ${(props) => props.theme.eui.euiColorPrimary}; + } +`; + +interface Props { + updateAgentPolicy: (u: string) => void; + isFleetServerPolicy?: boolean; +} + +export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ + updateAgentPolicy, + isFleetServerPolicy, +}) => { + const [touchedFields, setTouchedFields] = useState<{ [key: string]: boolean }>({}); + + const defaultPolicy = { + name: isFleetServerPolicy ? 'Default Fleet Server policy' : 'Default policy', + description: '', + namespace: 'default', + monitoring_enabled: Object.values(dataTypes), + is_default_fleet_server: isFleetServerPolicy || undefined, + }; + + const [newAgentPolicy, setNewAgentPolicy] = useState({ + ...defaultPolicy, + }); + + const updateNewAgentPolicy = useCallback( + (updatedFields: Partial) => { + setNewAgentPolicy({ + ...newAgentPolicy, + ...updatedFields, + }); + }, + [setNewAgentPolicy, newAgentPolicy] + ); + + const [withSysMonitoring, setWithSysMonitoring] = useState(true); + const validation = agentPolicyFormValidation(newAgentPolicy); + + const [isLoading, setIsLoading] = useState(false); + + const { notifications } = useStartServices(); + + const createAgentPolicy = useCallback(async () => { + try { + setIsLoading(true); + const resp = await sendCreateAgentPolicy(newAgentPolicy, { withSysMonitoring }); + if (resp.error) throw resp.error; + if (resp.data) { + notifications.toasts.addSuccess( + i18n.translate('xpack.fleet.createAgentPolicy.successNotificationTitle', { + defaultMessage: "Agent policy '{name}' created", + values: { name: newAgentPolicy.name }, + }) + ); + updateAgentPolicy(resp.data.item.id); + } + } catch (e) { + notifications.toasts.addDanger( + i18n.translate('xpack.fleet.createAgentPolicy.errorNotificationTitle', { + defaultMessage: 'Unable to create agent policy', + }) + ); + } finally { + setIsLoading(false); + } + }, [newAgentPolicy, withSysMonitoring, notifications, updateAgentPolicy]); + + return ( + + + {isFleetServerPolicy ? ( + + ) : ( + + + + ), + }} + /> + )} + + + + + + updateNewAgentPolicy({ name: e.target.value })} + isInvalid={Boolean(touchedFields.name && validation.name)} + onBlur={() => setTouchedFields({ ...touchedFields, name: true })} + placeholder={i18n.translate('xpack.fleet.agentPolicyForm.nameFieldPlaceholder', { + defaultMessage: 'Choose a name', + })} + /> + + + + createAgentPolicy()} + isLoading={isLoading} + > + + + + + + setWithSysMonitoring(value)} + /> + + <> + + + } + buttonClassName="ingest-active-button" + > + + {}} + /> + + + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/index.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/index.ts index f805ae5c3b15e..f57714f7e76f5 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/index.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/index.ts @@ -16,3 +16,4 @@ export { ConfirmDeployAgentPolicyModal } from './confirm_deploy_modal'; export { AgentPolicyActionMenu } from './actions_menu'; export { AgentPolicyIntegrationForm } from './agent_policy_integration'; export { agentPolicyFormValidation } from './agent_policy_validation'; +export { AgentPolicyCreateInlineForm } from './agent_policy_create_inline'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index b2eaf904ee1bb..db9bbd25e6538 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -48,6 +48,8 @@ import type { PackagePolicy } from '../../../../types'; import { FLEET_SERVER_PACKAGE } from '../../../../constants'; import { FleetServerOnPremRequiredCallout } from '../../components'; +import { AgentPolicyCreateInlineForm } from '../../../agent_policy/components'; + import { getInstallCommandForPlatform } from './install_command_utils'; const URL_REGEX = /^(https?):\/\/[^\s$.?#].[^\s]*$/gm; @@ -369,6 +371,21 @@ const AgentPolicySelectionStep = ({ [setPolicyId] ); + if (agentPolicies.length === 0) { + return { + title: i18n.translate('xpack.fleet.fleetServerSetup.stepCreateAgentPolicyTitle', { + defaultMessage: 'Create a Fleet Server agent policy', + }), + status: undefined, + children: ( + setPolicyId(value)} + isFleetServerPolicy={true} + /> + ), + }; + } + return { title: i18n.translate('xpack.fleet.fleetServerSetup.stepSelectAgentPolicyTitle', { defaultMessage: 'Select an Agent policy', diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx index 8cdae7eaf90be..1eeaa117d4294 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx @@ -16,6 +16,8 @@ import semverPatch from 'semver/functions/patch'; import type { AgentPolicy } from '../../types'; import { useKibanaVersion } from '../../hooks'; +import { AgentPolicyCreateInlineForm } from '../../applications/fleet/sections/agent_policy/components'; + import { EnrollmentStepAgentPolicy } from './agent_policy_selection'; import { AdvancedAgentAuthenticationSettings } from './advanced_agent_authentication_settings'; @@ -106,18 +108,21 @@ export const AgentPolicySelectionStep = ({ return { title: i18n.translate('xpack.fleet.agentEnrollment.stepChooseAgentPolicyTitle', { - defaultMessage: 'Choose an agent policy', + defaultMessage: 'What type of host are you adding?', }), - children: ( - - ), + children: + (agentPolicies ?? []).length > 0 ? ( + + ) : ( + + ), }; }; diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index 45677d21be7d0..aab087ce5db34 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -24,7 +24,11 @@ import type { GetFullAgentPolicyRequestSchema, FleetRequestHandler, } from '../../types'; -import { FLEET_ELASTIC_AGENT_PACKAGE, FLEET_SYSTEM_PACKAGE } from '../../../common'; +import { + FLEET_ELASTIC_AGENT_PACKAGE, + FLEET_SERVER_PACKAGE, + FLEET_SYSTEM_PACKAGE, +} from '../../../common'; import type { GetAgentPoliciesResponse, GetAgentPoliciesResponseItem, @@ -110,10 +114,19 @@ export const createAgentPolicyHandler: FleetRequestHandler< const esClient = context.core.elasticsearch.client.asInternalUser; const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined; const withSysMonitoring = request.query.sys_monitoring ?? false; + const isDefaultFleetServer = request.body.is_default_fleet_server ?? false; const spaceId = context.fleet.spaceId; // TODO set first default policy to is_default // TODO installing these packages might take long (about 2 mins) which causes network timeout. this results in an error, and fails next agent policy creation request. Could this be improved by bundled default packages? try { + if (isDefaultFleetServer) { + // install fleet server package if not yet installed + await ensureInstalledPackage({ + savedObjectsClient: soClient, + pkgName: FLEET_SERVER_PACKAGE, + esClient, + }); + } if (withSysMonitoring) { // install system package if not yet installed await ensureInstalledPackage({ @@ -135,10 +148,15 @@ export const createAgentPolicyHandler: FleetRequestHandler< agentPolicyService.create(soClient, esClient, request.body, { user, }), - // If needed, retrieve System package information and build a new package policy for the system package - // NOTE: we ignore failures in attempting to create package policy, since agent policy might have been created - // successfully - withSysMonitoring + // TODO case when both isDefaultFleetServer and withSysMonitoring is true + isDefaultFleetServer + ? packagePolicyService + .buildPackagePolicyFromPackage(soClient, FLEET_SERVER_PACKAGE) + .catch(() => undefined) + : // If needed, retrieve System package information and build a new package policy for the system package + // NOTE: we ignore failures in attempting to create package policy, since agent policy might have been created + // successfully + withSysMonitoring ? packagePolicyService .buildPackagePolicyFromPackage(soClient, FLEET_SYSTEM_PACKAGE) .catch(() => undefined) diff --git a/x-pack/plugins/fleet/server/types/models/agent_policy.ts b/x-pack/plugins/fleet/server/types/models/agent_policy.ts index 2e17c4ffe898e..c2ecd1c655cdc 100644 --- a/x-pack/plugins/fleet/server/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/server/types/models/agent_policy.ts @@ -16,6 +16,7 @@ export const AgentPolicyBaseSchema = { namespace: NamespaceSchema, description: schema.maybe(schema.string()), is_managed: schema.maybe(schema.boolean()), + is_default_fleet_server: schema.maybe(schema.boolean()), unenroll_timeout: schema.maybe(schema.number({ min: 0 })), monitoring_enabled: schema.maybe( schema.arrayOf( From be86eb5f6c2da79b479284840567d92fe976ef7a Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 30 Dec 2021 09:40:14 +0100 Subject: [PATCH 10/99] fix bug with monitoring checkbox --- .../components/agent_policy_advanced_fields.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx index a509dfacaa4ac..a7f6dd4f6d528 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx @@ -49,6 +49,9 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent = const { docLinks } = useStartServices(); const [touchedFields, setTouchedFields] = useState<{ [key: string]: boolean }>({}); + // agent monitoring checkbox group can appear multiple times in the DOM, ids have to be unique to work correctly + const monitoringCheckboxIdSuffix = Date.now(); + return ( <> = disabled={agentPolicy.is_managed === true} options={[ { - id: dataTypes.Logs, + id: `${dataTypes.Logs}_${monitoringCheckboxIdSuffix}`, label: ( <> = ), }, { - id: dataTypes.Metrics, + id: `${dataTypes.Metrics}_${monitoringCheckboxIdSuffix}`, label: ( <> = }, ]} idToSelectedMap={(agentPolicy.monitoring_enabled || []).reduce( - (acc: { logs: boolean; metrics: boolean }, key) => { - acc[key] = true; + (acc: { [key: string]: boolean }, key) => { + acc[`${key}_${monitoringCheckboxIdSuffix}`] = true; return acc; }, { logs: false, metrics: false } )} - onChange={(id) => { + onChange={(longId) => { + const id = longId.split('_')[0]; if (id !== dataTypes.Logs && id !== dataTypes.Metrics) { return; } From 0eca9f6b045f17aeaf141281f72f284c93d69ac8 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 30 Dec 2021 10:32:40 +0100 Subject: [PATCH 11/99] fix test --- x-pack/test/fleet_api_integration/apis/epm/delete.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/test/fleet_api_integration/apis/epm/delete.ts b/x-pack/test/fleet_api_integration/apis/epm/delete.ts index 5e839e51113c4..642ef62d574e0 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/delete.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/delete.ts @@ -41,11 +41,11 @@ export default function (providerContext: FtrProviderContext) { await deletePackage(requiredPackage, pkgVersion); }); - it('should return 400 if trying to uninstall a required package', async function () { + it('should return 200 if trying to uninstall a required package', async function () { await supertest .delete(`/api/fleet/epm/packages/${requiredPackage}/${pkgVersion}`) .set('kbn-xsrf', 'xxxx') - .expect(400); + .expect(200); }); it('should return 200 if trying to force uninstall a required package', async function () { From b0d476f55ecf4f179494dcf88e5a0f994c6f5dce Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 30 Dec 2021 10:34:12 +0100 Subject: [PATCH 12/99] skip test --- x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 5938e07c115ec..ee070396f53a8 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -13,7 +13,7 @@ describe('Fleet startup', () => { navigateTo(FLEET); }); - it('should display Add agent button and Healthy agent once Fleet Agent page loaded', () => { + it.skip('should display Add agent button and Healthy agent once Fleet Agent page loaded', () => { cy.getBySel(ADD_AGENT_BUTTON).contains('Add agent'); cy.get('.euiBadge').contains('Healthy'); }); From fef20325b7426d1530f493f4dadc4bd1b694f559 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 30 Dec 2021 15:23:00 +0100 Subject: [PATCH 13/99] fixed validation --- .../create_package_policy_page/index.tsx | 52 ++++++++++++++++--- .../step_select_hosts.tsx | 32 ++++++++++-- .../server/routes/agent_policy/handlers.ts | 1 - .../fleet_api_integration/apis/epm/delete.ts | 2 +- 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index 335a78dd87076..0641c0b3d0ed5 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -57,7 +57,7 @@ import { validatePackagePolicy, validationHasErrors } from './services'; import { appendOnSaveQueryParamsToPath } from './utils'; import { StepConfigurePackagePolicy } from './step_configure_package'; import { StepDefinePackagePolicy } from './step_define_package_policy'; -import { StepSelectHosts } from './step_select_hosts'; +import { SelectedPolicyTab, StepSelectHosts } from './step_select_hosts'; const StepsWithLessPadding = styled(EuiSteps)` .euiStep__content { @@ -151,6 +151,10 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { }, [agentPolicyId, isFleetEnabled]); const [agentCount, setAgentCount] = useState(0); + const [selectedPolicyTab, setSelectedPolicyTab] = useState( + SelectedPolicyTab.NEW + ); + // New package policy state const [packagePolicy, setPackagePolicy] = useState({ name: '', @@ -201,14 +205,37 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { [packageInfo, setAgentPolicy, setFormState] ); + const setPolicyValidation = ( + selectedTab: SelectedPolicyTab, + updatedAgentPolicy: NewAgentPolicy + ) => { + if (selectedTab === SelectedPolicyTab.NEW) { + if (!updatedAgentPolicy.name || !updatedAgentPolicy.namespace) { + setHasAgentPolicyError(true); + } else { + setHasAgentPolicyError(false); + } + } + }; + const updateNewAgentPolicy = useCallback( (updatedFields: Partial) => { - setNewAgentPolicy({ + const updatedAgentPolicy = { ...newAgentPolicy, ...updatedFields, - }); + }; + setNewAgentPolicy(updatedAgentPolicy); + setPolicyValidation(selectedPolicyTab, updatedAgentPolicy); }, - [setNewAgentPolicy, newAgentPolicy] + [setNewAgentPolicy, newAgentPolicy, selectedPolicyTab] + ); + + const updateSelectedPolicy = useCallback( + (policy) => { + setSelectedPolicyTab(policy); + setPolicyValidation(policy, newAgentPolicy); + }, + [setSelectedPolicyTab, newAgentPolicy] ); const hasErrors = validationResults ? validationHasErrors(validationResults) : false; @@ -249,11 +276,17 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { ? validationHasErrors(newValidationResults) : false; const hasAgentPolicy = newPackagePolicy.policy_id && newPackagePolicy.policy_id !== ''; - if (hasPackage && hasAgentPolicy && !hasValidationErrors) { + if ( + hasPackage && + (hasAgentPolicy || selectedPolicyTab === SelectedPolicyTab.NEW) && + !hasValidationErrors + ) { setFormState('VALID'); + } else { + setFormState('INVALID'); } }, - [packagePolicy, updatePackagePolicyValidation] + [packagePolicy, updatePackagePolicyValidation, selectedPolicyTab] ); const handleExtensionViewOnChange = useCallback< @@ -356,7 +389,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { } let policyId = ''; // save agent policy - if (!agentPolicy?.id && newAgentPolicy) { + if (selectedPolicyTab === SelectedPolicyTab.NEW) { try { setFormState('LOADING'); const resp = await sendCreateAgentPolicy(newAgentPolicy, { withSysMonitoring }); @@ -387,7 +420,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { // passing pkgPolicy with policy_id here as setPackagePolicy doesn't propagate immediately const { error, data } = await savePackagePolicy({ ...packagePolicy, - policy_id: packagePolicy.policy_id || policyId, + policy_id: policyId || packagePolicy.policy_id, }); if (!error) { setSavedPackagePolicy(data!.item); @@ -434,6 +467,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { packagePolicy, updatePackagePolicy, withSysMonitoring, + selectedPolicyTab, ]); const integrationInfo = useMemo( @@ -471,6 +505,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { packageInfo={packageInfo} setHasAgentPolicyError={setHasAgentPolicyError} defaultAgentPolicyId={queryParamsPolicyId} + updateSelectedTab={updateSelectedPolicy} /> ), [ @@ -482,6 +517,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { updateNewAgentPolicy, validation, withSysMonitoring, + updateSelectedPolicy, ] ); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx index 5aa46674d58d9..60aa2dd6dde86 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -5,7 +5,8 @@ * 2.0. */ -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; +import type { EuiTabbedContentTab } from '@elastic/eui'; import { EuiTabbedContent } from '@elastic/eui'; import styled from 'styled-components'; @@ -16,6 +17,11 @@ import type { ValidationResults } from '../components/agent_policy_validation'; import { StepSelectAgentPolicy } from './step_select_agent_policy'; +export enum SelectedPolicyTab { + NEW = 'new', + EXISTING = 'existing', +} + const StyledEuiTabbedContent = styled(EuiTabbedContent)` [role='tabpanel'] { padding-top: ${(props) => props.theme.eui.paddingSizes.m}; @@ -33,6 +39,7 @@ interface Props { packageInfo?: PackageInfo; setHasAgentPolicyError: (hasError: boolean) => void; defaultAgentPolicyId?: string; + updateSelectedTab: (tab: SelectedPolicyTab) => void; } export const StepSelectHosts: React.FunctionComponent = ({ @@ -46,6 +53,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ packageInfo, setHasAgentPolicyError, defaultAgentPolicyId, + updateSelectedTab, }) => { let agentPolicies = []; const { data: agentPoliciesData, error: err } = useGetAgentPolicies({ @@ -64,9 +72,18 @@ export const StepSelectHosts: React.FunctionComponent = ({ [agentPoliciesData?.items] ); + useEffect(() => { + if (agentPolicies.length > 0) { + updateNewAgentPolicy({ + ...newAgentPolicy, + name: '', + }); + } + }, [agentPolicies.length]); // eslint-disable-line react-hooks/exhaustive-deps + const tabs = [ { - id: 'new', + id: SelectedPolicyTab.NEW, name: 'New hosts', content: ( = ({ ), }, { - id: 'existing', + id: SelectedPolicyTab.EXISTING, name: 'Existing hosts', content: ( = ({ }, ]; + const handleOnTabClick = (tab: EuiTabbedContentTab) => + updateSelectedTab(tab.id as SelectedPolicyTab); + return agentPolicies.length > 0 ? ( - + ) : ( Date: Thu, 30 Dec 2021 16:15:10 +0100 Subject: [PATCH 14/99] fixed fleet server policy install and missing enrollment keys --- .../agent_enrollment_flyout/steps.tsx | 2 +- .../server/routes/agent_policy/handlers.ts | 36 +++++++++++-------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx index 1eeaa117d4294..c47fcffa11c63 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx @@ -111,7 +111,7 @@ export const AgentPolicySelectionStep = ({ defaultMessage: 'What type of host are you adding?', }), children: - (agentPolicies ?? []).length > 0 ? ( + regularAgentPolicies.length > 0 ? ( undefined) - : // If needed, retrieve System package information and build a new package policy for the system package - // NOTE: we ignore failures in attempting to create package policy, since agent policy might have been created - // successfully - withSysMonitoring - ? packagePolicyService - .buildPackagePolicyFromPackage(soClient, FLEET_SYSTEM_PACKAGE) + .buildPackagePolicyFromPackage(soClient, packageToInstall) .catch(() => undefined) : undefined, ]); // Create the system monitoring package policy and add it to agent policy. - if (withSysMonitoring && newSysPackagePolicy !== undefined && agentPolicy !== undefined) { - newSysPackagePolicy.policy_id = agentPolicy.id; - newSysPackagePolicy.namespace = agentPolicy.namespace; - newSysPackagePolicy.name = await incrementPackageName(soClient, FLEET_SYSTEM_PACKAGE); + if ( + (withSysMonitoring || isDefaultFleetServer) && + newPackagePolicy !== undefined && + agentPolicy !== undefined + ) { + newPackagePolicy.policy_id = agentPolicy.id; + newPackagePolicy.namespace = agentPolicy.namespace; + newPackagePolicy.name = await incrementPackageName(soClient, packageToInstall); - await packagePolicyService.create(soClient, esClient, newSysPackagePolicy, { + await packagePolicyService.create(soClient, esClient, newPackagePolicy, { spaceId, user, bumpRevision: false, @@ -177,6 +181,8 @@ export const createAgentPolicyHandler: FleetRequestHandler< await agentPolicyService.createFleetServerPolicy(soClient, agentPolicy.id); + ensureDefaultEnrollmentAPIKeysExists(soClient, esClient); + const body: CreateAgentPolicyResponse = { item: agentPolicy, }; From 3bafb802563fae9aba65002c38f45a5f31d9972d Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 31 Dec 2021 09:42:45 +0100 Subject: [PATCH 15/99] fixed test --- x-pack/test/fleet_api_integration/apis/epm/setup.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/x-pack/test/fleet_api_integration/apis/epm/setup.ts b/x-pack/test/fleet_api_integration/apis/epm/setup.ts index b4812b39f74ef..351ec27c3abe3 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/setup.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/setup.ts @@ -82,12 +82,18 @@ export default function (providerContext: FtrProviderContext) { .set('Authorization', `Bearer ${token.value}`) .set('kbn-xsrf', 'xxx') .expect(200); - const response = await supertestWithoutAuth + await supertestWithoutAuth .get('/api/fleet/enrollment_api_keys') .set('Authorization', `Bearer ${token.value}`) .set('kbn-xsrf', 'xxx') .expect(200); - const enrollmentApiKeyId = response.body.items[0].id; + const response = await supertest + .post('/api/fleet/enrollment_api_keys') + .set('Authorization', `Bearer ${token.value}`) + .set('kbn-xsrf', 'xxx') + .send({ policy_id: '' }) + .expect(200); + const enrollmentApiKeyId = response.body.item.id; await supertestWithoutAuth .get(`/api/fleet/enrollment_api_keys/${enrollmentApiKeyId}`) .set('Authorization', `Bearer ${token.value}`) From d9611bf456013d6b9e55044a34b6ac4824f040db Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 31 Dec 2021 11:18:17 +0100 Subject: [PATCH 16/99] fixed test --- x-pack/test/fleet_api_integration/apis/fleet_setup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/fleet_api_integration/apis/fleet_setup.ts b/x-pack/test/fleet_api_integration/apis/fleet_setup.ts index c399f53fe8366..1d640f50c04a3 100644 --- a/x-pack/test/fleet_api_integration/apis/fleet_setup.ts +++ b/x-pack/test/fleet_api_integration/apis/fleet_setup.ts @@ -75,7 +75,7 @@ export default function (providerContext: FtrProviderContext) { .map((p: any) => p.name) .sort(); - expect(installedPackages).to.eql(['elastic_agent', 'endpoint', 'fleet_server', 'system']); + expect(installedPackages).to.eql(['endpoint']); }); }); } From 9383a7d1fc6353a0af2fa71b5a9bb766305daaf0 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 31 Dec 2021 14:33:42 +0100 Subject: [PATCH 17/99] cypress tests --- .../cypress/integration/fleet_startup.spec.ts | 68 +++++++++++++++---- x-pack/plugins/fleet/cypress/support/index.ts | 2 +- .../fleet/cypress/tasks/integrations.ts | 1 + .../components/agent_policy_create_inline.tsx | 1 + .../components/create_agent_policy.tsx | 1 + .../fleet/sections/agents/index.tsx | 7 +- x-pack/test/fleet_cypress/runner.ts | 5 ++ 7 files changed, 68 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index ee070396f53a8..e02e402267225 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -5,30 +5,68 @@ * 2.0. */ -import { ADD_AGENT_BUTTON, AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; +import { AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; import { FLEET, navigateTo } from '../tasks/navigation'; describe('Fleet startup', () => { - before(() => { + beforeEach(() => { navigateTo(FLEET); }); - it.skip('should display Add agent button and Healthy agent once Fleet Agent page loaded', () => { - cy.getBySel(ADD_AGENT_BUTTON).contains('Add agent'); - cy.get('.euiBadge').contains('Healthy'); + function navigateToAgentPolicies() { + cy.getBySel(AGENT_POLICIES_TAB).click(); + cy.get('.euiLoadingSpinner').should('not.exist'); + } + + function navigateToAgentPolicy(name: string) { + cy.get('.euiLink').contains(name).click(); + cy.get('.euiLoadingSpinner').should('not.exist'); + } + + function navigateToEnrollmentTokens() { + cy.getBySel(ENROLLMENT_TOKENS_TAB).click(); + cy.get('.euiButtonIcon--danger'); // wait for trash icon + } + + it('should create Default Fleet Server policy', () => { + cy.getBySel('createFleetServerPolicyBtn').click(); + cy.getBySel('euiToastHeader'); + + navigateToAgentPolicies(); + + navigateToAgentPolicy('Default Fleet Server policy'); + cy.get('.euiLink').contains('Fleet Server'); + + cy.get('.euiButtonEmpty').contains('View all agent policies').click(); + + navigateToEnrollmentTokens(); + + cy.get('.euiTableCellContent').contains('Default Fleet Server policy'); }); - // TODO update assertions - it.skip('should display default agent policies on agent policies tab', () => { - cy.getBySel(AGENT_POLICIES_TAB).click(); - cy.get('.euiLink').contains('Default policy'); - cy.get('.euiLink').contains('Default Fleet Server policy'); + it('should create Default policy', () => { + cy.getBySel('addAgentBtnTop').click(); + cy.getBySel('createPolicyBtn').click(); + cy.getBySel('euiToastHeader'); + cy.getBySel('euiFlyoutCloseButton').click(); + + navigateToAgentPolicies(); + + navigateToAgentPolicy('Default policy'); + cy.get('.euiLink').contains('System'); + + cy.get('.euiButtonEmpty').contains('View all agent policies').click(); + + navigateToEnrollmentTokens(); + cy.get('.euiTableCellContent').contains('Default policy'); + + cy.visit('/app/integrations/installed'); + cy.getBySel('integration-card:epr:elastic_agent'); }); - it.skip('should display default tokens on enrollment tokens tab', () => { - cy.getBySel(ENROLLMENT_TOKENS_TAB).click(); - cy.get('.euiTableRow').should('have.length', 2); - cy.get('.euiTableRowCell').contains('Default policy'); - cy.get('.euiTableRowCell').contains('Default Fleet Server policy'); + // TODO enroll fleet server agent + + it.skip('should display Add agent button and Healthy agent once Fleet Agent page loaded', () => { + cy.get('.euiBadge').contains('Healthy'); }); }); diff --git a/x-pack/plugins/fleet/cypress/support/index.ts b/x-pack/plugins/fleet/cypress/support/index.ts index f074e424d93c3..3fe732a027a65 100644 --- a/x-pack/plugins/fleet/cypress/support/index.ts +++ b/x-pack/plugins/fleet/cypress/support/index.ts @@ -35,7 +35,7 @@ declare global { } function getBySel(selector: string, ...args: any[]) { - return cy.get(`[data-test-subj=${selector}]`, ...args); + return cy.get(`[data-test-subj="${selector}"]`, ...args); } Cypress.Commands.add('getBySel', getBySel); diff --git a/x-pack/plugins/fleet/cypress/tasks/integrations.ts b/x-pack/plugins/fleet/cypress/tasks/integrations.ts index e9e3f2613c3e8..749bb9b7a2842 100644 --- a/x-pack/plugins/fleet/cypress/tasks/integrations.ts +++ b/x-pack/plugins/fleet/cypress/tasks/integrations.ts @@ -15,6 +15,7 @@ import { export const addIntegration = () => { cy.getBySel(ADD_POLICY_BTN).click(); + cy.get('#existing').click(); // select Existing Hosts tab for agent policy cy.getBySel(CREATE_PACKAGE_POLICY_SAVE_BTN).click(); // sometimes agent is assigned to default policy, sometimes not cy.getBySel(CONFIRM_MODAL_BTN).click(); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index dbe2f4084884b..67d7956897826 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -155,6 +155,7 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ disabled={!newAgentPolicy.name} onClick={() => createAgentPolicy()} isLoading={isLoading} + data-test-subj={isFleetServerPolicy ? 'createFleetServerPolicyBtn' : 'createPolicyBtn'} > = ({ ); } }} + data-test-subj="createAgentPolicyFlyoutBtn" > { )} - setIsEnrollmentFlyoutOpen(true)}> + setIsEnrollmentFlyoutOpen(true)} + data-test-subj="addAgentBtnTop" + > diff --git a/x-pack/test/fleet_cypress/runner.ts b/x-pack/test/fleet_cypress/runner.ts index b49bfbdc091e2..19509174af843 100644 --- a/x-pack/test/fleet_cypress/runner.ts +++ b/x-pack/test/fleet_cypress/runner.ts @@ -50,6 +50,11 @@ async function withFleetAgent( process.exit(1); }); + // TODO fleet server should be started in tests after default policy is created + + await runner({}); + return; + await agentManager.setup(); await fleetManager.setup(); try { From 9f18b8f3b9a3e932af42cbc88d9c6670d3096c0a Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 31 Dec 2021 14:40:27 +0100 Subject: [PATCH 18/99] fix test --- .../fleet_api_integration/apis/enrollment_api_keys/crud.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/test/fleet_api_integration/apis/enrollment_api_keys/crud.ts b/x-pack/test/fleet_api_integration/apis/enrollment_api_keys/crud.ts index 1c584315a1871..6739521dcd71b 100644 --- a/x-pack/test/fleet_api_integration/apis/enrollment_api_keys/crud.ts +++ b/x-pack/test/fleet_api_integration/apis/enrollment_api_keys/crud.ts @@ -37,9 +37,9 @@ export default function (providerContext: FtrProviderContext) { .get(`/api/fleet/enrollment_api_keys`) .expect(200); - expect(apiResponse.total).to.be(3); + expect(apiResponse.total).to.be(2); expect(apiResponse.items[0]).to.have.keys('id', 'api_key_id', 'name'); - expect(apiResponse).to.have.keys('list'); + expect(apiResponse).to.have.keys('items'); }); }); From 8728d1ecea6dea20010d207f67ab0af8a6a79924 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 4 Jan 2022 11:19:44 +0100 Subject: [PATCH 19/99] added is_default, fixed test --- .../components/agent_policy_create_inline.tsx | 1 + .../create_package_policy_page/index.tsx | 1 + .../step_select_hosts.tsx | 1 + .../server/routes/agent_policy/handlers.ts | 1 - .../fleet/server/types/models/agent_policy.ts | 1 + .../apis/fleet_telemetry.ts | 28 +++++++++++++++---- 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index 67d7956897826..e62327491b72e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -55,6 +55,7 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ namespace: 'default', monitoring_enabled: Object.values(dataTypes), is_default_fleet_server: isFleetServerPolicy || undefined, + is_default: !isFleetServerPolicy, }; const [newAgentPolicy, setNewAgentPolicy] = useState({ diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index 0641c0b3d0ed5..b47be85d1e8dd 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -123,6 +123,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { description: '', namespace: 'default', monitoring_enabled: Object.values(dataTypes), + is_default: true, }; const [newAgentPolicy, setNewAgentPolicy] = useState({ diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx index 60aa2dd6dde86..82183cf7433c9 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -77,6 +77,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ updateNewAgentPolicy({ ...newAgentPolicy, name: '', + is_default: false, }); } }, [agentPolicies.length]); // eslint-disable-line react-hooks/exhaustive-deps diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index 5981b588d0ab3..9aa084462a7a8 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -117,7 +117,6 @@ export const createAgentPolicyHandler: FleetRequestHandler< const withSysMonitoring = request.query.sys_monitoring ?? false; const isDefaultFleetServer = request.body.is_default_fleet_server ?? false; const spaceId = context.fleet.spaceId; - // TODO set first default policy to is_default try { if (isDefaultFleetServer) { // install fleet server package if not yet installed diff --git a/x-pack/plugins/fleet/server/types/models/agent_policy.ts b/x-pack/plugins/fleet/server/types/models/agent_policy.ts index c2ecd1c655cdc..7f0376b32de7e 100644 --- a/x-pack/plugins/fleet/server/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/server/types/models/agent_policy.ts @@ -16,6 +16,7 @@ export const AgentPolicyBaseSchema = { namespace: NamespaceSchema, description: schema.maybe(schema.string()), is_managed: schema.maybe(schema.boolean()), + is_default: schema.maybe(schema.boolean()), is_default_fleet_server: schema.maybe(schema.boolean()), unenroll_timeout: schema.maybe(schema.number({ min: 0 })), monitoring_enabled: schema.maybe( diff --git a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts index 4d06de83f6917..291c535cc1221 100644 --- a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts +++ b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts @@ -70,13 +70,29 @@ export default function (providerContext: FtrProviderContext) { }); before(async () => { - // Get FleetServer policy id - const { body: apiResponse } = await supertest.get(`/api/fleet/agent_policies`).expect(200); - const defaultFleetServerPolicy = apiResponse.items.find( - (item: any) => item.is_default_fleet_server - ); + // create default policies + let { body: apiResponse } = await supertest + .post(`/api/fleet/agent_policies`) + .set('kbn-xsrf', 'kibana') + .send({ + name: 'Default Fleet Server policy', + namespace: 'default', + is_default_fleet_server: true, + }) + .expect(200); + const defaultFleetServerPolicy = apiResponse.item; + + ({ body: apiResponse } = await supertest + .post(`/api/fleet/agent_policies`) + .set('kbn-xsrf', 'kibana') + .send({ + name: 'Default policy', + namespace: 'default', + is_default: true, + }) + .expect(200)); - const defaultServerPolicy = apiResponse.items.find((item: any) => item.is_default); + const defaultServerPolicy = apiResponse.item; if (!defaultFleetServerPolicy) { throw new Error('No default Fleet server policy'); From c9fd581178402bf4db08c2735bfa331d3bf08eb5 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 4 Jan 2022 14:33:01 +0100 Subject: [PATCH 20/99] fix cypress --- .../fleet/cypress/integration/fleet_startup.spec.ts | 12 ++++-------- .../fleet/server/routes/agent_policy/handlers.ts | 2 -- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index e02e402267225..a1575cb07cf44 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -15,7 +15,7 @@ describe('Fleet startup', () => { function navigateToAgentPolicies() { cy.getBySel(AGENT_POLICIES_TAB).click(); - cy.get('.euiLoadingSpinner').should('not.exist'); + cy.get('.euiBasicTable-loading').should('not.exist'); } function navigateToAgentPolicy(name: string) { @@ -25,10 +25,11 @@ describe('Fleet startup', () => { function navigateToEnrollmentTokens() { cy.getBySel(ENROLLMENT_TOKENS_TAB).click(); - cy.get('.euiButtonIcon--danger'); // wait for trash icon + cy.get('.euiBasicTable-loading').should('not.exist'); } it('should create Default Fleet Server policy', () => { + cy.getBySel('toastCloseButton').click(); cy.getBySel('createFleetServerPolicyBtn').click(); cy.getBySel('euiToastHeader'); @@ -46,6 +47,7 @@ describe('Fleet startup', () => { it('should create Default policy', () => { cy.getBySel('addAgentBtnTop').click(); + cy.getBySel('toastCloseButton').click(); cy.getBySel('createPolicyBtn').click(); cy.getBySel('euiToastHeader'); cy.getBySel('euiFlyoutCloseButton').click(); @@ -63,10 +65,4 @@ describe('Fleet startup', () => { cy.visit('/app/integrations/installed'); cy.getBySel('integration-card:epr:elastic_agent'); }); - - // TODO enroll fleet server agent - - it.skip('should display Add agent button and Healthy agent once Fleet Agent page loaded', () => { - cy.get('.euiBadge').contains('Healthy'); - }); }); diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index 9aa084462a7a8..7c38dd32ab0a6 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -178,8 +178,6 @@ export const createAgentPolicyHandler: FleetRequestHandler< }); } - await agentPolicyService.createFleetServerPolicy(soClient, agentPolicy.id); - ensureDefaultEnrollmentAPIKeysExists(soClient, esClient); const body: CreateAgentPolicyResponse = { From b4f12b5aaea8940c57e2e70c8165edaf2fd82849 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 4 Jan 2022 15:19:25 +0100 Subject: [PATCH 21/99] cypress fix --- .../fleet/cypress/integration/fleet_startup.spec.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index a1575cb07cf44..c2f4459e25f33 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -26,8 +26,15 @@ describe('Fleet startup', () => { function navigateToEnrollmentTokens() { cy.getBySel(ENROLLMENT_TOKENS_TAB).click(); cy.get('.euiBasicTable-loading').should('not.exist'); + cy.get('.euiButtonIcon--danger'); // wait for trash icon } + it('should have no agent policies by default', () => { + cy.request('/api/fleet/agent_policies?full=true').then((response: any) => { + expect(response.body.items.length).to.equal(0); + }); + }); + it('should create Default Fleet Server policy', () => { cy.getBySel('toastCloseButton').click(); cy.getBySel('createFleetServerPolicyBtn').click(); @@ -50,6 +57,7 @@ describe('Fleet startup', () => { cy.getBySel('toastCloseButton').click(); cy.getBySel('createPolicyBtn').click(); cy.getBySel('euiToastHeader'); + cy.get('.euiLoadingSpinner').should('not.exist'); cy.getBySel('euiFlyoutCloseButton').click(); navigateToAgentPolicies(); From 2d7cbdfa1de7cba3b4bd9057c6c495f20faa48e2 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 5 Jan 2022 10:08:46 +0100 Subject: [PATCH 22/99] added missing link --- .../agent_policy/components/agent_policy_create_inline.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index e62327491b72e..93d91bb5df13b 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -118,7 +118,10 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ defaultMessage="Type of hosts are controlled by an {agentPolicy}. Create a new agent policy to get started." values={{ agentPolicy: ( - + Date: Wed, 5 Jan 2022 12:17:51 +0100 Subject: [PATCH 23/99] removed is_default, default from naming --- x-pack/plugins/fleet/common/constants/epm.ts | 22 +- .../common/constants/preconfiguration.ts | 71 +- .../schemas/preconfigured_agent_policies.yaml | 4 + .../fleet/common/types/models/agent_policy.ts | 5 +- .../fixtures/integrations/agent_policies.json | 978 --------------- .../fixtures/integrations/agent_policy.json | 644 ---------- .../cypress/fixtures/integrations/apache.json | 1060 ----------------- .../create_integration_response.json | 255 ---- .../cypress/fixtures/integrations/list.json | 260 ---- .../cypress/integration/fleet_startup.spec.ts | 19 +- .../cypress/integration/integrations.spec.ts | 27 +- x-pack/plugins/fleet/cypress/tasks/cleanup.ts | 19 + .../fleet/cypress/tasks/integrations.ts | 1 - x-pack/plugins/fleet/cypress/tsconfig.json | 1 + .../agent_policy_advanced_fields.tsx | 19 +- .../components/agent_policy_create_inline.tsx | 5 +- .../create_package_policy_page/index.tsx | 9 +- .../step_select_hosts.tsx | 15 +- .../components/create_agent_policy.tsx | 1 - .../sections/agents/agent_list_page/index.tsx | 7 +- .../fleet_server_on_prem_instructions.tsx | 11 +- .../epm/screens/detail/index.test.tsx | 2 - .../agent_policy_selection.tsx | 5 - .../agent_enrollment_flyout/steps.tsx | 5 +- .../components/new_enrollment_key_modal.tsx | 4 +- .../package_policy_actions_menu.test.tsx | 1 - .../plugins/fleet/public/constants/index.ts | 1 - .../plugins/fleet/server/constants/index.ts | 3 - x-pack/plugins/fleet/server/mocks/index.ts | 1 - x-pack/plugins/fleet/server/plugin.ts | 1 - .../server/routes/agent_policy/handlers.ts | 79 +- .../fleet/server/saved_objects/index.ts | 2 - .../saved_objects/migrations/to_v7_16_0.ts | 4 +- .../fleet/server/services/agent_policy.ts | 41 +- .../services/api_keys/enrollment_api_key.ts | 5 +- .../server/services/epm/packages/index.ts | 10 +- x-pack/plugins/fleet/server/services/index.ts | 1 - .../fleet/server/services/package_policy.ts | 3 +- .../fleet/server/services/preconfiguration.ts | 8 +- .../fleet/server/types/models/agent_policy.ts | 1 + .../server/types/models/preconfiguration.ts | 1 + .../cypress/integration/integration.spec.ts | 2 +- .../apis/fleet_telemetry.ts | 12 +- 43 files changed, 138 insertions(+), 3487 deletions(-) delete mode 100644 x-pack/plugins/fleet/cypress/fixtures/integrations/agent_policies.json delete mode 100644 x-pack/plugins/fleet/cypress/fixtures/integrations/agent_policy.json delete mode 100644 x-pack/plugins/fleet/cypress/fixtures/integrations/apache.json delete mode 100644 x-pack/plugins/fleet/cypress/fixtures/integrations/create_integration_response.json delete mode 100644 x-pack/plugins/fleet/cypress/fixtures/integrations/list.json create mode 100644 x-pack/plugins/fleet/cypress/tasks/cleanup.ts diff --git a/x-pack/plugins/fleet/common/constants/epm.ts b/x-pack/plugins/fleet/common/constants/epm.ts index 97672f4d4d657..b162cfddf6cff 100644 --- a/x-pack/plugins/fleet/common/constants/epm.ts +++ b/x-pack/plugins/fleet/common/constants/epm.ts @@ -23,16 +23,10 @@ export const STANDALONE_RUN_INSTRUCTIONS_WINDOWS = '.\\elastic-agent.exe install /* Package rules: -| | unremovablePackages | defaultPackages | autoUpdatePackages | -|---------------|:---------------------:|:---------------:|:------------------:| -| Removable | ❌ | ✔️ | ✔️ | -| Auto-installs | ❌ | ✔️ | ❌ | -| Auto-updates | ❌ | ✔️ | ✔️ | - -`endpoint` is a special package. It needs to autoupdate, it needs to _not_ be -removable, but it doesn't install by default. Following the table, it needs to -be in `unremovablePackages` and in `autoUpdatePackages`, but not in -`defaultPackages`. +| | autoUpdatePackages | +|---------------|:------------------:| +| Auto-installs | ❌ | +| Auto-updates | ✔️ | We also define "auto upgrade policies" packages below. These are packages that are considered "stack-aligned" @@ -42,17 +36,11 @@ in their custom policy editor implementations. */ -export const unremovablePackages = [ +export const autoUpdatePackages = [ FLEET_SYSTEM_PACKAGE, FLEET_ELASTIC_AGENT_PACKAGE, FLEET_SERVER_PACKAGE, FLEET_ENDPOINT_PACKAGE, -]; - -export const defaultPackages = unremovablePackages.filter((p) => p !== FLEET_ENDPOINT_PACKAGE); - -export const autoUpdatePackages = [ - FLEET_ENDPOINT_PACKAGE, FLEET_APM_PACKAGE, FLEET_SYNTHETICS_PACKAGE, ]; diff --git a/x-pack/plugins/fleet/common/constants/preconfiguration.ts b/x-pack/plugins/fleet/common/constants/preconfiguration.ts index 7d22716bc0f1e..5689223852a32 100644 --- a/x-pack/plugins/fleet/common/constants/preconfiguration.ts +++ b/x-pack/plugins/fleet/common/constants/preconfiguration.ts @@ -6,18 +6,8 @@ */ import { uniqBy } from 'lodash'; -import uuidv5 from 'uuid/v5'; -import type { PreconfiguredAgentPolicy } from '../types'; - -import { - defaultPackages, - FLEET_SYSTEM_PACKAGE, - FLEET_SERVER_PACKAGE, - autoUpdatePackages, - monitoringTypes, - autoUpgradePoliciesPackages, -} from './epm'; +import { autoUpdatePackages, autoUpgradePoliciesPackages } from './epm'; // UUID v5 values require a namespace. We use UUID v5 for some of our preconfigured ID values. export const UUID_V5_NAMESPACE = 'dde7c2de-1370-4c19-9975-b473d0e03508'; @@ -27,63 +17,6 @@ export const PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE = export const PRECONFIGURATION_LATEST_KEYWORD = 'latest'; -type PreconfiguredAgentPolicyWithDefaultInputs = Omit< - PreconfiguredAgentPolicy, - 'package_policies' -> & { - package_policies: Array>; -}; - -export const DEFAULT_AGENT_POLICY_ID_SEED = 'default-agent-policy'; -export const DEFAULT_SYSTEM_PACKAGE_POLICY_ID = 'default-system-policy'; - -export const DEFAULT_AGENT_POLICY: PreconfiguredAgentPolicyWithDefaultInputs = { - id: uuidv5(DEFAULT_AGENT_POLICY_ID_SEED, UUID_V5_NAMESPACE), - name: 'Default policy', - namespace: 'default', - description: 'Default agent policy created by Kibana', - package_policies: [ - { - id: DEFAULT_SYSTEM_PACKAGE_POLICY_ID, - name: `${FLEET_SYSTEM_PACKAGE}-1`, - package: { - name: FLEET_SYSTEM_PACKAGE, - }, - }, - ], - is_default: true, - is_managed: false, - monitoring_enabled: monitoringTypes, -}; - -export const DEFAULT_FLEET_SERVER_POLICY_ID = 'default-fleet-server-agent-policy'; -export const DEFAULT_FLEET_SERVER_AGENT_POLICY_ID_SEED = 'default-fleet-server'; - -export const DEFAULT_FLEET_SERVER_AGENT_POLICY: PreconfiguredAgentPolicyWithDefaultInputs = { - id: uuidv5(DEFAULT_FLEET_SERVER_AGENT_POLICY_ID_SEED, UUID_V5_NAMESPACE), - name: 'Default Fleet Server policy', - namespace: 'default', - description: 'Default Fleet Server agent policy created by Kibana', - package_policies: [ - { - id: DEFAULT_FLEET_SERVER_POLICY_ID, - name: `${FLEET_SERVER_PACKAGE}-1`, - package: { - name: FLEET_SERVER_PACKAGE, - }, - }, - ], - is_default: false, - is_default_fleet_server: true, - is_managed: false, - monitoring_enabled: monitoringTypes, -}; - -export const DEFAULT_PACKAGES = defaultPackages.map((name) => ({ - name, - version: PRECONFIGURATION_LATEST_KEYWORD, -})); - export const AUTO_UPDATE_PACKAGES = autoUpdatePackages.map((name) => ({ name, version: PRECONFIGURATION_LATEST_KEYWORD, @@ -97,7 +30,7 @@ export const AUTO_UPGRADE_POLICIES_PACKAGES = autoUpgradePoliciesPackages.map((n // Controls whether the `Keep Policies up to date` setting is exposed to the user export const KEEP_POLICIES_UP_TO_DATE_PACKAGES = uniqBy( - [...AUTO_UPGRADE_POLICIES_PACKAGES, ...DEFAULT_PACKAGES, ...AUTO_UPDATE_PACKAGES], + [...AUTO_UPGRADE_POLICIES_PACKAGES, ...AUTO_UPDATE_PACKAGES], ({ name }) => name ); diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/preconfigured_agent_policies.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/preconfigured_agent_policies.yaml index 3e3cead7dadca..84feaf8fdeb91 100644 --- a/x-pack/plugins/fleet/common/openapi/components/schemas/preconfigured_agent_policies.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/preconfigured_agent_policies.yaml @@ -24,8 +24,12 @@ properties: - type: number is_default: type: boolean + deprecated: true is_default_fleet_server: type: boolean + deprecated: true + has_fleet_server: + type: boolean data_output_id: type: string monitoring_output_id: diff --git a/x-pack/plugins/fleet/common/types/models/agent_policy.ts b/x-pack/plugins/fleet/common/types/models/agent_policy.ts index 3f9e43e72c51d..bb778e9c90d1b 100644 --- a/x-pack/plugins/fleet/common/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/common/types/models/agent_policy.ts @@ -19,6 +19,7 @@ export interface NewAgentPolicy { description?: string; is_default?: boolean; is_default_fleet_server?: boolean; // Optional when creating a policy + has_fleet_server?: boolean; is_managed?: boolean; // Optional when creating a policy monitoring_enabled?: MonitoringType; unenroll_timeout?: number; @@ -139,10 +140,6 @@ export interface FleetServerPolicy { data: { [k: string]: unknown; }; - /** - * True when this policy is the default policy to start Fleet Server - */ - default_fleet_server: boolean; /** * Auto unenroll any Elastic Agents which have not checked in for this many seconds */ diff --git a/x-pack/plugins/fleet/cypress/fixtures/integrations/agent_policies.json b/x-pack/plugins/fleet/cypress/fixtures/integrations/agent_policies.json deleted file mode 100644 index ba1360e11a21d..0000000000000 --- a/x-pack/plugins/fleet/cypress/fixtures/integrations/agent_policies.json +++ /dev/null @@ -1,978 +0,0 @@ -{ - "items": [ - { - "id": "30e16140-2106-11ec-a289-25321523992d", - "namespace": "default", - "monitoring_enabled": [ - "logs", - "metrics" - ], - "name": "Default policy", - "description": "Default agent policy created by Kibana", - "is_default": true, - "is_preconfigured": true, - "status": "active", - "is_managed": false, - "revision": 4, - "updated_at": "2021-09-29T09:52:13.879Z", - "updated_by": "elastic", - "package_policies": [ - { - "id": "15785537-fdf2-4e38-bd49-ae0537bbe162", - "version": "WzU5NSwxXQ==", - "name": "system-1", - "namespace": "default", - "package": { - "name": "system", - "title": "System", - "version": "1.4.0" - }, - "enabled": true, - "policy_id": "30e16140-2106-11ec-a289-25321523992d", - "output_id": "1ffdf460-2106-11ec-a289-25321523992d", - "inputs": [ - { - "type": "logfile", - "policy_template": "system", - "enabled": true, - "streams": [ - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "system.auth" - }, - "vars": { - "paths": { - "value": [ - "/var/log/auth.log*", - "/var/log/secure*" - ], - "type": "text" - } - }, - "id": "logfile-system.auth-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "paths": [ - "/var/log/auth.log*", - "/var/log/secure*" - ], - "exclude_files": [ - ".gz$" - ], - "multiline": { - "pattern": "^\\s", - "match": "after" - }, - "processors": [ - { - "add_locale": null - } - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "system.syslog" - }, - "vars": { - "paths": { - "value": [ - "/var/log/messages*", - "/var/log/syslog*" - ], - "type": "text" - } - }, - "id": "logfile-system.syslog-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "paths": [ - "/var/log/messages*", - "/var/log/syslog*" - ], - "exclude_files": [ - ".gz$" - ], - "multiline": { - "pattern": "^\\s", - "match": "after" - }, - "processors": [ - { - "add_locale": null - } - ] - } - } - ] - }, - { - "type": "winlog", - "policy_template": "system", - "enabled": true, - "streams": [ - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "system.application" - }, - "vars": { - "event_id": { - "type": "text" - }, - "processors": { - "type": "yaml" - }, - "tags": { - "value": [], - "type": "text" - } - }, - "id": "winlog-system.application-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "name": "Application", - "condition": "${host.platform} == 'windows'", - "ignore_older": "72h", - "tags": null - } - }, - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "system.security" - }, - "vars": { - "event_id": { - "type": "text" - }, - "processors": { - "type": "yaml" - }, - "tags": { - "value": [], - "type": "text" - } - }, - "id": "winlog-system.security-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "name": "Security", - "condition": "${host.platform} == 'windows'", - "tags": null - } - }, - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "system.system" - }, - "vars": { - "event_id": { - "type": "text" - }, - "processors": { - "type": "yaml" - }, - "tags": { - "value": [], - "type": "text" - } - }, - "id": "winlog-system.system-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "name": "System", - "condition": "${host.platform} == 'windows'", - "tags": null - } - } - ], - "vars": { - "preserve_original_event": { - "value": false, - "type": "bool" - } - } - }, - { - "type": "system/metrics", - "policy_template": "system", - "enabled": true, - "streams": [ - { - "enabled": false, - "data_stream": { - "type": "metrics", - "dataset": "system.core" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - }, - "core.metrics": { - "value": [ - "percentages" - ], - "type": "text" - } - }, - "id": "system/metrics-system.core-15785537-fdf2-4e38-bd49-ae0537bbe162" - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.cpu" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - }, - "cpu.metrics": { - "value": [ - "percentages", - "normalized_percentages" - ], - "type": "text" - } - }, - "id": "system/metrics-system.cpu-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "cpu" - ], - "cpu.metrics": [ - "percentages", - "normalized_percentages" - ], - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.diskio" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - }, - "diskio.include_devices": { - "value": [], - "type": "text" - } - }, - "id": "system/metrics-system.diskio-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "diskio" - ], - "diskio.include_devices": null, - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.filesystem" - }, - "vars": { - "period": { - "value": "1m", - "type": "text" - }, - "processors": { - "value": "- drop_event.when.regexp:\n system.filesystem.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/)\n", - "type": "yaml" - } - }, - "id": "system/metrics-system.filesystem-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "filesystem" - ], - "period": "1m", - "processors": [ - { - "drop_event.when.regexp": { - "system.filesystem.mount_point": "^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/)" - } - } - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.fsstat" - }, - "vars": { - "period": { - "value": "1m", - "type": "text" - }, - "processors": { - "value": "- drop_event.when.regexp:\n system.fsstat.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/)\n", - "type": "yaml" - } - }, - "id": "system/metrics-system.fsstat-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "fsstat" - ], - "period": "1m", - "processors": [ - { - "drop_event.when.regexp": { - "system.fsstat.mount_point": "^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/)" - } - } - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.load" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - } - }, - "id": "system/metrics-system.load-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "load" - ], - "condition": "${host.platform} != 'windows'", - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.memory" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - } - }, - "id": "system/metrics-system.memory-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "memory" - ], - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.network" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - }, - "network.interfaces": { - "value": [], - "type": "text" - } - }, - "id": "system/metrics-system.network-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "network" - ], - "period": "10s", - "network.interfaces": null - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.process" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - }, - "process.include_top_n.by_cpu": { - "value": 5, - "type": "integer" - }, - "process.include_top_n.by_memory": { - "value": 5, - "type": "integer" - }, - "process.cmdline.cache.enabled": { - "value": true, - "type": "bool" - }, - "process.cgroups.enabled": { - "value": false, - "type": "bool" - }, - "process.env.whitelist": { - "value": [], - "type": "text" - }, - "process.include_cpu_ticks": { - "value": false, - "type": "bool" - }, - "processes": { - "value": [ - ".*" - ], - "type": "text" - } - }, - "id": "system/metrics-system.process-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "process" - ], - "period": "10s", - "process.include_top_n.by_cpu": 5, - "process.include_top_n.by_memory": 5, - "process.cmdline.cache.enabled": true, - "process.cgroups.enabled": false, - "process.include_cpu_ticks": false, - "processes": [ - ".*" - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.process.summary" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - } - }, - "id": "system/metrics-system.process.summary-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "process_summary" - ], - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.socket_summary" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - } - }, - "id": "system/metrics-system.socket_summary-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "socket_summary" - ], - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.uptime" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - } - }, - "id": "system/metrics-system.uptime-15785537-fdf2-4e38-bd49-ae0537bbe162", - "compiled_stream": { - "metricsets": [ - "uptime" - ], - "period": "10s" - } - } - ], - "vars": { - "system.hostfs": { - "type": "text" - } - } - }, - { - "type": "httpjson", - "policy_template": "system", - "enabled": false, - "streams": [ - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "system.application" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=\"XmlWinEventLog:Application\"", - "type": "text" - }, - "tags": { - "value": [ - "forwarded" - ], - "type": "text" - } - }, - "id": "httpjson-system.application-15785537-fdf2-4e38-bd49-ae0537bbe162" - }, - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "system.security" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=\"XmlWinEventLog:Security\"", - "type": "text" - }, - "tags": { - "value": [ - "forwarded" - ], - "type": "text" - } - }, - "id": "httpjson-system.security-15785537-fdf2-4e38-bd49-ae0537bbe162" - }, - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "system.system" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=\"XmlWinEventLog:System\"", - "type": "text" - }, - "tags": { - "value": [ - "forwarded" - ], - "type": "text" - } - }, - "id": "httpjson-system.system-15785537-fdf2-4e38-bd49-ae0537bbe162" - } - ], - "vars": { - "url": { - "value": "https://server.example.com:8089", - "type": "text" - }, - "username": { - "type": "text" - }, - "password": { - "type": "password" - }, - "token": { - "type": "password" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "ssl": { - "value": "#certificate_authorities:\n# - |\n# -----BEGIN CERTIFICATE-----\n# MIIDCjCCAfKgAwIBAgITJ706Mu2wJlKckpIvkWxEHvEyijANBgkqhkiG9w0BAQsF\n# ADAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwIBcNMTkwNzIyMTkyOTA0WhgPMjExOTA2\n# MjgxOTI5MDRaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB\n# BQADggEPADCCAQoCggEBANce58Y/JykI58iyOXpxGfw0/gMvF0hUQAcUrSMxEO6n\n# fZRA49b4OV4SwWmA3395uL2eB2NB8y8qdQ9muXUdPBWE4l9rMZ6gmfu90N5B5uEl\n# 94NcfBfYOKi1fJQ9i7WKhTjlRkMCgBkWPkUokvBZFRt8RtF7zI77BSEorHGQCk9t\n# /D7BS0GJyfVEhftbWcFEAG3VRcoMhF7kUzYwp+qESoriFRYLeDWv68ZOvG7eoWnP\n# PsvZStEVEimjvK5NSESEQa9xWyJOmlOKXhkdymtcUd/nXnx6UTCFgnkgzSdTWV41\n# CI6B6aJ9svCTI2QuoIq2HxX/ix7OvW1huVmcyHVxyUECAwEAAaNTMFEwHQYDVR0O\n# BBYEFPwN1OceFGm9v6ux8G+DZ3TUDYxqMB8GA1UdIwQYMBaAFPwN1OceFGm9v6ux\n# 8G+DZ3TUDYxqMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAG5D\n# 874A4YI7YUwOVsVAdbWtgp1d0zKcPRR+r2OdSbTAV5/gcS3jgBJ3i1BN34JuDVFw\n# 3DeJSYT3nxy2Y56lLnxDeF8CUTUtVQx3CuGkRg1ouGAHpO/6OqOhwLLorEmxi7tA\n# H2O8mtT0poX5AnOAhzVy7QW0D/k4WaoLyckM5hUa6RtvgvLxOwA0U+VGurCDoctu\n# 8F4QOgTAWyh8EZIwaKCliFRSynDpv3JTUwtfZkxo6K6nce1RhCWFAsMvDZL8Dgc0\n# yvgJ38BRsFOtkRuAGSf6ZUwTO8JJRRIFnpUzXflAnGivK9M13D5GEQMmIl6U9Pvk\n# sxSmbIUfc2SGJGCJD4I=\n# -----END CERTIFICATE-----\n", - "type": "yaml" - } - } - } - ], - "revision": 1, - "created_at": "2021-09-29T09:18:23.207Z", - "created_by": "system", - "updated_at": "2021-09-29T09:18:23.207Z", - "updated_by": "system" - }, - { - "id": "63172a6b-4f00-4376-b5e6-fe9b3f00fc79", - "version": "WzczOSwxXQ==", - "name": "apache-1", - "description": "", - "namespace": "default", - "policy_id": "30e16140-2106-11ec-a289-25321523992d", - "enabled": true, - "output_id": "", - "inputs": [ - { - "type": "logfile", - "policy_template": "apache", - "enabled": true, - "streams": [ - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "apache.access" - }, - "vars": { - "paths": { - "value": [ - "/var/log/apache2/access.log*", - "/var/log/apache2/other_vhosts_access.log*", - "/var/log/httpd/access_log*" - ], - "type": "text" - }, - "tags": { - "value": [ - "apache-access" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "logfile-apache.access-63172a6b-4f00-4376-b5e6-fe9b3f00fc79", - "compiled_stream": { - "paths": [ - "/var/log/apache2/access.log*", - "/var/log/apache2/other_vhosts_access.log*", - "/var/log/httpd/access_log*" - ], - "tags": [ - "apache-access" - ], - "exclude_files": [ - ".gz$" - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "apache.error" - }, - "vars": { - "paths": { - "value": [ - "/var/log/apache2/error.log*", - "/var/log/httpd/error_log*" - ], - "type": "text" - }, - "tags": { - "value": [ - "apache-error" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "logfile-apache.error-63172a6b-4f00-4376-b5e6-fe9b3f00fc79", - "compiled_stream": { - "paths": [ - "/var/log/apache2/error.log*", - "/var/log/httpd/error_log*" - ], - "exclude_files": [ - ".gz$" - ], - "tags": [ - "apache-error" - ], - "processors": [ - { - "add_locale": null - } - ] - } - } - ] - }, - { - "type": "httpjson", - "policy_template": "apache", - "enabled": false, - "streams": [ - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "apache.access" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=\"access*\"", - "type": "text" - }, - "tags": { - "value": [ - "forwarded", - "apache-access" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "httpjson-apache.access-63172a6b-4f00-4376-b5e6-fe9b3f00fc79" - }, - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "apache.error" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=apache:error OR sourcetype=apache_error", - "type": "text" - }, - "tags": { - "value": [ - "forwarded", - "apache-error" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "httpjson-apache.error-63172a6b-4f00-4376-b5e6-fe9b3f00fc79" - } - ], - "vars": { - "url": { - "value": "https://server.example.com:8089", - "type": "text" - }, - "username": { - "type": "text" - }, - "password": { - "type": "password" - }, - "token": { - "type": "password" - }, - "ssl": { - "value": "#certificate_authorities:\n# - |\n# -----BEGIN CERTIFICATE-----\n# MIIDCjCCAfKgAwIBAgITJ706Mu2wJlKckpIvkWxEHvEyijANBgkqhkiG9w0BAQsF\n# ADAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwIBcNMTkwNzIyMTkyOTA0WhgPMjExOTA2\n# MjgxOTI5MDRaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB\n# BQADggEPADCCAQoCggEBANce58Y/JykI58iyOXpxGfw0/gMvF0hUQAcUrSMxEO6n\n# fZRA49b4OV4SwWmA3395uL2eB2NB8y8qdQ9muXUdPBWE4l9rMZ6gmfu90N5B5uEl\n# 94NcfBfYOKi1fJQ9i7WKhTjlRkMCgBkWPkUokvBZFRt8RtF7zI77BSEorHGQCk9t\n# /D7BS0GJyfVEhftbWcFEAG3VRcoMhF7kUzYwp+qESoriFRYLeDWv68ZOvG7eoWnP\n# PsvZStEVEimjvK5NSESEQa9xWyJOmlOKXhkdymtcUd/nXnx6UTCFgnkgzSdTWV41\n# CI6B6aJ9svCTI2QuoIq2HxX/ix7OvW1huVmcyHVxyUECAwEAAaNTMFEwHQYDVR0O\n# BBYEFPwN1OceFGm9v6ux8G+DZ3TUDYxqMB8GA1UdIwQYMBaAFPwN1OceFGm9v6ux\n# 8G+DZ3TUDYxqMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAG5D\n# 874A4YI7YUwOVsVAdbWtgp1d0zKcPRR+r2OdSbTAV5/gcS3jgBJ3i1BN34JuDVFw\n# 3DeJSYT3nxy2Y56lLnxDeF8CUTUtVQx3CuGkRg1ouGAHpO/6OqOhwLLorEmxi7tA\n# H2O8mtT0poX5AnOAhzVy7QW0D/k4WaoLyckM5hUa6RtvgvLxOwA0U+VGurCDoctu\n# 8F4QOgTAWyh8EZIwaKCliFRSynDpv3JTUwtfZkxo6K6nce1RhCWFAsMvDZL8Dgc0\n# yvgJ38BRsFOtkRuAGSf6ZUwTO8JJRRIFnpUzXflAnGivK9M13D5GEQMmIl6U9Pvk\n# sxSmbIUfc2SGJGCJD4I=\n# -----END CERTIFICATE-----\n", - "type": "yaml" - } - } - }, - { - "type": "apache/metrics", - "policy_template": "apache", - "enabled": true, - "streams": [ - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "apache.status" - }, - "vars": { - "period": { - "value": "30s", - "type": "text" - }, - "server_status_path": { - "value": "/server-status", - "type": "text" - } - }, - "id": "apache/metrics-apache.status-63172a6b-4f00-4376-b5e6-fe9b3f00fc79", - "compiled_stream": { - "metricsets": [ - "status" - ], - "hosts": [ - "http://127.0.0.1" - ], - "period": "30s", - "server_status_path": "/server-status" - } - } - ], - "vars": { - "hosts": { - "value": [ - "http://127.0.0.1" - ], - "type": "text" - } - } - } - ], - "package": { - "name": "apache", - "title": "Apache", - "version": "1.1.0" - }, - "revision": 1, - "created_at": "2021-09-29T09:52:12.865Z", - "created_by": "elastic", - "updated_at": "2021-09-29T09:52:12.865Z", - "updated_by": "elastic" - } - ], - "agents": 1 - }, - { - "id": "30e16141-2106-11ec-a289-25321523992d", - "namespace": "default", - "monitoring_enabled": [ - "logs", - "metrics" - ], - "name": "Default Fleet Server policy", - "description": "Default Fleet Server agent policy created by Kibana", - "is_default": false, - "is_default_fleet_server": true, - "is_preconfigured": true, - "status": "active", - "is_managed": false, - "revision": 1, - "updated_at": "2021-09-29T09:18:25.581Z", - "updated_by": "system", - "package_policies": [ - { - "id": "3f79c8a2-ed32-45d9-a7e7-b58852f4cb7d", - "version": "WzU5NywxXQ==", - "name": "fleet_server-1", - "namespace": "default", - "package": { - "name": "fleet_server", - "title": "Fleet Server", - "version": "1.0.1" - }, - "enabled": true, - "policy_id": "30e16141-2106-11ec-a289-25321523992d", - "output_id": "1ffdf460-2106-11ec-a289-25321523992d", - "inputs": [ - { - "type": "fleet-server", - "policy_template": "fleet_server", - "enabled": true, - "streams": [], - "vars": { - "host": { - "value": [ - "0.0.0.0" - ], - "type": "text" - }, - "port": { - "value": [ - 8220 - ], - "type": "integer" - }, - "max_connections": { - "type": "integer" - }, - "custom": { - "value": "", - "type": "yaml" - } - }, - "compiled_input": { - "server": { - "port": 8220, - "host": "0.0.0.0" - } - } - } - ], - "revision": 1, - "created_at": "2021-09-29T09:18:25.204Z", - "created_by": "system", - "updated_at": "2021-09-29T09:18:25.204Z", - "updated_by": "system" - } - ], - "agents": 0 - } - ], - "total": 2, - "page": 1, - "perPage": 20 -} \ No newline at end of file diff --git a/x-pack/plugins/fleet/cypress/fixtures/integrations/agent_policy.json b/x-pack/plugins/fleet/cypress/fixtures/integrations/agent_policy.json deleted file mode 100644 index aa6520f513acd..0000000000000 --- a/x-pack/plugins/fleet/cypress/fixtures/integrations/agent_policy.json +++ /dev/null @@ -1,644 +0,0 @@ -{ - "item": { - "id": "30e16140-2106-11ec-a289-25321523992d", - "namespace": "default", - "monitoring_enabled": [ - "logs", - "metrics" - ], - "name": "Default policy", - "description": "Default agent policy created by Kibana", - "is_default": true, - "is_preconfigured": true, - "status": "active", - "is_managed": false, - "revision": 1, - "updated_at": "2021-09-30T10:02:50.389Z", - "updated_by": "system", - "package_policies": [ - { - "id": "4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "version": "WzEyNjQsMV0=", - "name": "system-1", - "namespace": "default", - "package": { - "name": "system", - "title": "System", - "version": "1.4.0" - }, - "enabled": true, - "policy_id": "8f108d20-21d5-11ec-9dad-073c0cd6096b", - "output_id": "4f979e90-21d5-11ec-9dad-073c0cd6096b", - "inputs": [ - { - "type": "logfile", - "policy_template": "system", - "enabled": true, - "streams": [ - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "system.auth" - }, - "vars": { - "paths": { - "value": [ - "/var/log/auth.log*", - "/var/log/secure*" - ], - "type": "text" - } - }, - "id": "logfile-system.auth-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "paths": [ - "/var/log/auth.log*", - "/var/log/secure*" - ], - "exclude_files": [ - ".gz$" - ], - "multiline": { - "pattern": "^\\s", - "match": "after" - }, - "processors": [ - { - "add_locale": null - } - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "system.syslog" - }, - "vars": { - "paths": { - "value": [ - "/var/log/messages*", - "/var/log/syslog*" - ], - "type": "text" - } - }, - "id": "logfile-system.syslog-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "paths": [ - "/var/log/messages*", - "/var/log/syslog*" - ], - "exclude_files": [ - ".gz$" - ], - "multiline": { - "pattern": "^\\s", - "match": "after" - }, - "processors": [ - { - "add_locale": null - } - ] - } - } - ] - }, - { - "type": "winlog", - "policy_template": "system", - "enabled": true, - "streams": [ - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "system.application" - }, - "vars": { - "event_id": { - "type": "text" - }, - "processors": { - "type": "yaml" - }, - "tags": { - "value": [], - "type": "text" - } - }, - "id": "winlog-system.application-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "name": "Application", - "condition": "${host.platform} == 'windows'", - "ignore_older": "72h", - "tags": null - } - }, - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "system.security" - }, - "vars": { - "event_id": { - "type": "text" - }, - "processors": { - "type": "yaml" - }, - "tags": { - "value": [], - "type": "text" - } - }, - "id": "winlog-system.security-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "name": "Security", - "condition": "${host.platform} == 'windows'", - "tags": null - } - }, - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "system.system" - }, - "vars": { - "event_id": { - "type": "text" - }, - "processors": { - "type": "yaml" - }, - "tags": { - "value": [], - "type": "text" - } - }, - "id": "winlog-system.system-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "name": "System", - "condition": "${host.platform} == 'windows'", - "tags": null - } - } - ], - "vars": { - "preserve_original_event": { - "value": false, - "type": "bool" - } - } - }, - { - "type": "system/metrics", - "policy_template": "system", - "enabled": true, - "streams": [ - { - "enabled": false, - "data_stream": { - "type": "metrics", - "dataset": "system.core" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - }, - "core.metrics": { - "value": [ - "percentages" - ], - "type": "text" - } - }, - "id": "system/metrics-system.core-4243f6b9-6ce2-48ec-859a-b5df4baa7c11" - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.cpu" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - }, - "cpu.metrics": { - "value": [ - "percentages", - "normalized_percentages" - ], - "type": "text" - } - }, - "id": "system/metrics-system.cpu-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "cpu" - ], - "cpu.metrics": [ - "percentages", - "normalized_percentages" - ], - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.diskio" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - }, - "diskio.include_devices": { - "value": [], - "type": "text" - } - }, - "id": "system/metrics-system.diskio-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "diskio" - ], - "diskio.include_devices": null, - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.filesystem" - }, - "vars": { - "period": { - "value": "1m", - "type": "text" - }, - "processors": { - "value": "- drop_event.when.regexp:\n system.filesystem.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/)\n", - "type": "yaml" - } - }, - "id": "system/metrics-system.filesystem-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "filesystem" - ], - "period": "1m", - "processors": [ - { - "drop_event.when.regexp": { - "system.filesystem.mount_point": "^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/)" - } - } - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.fsstat" - }, - "vars": { - "period": { - "value": "1m", - "type": "text" - }, - "processors": { - "value": "- drop_event.when.regexp:\n system.fsstat.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/)\n", - "type": "yaml" - } - }, - "id": "system/metrics-system.fsstat-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "fsstat" - ], - "period": "1m", - "processors": [ - { - "drop_event.when.regexp": { - "system.fsstat.mount_point": "^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/)" - } - } - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.load" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - } - }, - "id": "system/metrics-system.load-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "load" - ], - "condition": "${host.platform} != 'windows'", - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.memory" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - } - }, - "id": "system/metrics-system.memory-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "memory" - ], - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.network" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - }, - "network.interfaces": { - "value": [], - "type": "text" - } - }, - "id": "system/metrics-system.network-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "network" - ], - "period": "10s", - "network.interfaces": null - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.process" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - }, - "process.include_top_n.by_cpu": { - "value": 5, - "type": "integer" - }, - "process.include_top_n.by_memory": { - "value": 5, - "type": "integer" - }, - "process.cmdline.cache.enabled": { - "value": true, - "type": "bool" - }, - "process.cgroups.enabled": { - "value": false, - "type": "bool" - }, - "process.env.whitelist": { - "value": [], - "type": "text" - }, - "process.include_cpu_ticks": { - "value": false, - "type": "bool" - }, - "processes": { - "value": [ - ".*" - ], - "type": "text" - } - }, - "id": "system/metrics-system.process-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "process" - ], - "period": "10s", - "process.include_top_n.by_cpu": 5, - "process.include_top_n.by_memory": 5, - "process.cmdline.cache.enabled": true, - "process.cgroups.enabled": false, - "process.include_cpu_ticks": false, - "processes": [ - ".*" - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.process.summary" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - } - }, - "id": "system/metrics-system.process.summary-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "process_summary" - ], - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.socket_summary" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - } - }, - "id": "system/metrics-system.socket_summary-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "socket_summary" - ], - "period": "10s" - } - }, - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "system.uptime" - }, - "vars": { - "period": { - "value": "10s", - "type": "text" - } - }, - "id": "system/metrics-system.uptime-4243f6b9-6ce2-48ec-859a-b5df4baa7c11", - "compiled_stream": { - "metricsets": [ - "uptime" - ], - "period": "10s" - } - } - ], - "vars": { - "system.hostfs": { - "type": "text" - } - } - }, - { - "type": "httpjson", - "policy_template": "system", - "enabled": false, - "streams": [ - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "system.application" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=\"XmlWinEventLog:Application\"", - "type": "text" - }, - "tags": { - "value": [ - "forwarded" - ], - "type": "text" - } - }, - "id": "httpjson-system.application-4243f6b9-6ce2-48ec-859a-b5df4baa7c11" - }, - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "system.security" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=\"XmlWinEventLog:Security\"", - "type": "text" - }, - "tags": { - "value": [ - "forwarded" - ], - "type": "text" - } - }, - "id": "httpjson-system.security-4243f6b9-6ce2-48ec-859a-b5df4baa7c11" - }, - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "system.system" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=\"XmlWinEventLog:System\"", - "type": "text" - }, - "tags": { - "value": [ - "forwarded" - ], - "type": "text" - } - }, - "id": "httpjson-system.system-4243f6b9-6ce2-48ec-859a-b5df4baa7c11" - } - ], - "vars": { - "url": { - "value": "https://server.example.com:8089", - "type": "text" - }, - "username": { - "type": "text" - }, - "password": { - "type": "password" - }, - "token": { - "type": "password" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "ssl": { - "value": "#certificate_authorities:\n# - |\n# -----BEGIN CERTIFICATE-----\n# MIIDCjCCAfKgAwIBAgITJ706Mu2wJlKckpIvkWxEHvEyijANBgkqhkiG9w0BAQsF\n# ADAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwIBcNMTkwNzIyMTkyOTA0WhgPMjExOTA2\n# MjgxOTI5MDRaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB\n# BQADggEPADCCAQoCggEBANce58Y/JykI58iyOXpxGfw0/gMvF0hUQAcUrSMxEO6n\n# fZRA49b4OV4SwWmA3395uL2eB2NB8y8qdQ9muXUdPBWE4l9rMZ6gmfu90N5B5uEl\n# 94NcfBfYOKi1fJQ9i7WKhTjlRkMCgBkWPkUokvBZFRt8RtF7zI77BSEorHGQCk9t\n# /D7BS0GJyfVEhftbWcFEAG3VRcoMhF7kUzYwp+qESoriFRYLeDWv68ZOvG7eoWnP\n# PsvZStEVEimjvK5NSESEQa9xWyJOmlOKXhkdymtcUd/nXnx6UTCFgnkgzSdTWV41\n# CI6B6aJ9svCTI2QuoIq2HxX/ix7OvW1huVmcyHVxyUECAwEAAaNTMFEwHQYDVR0O\n# BBYEFPwN1OceFGm9v6ux8G+DZ3TUDYxqMB8GA1UdIwQYMBaAFPwN1OceFGm9v6ux\n# 8G+DZ3TUDYxqMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAG5D\n# 874A4YI7YUwOVsVAdbWtgp1d0zKcPRR+r2OdSbTAV5/gcS3jgBJ3i1BN34JuDVFw\n# 3DeJSYT3nxy2Y56lLnxDeF8CUTUtVQx3CuGkRg1ouGAHpO/6OqOhwLLorEmxi7tA\n# H2O8mtT0poX5AnOAhzVy7QW0D/k4WaoLyckM5hUa6RtvgvLxOwA0U+VGurCDoctu\n# 8F4QOgTAWyh8EZIwaKCliFRSynDpv3JTUwtfZkxo6K6nce1RhCWFAsMvDZL8Dgc0\n# yvgJ38BRsFOtkRuAGSf6ZUwTO8JJRRIFnpUzXflAnGivK9M13D5GEQMmIl6U9Pvk\n# sxSmbIUfc2SGJGCJD4I=\n# -----END CERTIFICATE-----\n", - "type": "yaml" - } - } - } - ], - "revision": 1, - "created_at": "2021-09-30T10:02:48.904Z", - "created_by": "system", - "updated_at": "2021-09-30T10:02:48.904Z", - "updated_by": "system" - } - ] - } -} \ No newline at end of file diff --git a/x-pack/plugins/fleet/cypress/fixtures/integrations/apache.json b/x-pack/plugins/fleet/cypress/fixtures/integrations/apache.json deleted file mode 100644 index b8c4c31767f3d..0000000000000 --- a/x-pack/plugins/fleet/cypress/fixtures/integrations/apache.json +++ /dev/null @@ -1,1060 +0,0 @@ -{ - "item": { - "name": "apache", - "title": "Apache", - "version": "1.1.0", - "release": "ga", - "description": "This Elastic integration collects logs and metrics from Apache servers", - "type": "integration", - "download": "/epr/apache/apache-1.1.0.zip", - "path": "/package/apache/1.1.0", - "icons": [ - { - "src": "/img/logo_apache.svg", - "path": "/package/apache/1.1.0/img/logo_apache.svg", - "title": "Apache Logo", - "size": "32x32", - "type": "image/svg+xml" - } - ], - "format_version": "1.0.0", - "readme": "/package/apache/1.1.0/docs/README.md", - "license": "basic", - "categories": [ - "web" - ], - "conditions": { - "kibana.version": "^7.14.0" - }, - "screenshots": [ - { - "src": "/img/apache-metrics-overview.png", - "path": "/package/apache/1.1.0/img/apache-metrics-overview.png", - "title": "Apache metrics overview", - "size": "3360x3064", - "type": "image/png" - }, - { - "src": "/img/apache-logs-overview.png", - "path": "/package/apache/1.1.0/img/apache-logs-overview.png", - "title": "Apache logs overview", - "size": "3342x1384", - "type": "image/png" - } - ], - "assets": { - "kibana": { - "dashboard": [ - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "dashboard", - "file": "apache-Logs-Apache-Dashboard.json", - "path": "apache-1.1.0/kibana/dashboard/apache-Logs-Apache-Dashboard.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "dashboard", - "file": "apache-Metrics-Apache-HTTPD-server-status.json", - "path": "apache-1.1.0/kibana/dashboard/apache-Metrics-Apache-HTTPD-server-status.json" - } - ], - "ml_module": [ - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "ml_module", - "file": "apache-Logs-ml.json", - "path": "apache-1.1.0/kibana/ml_module/apache-Logs-ml.json" - } - ], - "search": [ - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "search", - "file": "apache-HTTPD.json", - "path": "apache-1.1.0/kibana/search/apache-HTTPD.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "search", - "file": "apache-access-logs.json", - "path": "apache-1.1.0/kibana/search/apache-access-logs.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "search", - "file": "apache-errors-log.json", - "path": "apache-1.1.0/kibana/search/apache-errors-log.json" - } - ], - "visualization": [ - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-22057f20-3a12-11eb-8946-296aab7b13db.json", - "path": "apache-1.1.0/kibana/visualization/apache-22057f20-3a12-11eb-8946-296aab7b13db.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-320cd980-3a36-11eb-8946-296aab7b13db.json", - "path": "apache-1.1.0/kibana/visualization/apache-320cd980-3a36-11eb-8946-296aab7b13db.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-47820ce0-3a1d-11eb-8946-296aab7b13db.json", - "path": "apache-1.1.0/kibana/visualization/apache-47820ce0-3a1d-11eb-8946-296aab7b13db.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-7724cf20-3a39-11eb-8946-296aab7b13db.json", - "path": "apache-1.1.0/kibana/visualization/apache-7724cf20-3a39-11eb-8946-296aab7b13db.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-7d68f730-3a39-11eb-8946-296aab7b13db.json", - "path": "apache-1.1.0/kibana/visualization/apache-7d68f730-3a39-11eb-8946-296aab7b13db.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-805d7bb0-3a10-11eb-8946-296aab7b13db.json", - "path": "apache-1.1.0/kibana/visualization/apache-805d7bb0-3a10-11eb-8946-296aab7b13db.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-99666080-3a20-11eb-8946-296aab7b13db.json", - "path": "apache-1.1.0/kibana/visualization/apache-99666080-3a20-11eb-8946-296aab7b13db.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-HTTPD-CPU.json", - "path": "apache-1.1.0/kibana/visualization/apache-HTTPD-CPU.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-HTTPD-Load1-slash-5-slash-15.json", - "path": "apache-1.1.0/kibana/visualization/apache-HTTPD-Load1-slash-5-slash-15.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-HTTPD-Scoreboard.json", - "path": "apache-1.1.0/kibana/visualization/apache-HTTPD-Scoreboard.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-a45311f0-3a34-11eb-8946-296aab7b13db.json", - "path": "apache-1.1.0/kibana/visualization/apache-a45311f0-3a34-11eb-8946-296aab7b13db.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-access-unique-IPs-map.json", - "path": "apache-1.1.0/kibana/visualization/apache-access-unique-IPs-map.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-browsers.json", - "path": "apache-1.1.0/kibana/visualization/apache-browsers.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-ed44f820-3a10-11eb-8946-296aab7b13db.json", - "path": "apache-1.1.0/kibana/visualization/apache-ed44f820-3a10-11eb-8946-296aab7b13db.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-error-logs-over-time.json", - "path": "apache-1.1.0/kibana/visualization/apache-error-logs-over-time.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-f4ffec70-3a36-11eb-8946-296aab7b13db.json", - "path": "apache-1.1.0/kibana/visualization/apache-f4ffec70-3a36-11eb-8946-296aab7b13db.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-operating-systems.json", - "path": "apache-1.1.0/kibana/visualization/apache-operating-systems.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-response-codes-of-top-URLs.json", - "path": "apache-1.1.0/kibana/visualization/apache-response-codes-of-top-URLs.json" - }, - { - "pkgkey": "apache-1.1.0", - "service": "kibana", - "type": "visualization", - "file": "apache-response-codes-over-time.json", - "path": "apache-1.1.0/kibana/visualization/apache-response-codes-over-time.json" - } - ] - }, - "elasticsearch": { - "ingest_pipeline": [ - { - "pkgkey": "apache-1.1.0", - "service": "elasticsearch", - "type": "ingest_pipeline", - "file": "default.yml", - "dataset": "access", - "path": "apache-1.1.0/data_stream/access/elasticsearch/ingest_pipeline/default.yml" - }, - { - "pkgkey": "apache-1.1.0", - "service": "elasticsearch", - "type": "ingest_pipeline", - "file": "third-party.yml", - "dataset": "access", - "path": "apache-1.1.0/data_stream/access/elasticsearch/ingest_pipeline/third-party.yml" - }, - { - "pkgkey": "apache-1.1.0", - "service": "elasticsearch", - "type": "ingest_pipeline", - "file": "default.yml", - "dataset": "error", - "path": "apache-1.1.0/data_stream/error/elasticsearch/ingest_pipeline/default.yml" - }, - { - "pkgkey": "apache-1.1.0", - "service": "elasticsearch", - "type": "ingest_pipeline", - "file": "third-party.yml", - "dataset": "error", - "path": "apache-1.1.0/data_stream/error/elasticsearch/ingest_pipeline/third-party.yml" - } - ] - } - }, - "policy_templates": [ - { - "name": "apache", - "title": "Apache logs and metrics", - "description": "Collect logs and metrics from Apache instances", - "inputs": [ - { - "type": "logfile", - "title": "Collect logs from Apache instances", - "description": "Collecting Apache access and error logs" - }, - { - "type": "httpjson", - "vars": [ - { - "name": "url", - "type": "text", - "title": "URL of Splunk Enterprise Server", - "description": "i.e. scheme://host:port, path is automatic", - "multi": false, - "required": true, - "show_user": true, - "default": "https://server.example.com:8089" - }, - { - "name": "username", - "type": "text", - "title": "Splunk REST API Username", - "multi": false, - "required": false, - "show_user": true - }, - { - "name": "password", - "type": "password", - "title": "Splunk REST API Password", - "multi": false, - "required": false, - "show_user": true - }, - { - "name": "token", - "type": "password", - "title": "Splunk Authorization Token", - "description": "Bearer Token or Session Key, e.g. \"Bearer eyJFd3e46...\"\nor \"Splunk 192fd3e...\". Cannot be used with username\nand password.\n", - "multi": false, - "required": false, - "show_user": true - }, - { - "name": "ssl", - "type": "yaml", - "title": "SSL Configuration", - "description": "i.e. certificate_authorities, supported_protocols, verification_mode etc.", - "multi": false, - "required": false, - "show_user": false, - "default": "#certificate_authorities:\n# - |\n# -----BEGIN CERTIFICATE-----\n# MIIDCjCCAfKgAwIBAgITJ706Mu2wJlKckpIvkWxEHvEyijANBgkqhkiG9w0BAQsF\n# ADAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwIBcNMTkwNzIyMTkyOTA0WhgPMjExOTA2\n# MjgxOTI5MDRaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB\n# BQADggEPADCCAQoCggEBANce58Y/JykI58iyOXpxGfw0/gMvF0hUQAcUrSMxEO6n\n# fZRA49b4OV4SwWmA3395uL2eB2NB8y8qdQ9muXUdPBWE4l9rMZ6gmfu90N5B5uEl\n# 94NcfBfYOKi1fJQ9i7WKhTjlRkMCgBkWPkUokvBZFRt8RtF7zI77BSEorHGQCk9t\n# /D7BS0GJyfVEhftbWcFEAG3VRcoMhF7kUzYwp+qESoriFRYLeDWv68ZOvG7eoWnP\n# PsvZStEVEimjvK5NSESEQa9xWyJOmlOKXhkdymtcUd/nXnx6UTCFgnkgzSdTWV41\n# CI6B6aJ9svCTI2QuoIq2HxX/ix7OvW1huVmcyHVxyUECAwEAAaNTMFEwHQYDVR0O\n# BBYEFPwN1OceFGm9v6ux8G+DZ3TUDYxqMB8GA1UdIwQYMBaAFPwN1OceFGm9v6ux\n# 8G+DZ3TUDYxqMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAG5D\n# 874A4YI7YUwOVsVAdbWtgp1d0zKcPRR+r2OdSbTAV5/gcS3jgBJ3i1BN34JuDVFw\n# 3DeJSYT3nxy2Y56lLnxDeF8CUTUtVQx3CuGkRg1ouGAHpO/6OqOhwLLorEmxi7tA\n# H2O8mtT0poX5AnOAhzVy7QW0D/k4WaoLyckM5hUa6RtvgvLxOwA0U+VGurCDoctu\n# 8F4QOgTAWyh8EZIwaKCliFRSynDpv3JTUwtfZkxo6K6nce1RhCWFAsMvDZL8Dgc0\n# yvgJ38BRsFOtkRuAGSf6ZUwTO8JJRRIFnpUzXflAnGivK9M13D5GEQMmIl6U9Pvk\n# sxSmbIUfc2SGJGCJD4I=\n# -----END CERTIFICATE-----\n" - } - ], - "title": "Collect logs from third-party REST API (experimental)", - "description": "Collect logs from third-party REST API (experimental)" - }, - { - "type": "apache/metrics", - "vars": [ - { - "name": "hosts", - "type": "text", - "title": "Hosts", - "multi": true, - "required": true, - "show_user": true, - "default": [ - "http://127.0.0.1" - ] - } - ], - "title": "Collect metrics from Apache instances", - "description": "Collecting Apache status metrics" - } - ], - "multiple": true - } - ], - "data_streams": [ - { - "type": "logs", - "dataset": "apache.access", - "title": "Apache access logs", - "release": "experimental", - "ingest_pipeline": "default", - "streams": [ - { - "input": "logfile", - "vars": [ - { - "name": "paths", - "type": "text", - "title": "Paths", - "multi": true, - "required": true, - "show_user": true, - "default": [ - "/var/log/apache2/access.log*", - "/var/log/apache2/other_vhosts_access.log*", - "/var/log/httpd/access_log*" - ] - }, - { - "name": "tags", - "type": "text", - "title": "Tags", - "multi": true, - "required": true, - "show_user": false, - "default": [ - "apache-access" - ] - }, - { - "name": "preserve_original_event", - "type": "bool", - "title": "Preserve original event", - "description": "Preserves a raw copy of the original event, added to the field `event.original`", - "multi": false, - "required": true, - "show_user": true, - "default": false - }, - { - "name": "processors", - "type": "yaml", - "title": "Processors", - "description": "Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed. See [Processors](https://www.elastic.co/guide/en/beats/filebeat/current/filtering-and-enhancing-data.html) for details.\n", - "multi": false, - "required": false, - "show_user": false - } - ], - "template_path": "log.yml.hbs", - "title": "Apache access logs", - "description": "Collect Apache access logs", - "enabled": true - }, - { - "input": "httpjson", - "vars": [ - { - "name": "interval", - "type": "text", - "title": "Interval to query Splunk Enterprise REST API", - "description": "Go Duration syntax (eg. 10s)", - "multi": false, - "required": true, - "show_user": true, - "default": "10s" - }, - { - "name": "search", - "type": "text", - "title": "Splunk search string", - "multi": false, - "required": true, - "show_user": true, - "default": "search sourcetype=\"access*\"" - }, - { - "name": "tags", - "type": "text", - "title": "Tags", - "multi": true, - "required": false, - "show_user": false, - "default": [ - "forwarded", - "apache-access" - ] - }, - { - "name": "preserve_original_event", - "type": "bool", - "title": "Preserve original event", - "description": "Preserves a raw copy of the original event, added to the field `event.original`", - "multi": false, - "required": true, - "show_user": true, - "default": false - }, - { - "name": "processors", - "type": "yaml", - "title": "Processors", - "description": "Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed. See [Processors](https://www.elastic.co/guide/en/beats/filebeat/current/filtering-and-enhancing-data.html) for details.\n", - "multi": false, - "required": false, - "show_user": false - } - ], - "template_path": "httpjson.yml.hbs", - "title": "Apache access logs via Splunk Enterprise REST API", - "description": "Collect apache access logs via Splunk Enterprise REST API", - "enabled": false - } - ], - "package": "apache", - "path": "access" - }, - { - "type": "logs", - "dataset": "apache.error", - "title": "Apache error logs", - "release": "experimental", - "ingest_pipeline": "default", - "streams": [ - { - "input": "logfile", - "vars": [ - { - "name": "paths", - "type": "text", - "title": "Paths", - "multi": true, - "required": true, - "show_user": true, - "default": [ - "/var/log/apache2/error.log*", - "/var/log/httpd/error_log*" - ] - }, - { - "name": "tags", - "type": "text", - "title": "Tags", - "multi": true, - "required": true, - "show_user": false, - "default": [ - "apache-error" - ] - }, - { - "name": "preserve_original_event", - "type": "bool", - "title": "Preserve original event", - "description": "Preserves a raw copy of the original event, added to the field `event.original`", - "multi": false, - "required": true, - "show_user": true, - "default": false - }, - { - "name": "processors", - "type": "yaml", - "title": "Processors", - "description": "Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed. See [Processors](https://www.elastic.co/guide/en/beats/filebeat/current/filtering-and-enhancing-data.html) for details.\n", - "multi": false, - "required": false, - "show_user": false - } - ], - "template_path": "log.yml.hbs", - "title": "Apache error logs", - "description": "Collect Apache error logs", - "enabled": true - }, - { - "input": "httpjson", - "vars": [ - { - "name": "interval", - "type": "text", - "title": "Interval to query Splunk Enterprise REST API", - "description": "Go Duration syntax (eg. 10s)", - "multi": false, - "required": true, - "show_user": true, - "default": "10s" - }, - { - "name": "search", - "type": "text", - "title": "Splunk search string", - "multi": false, - "required": true, - "show_user": true, - "default": "search sourcetype=apache:error OR sourcetype=apache_error" - }, - { - "name": "tags", - "type": "text", - "title": "Tags", - "multi": true, - "required": false, - "show_user": false, - "default": [ - "forwarded", - "apache-error" - ] - }, - { - "name": "preserve_original_event", - "type": "bool", - "title": "Preserve original event", - "description": "Preserves a raw copy of the original event, added to the field `event.original`", - "multi": false, - "required": true, - "show_user": true, - "default": false - }, - { - "name": "processors", - "type": "yaml", - "title": "Processors", - "description": "Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed. See [Processors](https://www.elastic.co/guide/en/beats/filebeat/current/filtering-and-enhancing-data.html) for details.\n", - "multi": false, - "required": false, - "show_user": false - } - ], - "template_path": "httpjson.yml.hbs", - "title": "Apache error logs via Splunk Enterprise REST API", - "description": "Collect apache error logs via Splunk Enterprise REST API", - "enabled": false - } - ], - "package": "apache", - "path": "error" - }, - { - "type": "metrics", - "dataset": "apache.status", - "title": "Apache status metrics", - "release": "experimental", - "streams": [ - { - "input": "apache/metrics", - "vars": [ - { - "name": "period", - "type": "text", - "title": "Period", - "multi": false, - "required": true, - "show_user": true, - "default": "30s" - }, - { - "name": "server_status_path", - "type": "text", - "title": "Server Status Path", - "multi": false, - "required": true, - "show_user": false, - "default": "/server-status" - } - ], - "template_path": "stream.yml.hbs", - "title": "Apache status metrics", - "description": "Collect Apache status metrics", - "enabled": true - } - ], - "package": "apache", - "path": "status" - } - ], - "owner": { - "github": "elastic/integrations" - }, - "latestVersion": "1.1.0", - "removable": true, - "status": "installed", - "savedObject": { - "id": "apache", - "type": "epm-packages", - "namespaces": [], - "updated_at": "2021-09-30T10:47:12.961Z", - "version": "WzI1NjgsMV0=", - "attributes": { - "installed_kibana_space_id": "default", - "installed_kibana": [ - { - "id": "apache-Logs-Apache-Dashboard", - "type": "dashboard" - }, - { - "id": "apache-Metrics-Apache-HTTPD-server-status", - "type": "dashboard" - }, - { - "id": "apache-22057f20-3a12-11eb-8946-296aab7b13db", - "type": "visualization" - }, - { - "id": "apache-320cd980-3a36-11eb-8946-296aab7b13db", - "type": "visualization" - }, - { - "id": "apache-47820ce0-3a1d-11eb-8946-296aab7b13db", - "type": "visualization" - }, - { - "id": "apache-7724cf20-3a39-11eb-8946-296aab7b13db", - "type": "visualization" - }, - { - "id": "apache-7d68f730-3a39-11eb-8946-296aab7b13db", - "type": "visualization" - }, - { - "id": "apache-805d7bb0-3a10-11eb-8946-296aab7b13db", - "type": "visualization" - }, - { - "id": "apache-99666080-3a20-11eb-8946-296aab7b13db", - "type": "visualization" - }, - { - "id": "apache-HTTPD-CPU", - "type": "visualization" - }, - { - "id": "apache-HTTPD-Load1-slash-5-slash-15", - "type": "visualization" - }, - { - "id": "apache-HTTPD-Scoreboard", - "type": "visualization" - }, - { - "id": "apache-a45311f0-3a34-11eb-8946-296aab7b13db", - "type": "visualization" - }, - { - "id": "apache-access-unique-IPs-map", - "type": "visualization" - }, - { - "id": "apache-browsers", - "type": "visualization" - }, - { - "id": "apache-ed44f820-3a10-11eb-8946-296aab7b13db", - "type": "visualization" - }, - { - "id": "apache-error-logs-over-time", - "type": "visualization" - }, - { - "id": "apache-f4ffec70-3a36-11eb-8946-296aab7b13db", - "type": "visualization" - }, - { - "id": "apache-operating-systems", - "type": "visualization" - }, - { - "id": "apache-response-codes-of-top-URLs", - "type": "visualization" - }, - { - "id": "apache-response-codes-over-time", - "type": "visualization" - }, - { - "id": "apache-HTTPD", - "type": "search" - }, - { - "id": "apache-access-logs", - "type": "search" - }, - { - "id": "apache-errors-log", - "type": "search" - }, - { - "id": "apache-Logs-ml", - "type": "ml-module" - } - ], - "installed_es": [ - { - "id": "logs-apache.access-1.1.0", - "type": "ingest_pipeline" - }, - { - "id": "logs-apache.access-1.1.0-third-party", - "type": "ingest_pipeline" - }, - { - "id": "logs-apache.error-1.1.0", - "type": "ingest_pipeline" - }, - { - "id": "logs-apache.error-1.1.0-third-party", - "type": "ingest_pipeline" - }, - { - "id": "logs-apache.access", - "type": "index_template" - }, - { - "id": "logs-apache.access@settings", - "type": "component_template" - }, - { - "id": "logs-apache.access@custom", - "type": "component_template" - }, - { - "id": "logs-apache.error", - "type": "index_template" - }, - { - "id": "logs-apache.error@settings", - "type": "component_template" - }, - { - "id": "logs-apache.error@custom", - "type": "component_template" - }, - { - "id": "metrics-apache.status", - "type": "index_template" - }, - { - "id": "metrics-apache.status@settings", - "type": "component_template" - }, - { - "id": "metrics-apache.status@custom", - "type": "component_template" - } - ], - "package_assets": [ - { - "id": "c99057a8-c51a-5795-9e00-b4b09237f780", - "type": "epm-packages-assets" - }, - { - "id": "1388d2c7-254a-5cd4-882d-89b3e8b681cd", - "type": "epm-packages-assets" - }, - { - "id": "c3068bcb-5a74-5044-91f6-c8e99eefb003", - "type": "epm-packages-assets" - }, - { - "id": "4cea5f13-0ec6-5ecc-9012-f2dba2c86fab", - "type": "epm-packages-assets" - }, - { - "id": "6f27b654-fc39-502b-bdda-83ed13e775c1", - "type": "epm-packages-assets" - }, - { - "id": "baa6d518-fa85-530f-9cdc-b0f2207599f8", - "type": "epm-packages-assets" - }, - { - "id": "ea0cfbd9-8173-5429-a83b-6168b2cd4f27", - "type": "epm-packages-assets" - }, - { - "id": "3745632e-1306-5ac6-84ee-0fceae577988", - "type": "epm-packages-assets" - }, - { - "id": "079a3007-eec5-504e-a993-8c489ccc992c", - "type": "epm-packages-assets" - }, - { - "id": "625ba117-a66d-5eba-9172-201e4f03fbf0", - "type": "epm-packages-assets" - }, - { - "id": "f0dd03dd-3dee-51da-881b-425e76966139", - "type": "epm-packages-assets" - }, - { - "id": "c356fb2c-395b-595e-bdf4-51c5750d6efe", - "type": "epm-packages-assets" - }, - { - "id": "861a6d88-8e80-5282-8cc4-b74b13da22f8", - "type": "epm-packages-assets" - }, - { - "id": "49186533-1536-5d2d-a45a-b51a4db1eeca", - "type": "epm-packages-assets" - }, - { - "id": "533a5c29-648c-593c-9444-df3d03c4aae0", - "type": "epm-packages-assets" - }, - { - "id": "9d34d784-f5a7-5213-a711-37bf2af21da5", - "type": "epm-packages-assets" - }, - { - "id": "4d5fa019-7503-5a89-95af-a03227622ecd", - "type": "epm-packages-assets" - }, - { - "id": "edc0c10d-f7f4-5523-8dac-ce9c64aff44d", - "type": "epm-packages-assets" - }, - { - "id": "5792421c-b31c-59a3-891c-1566bc85447b", - "type": "epm-packages-assets" - }, - { - "id": "7a72f59a-27a6-5514-9489-1258de496199", - "type": "epm-packages-assets" - }, - { - "id": "69dffce3-96d1-5c71-b4ae-41b6d61fdd4a", - "type": "epm-packages-assets" - }, - { - "id": "0b971e05-221e-5430-87e6-fbebbc8d4a23", - "type": "epm-packages-assets" - }, - { - "id": "5d7fb7e1-e775-5832-95a7-074d692fb176", - "type": "epm-packages-assets" - }, - { - "id": "4a50c74b-e4ce-511c-badd-54997537b6b8", - "type": "epm-packages-assets" - }, - { - "id": "54e21b74-9ea5-537f-8cce-673b10b8ac39", - "type": "epm-packages-assets" - }, - { - "id": "c9fd9a64-722c-59f7-a686-4d92d4395be0", - "type": "epm-packages-assets" - }, - { - "id": "5a53ca55-23ec-59bc-8d04-be12f1776358", - "type": "epm-packages-assets" - }, - { - "id": "b2652216-a523-5183-8eaa-c26f9ba4bbee", - "type": "epm-packages-assets" - }, - { - "id": "97f717d7-78d6-5b8c-acde-edf80aa27201", - "type": "epm-packages-assets" - }, - { - "id": "6b27939a-1f2a-536d-8d84-560ed372d21a", - "type": "epm-packages-assets" - }, - { - "id": "7d68617a-88b0-5d34-8a98-8f51d3c49568", - "type": "epm-packages-assets" - }, - { - "id": "8e212777-acac-5068-acbb-143e0cbfb3eb", - "type": "epm-packages-assets" - }, - { - "id": "436ed6b2-aa68-55d4-912a-346e14903d7b", - "type": "epm-packages-assets" - }, - { - "id": "5169ccd9-75f9-5d84-8116-2f2bac0dd93f", - "type": "epm-packages-assets" - }, - { - "id": "a36f82fe-4aa0-508f-92e4-e33d779c1ed2", - "type": "epm-packages-assets" - }, - { - "id": "96d9ae25-0ee7-59aa-b8a0-4fbb929cce4a", - "type": "epm-packages-assets" - }, - { - "id": "05e1449f-3723-5d3c-a76f-5e307d88c35b", - "type": "epm-packages-assets" - }, - { - "id": "a0e8abee-4777-5a7f-bb9a-c2c60d49d060", - "type": "epm-packages-assets" - }, - { - "id": "4c77c830-b4e2-5c77-a3dd-941249799ce7", - "type": "epm-packages-assets" - }, - { - "id": "e082c4c2-3215-5fb0-a485-b261a774314e", - "type": "epm-packages-assets" - }, - { - "id": "1f4467ca-6aa9-5fcb-a346-f334e018db3f", - "type": "epm-packages-assets" - }, - { - "id": "fc831e85-d43f-5402-8780-c9fb3b040b34", - "type": "epm-packages-assets" - }, - { - "id": "208cc640-7cb1-5dd0-902e-47d82fe273af", - "type": "epm-packages-assets" - }, - { - "id": "65e211ff-9497-5882-88cc-ebfd79578cff", - "type": "epm-packages-assets" - }, - { - "id": "a6ea40cc-bb98-5039-8d52-151ac69cbfb5", - "type": "epm-packages-assets" - }, - { - "id": "d9e1d1e6-1c31-5164-8805-b8b2249bd8b5", - "type": "epm-packages-assets" - }, - { - "id": "aa843dec-f345-5c94-99e3-8bd2bffb9b4e", - "type": "epm-packages-assets" - }, - { - "id": "2b019917-8d4c-5da9-80b2-5005524a1290", - "type": "epm-packages-assets" - }, - { - "id": "617effde-ae31-5f48-928a-acdf7b6bc0bb", - "type": "epm-packages-assets" - }, - { - "id": "10245259-aff6-5cc9-b60b-9d88a230894e", - "type": "epm-packages-assets" - }, - { - "id": "753a2e77-13fe-5aa8-94a7-08e9357e64f0", - "type": "epm-packages-assets" - }, - { - "id": "4132f76c-78bc-5d70-a7cd-421910242f96", - "type": "epm-packages-assets" - }, - { - "id": "74230ee0-f671-57fc-bf3a-1c1be03acf22", - "type": "epm-packages-assets" - }, - { - "id": "a2465b23-c15e-56f9-acad-e2d5387cae48", - "type": "epm-packages-assets" - }, - { - "id": "94586e3f-78a0-5cf8-b4c2-923f4516153a", - "type": "epm-packages-assets" - }, - { - "id": "7b356571-eb79-541c-ba99-e6fdebf74e98", - "type": "epm-packages-assets" - }, - { - "id": "babd82eb-7317-58c0-a5fc-4d14ca1f2d17", - "type": "epm-packages-assets" - }, - { - "id": "aa68dd98-4844-5162-b96f-e6b5eae5f987", - "type": "epm-packages-assets" - } - ], - "es_index_patterns": { - "access": "logs-apache.access-*", - "error": "logs-apache.error-*", - "status": "metrics-apache.status-*" - }, - "name": "apache", - "version": "1.1.0", - "internal": false, - "removable": true, - "install_version": "1.1.0", - "install_status": "installed", - "install_started_at": "2021-09-30T10:46:58.713Z", - "install_source": "registry" - }, - "references": [], - "migrationVersion": { - "epm-packages": "7.14.1" - }, - "coreMigrationVersion": "8.0.0" - } - } -} \ No newline at end of file diff --git a/x-pack/plugins/fleet/cypress/fixtures/integrations/create_integration_response.json b/x-pack/plugins/fleet/cypress/fixtures/integrations/create_integration_response.json deleted file mode 100644 index 6820aadd01fb1..0000000000000 --- a/x-pack/plugins/fleet/cypress/fixtures/integrations/create_integration_response.json +++ /dev/null @@ -1,255 +0,0 @@ -{ - "item": { - "id": "1", - "version": "WzI4NDAsMV0=", - "name": "apache-1", - "description": "", - "namespace": "default", - "policy_id": "9ced27e0-20ff-11ec-b353-dd9d66c6f483", - "enabled": true, - "output_id": "", - "inputs": [ - { - "type": "logfile", - "policy_template": "apache", - "enabled": true, - "streams": [ - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "apache.access" - }, - "vars": { - "paths": { - "value": [ - "/var/log/apache2/access.log*", - "/var/log/apache2/other_vhosts_access.log*", - "/var/log/httpd/access_log*" - ], - "type": "text" - }, - "tags": { - "value": [ - "apache-access" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "logfile-apache.access-1c588150-010b-448a-b2b8-820d1b33811e", - "compiled_stream": { - "paths": [ - "/var/log/apache2/access.log*", - "/var/log/apache2/other_vhosts_access.log*", - "/var/log/httpd/access_log*" - ], - "tags": [ - "apache-access" - ], - "exclude_files": [ - ".gz$" - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "apache.error" - }, - "vars": { - "paths": { - "value": [ - "/var/log/apache2/error.log*", - "/var/log/httpd/error_log*" - ], - "type": "text" - }, - "tags": { - "value": [ - "apache-error" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "logfile-apache.error-1c588150-010b-448a-b2b8-820d1b33811e", - "compiled_stream": { - "paths": [ - "/var/log/apache2/error.log*", - "/var/log/httpd/error_log*" - ], - "exclude_files": [ - ".gz$" - ], - "tags": [ - "apache-error" - ], - "processors": [ - { - "add_locale": null - } - ] - } - } - ] - }, - { - "type": "httpjson", - "policy_template": "apache", - "enabled": false, - "streams": [ - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "apache.access" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=\"access*\"", - "type": "text" - }, - "tags": { - "value": [ - "forwarded", - "apache-access" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "httpjson-apache.access-1c588150-010b-448a-b2b8-820d1b33811e" - }, - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "apache.error" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=apache:error OR sourcetype=apache_error", - "type": "text" - }, - "tags": { - "value": [ - "forwarded", - "apache-error" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "httpjson-apache.error-1c588150-010b-448a-b2b8-820d1b33811e" - } - ], - "vars": { - "url": { - "value": "https://server.example.com:8089", - "type": "text" - }, - "username": { - "type": "text" - }, - "password": { - "type": "password" - }, - "token": { - "type": "password" - }, - "ssl": { - "value": "#certificate_authorities:\n# - |\n# -----BEGIN CERTIFICATE-----\n# MIIDCjCCAfKgAwIBAgITJ706Mu2wJlKckpIvkWxEHvEyijANBgkqhkiG9w0BAQsF\n# ADAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwIBcNMTkwNzIyMTkyOTA0WhgPMjExOTA2\n# MjgxOTI5MDRaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB\n# BQADggEPADCCAQoCggEBANce58Y/JykI58iyOXpxGfw0/gMvF0hUQAcUrSMxEO6n\n# fZRA49b4OV4SwWmA3395uL2eB2NB8y8qdQ9muXUdPBWE4l9rMZ6gmfu90N5B5uEl\n# 94NcfBfYOKi1fJQ9i7WKhTjlRkMCgBkWPkUokvBZFRt8RtF7zI77BSEorHGQCk9t\n# /D7BS0GJyfVEhftbWcFEAG3VRcoMhF7kUzYwp+qESoriFRYLeDWv68ZOvG7eoWnP\n# PsvZStEVEimjvK5NSESEQa9xWyJOmlOKXhkdymtcUd/nXnx6UTCFgnkgzSdTWV41\n# CI6B6aJ9svCTI2QuoIq2HxX/ix7OvW1huVmcyHVxyUECAwEAAaNTMFEwHQYDVR0O\n# BBYEFPwN1OceFGm9v6ux8G+DZ3TUDYxqMB8GA1UdIwQYMBaAFPwN1OceFGm9v6ux\n# 8G+DZ3TUDYxqMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAG5D\n# 874A4YI7YUwOVsVAdbWtgp1d0zKcPRR+r2OdSbTAV5/gcS3jgBJ3i1BN34JuDVFw\n# 3DeJSYT3nxy2Y56lLnxDeF8CUTUtVQx3CuGkRg1ouGAHpO/6OqOhwLLorEmxi7tA\n# H2O8mtT0poX5AnOAhzVy7QW0D/k4WaoLyckM5hUa6RtvgvLxOwA0U+VGurCDoctu\n# 8F4QOgTAWyh8EZIwaKCliFRSynDpv3JTUwtfZkxo6K6nce1RhCWFAsMvDZL8Dgc0\n# yvgJ38BRsFOtkRuAGSf6ZUwTO8JJRRIFnpUzXflAnGivK9M13D5GEQMmIl6U9Pvk\n# sxSmbIUfc2SGJGCJD4I=\n# -----END CERTIFICATE-----\n", - "type": "yaml" - } - } - }, - { - "type": "apache/metrics", - "policy_template": "apache", - "enabled": true, - "streams": [ - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "apache.status" - }, - "vars": { - "period": { - "value": "30s", - "type": "text" - }, - "server_status_path": { - "value": "/server-status", - "type": "text" - } - }, - "id": "apache/metrics-apache.status-1c588150-010b-448a-b2b8-820d1b33811e", - "compiled_stream": { - "metricsets": [ - "status" - ], - "hosts": [ - "http://127.0.0.1" - ], - "period": "30s", - "server_status_path": "/server-status" - } - } - ], - "vars": { - "hosts": { - "value": [ - "http://127.0.0.1" - ], - "type": "text" - } - } - } - ], - "package": { - "name": "apache", - "title": "Apache", - "version": "1.1.0" - }, - "revision": 1, - "created_at": "2021-09-29T09:12:55.869Z", - "created_by": "elastic", - "updated_at": "2021-09-29T09:12:55.869Z", - "updated_by": "elastic" - } -} \ No newline at end of file diff --git a/x-pack/plugins/fleet/cypress/fixtures/integrations/list.json b/x-pack/plugins/fleet/cypress/fixtures/integrations/list.json deleted file mode 100644 index 73c3ff54c5d95..0000000000000 --- a/x-pack/plugins/fleet/cypress/fixtures/integrations/list.json +++ /dev/null @@ -1,260 +0,0 @@ -{ - "items": [ - { - "id": "1", - "version": "WzczOSwxXQ==", - "name": "apache-1", - "description": "", - "namespace": "default", - "policy_id": "30e16140-2106-11ec-a289-25321523992d", - "enabled": true, - "output_id": "", - "inputs": [ - { - "type": "logfile", - "policy_template": "apache", - "enabled": true, - "streams": [ - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "apache.access" - }, - "vars": { - "paths": { - "value": [ - "/var/log/apache2/access.log*", - "/var/log/apache2/other_vhosts_access.log*", - "/var/log/httpd/access_log*" - ], - "type": "text" - }, - "tags": { - "value": [ - "apache-access" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "logfile-apache.access-63172a6b-4f00-4376-b5e6-fe9b3f00fc79", - "compiled_stream": { - "paths": [ - "/var/log/apache2/access.log*", - "/var/log/apache2/other_vhosts_access.log*", - "/var/log/httpd/access_log*" - ], - "tags": [ - "apache-access" - ], - "exclude_files": [ - ".gz$" - ] - } - }, - { - "enabled": true, - "data_stream": { - "type": "logs", - "dataset": "apache.error" - }, - "vars": { - "paths": { - "value": [ - "/var/log/apache2/error.log*", - "/var/log/httpd/error_log*" - ], - "type": "text" - }, - "tags": { - "value": [ - "apache-error" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "logfile-apache.error-63172a6b-4f00-4376-b5e6-fe9b3f00fc79", - "compiled_stream": { - "paths": [ - "/var/log/apache2/error.log*", - "/var/log/httpd/error_log*" - ], - "exclude_files": [ - ".gz$" - ], - "tags": [ - "apache-error" - ], - "processors": [ - { - "add_locale": null - } - ] - } - } - ] - }, - { - "type": "httpjson", - "policy_template": "apache", - "enabled": false, - "streams": [ - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "apache.access" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=\"access*\"", - "type": "text" - }, - "tags": { - "value": [ - "forwarded", - "apache-access" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "httpjson-apache.access-63172a6b-4f00-4376-b5e6-fe9b3f00fc79" - }, - { - "enabled": false, - "data_stream": { - "type": "logs", - "dataset": "apache.error" - }, - "vars": { - "interval": { - "value": "10s", - "type": "text" - }, - "search": { - "value": "search sourcetype=apache:error OR sourcetype=apache_error", - "type": "text" - }, - "tags": { - "value": [ - "forwarded", - "apache-error" - ], - "type": "text" - }, - "preserve_original_event": { - "value": false, - "type": "bool" - }, - "processors": { - "type": "yaml" - } - }, - "id": "httpjson-apache.error-63172a6b-4f00-4376-b5e6-fe9b3f00fc79" - } - ], - "vars": { - "url": { - "value": "https://server.example.com:8089", - "type": "text" - }, - "username": { - "type": "text" - }, - "password": { - "type": "password" - }, - "token": { - "type": "password" - }, - "ssl": { - "value": "#certificate_authorities:\n# - |\n# -----BEGIN CERTIFICATE-----\n# MIIDCjCCAfKgAwIBAgITJ706Mu2wJlKckpIvkWxEHvEyijANBgkqhkiG9w0BAQsF\n# ADAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwIBcNMTkwNzIyMTkyOTA0WhgPMjExOTA2\n# MjgxOTI5MDRaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB\n# BQADggEPADCCAQoCggEBANce58Y/JykI58iyOXpxGfw0/gMvF0hUQAcUrSMxEO6n\n# fZRA49b4OV4SwWmA3395uL2eB2NB8y8qdQ9muXUdPBWE4l9rMZ6gmfu90N5B5uEl\n# 94NcfBfYOKi1fJQ9i7WKhTjlRkMCgBkWPkUokvBZFRt8RtF7zI77BSEorHGQCk9t\n# /D7BS0GJyfVEhftbWcFEAG3VRcoMhF7kUzYwp+qESoriFRYLeDWv68ZOvG7eoWnP\n# PsvZStEVEimjvK5NSESEQa9xWyJOmlOKXhkdymtcUd/nXnx6UTCFgnkgzSdTWV41\n# CI6B6aJ9svCTI2QuoIq2HxX/ix7OvW1huVmcyHVxyUECAwEAAaNTMFEwHQYDVR0O\n# BBYEFPwN1OceFGm9v6ux8G+DZ3TUDYxqMB8GA1UdIwQYMBaAFPwN1OceFGm9v6ux\n# 8G+DZ3TUDYxqMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAG5D\n# 874A4YI7YUwOVsVAdbWtgp1d0zKcPRR+r2OdSbTAV5/gcS3jgBJ3i1BN34JuDVFw\n# 3DeJSYT3nxy2Y56lLnxDeF8CUTUtVQx3CuGkRg1ouGAHpO/6OqOhwLLorEmxi7tA\n# H2O8mtT0poX5AnOAhzVy7QW0D/k4WaoLyckM5hUa6RtvgvLxOwA0U+VGurCDoctu\n# 8F4QOgTAWyh8EZIwaKCliFRSynDpv3JTUwtfZkxo6K6nce1RhCWFAsMvDZL8Dgc0\n# yvgJ38BRsFOtkRuAGSf6ZUwTO8JJRRIFnpUzXflAnGivK9M13D5GEQMmIl6U9Pvk\n# sxSmbIUfc2SGJGCJD4I=\n# -----END CERTIFICATE-----\n", - "type": "yaml" - } - } - }, - { - "type": "apache/metrics", - "policy_template": "apache", - "enabled": true, - "streams": [ - { - "enabled": true, - "data_stream": { - "type": "metrics", - "dataset": "apache.status" - }, - "vars": { - "period": { - "value": "30s", - "type": "text" - }, - "server_status_path": { - "value": "/server-status", - "type": "text" - } - }, - "id": "apache/metrics-apache.status-63172a6b-4f00-4376-b5e6-fe9b3f00fc79", - "compiled_stream": { - "metricsets": [ - "status" - ], - "hosts": [ - "http://127.0.0.1" - ], - "period": "30s", - "server_status_path": "/server-status" - } - } - ], - "vars": { - "hosts": { - "value": [ - "http://127.0.0.1" - ], - "type": "text" - } - } - } - ], - "package": { - "name": "apache", - "title": "Apache", - "version": "1.1.0" - }, - "revision": 1, - "created_at": "2021-09-29T09:52:12.865Z", - "created_by": "elastic", - "updated_at": "2021-09-29T09:52:12.865Z", - "updated_by": "elastic" - } - ], - "total": 1, - "page": 1, - "perPage": 20 -} \ No newline at end of file diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index c2f4459e25f33..3ff6a2adee70c 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -6,6 +6,7 @@ */ import { AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; +import { cleanupAgentPolicies } from '../tasks/cleanup'; import { FLEET, navigateTo } from '../tasks/navigation'; describe('Fleet startup', () => { @@ -13,6 +14,10 @@ describe('Fleet startup', () => { navigateTo(FLEET); }); + after(() => { + cleanupAgentPolicies(); + }); + function navigateToAgentPolicies() { cy.getBySel(AGENT_POLICIES_TAB).click(); cy.get('.euiBasicTable-loading').should('not.exist'); @@ -35,24 +40,24 @@ describe('Fleet startup', () => { }); }); - it('should create Default Fleet Server policy', () => { + it('should create Fleet Server policy', () => { cy.getBySel('toastCloseButton').click(); cy.getBySel('createFleetServerPolicyBtn').click(); cy.getBySel('euiToastHeader'); navigateToAgentPolicies(); - navigateToAgentPolicy('Default Fleet Server policy'); + navigateToAgentPolicy('Fleet Server policy 1'); cy.get('.euiLink').contains('Fleet Server'); cy.get('.euiButtonEmpty').contains('View all agent policies').click(); navigateToEnrollmentTokens(); - cy.get('.euiTableCellContent').contains('Default Fleet Server policy'); + cy.get('.euiTableCellContent').contains('Fleet Server policy 1'); }); - it('should create Default policy', () => { + it('should create agent policy', () => { cy.getBySel('addAgentBtnTop').click(); cy.getBySel('toastCloseButton').click(); cy.getBySel('createPolicyBtn').click(); @@ -62,13 +67,15 @@ describe('Fleet startup', () => { navigateToAgentPolicies(); - navigateToAgentPolicy('Default policy'); + navigateToAgentPolicy('Agent policy 1'); cy.get('.euiLink').contains('System'); cy.get('.euiButtonEmpty').contains('View all agent policies').click(); navigateToEnrollmentTokens(); - cy.get('.euiTableCellContent').contains('Default policy'); + cy.get('.euiTableCellContent').contains('Agent policy 1'); + + // TODO might take longer to install elastic agent async cy.visit('/app/integrations/installed'); cy.getBySel('integration-card:epr:elastic_agent'); diff --git a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts index 8b1a5e97279e8..7eb7f8aab454e 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts @@ -23,10 +23,15 @@ import { SETTINGS_TAB, UPDATE_PACKAGE_BTN, } from '../screens/integrations'; +import { cleanupAgentPolicies } from '../tasks/cleanup'; describe('Add Integration', () => { const integration = 'Apache'; + after(() => { + cleanupAgentPolicies(); + }); + describe('Real API', () => { afterEach(() => { deleteIntegrations(integration); @@ -71,26 +76,4 @@ describe('Add Integration', () => { addIntegration(); cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-'); } - - it.skip('[Mocked requests] should display Apache integration in the Policies list once installed ', () => { - cy.intercept('POST', '/api/fleet/package_policies', { - fixture: 'integrations/create_integration_response.json', - }); - cy.intercept( - 'GET', - '/api/fleet/package_policies?page=1&perPage=20&kuery=ingest-package-policies.package.name%3A%20apache', - { fixture: 'integrations/list.json' } - ); - cy.intercept('GET', '/api/fleet/agent_policies?*', { - fixture: 'integrations/agent_policies.json', - }); - cy.intercept('GET', '/api/fleet/agent_policies/30e16140-2106-11ec-a289-25321523992d', { - fixture: 'integrations/agent_policy.json', - }); - // TODO fixture includes 1 package policy, should be empty initially - cy.intercept('GET', '/api/fleet/epm/packages/apache/1.1.0', { - fixture: 'integrations/apache.json', - }); - addAndVerifyIntegration(); - }); }); diff --git a/x-pack/plugins/fleet/cypress/tasks/cleanup.ts b/x-pack/plugins/fleet/cypress/tasks/cleanup.ts new file mode 100644 index 0000000000000..9a78c3362cd5a --- /dev/null +++ b/x-pack/plugins/fleet/cypress/tasks/cleanup.ts @@ -0,0 +1,19 @@ +/* + * 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. + */ + +export function cleanupAgentPolicies() { + cy.request('/api/fleet/agent_policies').then((response: any) => { + response.body.items.forEach((policy: any) => { + cy.request({ + method: 'POST', + url: '/api/fleet/agent_policies/delete', + body: { agentPolicyId: policy.id }, + headers: { 'kbn-xsrf': 'kibana' }, + }); + }); + }); +} diff --git a/x-pack/plugins/fleet/cypress/tasks/integrations.ts b/x-pack/plugins/fleet/cypress/tasks/integrations.ts index 749bb9b7a2842..e9e3f2613c3e8 100644 --- a/x-pack/plugins/fleet/cypress/tasks/integrations.ts +++ b/x-pack/plugins/fleet/cypress/tasks/integrations.ts @@ -15,7 +15,6 @@ import { export const addIntegration = () => { cy.getBySel(ADD_POLICY_BTN).click(); - cy.get('#existing').click(); // select Existing Hosts tab for agent policy cy.getBySel(CREATE_PACKAGE_POLICY_SAVE_BTN).click(); // sometimes agent is assigned to default policy, sometimes not cy.getBySel(CONFIRM_MODAL_BTN).click(); diff --git a/x-pack/plugins/fleet/cypress/tsconfig.json b/x-pack/plugins/fleet/cypress/tsconfig.json index 1adb067fe682e..0d8d83e1feeb7 100644 --- a/x-pack/plugins/fleet/cypress/tsconfig.json +++ b/x-pack/plugins/fleet/cypress/tsconfig.json @@ -13,5 +13,6 @@ "node" ], "resolveJsonModule": true, + "target": "ES2019", }, } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx index a7f6dd4f6d528..933cbc7e566c3 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx @@ -10,7 +10,6 @@ import { EuiDescribedFormGroup, EuiFormRow, EuiSpacer, - EuiText, EuiComboBox, EuiIconTip, EuiCheckboxGroup, @@ -274,11 +273,7 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent = /> - {isEditing && - 'id' in agentPolicy && - !agentPolicy.is_managed && - !agentPolicy.is_default && - !agentPolicy.is_default_fleet_server ? ( + {isEditing && 'id' in agentPolicy && !agentPolicy.is_managed ? ( @@ -300,7 +295,6 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent = return ( deleteAgentPolicyPrompt(agentPolicy.id!, onDelete)} > = ); }} - {agentPolicy.is_default ? ( - <> - - - - - - ) : null} } /> diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index 93d91bb5df13b..d3a2912152ede 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -50,12 +50,11 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ const [touchedFields, setTouchedFields] = useState<{ [key: string]: boolean }>({}); const defaultPolicy = { - name: isFleetServerPolicy ? 'Default Fleet Server policy' : 'Default policy', + name: isFleetServerPolicy ? 'Fleet Server policy 1' : 'Agent policy 1', description: '', namespace: 'default', monitoring_enabled: Object.values(dataTypes), - is_default_fleet_server: isFleetServerPolicy || undefined, - is_default: !isFleetServerPolicy, + has_fleet_server: isFleetServerPolicy, }; const [newAgentPolicy, setNewAgentPolicy] = useState({ diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index b47be85d1e8dd..db0ab3d3121ce 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -118,16 +118,11 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { // Agent policy state const [agentPolicy, setAgentPolicy] = useState(); - const defaultPolicy = { - name: 'Default policy', + const [newAgentPolicy, setNewAgentPolicy] = useState({ + name: 'Agent policy 1', description: '', namespace: 'default', monitoring_enabled: Object.values(dataTypes), - is_default: true, - }; - - const [newAgentPolicy, setNewAgentPolicy] = useState({ - ...defaultPolicy, }); const [withSysMonitoring, setWithSysMonitoring] = useState(true); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx index 82183cf7433c9..ac3c284eefdd8 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -42,6 +42,16 @@ interface Props { updateSelectedTab: (tab: SelectedPolicyTab) => void; } +const getLatestPolicyIndex = (policies: AgentPolicy[]) => { + const indices = policies + .map((pol: AgentPolicy) => pol.name) + .map((name) => { + const match = name.match(/Agent policy (\d+)/); + return match ? parseInt(match[1], 10) : 1; + }); + return Math.max(...indices, 1) + 1; +}; + export const StepSelectHosts: React.FunctionComponent = ({ agentPolicy, updateAgentPolicy, @@ -55,7 +65,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ defaultAgentPolicyId, updateSelectedTab, }) => { - let agentPolicies = []; + let agentPolicies: AgentPolicy[] = []; const { data: agentPoliciesData, error: err } = useGetAgentPolicies({ page: 1, perPage: 1000, @@ -76,8 +86,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ if (agentPolicies.length > 0) { updateNewAgentPolicy({ ...newAgentPolicy, - name: '', - is_default: false, + name: `Agent policy ${getLatestPolicyIndex(agentPolicies)}`, }); } }, [agentPolicies.length]); // eslint-disable-line react-hooks/exhaustive-deps diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx index 492c77dbfca47..eba847fe0d5b2 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx @@ -48,7 +48,6 @@ export const CreateAgentPolicyFlyout: React.FunctionComponent = ({ name: '', description: '', namespace: 'default', - is_default: undefined, monitoring_enabled: Object.values(dataTypes), }); const [isLoading, setIsLoading] = useState(false); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx index c64d065c1e058..5a2c83648a926 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx @@ -379,12 +379,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { // Fleet server unhealthy status const { isUnhealthy: isFleetServerUnhealthy } = useFleetServerUnhealthy(); - const onClickAddFleetServer = useCallback(() => { - const defaultPolicy = agentPolicies.find((policy) => policy.is_default_fleet_server); - if (defaultPolicy) { - setEnrollmentFlyoutState({ isOpen: true, selectedPolicyId: defaultPolicy.id }); - } - }, [agentPolicies]); + const onClickAddFleetServer = () => setEnrollmentFlyoutState({ isOpen: true }); const columns = [ { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index db9bbd25e6538..f2dec146004cd 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -355,15 +355,6 @@ const AgentPolicySelectionStep = ({ return agentPolicies.map((policy) => ({ text: policy.name, value: policy.id })); }, [agentPolicies]); - useEffect(() => { - // Select default value - if (agentPolicies.length && !policyId) { - const defaultPolicy = - agentPolicies.find((p) => p.is_default_fleet_server) || agentPolicies[0]; - setPolicyId(defaultPolicy.id); - } - }, [options, agentPolicies, policyId, setPolicyId]); - const onChangeCallback = useCallback( (e: React.ChangeEvent) => { setPolicyId(e.target.value); @@ -396,7 +387,7 @@ const AgentPolicySelectionStep = ({ diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx index 02874f12c6592..d1d7abd0fa4bc 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx @@ -708,7 +708,6 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos '2babac18-eb8e-4ce4-b53b-4b7c5f507019', 'e8a37031-2907-44f6-89d2-98bd493f60dc', ], - is_default: true, is_managed: false, monitoring_enabled: ['logs', 'metrics'], revision: 6, @@ -723,7 +722,6 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos description: 'Protect EU from COVID', status: 'active', package_policies: ['e8a37031-2907-44f6-89d2-98bd493f60cd'], - is_default: false, is_managed: false, monitoring_enabled: ['logs', 'metrics'], revision: 2, diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx index bc17f8eb3fbcf..8aba3344340db 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx @@ -38,11 +38,6 @@ const resolveAgentId = ( if (agentPolicies.length === 1) { return agentPolicies[0].id; } - - const defaultAgentPolicy = agentPolicies.find((agentPolicy) => agentPolicy.is_default); - if (defaultAgentPolicy) { - return defaultAgentPolicy.id; - } } return selectedAgentPolicyId; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx index c47fcffa11c63..3fd03fdea18f4 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx @@ -90,10 +90,7 @@ export const AgentPolicySelectionStep = ({ }) => { const regularAgentPolicies = useMemo(() => { return Array.isArray(agentPolicies) - ? agentPolicies.filter( - (policy) => - policy && !policy.is_managed && (!excludeFleetServer || !policy.is_default_fleet_server) - ) + ? agentPolicies.filter((policy) => policy && !policy.is_managed && !excludeFleetServer) : []; }, [agentPolicies, excludeFleetServer]); diff --git a/x-pack/plugins/fleet/public/components/new_enrollment_key_modal.tsx b/x-pack/plugins/fleet/public/components/new_enrollment_key_modal.tsx index 362c6e6bdb061..c73ccb48bf6b6 100644 --- a/x-pack/plugins/fleet/public/components/new_enrollment_key_modal.tsx +++ b/x-pack/plugins/fleet/public/components/new_enrollment_key_modal.tsx @@ -63,9 +63,8 @@ export const NewEnrollmentTokenModal: React.FunctionComponent = ({ agentPolicies = [], }) => { const { notifications } = useStartServices(); - const policyIdDefaultValue = agentPolicies.find((agentPolicy) => agentPolicy.is_default)?.id; const form = useCreateApiKeyForm( - policyIdDefaultValue, + undefined, (key: EnrollmentAPIKey) => { onClose(key); notifications.toasts.addSuccess( @@ -109,7 +108,6 @@ export const NewEnrollmentTokenModal: React.FunctionComponent = ({ > !agentPolicy.is_managed) diff --git a/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx b/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx index 63a3a93b7e894..4e8f598a45472 100644 --- a/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx +++ b/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx @@ -48,7 +48,6 @@ function createMockAgentPolicy(props: Partial = {}): AgentPolicy { monitoring_enabled: [], name: 'Test Policy', description: '', - is_default: false, is_preconfigured: false, status: 'active', is_managed: false, diff --git a/x-pack/plugins/fleet/public/constants/index.ts b/x-pack/plugins/fleet/public/constants/index.ts index 139f9d3d1f1c4..dddd7552f0151 100644 --- a/x-pack/plugins/fleet/public/constants/index.ts +++ b/x-pack/plugins/fleet/public/constants/index.ts @@ -20,7 +20,6 @@ export { ENROLLMENT_API_KEYS_INDEX, // Preconfiguration AUTO_UPDATE_PACKAGES, - DEFAULT_PACKAGES, KEEP_POLICIES_UP_TO_DATE_PACKAGES, AUTO_UPGRADE_POLICIES_PACKAGES, } from '../../common/constants'; diff --git a/x-pack/plugins/fleet/server/constants/index.ts b/x-pack/plugins/fleet/server/constants/index.ts index 0769f02fc0272..0ccbeb9f025e4 100644 --- a/x-pack/plugins/fleet/server/constants/index.ts +++ b/x-pack/plugins/fleet/server/constants/index.ts @@ -43,11 +43,8 @@ export { ASSETS_SAVED_OBJECT_TYPE, GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, // Defaults - DEFAULT_AGENT_POLICY, - DEFAULT_FLEET_SERVER_AGENT_POLICY, DEFAULT_OUTPUT, DEFAULT_OUTPUT_ID, - DEFAULT_PACKAGES, PACKAGE_POLICY_DEFAULT_INDEX_PRIVILEGES, AGENT_POLICY_DEFAULT_MONITORING_DATASETS, // Fleet Server index diff --git a/x-pack/plugins/fleet/server/mocks/index.ts b/x-pack/plugins/fleet/server/mocks/index.ts index 7e47c8b59ac7a..b8b52f8c706a4 100644 --- a/x-pack/plugins/fleet/server/mocks/index.ts +++ b/x-pack/plugins/fleet/server/mocks/index.ts @@ -126,7 +126,6 @@ export const createMockAgentPolicyService = (): jest.Mocked undefined) - : undefined, - ]); + }); + } // Create the system monitoring package policy and add it to agent policy. - if ( - (withSysMonitoring || isDefaultFleetServer) && - newPackagePolicy !== undefined && - agentPolicy !== undefined - ) { - newPackagePolicy.policy_id = agentPolicy.id; - newPackagePolicy.namespace = agentPolicy.namespace; - newPackagePolicy.name = await incrementPackageName(soClient, packageToInstall); - - await packagePolicyService.create(soClient, esClient, newPackagePolicy, { + if (withSysMonitoring) { + await createPackagePolicy(soClient, esClient, agentPolicy, FLEET_SYSTEM_PACKAGE, { spaceId, user, - bumpRevision: false, }); } @@ -192,6 +184,33 @@ export const createAgentPolicyHandler: FleetRequestHandler< } }; +async function createPackagePolicy( + soClient: SavedObjectsClientContract, + esClient: ElasticsearchClient, + agentPolicy: AgentPolicy, + packageToInstall: string, + options: { spaceId: string; user: AuthenticatedUser | undefined } +) { + // If needed, retrieve package information and build a new package policy for the package + // NOTE: we ignore failures in attempting to create package policy, since agent policy might have been created + // successfully + const newPackagePolicy = await packagePolicyService + .buildPackagePolicyFromPackage(soClient, packageToInstall) + .catch(() => undefined); + + if (!newPackagePolicy) return; + + newPackagePolicy.policy_id = agentPolicy.id; + newPackagePolicy.namespace = agentPolicy.namespace; + newPackagePolicy.name = await incrementPackageName(soClient, packageToInstall); + + await packagePolicyService.create(soClient, esClient, newPackagePolicy, { + spaceId: options.spaceId, + user: options.user, + bumpRevision: false, + }); +} + export const updateAgentPolicyHandler: RequestHandler< TypeOf, unknown, diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index 96cb51af53b45..5ab1c7a76dabf 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -77,8 +77,6 @@ const getSavedObjectTypes = ( name: { type: 'keyword' }, description: { type: 'text' }, namespace: { type: 'keyword' }, - is_default: { type: 'boolean' }, - is_default_fleet_server: { type: 'boolean' }, is_managed: { type: 'boolean' }, status: { type: 'keyword' }, package_policies: { type: 'keyword' }, diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_16_0.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_16_0.ts index c435e504a2bfe..33ea56c538616 100644 --- a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_16_0.ts +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_16_0.ts @@ -8,7 +8,7 @@ import type { SavedObjectMigrationFn } from 'kibana/server'; import type { Installation, PackagePolicy } from '../../../common'; -import { DEFAULT_PACKAGES } from '../../../common'; +import { AUTO_UPDATE_PACKAGES } from '../../../common'; import { migratePackagePolicyToV7160 as SecSolMigratePackagePolicyToV7160 } from './security_solution'; @@ -18,7 +18,7 @@ export const migrateInstallationToV7160: SavedObjectMigrationFn { const updatedInstallationDoc = installationDoc; - if (DEFAULT_PACKAGES.some((pkg) => pkg.name === updatedInstallationDoc.attributes.name)) { + if (AUTO_UPDATE_PACKAGES.some((pkg) => pkg.name === updatedInstallationDoc.attributes.name)) { updatedInstallationDoc.attributes.keep_policies_up_to_date = true; } diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index b63f86e0bf81f..7209433e3d1b9 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -135,19 +135,7 @@ class AgentPolicyService { let searchParams; - const isDefaultPolicy = - preconfiguredAgentPolicy.is_default || preconfiguredAgentPolicy.is_default_fleet_server; - - if (isDefaultPolicy) { - searchParams = { - searchFields: [ - preconfiguredAgentPolicy.is_default_fleet_server - ? 'is_default_fleet_server' - : 'is_default', - ], - search: 'true', - }; - } else if (id) { + if (id) { searchParams = { id: String(id), }; @@ -239,9 +227,7 @@ class AgentPolicyService { options ); - if (!agentPolicy.is_default && !agentPolicy.is_default_fleet_server) { - await this.triggerAgentPolicyUpdatedEvent(soClient, esClient, 'created', newSo.id); - } + await this.triggerAgentPolicyUpdatedEvent(soClient, esClient, 'created', newSo.id); return { id: newSo.id, ...newSo.attributes }; } @@ -596,20 +582,6 @@ class AgentPolicyService { ); } - public async getDefaultAgentPolicyId(soClient: SavedObjectsClientContract) { - const agentPolicies = await soClient.find({ - type: AGENT_POLICY_SAVED_OBJECT_TYPE, - searchFields: ['is_default'], - search: 'true', - }); - - if (agentPolicies.saved_objects.length === 0) { - throw new Error('No default agent policy'); - } - - return agentPolicies.saved_objects[0].id; - } - public async delete( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, @@ -624,14 +596,6 @@ class AgentPolicyService { throw new HostedAgentPolicyRestrictionRelatedError(`Cannot delete hosted agent policy ${id}`); } - if (agentPolicy.is_default) { - throw new Error('The default agent policy cannot be deleted'); - } - - if (agentPolicy.is_default_fleet_server) { - throw new Error('The default fleet server agent policy cannot be deleted'); - } - const { total } = await getAgentsByKuery(esClient, { showInactive: false, perPage: 0, @@ -700,7 +664,6 @@ class AgentPolicyService { coordinator_idx: 0, data: fullPolicy as unknown as FleetServerPolicy['data'], policy_id: fullPolicy.id, - default_fleet_server: policy.is_default_fleet_server === true, }; if (policy.unenroll_timeout) { diff --git a/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts b/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts index 166bd26e0d706..ae490efe83125 100644 --- a/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts +++ b/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts @@ -144,7 +144,7 @@ export async function generateEnrollmentAPIKey( data: { name?: string; expiration?: string; - agentPolicyId?: string; + agentPolicyId: string; forceRecreate?: boolean; } ): Promise { @@ -153,8 +153,7 @@ export async function generateEnrollmentAPIKey( if (data.agentPolicyId) { await validateAgentPolicyId(soClient, data.agentPolicyId); } - const agentPolicyId = - data.agentPolicyId ?? (await agentPolicyService.getDefaultAgentPolicyId(soClient)); + const agentPolicyId = data.agentPolicyId; // TODO agentPolicyId should be required, BWC? if (providedKeyName && !forceRecreate) { let hasMore = true; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/index.ts b/x-pack/plugins/fleet/server/services/epm/packages/index.ts index feee4277ab0e1..2c79045c626d3 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/index.ts @@ -7,11 +7,7 @@ import type { SavedObject } from 'src/core/server'; -import { - unremovablePackages, - installationStatuses, - KibanaSavedObjectType, -} from '../../../../common'; +import { installationStatuses, KibanaSavedObjectType } from '../../../../common'; import { KibanaAssetType } from '../../../types'; import type { AssetType, Installable, Installation } from '../../../types'; @@ -32,10 +28,6 @@ export type { BulkInstallResponse, IBulkInstallPackageError } from './install'; export { handleInstallPackageFailure, installPackage, ensureInstalledPackage } from './install'; export { removeInstallation } from './remove'; -export function isUnremovablePackage(value: string): boolean { - return unremovablePackages.includes(value); -} - export class PackageNotInstalledError extends Error { constructor(pkgkey: string) { super(`${pkgkey} is not installed`); diff --git a/x-pack/plugins/fleet/server/services/index.ts b/x-pack/plugins/fleet/server/services/index.ts index 7e615f923b221..332410e6c9224 100644 --- a/x-pack/plugins/fleet/server/services/index.ts +++ b/x-pack/plugins/fleet/server/services/index.ts @@ -37,7 +37,6 @@ export interface PackageService { export interface AgentPolicyServiceInterface { get: typeof agentPolicyService['get']; list: typeof agentPolicyService['list']; - getDefaultAgentPolicyId: typeof agentPolicyService['getDefaultAgentPolicyId']; getFullAgentPolicy: typeof agentPolicyService['getFullAgentPolicy']; getByIds: typeof agentPolicyService['getByIDs']; } diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index 5e4c6d6a71b3c..91375f52a655b 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -733,8 +733,7 @@ class PackagePolicyService { namespace: newPolicy.namespace ?? 'default', description: newPolicy.description ?? '', enabled: newPolicy.enabled ?? true, - policy_id: - newPolicy.policy_id ?? (await agentPolicyService.getDefaultAgentPolicyId(soClient)), + policy_id: newPolicy.policy_id, // TODO BWC previously optional output_id: newPolicy.output_id ?? '', inputs: newPolicy.inputs[0]?.streams ? newPolicy.inputs : inputs, vars: newPolicy.vars || newPP.vars, diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.ts b/x-pack/plugins/fleet/server/services/preconfiguration.ts index 8593f753de738..d0f828995f550 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.ts @@ -226,14 +226,10 @@ export async function ensurePreconfiguredPackagesAndPolicies( if (wasDeleted) { return { created: false, deleted: preconfigurationId }; } - } else if ( - !preconfiguredAgentPolicy.is_default && - !preconfiguredAgentPolicy.is_default_fleet_server - ) { + } else { throw new Error( i18n.translate('xpack.fleet.preconfiguration.missingIDError', { - defaultMessage: - '{agentPolicyName} is missing an `id` field. `id` is required, except for policies marked is_default or is_default_fleet_server.', + defaultMessage: '{agentPolicyName} is missing an `id` field. `id` is required.', values: { agentPolicyName: preconfiguredAgentPolicy.name }, }) ); diff --git a/x-pack/plugins/fleet/server/types/models/agent_policy.ts b/x-pack/plugins/fleet/server/types/models/agent_policy.ts index 7f0376b32de7e..624833c9a54e9 100644 --- a/x-pack/plugins/fleet/server/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/server/types/models/agent_policy.ts @@ -18,6 +18,7 @@ export const AgentPolicyBaseSchema = { is_managed: schema.maybe(schema.boolean()), is_default: schema.maybe(schema.boolean()), is_default_fleet_server: schema.maybe(schema.boolean()), + has_fleet_server: schema.maybe(schema.boolean()), unenroll_timeout: schema.maybe(schema.number({ min: 0 })), monitoring_enabled: schema.maybe( schema.arrayOf( diff --git a/x-pack/plugins/fleet/server/types/models/preconfiguration.ts b/x-pack/plugins/fleet/server/types/models/preconfiguration.ts index 1741e3d5f9e95..960ecbe67d593 100644 --- a/x-pack/plugins/fleet/server/types/models/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/types/models/preconfiguration.ts @@ -98,6 +98,7 @@ export const PreconfiguredAgentPoliciesSchema = schema.arrayOf( id: schema.maybe(schema.oneOf([schema.string(), schema.number()])), is_default: schema.maybe(schema.boolean()), is_default_fleet_server: schema.maybe(schema.boolean()), + has_fleet_server: schema.maybe(schema.boolean()), data_output_id: schema.maybe(schema.string()), monitoring_output_id: schema.maybe(schema.string()), package_policies: schema.arrayOf( diff --git a/x-pack/plugins/osquery/cypress/integration/integration.spec.ts b/x-pack/plugins/osquery/cypress/integration/integration.spec.ts index 99de19e0bbddb..6b704160921e5 100644 --- a/x-pack/plugins/osquery/cypress/integration/integration.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/integration.spec.ts @@ -50,7 +50,7 @@ describe('Add Integration', () => { function addAndVerifyIntegration() { navigateTo(FLEET_AGENT_POLICIES); - cy.contains('Default Fleet Server policy').click(); + cy.contains('Fleet Server policy 1').click(); cy.contains('Add integration').click(); cy.contains(integration).click(); diff --git a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts index 291c535cc1221..8a40c643553b0 100644 --- a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts +++ b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts @@ -70,14 +70,13 @@ export default function (providerContext: FtrProviderContext) { }); before(async () => { - // create default policies + // create agent policies let { body: apiResponse } = await supertest .post(`/api/fleet/agent_policies`) .set('kbn-xsrf', 'kibana') .send({ - name: 'Default Fleet Server policy', + name: 'Fleet Server policy 1', namespace: 'default', - is_default_fleet_server: true, }) .expect(200); const defaultFleetServerPolicy = apiResponse.item; @@ -86,20 +85,19 @@ export default function (providerContext: FtrProviderContext) { .post(`/api/fleet/agent_policies`) .set('kbn-xsrf', 'kibana') .send({ - name: 'Default policy', + name: 'Agent policy 1', namespace: 'default', - is_default: true, }) .expect(200)); const defaultServerPolicy = apiResponse.item; if (!defaultFleetServerPolicy) { - throw new Error('No default Fleet server policy'); + throw new Error('No Fleet server policy'); } if (!defaultServerPolicy) { - throw new Error('No default policy'); + throw new Error('No agent policy'); } await supertest From 01ad43c0363423c06e92f471cf7149a2cc6c92e4 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 5 Jan 2022 13:43:33 +0100 Subject: [PATCH 24/99] fix tests --- x-pack/plugins/fleet/server/saved_objects/index.ts | 2 ++ x-pack/plugins/fleet/server/services/agent_policy.test.ts | 1 - .../fleet/server/services/api_keys/enrollment_api_key.ts | 2 +- x-pack/plugins/fleet/server/services/package_policy.test.ts | 2 ++ x-pack/plugins/fleet/server/types/models/agent_policy.ts | 2 -- x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - x-pack/test/functional/es_archives/fleet/agents/mappings.json | 3 --- .../es_archives/fleet/empty_fleet_server/mappings.json | 3 --- 9 files changed, 5 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index 5ab1c7a76dabf..e91eaf0bb0569 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -78,6 +78,8 @@ const getSavedObjectTypes = ( description: { type: 'text' }, namespace: { type: 'keyword' }, is_managed: { type: 'boolean' }, + is_default: { type: 'boolean' }, + is_default_fleet_server: { type: 'boolean' }, status: { type: 'keyword' }, package_policies: { type: 'keyword' }, unenroll_timeout: { type: 'integer' }, diff --git a/x-pack/plugins/fleet/server/services/agent_policy.test.ts b/x-pack/plugins/fleet/server/services/agent_policy.test.ts index e28e2610b4b45..49c042fc112c9 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.test.ts @@ -278,7 +278,6 @@ describe('agent policy', () => { body: expect.objectContaining({ '@timestamp': expect.anything(), data: { id: 'policy123', inputs: [{ id: 'input-123' }], revision: 1 }, - default_fleet_server: false, policy_id: 'policy123', revision_idx: 1, }), diff --git a/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts b/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts index ae490efe83125..df4c92c2ec34c 100644 --- a/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts +++ b/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts @@ -153,7 +153,7 @@ export async function generateEnrollmentAPIKey( if (data.agentPolicyId) { await validateAgentPolicyId(soClient, data.agentPolicyId); } - const agentPolicyId = data.agentPolicyId; // TODO agentPolicyId should be required, BWC? + const agentPolicyId = data.agentPolicyId; if (providedKeyName && !forceRecreate) { let hasMore = true; diff --git a/x-pack/plugins/fleet/server/services/package_policy.test.ts b/x-pack/plugins/fleet/server/services/package_policy.test.ts index dca55d44630ce..25e17016d045e 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.test.ts @@ -2879,6 +2879,7 @@ describe('Package policy service', () => { name: 'apache-1', inputs: [{ type: 'logfile', enabled: false }], package: { name: 'apache', version: '0.3.3' }, + policy_id: '1', } as NewPackagePolicy; const result = await packagePolicyService.enrichPolicyWithDefaultsFromPackage( savedObjectsClientMock.create(), @@ -2955,6 +2956,7 @@ describe('Package policy service', () => { name: 'aws-1', inputs: [{ type: 'aws/metrics', policy_template: 'cloudwatch', enabled: true }], package: { name: 'aws', version: '1.0.0' }, + policy_id: '1', } as NewPackagePolicy; const result = await packagePolicyService.enrichPolicyWithDefaultsFromPackage( savedObjectsClientMock.create(), diff --git a/x-pack/plugins/fleet/server/types/models/agent_policy.ts b/x-pack/plugins/fleet/server/types/models/agent_policy.ts index 624833c9a54e9..07cf439d62f9f 100644 --- a/x-pack/plugins/fleet/server/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/server/types/models/agent_policy.ts @@ -16,8 +16,6 @@ export const AgentPolicyBaseSchema = { namespace: NamespaceSchema, description: schema.maybe(schema.string()), is_managed: schema.maybe(schema.boolean()), - is_default: schema.maybe(schema.boolean()), - is_default_fleet_server: schema.maybe(schema.boolean()), has_fleet_server: schema.maybe(schema.boolean()), unenroll_timeout: schema.maybe(schema.number({ min: 0 })), monitoring_enabled: schema.maybe( diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 8cd3b929a9651..bdc388b757bad 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10623,7 +10623,6 @@ "xpack.fleet.policyForm.deletePolicyGroupTitle": "ポリシーを削除", "xpack.fleet.policyForm.generalSettingsGroupDescription": "エージェントポリシーの名前と説明を選択してください。", "xpack.fleet.policyForm.generalSettingsGroupTitle": "一般設定", - "xpack.fleet.policyForm.unableToDeleteDefaultPolicyText": "デフォルトポリシーは削除できません", "xpack.fleet.preconfiguration.duplicatePackageError": "構成で重複するパッケージが指定されています。{duplicateList}", "xpack.fleet.preconfiguration.missingIDError": "{agentPolicyName}には「id」フィールドがありません。ポリシーのis_defaultまたはis_default_fleet_serverに設定されている場合をのぞき、「id」は必須です。", "xpack.fleet.preconfiguration.packageMissingError": "[{agentPolicyName}]を追加できませんでした。[{pkgName}]がインストールされていません。[{pkgName}]を[{packagesConfigValue}]に追加するか、[{packagePolicyName}]から削除してください。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index ea4fa4b67ddfa..ad10e00dff922 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -10729,7 +10729,6 @@ "xpack.fleet.policyForm.deletePolicyGroupTitle": "删除策略", "xpack.fleet.policyForm.generalSettingsGroupDescription": "为您的代理策略选择名称和描述。", "xpack.fleet.policyForm.generalSettingsGroupTitle": "常规设置", - "xpack.fleet.policyForm.unableToDeleteDefaultPolicyText": "默认策略无法删除", "xpack.fleet.preconfiguration.duplicatePackageError": "配置中指定的软件包重复:{duplicateList}", "xpack.fleet.preconfiguration.missingIDError": "{agentPolicyName} 缺失 `id` 字段。`id` 是必需的,但标记为 is_default 或 is_default_fleet_server 的策略除外。", "xpack.fleet.preconfiguration.packageMissingError": "无法添加 [{agentPolicyName}]。[{pkgName}] 未安装,请将 [{pkgName}] 添加到 [{packagesConfigValue}] 或将其从 [{packagePolicyName}] 中移除。", diff --git a/x-pack/test/functional/es_archives/fleet/agents/mappings.json b/x-pack/test/functional/es_archives/fleet/agents/mappings.json index 1f2df04713c4b..bf0ecb43232fc 100644 --- a/x-pack/test/functional/es_archives/fleet/agents/mappings.json +++ b/x-pack/test/functional/es_archives/fleet/agents/mappings.json @@ -3393,9 +3393,6 @@ "enabled": false, "type": "object" }, - "default_fleet_server": { - "type": "boolean" - }, "policy_id": { "type": "keyword" }, diff --git a/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json b/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json index a04b7a7dc21c7..9f7103ac42165 100644 --- a/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json +++ b/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json @@ -355,9 +355,6 @@ "enabled": false, "type": "object" }, - "default_fleet_server": { - "type": "boolean" - }, "policy_id": { "type": "keyword" }, From 7d9fa31e548addd1b7698ebbae75cc2c1ce84d89 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 5 Jan 2022 13:53:01 +0100 Subject: [PATCH 25/99] revert osquery change --- x-pack/plugins/osquery/cypress/integration/integration.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/osquery/cypress/integration/integration.spec.ts b/x-pack/plugins/osquery/cypress/integration/integration.spec.ts index 6b704160921e5..99de19e0bbddb 100644 --- a/x-pack/plugins/osquery/cypress/integration/integration.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/integration.spec.ts @@ -50,7 +50,7 @@ describe('Add Integration', () => { function addAndVerifyIntegration() { navigateTo(FLEET_AGENT_POLICIES); - cy.contains('Fleet Server policy 1').click(); + cy.contains('Default Fleet Server policy').click(); cy.contains('Add integration').click(); cy.contains(integration).click(); From 854d2ade7c115f90129f58778ce08253c3ba6018 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 5 Jan 2022 17:52:04 +0100 Subject: [PATCH 26/99] changes in cypress fleet server start --- .../cypress/integration/fleet_startup.spec.ts | 110 ++++++++++-------- .../fleet/server/saved_objects/index.ts | 4 +- .../saved_objects/migrations/to_v8_1_0.ts | 19 +++ x-pack/test/fleet_cypress/agent.ts | 15 +-- x-pack/test/fleet_cypress/artifact_manager.ts | 2 +- x-pack/test/fleet_cypress/fleet_server.ts | 46 +++++--- x-pack/test/fleet_cypress/runner.ts | 39 +++---- 7 files changed, 138 insertions(+), 97 deletions(-) create mode 100644 x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_1_0.ts diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 3ff6a2adee70c..73d2dc48ae868 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -14,70 +14,82 @@ describe('Fleet startup', () => { navigateTo(FLEET); }); - after(() => { - cleanupAgentPolicies(); - }); + describe.skip('Fleet Server', () => { + it('should display Add agent button and Healthy agent once Fleet Agent page loaded', () => { + cy.get('.euiBadge').contains('Healthy'); + }); - function navigateToAgentPolicies() { - cy.getBySel(AGENT_POLICIES_TAB).click(); - cy.get('.euiBasicTable-loading').should('not.exist'); - } - - function navigateToAgentPolicy(name: string) { - cy.get('.euiLink').contains(name).click(); - cy.get('.euiLoadingSpinner').should('not.exist'); - } - - function navigateToEnrollmentTokens() { - cy.getBySel(ENROLLMENT_TOKENS_TAB).click(); - cy.get('.euiBasicTable-loading').should('not.exist'); - cy.get('.euiButtonIcon--danger'); // wait for trash icon - } - - it('should have no agent policies by default', () => { - cy.request('/api/fleet/agent_policies?full=true').then((response: any) => { - expect(response.body.items.length).to.equal(0); + after(() => { + cleanupAgentPolicies(); }); }); - it('should create Fleet Server policy', () => { - cy.getBySel('toastCloseButton').click(); - cy.getBySel('createFleetServerPolicyBtn').click(); - cy.getBySel('euiToastHeader'); + describe('Create policies', () => { + after(() => { + cleanupAgentPolicies(); + }); - navigateToAgentPolicies(); + function navigateToAgentPolicies() { + cy.getBySel(AGENT_POLICIES_TAB).click(); + cy.get('.euiBasicTable-loading').should('not.exist'); + } + + function navigateToAgentPolicy(name: string) { + cy.get('.euiLink').contains(name).click(); + cy.get('.euiLoadingSpinner').should('not.exist'); + } + + function navigateToEnrollmentTokens() { + cy.getBySel(ENROLLMENT_TOKENS_TAB).click(); + cy.get('.euiBasicTable-loading').should('not.exist'); + cy.get('.euiButtonIcon--danger'); // wait for trash icon + } + + it('should have no agent policies by default', () => { + cy.request('/api/fleet/agent_policies?full=true').then((response: any) => { + expect(response.body.items.length).to.equal(0); + }); + }); - navigateToAgentPolicy('Fleet Server policy 1'); - cy.get('.euiLink').contains('Fleet Server'); + it('should create Fleet Server policy', () => { + cy.getBySel('toastCloseButton').click(); + cy.getBySel('createFleetServerPolicyBtn').click(); + cy.getBySel('euiToastHeader'); - cy.get('.euiButtonEmpty').contains('View all agent policies').click(); + navigateToAgentPolicies(); - navigateToEnrollmentTokens(); + navigateToAgentPolicy('Fleet Server policy 1'); + cy.get('.euiLink').contains('Fleet Server'); - cy.get('.euiTableCellContent').contains('Fleet Server policy 1'); - }); + cy.get('.euiButtonEmpty').contains('View all agent policies').click(); - it('should create agent policy', () => { - cy.getBySel('addAgentBtnTop').click(); - cy.getBySel('toastCloseButton').click(); - cy.getBySel('createPolicyBtn').click(); - cy.getBySel('euiToastHeader'); - cy.get('.euiLoadingSpinner').should('not.exist'); - cy.getBySel('euiFlyoutCloseButton').click(); + navigateToEnrollmentTokens(); - navigateToAgentPolicies(); + cy.get('.euiTableCellContent').contains('Fleet Server policy 1'); + }); + + it('should create agent policy', () => { + cy.getBySel('addAgentBtnTop').click(); + cy.getBySel('toastCloseButton').click(); + cy.getBySel('createPolicyBtn').click(); + cy.getBySel('euiToastHeader'); + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.getBySel('euiFlyoutCloseButton').click(); - navigateToAgentPolicy('Agent policy 1'); - cy.get('.euiLink').contains('System'); + navigateToAgentPolicies(); - cy.get('.euiButtonEmpty').contains('View all agent policies').click(); + navigateToAgentPolicy('Agent policy 1'); + cy.get('.euiLink').contains('System'); - navigateToEnrollmentTokens(); - cy.get('.euiTableCellContent').contains('Agent policy 1'); + cy.get('.euiButtonEmpty').contains('View all agent policies').click(); - // TODO might take longer to install elastic agent async + navigateToEnrollmentTokens(); + cy.get('.euiTableCellContent').contains('Agent policy 1'); - cy.visit('/app/integrations/installed'); - cy.getBySel('integration-card:epr:elastic_agent'); + // TODO might take longer to install elastic agent async + + cy.visit('/app/integrations/installed'); + cy.getBySel('integration-card:epr:elastic_agent'); + }); }); }); diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index e91eaf0bb0569..5a485af1300c3 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -36,6 +36,7 @@ import { migratePackagePolicyToV7140, migrateInstallationToV7140 } from './migra import { migratePackagePolicyToV7150 } from './migrations/to_v7_15_0'; import { migrateInstallationToV7160, migratePackagePolicyToV7160 } from './migrations/to_v7_16_0'; import { migrateInstallationToV800, migrateOutputToV800 } from './migrations/to_v8_0_0'; +import { migrateAgentPolicyToV810 } from './migrations/to_v8_1_0'; /* * Saved object types and mappings @@ -78,8 +79,6 @@ const getSavedObjectTypes = ( description: { type: 'text' }, namespace: { type: 'keyword' }, is_managed: { type: 'boolean' }, - is_default: { type: 'boolean' }, - is_default_fleet_server: { type: 'boolean' }, status: { type: 'keyword' }, package_policies: { type: 'keyword' }, unenroll_timeout: { type: 'integer' }, @@ -95,6 +94,7 @@ const getSavedObjectTypes = ( migrations: { '7.10.0': migrateAgentPolicyToV7100, '7.12.0': migrateAgentPolicyToV7120, + '8.1.0': migrateAgentPolicyToV810, }, }, [OUTPUT_SAVED_OBJECT_TYPE]: { diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_1_0.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_1_0.ts new file mode 100644 index 0000000000000..42ce665c3d788 --- /dev/null +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_1_0.ts @@ -0,0 +1,19 @@ +/* + * 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 type { SavedObjectMigrationFn } from 'kibana/server'; + +import type { AgentPolicy } from '../../types'; + +export const migrateAgentPolicyToV810: SavedObjectMigrationFn = ( + agentPolicyDoc +) => { + delete agentPolicyDoc.attributes.is_default; + delete agentPolicyDoc.attributes.is_default_fleet_server; + + return agentPolicyDoc; +}; diff --git a/x-pack/test/fleet_cypress/agent.ts b/x-pack/test/fleet_cypress/agent.ts index 1838d9df8b3e2..c0e5b2374889d 100644 --- a/x-pack/test/fleet_cypress/agent.ts +++ b/x-pack/test/fleet_cypress/agent.ts @@ -11,11 +11,12 @@ import { ChildProcess, spawn } from 'child_process'; import { getLatestVersion } from './artifact_manager'; import { Manager } from './resource_manager'; -interface AgentManagerParams { +export interface AgentManagerParams { user: string; password: string; kibanaUrl: string; esHost: string; + esPort: string; } export class AgentManager extends Manager { @@ -23,19 +24,11 @@ export class AgentManager extends Manager { private log: ToolingLog; private agentProcess?: ChildProcess; private requestOptions: AxiosRequestConfig; - constructor(params: AgentManagerParams, log: ToolingLog) { + constructor(params: AgentManagerParams, log: ToolingLog, requestOptions: AxiosRequestConfig) { super(); this.log = log; this.params = params; - this.requestOptions = { - headers: { - 'kbn-xsrf': 'kibana', - }, - auth: { - username: this.params.user, - password: this.params.password, - }, - }; + this.requestOptions = requestOptions; } public async setup() { diff --git a/x-pack/test/fleet_cypress/artifact_manager.ts b/x-pack/test/fleet_cypress/artifact_manager.ts index aea0eb8bbec86..17ba9b0a5517d 100644 --- a/x-pack/test/fleet_cypress/artifact_manager.ts +++ b/x-pack/test/fleet_cypress/artifact_manager.ts @@ -10,5 +10,5 @@ import { last } from 'lodash'; export async function getLatestVersion(): Promise { const response: any = await axios('https://artifacts-api.elastic.co/v1/versions'); - return last(response.data.versions as string[]) || '8.0.0-SNAPSHOT'; + return last(response.data.versions as string[]) || '8.1.0-SNAPSHOT'; } diff --git a/x-pack/test/fleet_cypress/fleet_server.ts b/x-pack/test/fleet_cypress/fleet_server.ts index fe2b8c7459229..d3bb4a385185d 100644 --- a/x-pack/test/fleet_cypress/fleet_server.ts +++ b/x-pack/test/fleet_cypress/fleet_server.ts @@ -7,37 +7,52 @@ import { ChildProcess, spawn } from 'child_process'; import { ToolingLog } from '@kbn/dev-utils'; -import axios from 'axios'; +import axios, { AxiosRequestConfig } from 'axios'; import { Manager } from './resource_manager'; import { getLatestVersion } from './artifact_manager'; - -export interface ElasticsearchConfig { - esHost: string; - user: string; - password: string; - port: string; -} +import { AgentManagerParams } from './agent'; export class FleetManager extends Manager { private fleetProcess?: ChildProcess; - private esConfig: ElasticsearchConfig; + private config: AgentManagerParams; private log: ToolingLog; - constructor(esConfig: ElasticsearchConfig, log: ToolingLog) { + private requestOptions: AxiosRequestConfig; + constructor(config: AgentManagerParams, log: ToolingLog, requestOptions: AxiosRequestConfig) { super(); - this.esConfig = esConfig; + this.config = config; this.log = log; + this.requestOptions = requestOptions; } public async setup(): Promise { this.log.info('Setting fleet up'); return new Promise(async (res, rej) => { try { const response = await axios.post( - `${this.esConfig.esHost}/_security/service/elastic/fleet-server/credential/token` + `${this.config.kibanaUrl}/api/fleet/service_tokens`, + {}, + this.requestOptions ); - const serviceToken = response.data.token.value; + const serviceToken = response.data.value; const artifact = `docker.elastic.co/beats/elastic-agent:${await getLatestVersion()}`; this.log.info(artifact); + // default fleet server policy no longer created by default + const { + data: { + item: { id: policyId }, + }, + } = await axios.post( + `${this.config.kibanaUrl}/api/fleet/agent_policies`, + { + name: 'Fleet Server policy', + description: '', + namespace: 'default', + monitoring_enabled: [], + has_fleet_server: true, + }, + this.requestOptions + ); + const host = 'host.docker.internal'; const args = [ @@ -49,12 +64,15 @@ export class FleetManager extends Manager { '--env', 'FLEET_SERVER_ENABLE=true', '--env', - `FLEET_SERVER_ELASTICSEARCH_HOST=http://${host}:${this.esConfig.port}`, + `FLEET_SERVER_ELASTICSEARCH_HOST=http://${host}:${this.config.esPort}`, '--env', `FLEET_SERVER_SERVICE_TOKEN=${serviceToken}`, + '--env', + `FLEET_SERVER_POLICY=${policyId}`, '--rm', artifact, ]; + this.log.info('docker ' + args.join(' ')); this.fleetProcess = spawn('docker', args, { stdio: 'inherit', }); diff --git a/x-pack/test/fleet_cypress/runner.ts b/x-pack/test/fleet_cypress/runner.ts index 19509174af843..ccc5827c860c9 100644 --- a/x-pack/test/fleet_cypress/runner.ts +++ b/x-pack/test/fleet_cypress/runner.ts @@ -12,7 +12,7 @@ import { withProcRunner } from '@kbn/dev-utils'; import { FtrProviderContext } from './ftr_provider_context'; -import { AgentManager } from './agent'; +import { AgentManager, AgentManagerParams } from './agent'; import { FleetManager } from './fleet_server'; async function withFleetAgent( @@ -23,25 +23,29 @@ async function withFleetAgent( const config = getService('config'); const esHost = Url.format(config.get('servers.elasticsearch')); - const esConfig = { + const params: AgentManagerParams = { user: config.get('servers.elasticsearch.username'), password: config.get('servers.elasticsearch.password'), esHost, - port: config.get('servers.elasticsearch.port'), + esPort: config.get('servers.elasticsearch.port'), + kibanaUrl: Url.format({ + protocol: config.get('servers.kibana.protocol'), + hostname: config.get('servers.kibana.hostname'), + port: config.get('servers.kibana.port'), + }), }; - const fleetManager = new FleetManager(esConfig, log); - - const agentManager = new AgentManager( - { - ...esConfig, - kibanaUrl: Url.format({ - protocol: config.get('servers.kibana.protocol'), - hostname: config.get('servers.kibana.hostname'), - port: config.get('servers.kibana.port'), - }), + const requestOptions = { + headers: { + 'kbn-xsrf': 'kibana', }, - log - ); + auth: { + username: params.user, + password: params.password, + }, + }; + const fleetManager = new FleetManager(params, log, requestOptions); + + const agentManager = new AgentManager(params, log, requestOptions); // Since the managers will create uncaughtException event handlers we need to exit manually process.on('uncaughtException', (err) => { @@ -50,11 +54,6 @@ async function withFleetAgent( process.exit(1); }); - // TODO fleet server should be started in tests after default policy is created - - await runner({}); - return; - await agentManager.setup(); await fleetManager.setup(); try { From c04eba2df2591f8232da87cc5b3da620f59a4999 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 6 Jan 2022 10:20:38 +0100 Subject: [PATCH 27/99] fix fleet enroll and cypress --- .../cypress/integration/fleet_startup.spec.ts | 86 +++++++++---------- x-pack/plugins/fleet/cypress/tasks/cleanup.ts | 16 ++-- ...fleet_server_on_prem_unhealthy_callout.tsx | 7 +- .../server/routes/agent_policy/handlers.ts | 1 + 4 files changed, 58 insertions(+), 52 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 73d2dc48ae868..e76d85ebbd0b5 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -14,13 +14,40 @@ describe('Fleet startup', () => { navigateTo(FLEET); }); - describe.skip('Fleet Server', () => { + function navigateToAgentPolicies() { + cy.getBySel(AGENT_POLICIES_TAB).click(); + cy.get('.euiBasicTable-loading').should('not.exist'); + } + + function navigateToAgentPolicy(name: string) { + cy.get('.euiLink').contains(name).click(); + cy.get('.euiLoadingSpinner').should('not.exist'); + } + + function navigateToEnrollmentTokens() { + cy.getBySel(ENROLLMENT_TOKENS_TAB).click(); + cy.get('.euiBasicTable-loading').should('not.exist'); + cy.get('.euiButtonIcon--danger'); // wait for trash icon + } + + function verifyFleetServerPolicy(name: string, integration: string) { + navigateToAgentPolicies(); + + navigateToAgentPolicy(name); + cy.get('.euiLink').contains(integration); + + cy.get('.euiButtonEmpty').contains('View all agent policies').click(); + + navigateToEnrollmentTokens(); + + cy.get('.euiTableCellContent').contains(name); + } + + describe('Fleet Server', () => { it('should display Add agent button and Healthy agent once Fleet Agent page loaded', () => { cy.get('.euiBadge').contains('Healthy'); - }); - after(() => { - cleanupAgentPolicies(); + verifyFleetServerPolicy('Fleet Server policy', 'Fleet Server'); }); }); @@ -29,62 +56,33 @@ describe('Fleet startup', () => { cleanupAgentPolicies(); }); - function navigateToAgentPolicies() { - cy.getBySel(AGENT_POLICIES_TAB).click(); - cy.get('.euiBasicTable-loading').should('not.exist'); - } - - function navigateToAgentPolicy(name: string) { - cy.get('.euiLink').contains(name).click(); - cy.get('.euiLoadingSpinner').should('not.exist'); - } - - function navigateToEnrollmentTokens() { - cy.getBySel(ENROLLMENT_TOKENS_TAB).click(); - cy.get('.euiBasicTable-loading').should('not.exist'); - cy.get('.euiButtonIcon--danger'); // wait for trash icon - } - - it('should have no agent policies by default', () => { + // one policy was created in runner.ts to enroll a fleet server before starting cypress tests + it('should have one agent policy by default created through API', () => { cy.request('/api/fleet/agent_policies?full=true').then((response: any) => { - expect(response.body.items.length).to.equal(0); + expect(response.body.items.length).to.equal(1); + expect(response.body.items[0].name).to.equal('Fleet Server policy'); }); }); - it('should create Fleet Server policy', () => { + // TODO can be recreated after force unenroll and delete policy + it.skip('should create Fleet Server policy', () => { cy.getBySel('toastCloseButton').click(); - cy.getBySel('createFleetServerPolicyBtn').click(); + cy.getBySel('addFleetServerBtn').click(); cy.getBySel('euiToastHeader'); - navigateToAgentPolicies(); - - navigateToAgentPolicy('Fleet Server policy 1'); - cy.get('.euiLink').contains('Fleet Server'); - - cy.get('.euiButtonEmpty').contains('View all agent policies').click(); - - navigateToEnrollmentTokens(); - - cy.get('.euiTableCellContent').contains('Fleet Server policy 1'); + verifyFleetServerPolicy('Fleet Server policy 1', 'Fleet Server'); }); it('should create agent policy', () => { - cy.getBySel('addAgentBtnTop').click(); + cy.getBySel('addAgentButton').click(); cy.getBySel('toastCloseButton').click(); + cy.getBySel('standaloneTab').click(); cy.getBySel('createPolicyBtn').click(); cy.getBySel('euiToastHeader'); cy.get('.euiLoadingSpinner').should('not.exist'); cy.getBySel('euiFlyoutCloseButton').click(); - navigateToAgentPolicies(); - - navigateToAgentPolicy('Agent policy 1'); - cy.get('.euiLink').contains('System'); - - cy.get('.euiButtonEmpty').contains('View all agent policies').click(); - - navigateToEnrollmentTokens(); - cy.get('.euiTableCellContent').contains('Agent policy 1'); + verifyFleetServerPolicy('Agent policy 1', 'System'); // TODO might take longer to install elastic agent async diff --git a/x-pack/plugins/fleet/cypress/tasks/cleanup.ts b/x-pack/plugins/fleet/cypress/tasks/cleanup.ts index 9a78c3362cd5a..f52190bae084b 100644 --- a/x-pack/plugins/fleet/cypress/tasks/cleanup.ts +++ b/x-pack/plugins/fleet/cypress/tasks/cleanup.ts @@ -7,13 +7,15 @@ export function cleanupAgentPolicies() { cy.request('/api/fleet/agent_policies').then((response: any) => { - response.body.items.forEach((policy: any) => { - cy.request({ - method: 'POST', - url: '/api/fleet/agent_policies/delete', - body: { agentPolicyId: policy.id }, - headers: { 'kbn-xsrf': 'kibana' }, + response.body.items + .filter((policy: any) => policy.agents === 0) + .forEach((policy: any) => { + cy.request({ + method: 'POST', + url: '/api/fleet/agent_policies/delete', + body: { agentPolicyId: policy.id }, + headers: { 'kbn-xsrf': 'kibana' }, + }); }); - }); }); } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/fleet_server_callouts/fleet_server_on_prem_unhealthy_callout.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/fleet_server_callouts/fleet_server_on_prem_unhealthy_callout.tsx index e7ba51ebf5247..d74433ca48a5b 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/fleet_server_callouts/fleet_server_on_prem_unhealthy_callout.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/fleet_server_callouts/fleet_server_on_prem_unhealthy_callout.tsx @@ -44,7 +44,12 @@ export const FleetServerOnPremUnhealthyCallout: React.FunctionComponent< }} /> - + Date: Thu, 6 Jan 2022 15:00:28 +0100 Subject: [PATCH 28/99] fixed add agent flyout when fleet agent unenrolled --- .../cypress/integration/fleet_startup.spec.ts | 42 +++++-- x-pack/plugins/fleet/cypress/screens/fleet.ts | 2 + x-pack/plugins/fleet/cypress/tasks/cleanup.ts | 15 +++ .../components/actions_menu.tsx | 13 +- .../sections/agents/agent_list_page/index.tsx | 7 +- .../fleet_server_on_prem_instructions.tsx | 7 ++ .../agents/services/has_fleet_server.ts | 19 +++ ...advanced_agent_authentication_settings.tsx | 4 +- .../agent_policy_selection.tsx | 114 ++++++++++++++---- .../managed_instructions.tsx | 17 ++- .../agent_enrollment_flyout/steps.tsx | 7 +- .../components/context_menu_actions.tsx | 1 + 12 files changed, 194 insertions(+), 54 deletions(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index e76d85ebbd0b5..f6b1f9e720d0b 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; -import { cleanupAgentPolicies } from '../tasks/cleanup'; +import { AGENTS_TAB, AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; +import { cleanupAgentPolicies, unenrollAgent } from '../tasks/cleanup'; import { FLEET, navigateTo } from '../tasks/navigation'; describe('Fleet startup', () => { @@ -49,6 +49,11 @@ describe('Fleet startup', () => { verifyFleetServerPolicy('Fleet Server policy', 'Fleet Server'); }); + + after(() => { + unenrollAgent(); + cleanupAgentPolicies(); + }); }); describe('Create policies', () => { @@ -56,21 +61,34 @@ describe('Fleet startup', () => { cleanupAgentPolicies(); }); - // one policy was created in runner.ts to enroll a fleet server before starting cypress tests - it('should have one agent policy by default created through API', () => { + it('should have no agent policy by default', () => { cy.request('/api/fleet/agent_policies?full=true').then((response: any) => { - expect(response.body.items.length).to.equal(1); - expect(response.body.items[0].name).to.equal('Fleet Server policy'); + expect(response.body.items.length).to.equal(0); }); }); - // TODO can be recreated after force unenroll and delete policy - it.skip('should create Fleet Server policy', () => { - cy.getBySel('toastCloseButton').click(); - cy.getBySel('addFleetServerBtn').click(); - cy.getBySel('euiToastHeader'); + describe('Fleet Server policy', () => { + before(() => { + cy.request({ + method: 'PUT', + url: '/api/fleet/settings', + body: { fleet_server_hosts: ['http://localhost:8220'] }, + headers: { 'kbn-xsrf': 'kibana' }, + }); + }); + + it('should create Fleet Server policy', () => { + cy.getBySel(AGENTS_TAB).click(); + cy.getBySel('addAgentButton').click(); + cy.getBySel('toastCloseButton').click(); + + cy.getBySel('createFleetServerPolicyBtn').click(); + cy.getBySel('euiToastHeader'); - verifyFleetServerPolicy('Fleet Server policy 1', 'Fleet Server'); + cy.getBySel('euiFlyoutCloseButton').click(); + + verifyFleetServerPolicy('Fleet Server policy 1', 'Fleet Server'); + }); }); it('should create agent policy', () => { diff --git a/x-pack/plugins/fleet/cypress/screens/fleet.ts b/x-pack/plugins/fleet/cypress/screens/fleet.ts index 6be51e5ed24bc..4c0bb7cea161e 100644 --- a/x-pack/plugins/fleet/cypress/screens/fleet.ts +++ b/x-pack/plugins/fleet/cypress/screens/fleet.ts @@ -7,5 +7,7 @@ export const ADD_AGENT_BUTTON = 'addAgentButton'; +export const AGENTS_TAB = 'fleet-agents-tab'; export const AGENT_POLICIES_TAB = 'fleet-agent-policies-tab'; export const ENROLLMENT_TOKENS_TAB = 'fleet-enrollment-tokens-tab'; +export const SETTINGS_TAB = 'fleet-settings-tab'; diff --git a/x-pack/plugins/fleet/cypress/tasks/cleanup.ts b/x-pack/plugins/fleet/cypress/tasks/cleanup.ts index f52190bae084b..e3ab5684777ca 100644 --- a/x-pack/plugins/fleet/cypress/tasks/cleanup.ts +++ b/x-pack/plugins/fleet/cypress/tasks/cleanup.ts @@ -19,3 +19,18 @@ export function cleanupAgentPolicies() { }); }); } + +export function unenrollAgent() { + cy.request('/api/fleet/agents?page=1&perPage=20&showInactive=false&showUpgradeable=false').then( + (response: any) => { + response.body.items.forEach((agent: any) => { + cy.request({ + method: 'POST', + url: `api/fleet/agents/${agent.id}/unenroll`, + body: { revoke: true }, + headers: { 'kbn-xsrf': 'kibana' }, + }); + }); + } + ); +} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx index 0f1c70f7cb481..33a400add62e9 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx @@ -9,7 +9,7 @@ import React, { memo, useState, useMemo } from 'react'; import { EuiPortal, EuiContextMenuItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { Agent, AgentPolicy, PackagePolicy } from '../../../../types'; +import type { Agent, AgentPolicy } from '../../../../types'; import { useCapabilities, useKibanaVersion } from '../../../../hooks'; import { ContextMenuActions } from '../../../../components'; import { @@ -19,7 +19,7 @@ import { } from '../../components'; import { useAgentRefresh } from '../hooks'; import { isAgentUpgradeable } from '../../../../services'; -import { FLEET_SERVER_PACKAGE } from '../../../../constants'; +import { policyHasFleetServer } from '../../services/has_fleet_server'; export const AgentDetailsActionMenu: React.FunctionComponent<{ agent: Agent; @@ -35,13 +35,6 @@ export const AgentDetailsActionMenu: React.FunctionComponent<{ const [isUpgradeModalOpen, setIsUpgradeModalOpen] = useState(false); const isUnenrolling = agent.status === 'unenrolling'; - const hasFleetServer = - agentPolicy && - agentPolicy.package_policies.some( - (ap: string | PackagePolicy) => - typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE - ); - const onClose = useMemo(() => { if (onCancelReassign) { return onCancelReassign; @@ -67,7 +60,7 @@ export const AgentDetailsActionMenu: React.FunctionComponent<{ refreshAgent(); }} useForceUnenroll={isUnenrolling} - hasFleetServer={hasFleetServer} + hasFleetServer={policyHasFleetServer} /> )} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx index 5a2c83648a926..77be593441637 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx @@ -379,7 +379,12 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { // Fleet server unhealthy status const { isUnhealthy: isFleetServerUnhealthy } = useFleetServerUnhealthy(); - const onClickAddFleetServer = () => setEnrollmentFlyoutState({ isOpen: true }); + const onClickAddFleetServer = useCallback(() => { + setEnrollmentFlyoutState({ + isOpen: true, + selectedPolicyId: agentPolicies.length > 0 ? agentPolicies[0].id : undefined, + }); + }, [agentPolicies]); const columns = [ { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index 7b7ddfe4b7abe..b54718caafc51 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -350,6 +350,13 @@ const AgentPolicySelectionStep = ({ return agentPolicies.map((policy) => ({ text: policy.name, value: policy.id })); }, [agentPolicies]); + useEffect(() => { + // Select default value + if (agentPolicies.length && !policyId) { + setPolicyId(agentPolicies[0].id); + } + }, [agentPolicies, policyId, setPolicyId]); + const onChangeCallback = useCallback( (e: React.ChangeEvent) => { setPolicyId(e.target.value); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts new file mode 100644 index 0000000000000..0e79a99530a87 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts @@ -0,0 +1,19 @@ +/* + * 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 type { AgentPolicy, PackagePolicy } from '../../../types'; +import { FLEET_SERVER_PACKAGE } from '../../../constants'; + +export function policyHasFleetServer(agentPolicy: AgentPolicy) { + return ( + agentPolicy && + agentPolicy.package_policies.some( + (ap: string | PackagePolicy) => + typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE + ) + ); +} diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/advanced_agent_authentication_settings.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/advanced_agent_authentication_settings.tsx index 7dc17f69377ba..3c3cb66b04ffa 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/advanced_agent_authentication_settings.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/advanced_agent_authentication_settings.tsx @@ -218,12 +218,12 @@ export const AdvancedAgentAuthenticationSettings: FunctionComponent = ({ /> ) : isLoadingEnrollmentApiKeys ? ( - ) : ( + ) : agentPolicyId ? ( - )} + ) : null} )} diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx index 8aba3344340db..1c2464e1abfa3 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx @@ -6,15 +6,34 @@ */ import React, { useState, useEffect } from 'react'; +import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiSelect, EuiSpacer, EuiText } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiLink, + EuiPortal, + EuiSelect, + EuiSpacer, + EuiText, +} from '@elastic/eui'; import type { AgentPolicy } from '../../types'; import { AgentPolicyPackageBadges } from '../agent_policy_package_badges'; +import { useCapabilities } from '../../hooks'; +import { CreateAgentPolicyFlyout } from '../../applications/fleet/sections/agent_policy/list_page/components'; + import { AdvancedAgentAuthenticationSettings } from './advanced_agent_authentication_settings'; +const AgentPolicyFormRow = styled(EuiFormRow)` + .euiFormRow__label { + width: 100%; + } +`; + type Props = { agentPolicies?: AgentPolicy[]; onAgentPolicyChange?: (key?: string) => void; @@ -46,10 +65,17 @@ const resolveAgentId = ( export const EnrollmentStepAgentPolicy: React.FC = (props) => { const { agentPolicies, onAgentPolicyChange, excludeFleetServer } = props; + const [agentPolicyList, setAgentPolicyList] = useState(agentPolicies || []); + const [selectedAgentPolicyId, setSelectedAgentPolicyId] = useState( - () => resolveAgentId(agentPolicies, undefined) // no agent id selected yet + () => resolveAgentId(agentPolicyList, undefined) // no agent id selected yet ); + // Create new agent policy flyout state + const hasWriteCapabilites = useCapabilities().write; + const [isCreateAgentPolicyFlyoutOpen, setIsCreateAgentPolicyFlyoutOpen] = + useState(false); + useEffect( function triggerOnAgentPolicyChangeEffect() { if (onAgentPolicyChange) { @@ -61,37 +87,77 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => { useEffect( function useDefaultAgentPolicyEffect() { - const resolvedId = resolveAgentId(agentPolicies, selectedAgentPolicyId); + const resolvedId = resolveAgentId(agentPolicyList, selectedAgentPolicyId); if (resolvedId !== selectedAgentPolicyId) { setSelectedAgentPolicyId(resolvedId); } }, - [agentPolicies, selectedAgentPolicyId] + [agentPolicyList, selectedAgentPolicyId] ); return ( <> - - - + {isCreateAgentPolicyFlyoutOpen ? ( + + { + setIsCreateAgentPolicyFlyoutOpen(false); + if (newAgentPolicy) { + setAgentPolicyList([...agentPolicyList, newAgentPolicy]); + + setSelectedAgentPolicyId(newAgentPolicy.id); + } + }} + ownFocus={true} + /> + + ) : null} + + +
+ setIsCreateAgentPolicyFlyoutOpen(true)} + > + + +
+
+ } - isLoading={!agentPolicies} - options={(agentPolicies || []).map((agentPolicy) => ({ - value: agentPolicy.id, - text: agentPolicy.name, - }))} - value={selectedAgentPolicyId || undefined} - onChange={(e) => setSelectedAgentPolicyId(e.target.value)} - aria-label={i18n.translate('xpack.fleet.enrollmentStepAgentPolicy.policySelectAriaLabel', { - defaultMessage: 'Agent policy', - })} - /> + > + + + + } + isLoading={!agentPolicies} + options={agentPolicyList.map((agentPolicy: AgentPolicy) => ({ + value: agentPolicy.id, + text: agentPolicy.name, + }))} + value={selectedAgentPolicyId || undefined} + onChange={(e) => setSelectedAgentPolicyId(e.target.value)} + aria-label={i18n.translate( + 'xpack.fleet.enrollmentStepAgentPolicy.policySelectAriaLabel', + { + defaultMessage: 'Agent policy', + } + )} + hasNoInitialSelection={agentPolicyList.length > 1} + /> +
{selectedAgentPolicyId && ( ( const apiKey = useGetOneEnrollmentAPIKey(selectedApiKeyId); const fleetServerInstructions = useFleetServerInstructions(apiKey?.data?.item?.policy_id); + const { data: agents } = useGetAgents({ + page: 1, + perPage: 1000, + showInactive: false, + }); + const fleetServerSteps = useMemo(() => { const { serviceToken, @@ -101,6 +107,7 @@ export const ManagedInstructions = React.memo( selectedApiKeyId, setSelectedAPIKeyId, setSelectedPolicyId, + excludeFleetServer: true, }) : AgentEnrollmentKeySelectionStep({ agentPolicy, selectedApiKeyId, setSelectedAPIKeyId }), DownloadStep(isFleetServerPolicySelected || false), @@ -140,7 +147,7 @@ export const ManagedInstructions = React.memo( return null; } - if (fleetStatus.isReady) { + if (fleetStatus.isReady && agents && agents.items.length > 0) { return ( <> @@ -157,8 +164,10 @@ export const ManagedInstructions = React.memo( return ( <> - {fleetStatus.missingRequirements?.length === 1 && - fleetStatus.missingRequirements[0] === 'fleet_server' ? ( + {(fleetStatus.missingRequirements?.length === 1 && + fleetStatus.missingRequirements[0] === 'fleet_server') || + !agents || + agents.items.length === 0 ? ( ) : ( diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx index 3fd03fdea18f4..bb67f8d3eb0c1 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx @@ -18,6 +18,8 @@ import { useKibanaVersion } from '../../hooks'; import { AgentPolicyCreateInlineForm } from '../../applications/fleet/sections/agent_policy/components'; +import { policyHasFleetServer } from '../../applications/fleet/sections/agents/services/has_fleet_server'; + import { EnrollmentStepAgentPolicy } from './agent_policy_selection'; import { AdvancedAgentAuthenticationSettings } from './advanced_agent_authentication_settings'; @@ -90,7 +92,10 @@ export const AgentPolicySelectionStep = ({ }) => { const regularAgentPolicies = useMemo(() => { return Array.isArray(agentPolicies) - ? agentPolicies.filter((policy) => policy && !policy.is_managed && !excludeFleetServer) + ? agentPolicies.filter( + (policy) => + policy && !policy.is_managed && (!excludeFleetServer || !policyHasFleetServer(policy)) + ) : []; }, [agentPolicies, excludeFleetServer]); diff --git a/x-pack/plugins/fleet/public/components/context_menu_actions.tsx b/x-pack/plugins/fleet/public/components/context_menu_actions.tsx index f25415101b9ac..5bfb12f865388 100644 --- a/x-pack/plugins/fleet/public/components/context_menu_actions.tsx +++ b/x-pack/plugins/fleet/public/components/context_menu_actions.tsx @@ -67,6 +67,7 @@ export const ContextMenuActions = React.memo(({ button, onChange, isOpen, aria-label={i18n.translate('xpack.fleet.genericActionsMenuText', { defaultMessage: 'Open', })} + data-test-subj="agentActionsBtn" /> ) } From a74232762e034358d13eda6ec20b413b8b6fbbc3 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 6 Jan 2022 15:41:07 +0100 Subject: [PATCH 29/99] fix tests --- .../components/actions_menu.tsx | 4 +- .../agents/services/has_fleet_server.ts | 9 +-- .../server/services/agent_policy.test.ts | 50 ++------------ .../fleet/server/services/agent_policy.ts | 67 +++++-------------- 4 files changed, 28 insertions(+), 102 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx index 33a400add62e9..de1fe109e2966 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx @@ -35,6 +35,8 @@ export const AgentDetailsActionMenu: React.FunctionComponent<{ const [isUpgradeModalOpen, setIsUpgradeModalOpen] = useState(false); const isUnenrolling = agent.status === 'unenrolling'; + const hasFleetServer = agentPolicy && policyHasFleetServer(agentPolicy); + const onClose = useMemo(() => { if (onCancelReassign) { return onCancelReassign; @@ -60,7 +62,7 @@ export const AgentDetailsActionMenu: React.FunctionComponent<{ refreshAgent(); }} useForceUnenroll={isUnenrolling} - hasFleetServer={policyHasFleetServer} + hasFleetServer={hasFleetServer} /> )} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts index 0e79a99530a87..8efee0953d4c1 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts @@ -9,11 +9,8 @@ import type { AgentPolicy, PackagePolicy } from '../../../types'; import { FLEET_SERVER_PACKAGE } from '../../../constants'; export function policyHasFleetServer(agentPolicy: AgentPolicy) { - return ( - agentPolicy && - agentPolicy.package_policies.some( - (ap: string | PackagePolicy) => - typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE - ) + return agentPolicy.package_policies.some( + (ap: string | PackagePolicy) => + typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE ); } diff --git a/x-pack/plugins/fleet/server/services/agent_policy.test.ts b/x-pack/plugins/fleet/server/services/agent_policy.test.ts index fcb6eb304c9c7..fad8fbf4a1a56 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.test.ts @@ -5,10 +5,10 @@ * 2.0. */ -import uuidv5 from 'uuid/v5'; - import { elasticsearchServiceMock, savedObjectsClientMock } from 'src/core/server/mocks'; +import { SavedObjectsErrorHelpers } from 'src/core/server'; + import type { AgentPolicy, FullAgentPolicy, @@ -296,14 +296,13 @@ describe('agent policy', () => { }); describe('ensurePreconfiguredAgentPolicy', () => { - it('should use preconfigured id if provided for default policy', async () => { + it('should use preconfigured id if provided for policy', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; const preconfiguredAgentPolicy: PreconfiguredAgentPolicy = { id: 'my-unique-id', name: 'My Preconfigured Policy', - is_default: true, package_policies: [ { name: 'my-package-policy', @@ -316,6 +315,7 @@ describe('agent policy', () => { }; soClient.find.mockResolvedValueOnce({ total: 0, saved_objects: [], page: 1, per_page: 10 }); + soClient.get.mockRejectedValueOnce(SavedObjectsErrorHelpers.createGenericNotFoundError()); soClient.create.mockResolvedValueOnce({ id: 'my-unique-id', @@ -337,47 +337,5 @@ describe('agent policy', () => { ); }); }); - - it('should generate uuid if no id is provided for default policy', async () => { - const soClient = savedObjectsClientMock.create(); - const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - - const preconfiguredAgentPolicy = { - name: 'My Preconfigured Policy', - is_default: true, - package_policies: [ - { - name: 'my-package-policy', - id: 'my-package-policy-id', - package: { - name: 'test-package', - }, - }, - ], - }; - - (uuidv5 as unknown as jest.Mock).mockReturnValueOnce('fake-uuid'); - - soClient.find.mockResolvedValueOnce({ total: 0, saved_objects: [], page: 1, per_page: 10 }); - - soClient.create.mockResolvedValueOnce({ - id: 'my-unique-id', - type: AGENT_POLICY_SAVED_OBJECT_TYPE, - attributes: {}, - references: [], - }); - - await agentPolicyService.ensurePreconfiguredAgentPolicy( - soClient, - esClient, - preconfiguredAgentPolicy as any - ); - - expect(soClient.create).toHaveBeenCalledWith( - AGENT_POLICY_SAVED_OBJECT_TYPE, - expect.anything(), - expect.objectContaining({ id: 'fake-uuid' }) - ); - }); }); }); diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index 307205a275b9f..89a2a037934a3 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -151,63 +151,32 @@ class AgentPolicyService { soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, newAgentPolicy: NewAgentPolicy, - searchParams: - | { id: string } - | { - searchFields: string[]; - search: string; - }, - id?: string | number + searchParams: { id: string } ): Promise<{ created: boolean; policy: AgentPolicy; }> { // For preconfigured policies with a specified ID - if ('id' in searchParams) { - try { - const agentPolicy = await soClient.get( - AGENT_POLICY_SAVED_OBJECT_TYPE, - searchParams.id - ); - return { - created: false, - policy: { - id: agentPolicy.id, - ...agentPolicy.attributes, - }, - }; - } catch (e) { - if (SavedObjectsErrorHelpers.isNotFoundError(e)) { - return { - created: true, - policy: await this.create(soClient, esClient, newAgentPolicy, { id: searchParams.id }), - }; - } else throw e; - } - } - - // For default policies without a specified ID - const agentPolicies = await soClient.find({ - type: AGENT_POLICY_SAVED_OBJECT_TYPE, - ...searchParams, - }); - - if (agentPolicies.total === 0) { + try { + const agentPolicy = await soClient.get( + AGENT_POLICY_SAVED_OBJECT_TYPE, + searchParams.id + ); return { - created: true, - policy: await this.create(soClient, esClient, newAgentPolicy, { - id: id ? String(id) : uuidv5(newAgentPolicy.name, UUID_V5_NAMESPACE), - }), + created: false, + policy: { + id: agentPolicy.id, + ...agentPolicy.attributes, + }, }; + } catch (e) { + if (SavedObjectsErrorHelpers.isNotFoundError(e)) { + return { + created: true, + policy: await this.create(soClient, esClient, newAgentPolicy, { id: searchParams.id }), + }; + } else throw e; } - - return { - created: false, - policy: { - id: agentPolicies.saved_objects[0].id, - ...agentPolicies.saved_objects[0].attributes, - }, - }; } public async create( From 6078869e36361065b1761c7fbe7c1ce34a264b2a Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 6 Jan 2022 16:15:45 +0100 Subject: [PATCH 30/99] existing hosts no policy selected when more than one --- .../cypress/integration/fleet_startup.spec.ts | 46 +++++----- .../create_package_policy_page/index.tsx | 2 - .../step_select_agent_policy.tsx | 83 +++++-------------- .../step_select_hosts.tsx | 3 - 4 files changed, 42 insertions(+), 92 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index f6b1f9e720d0b..b795b9537d909 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -61,33 +61,18 @@ describe('Fleet startup', () => { cleanupAgentPolicies(); }); - it('should have no agent policy by default', () => { - cy.request('/api/fleet/agent_policies?full=true').then((response: any) => { - expect(response.body.items.length).to.equal(0); + before(() => { + cy.request({ + method: 'PUT', + url: '/api/fleet/settings', + body: { fleet_server_hosts: ['http://localhost:8220'] }, + headers: { 'kbn-xsrf': 'kibana' }, }); }); - describe('Fleet Server policy', () => { - before(() => { - cy.request({ - method: 'PUT', - url: '/api/fleet/settings', - body: { fleet_server_hosts: ['http://localhost:8220'] }, - headers: { 'kbn-xsrf': 'kibana' }, - }); - }); - - it('should create Fleet Server policy', () => { - cy.getBySel(AGENTS_TAB).click(); - cy.getBySel('addAgentButton').click(); - cy.getBySel('toastCloseButton').click(); - - cy.getBySel('createFleetServerPolicyBtn').click(); - cy.getBySel('euiToastHeader'); - - cy.getBySel('euiFlyoutCloseButton').click(); - - verifyFleetServerPolicy('Fleet Server policy 1', 'Fleet Server'); + it('should have no agent policy by default', () => { + cy.request('/api/fleet/agent_policies?full=true').then((response: any) => { + expect(response.body.items.length).to.equal(0); }); }); @@ -107,5 +92,18 @@ describe('Fleet startup', () => { cy.visit('/app/integrations/installed'); cy.getBySel('integration-card:epr:elastic_agent'); }); + + it('should create Fleet Server policy', () => { + cy.getBySel(AGENTS_TAB).click(); + cy.getBySel('addAgentButton').click(); + cy.getBySel('toastCloseButton').click(); + + cy.getBySel('createFleetServerPolicyBtn').click(); + cy.getBySel('euiToastHeader'); + + cy.getBySel('euiFlyoutCloseButton').click(); + + verifyFleetServerPolicy('Fleet Server policy 1', 'Fleet Server'); + }); }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index db0ab3d3121ce..52a622a42d63f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -500,13 +500,11 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { validation={validation} packageInfo={packageInfo} setHasAgentPolicyError={setHasAgentPolicyError} - defaultAgentPolicyId={queryParamsPolicyId} updateSelectedTab={updateSelectedPolicy} /> ), [ packageInfo, - queryParamsPolicyId, agentPolicy, updateAgentPolicy, newAgentPolicy, diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx index c46ef8893fa40..3a04ed17046e6 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx @@ -9,11 +9,11 @@ import React, { useEffect, useState, useMemo, useCallback } from 'react'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { EuiComboBoxOptionOption } from '@elastic/eui'; +import type { EuiSelectOption } from '@elastic/eui'; +import { EuiSelect } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, - EuiComboBox, EuiPortal, EuiFormRow, EuiDescribedFormGroup, @@ -41,23 +41,12 @@ const AgentPolicyFormRow = styled(EuiFormRow)` export const StepSelectAgentPolicy: React.FunctionComponent<{ packageInfo?: PackageInfo; - defaultAgentPolicyId?: string; agentPolicy: AgentPolicy | undefined; updateAgentPolicy: (agentPolicy: AgentPolicy | undefined) => void; setHasAgentPolicyError: (hasError: boolean) => void; -}> = ({ - packageInfo, - agentPolicy, - updateAgentPolicy, - defaultAgentPolicyId, - setHasAgentPolicyError, -}) => { +}> = ({ packageInfo, agentPolicy, updateAgentPolicy, setHasAgentPolicyError }) => { const { isReady: isFleetReady } = useFleetStatus(); - // Selected agent policy state - const [selectedPolicyId, setSelectedPolicyId] = useState( - agentPolicy?.id ?? defaultAgentPolicyId - ); const [selectedAgentPolicyError, setSelectedAgentPolicyError] = useState(); // Create new agent policy flyout state @@ -90,6 +79,11 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ }, {}); }, [agentPolicies]); + // Selected agent policy state + const [selectedPolicyId, setSelectedPolicyId] = useState( + agentPolicy?.id ?? (agentPolicies.length === 1 ? agentPolicies[0].id : undefined) + ); + const doesAgentPolicyHaveLimitedPackage = useCallback( (policy: AgentPolicy, pkgInfo: PackageInfo) => { return policy @@ -121,12 +115,12 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ } }, [selectedPolicyId, agentPolicy, updateAgentPolicy]); - const agentPolicyOptions: Array> = useMemo( + const agentPolicyOptions: EuiSelectOption[] = useMemo( () => packageInfo ? agentPolicies.map((agentConf) => { return { - label: agentConf.name, + text: agentConf.name, value: agentConf.id, disabled: doesAgentPolicyHaveLimitedPackage(agentConf, packageInfo), 'data-test-subj': 'agentPolicyItem', @@ -136,49 +130,22 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ [agentPolicies, doesAgentPolicyHaveLimitedPackage, packageInfo] ); - const selectedAgentPolicyOption = useMemo( - () => agentPolicyOptions.find((option) => option.value === selectedPolicyId), - [agentPolicyOptions, selectedPolicyId] - ); - // Try to select default agent policy useEffect(() => { if (!selectedPolicyId && agentPolicies.length && agentPolicyOptions.length) { - const firstEnabledOption = agentPolicyOptions.find((option) => !option.disabled); - const defaultAgentPolicy = agentPolicies.find((policy) => policy.is_default); - if (defaultAgentPolicy) { - const defaultAgentPolicyOption = agentPolicyOptions.find( - (option) => option.value === defaultAgentPolicy.id - ); - if (defaultAgentPolicyOption && !defaultAgentPolicyOption.disabled) { - setSelectedPolicyId(defaultAgentPolicy.id); - } else { - if (firstEnabledOption) { - setSelectedPolicyId(firstEnabledOption.value); - } - } - } else if (firstEnabledOption) { - setSelectedPolicyId(firstEnabledOption.value); + const enabledOptions = agentPolicyOptions.filter((option) => !option.disabled); + if (enabledOptions.length === 1) { + setSelectedPolicyId(enabledOptions[0].value as string | undefined); } } }, [agentPolicies, agentPolicyOptions, selectedPolicyId]); // Bubble up any issues with agent policy selection useEffect(() => { - if ( - selectedPolicyId && - !selectedAgentPolicyError && - selectedAgentPolicyOption && - !selectedAgentPolicyOption.disabled - ) { + if (selectedPolicyId && !selectedAgentPolicyError) { setHasAgentPolicyError(false); } else setHasAgentPolicyError(true); - }, [ - selectedAgentPolicyError, - selectedAgentPolicyOption, - selectedPolicyId, - setHasAgentPolicyError, - ]); + }, [selectedAgentPolicyError, selectedPolicyId, setHasAgentPolicyError]); // Display agent policies list error if there is one if (agentPoliciesError) { @@ -293,29 +260,19 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ ) } > - 1} + fullWidth isLoading={isAgentPoliciesLoading || !packageInfo} options={agentPolicyOptions} - selectedOptions={selectedAgentPolicyOption ? [selectedAgentPolicyOption] : []} - onChange={(options) => { - const selectedOption = options[0] || undefined; - if (selectedOption) { - if (selectedOption.value !== selectedPolicyId) { - setSelectedPolicyId(selectedOption.value); - } - } else { - setSelectedPolicyId(undefined); - } - }} + value={selectedPolicyId || undefined} + onChange={(e) => setSelectedPolicyId(e.target.value)} />
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx index ac3c284eefdd8..3d69fc75d5658 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -38,7 +38,6 @@ interface Props { validation: ValidationResults; packageInfo?: PackageInfo; setHasAgentPolicyError: (hasError: boolean) => void; - defaultAgentPolicyId?: string; updateSelectedTab: (tab: SelectedPolicyTab) => void; } @@ -62,7 +61,6 @@ export const StepSelectHosts: React.FunctionComponent = ({ validation, packageInfo, setHasAgentPolicyError, - defaultAgentPolicyId, updateSelectedTab, }) => { let agentPolicies: AgentPolicy[] = []; @@ -111,7 +109,6 @@ export const StepSelectHosts: React.FunctionComponent = ({ content: ( Date: Thu, 6 Jan 2022 16:21:35 +0100 Subject: [PATCH 31/99] updated openapi spec --- x-pack/plugins/fleet/common/openapi/bundled.json | 7 ++++++- x-pack/plugins/fleet/common/openapi/bundled.yaml | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index 7a2b8af907e5b..98824ccdbfbcf 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -3002,9 +3002,14 @@ ] }, "is_default": { - "type": "boolean" + "type": "boolean", + "deprecated": true }, "is_default_fleet_server": { + "type": "boolean", + "deprecated": true + }, + "has_fleet_server": { "type": "boolean" }, "data_output_id": { diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index bee0294c9f3b9..6af428f3c3522 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -1850,8 +1850,12 @@ components: - type: number is_default: type: boolean + deprecated: true is_default_fleet_server: type: boolean + deprecated: true + has_fleet_server: + type: boolean data_output_id: type: string monitoring_output_id: From 1f03ecd2d3a22ddae50ffd13d8053b067277aa25 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 6 Jan 2022 16:38:59 +0100 Subject: [PATCH 32/99] refactor and unit test for increment policy name --- .../step_select_hosts.tsx | 13 ++------ .../utils/increment_policy_name.test.ts | 33 +++++++++++++++++++ .../utils/increment_policy_name.ts | 18 ++++++++++ .../create_package_policy_page/utils/index.ts | 2 ++ 4 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.test.ts create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.ts diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx index 3d69fc75d5658..873da56277568 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -16,6 +16,7 @@ import { AgentPolicyIntegrationForm } from '../components'; import type { ValidationResults } from '../components/agent_policy_validation'; import { StepSelectAgentPolicy } from './step_select_agent_policy'; +import { incrementPolicyName } from './utils'; export enum SelectedPolicyTab { NEW = 'new', @@ -41,16 +42,6 @@ interface Props { updateSelectedTab: (tab: SelectedPolicyTab) => void; } -const getLatestPolicyIndex = (policies: AgentPolicy[]) => { - const indices = policies - .map((pol: AgentPolicy) => pol.name) - .map((name) => { - const match = name.match(/Agent policy (\d+)/); - return match ? parseInt(match[1], 10) : 1; - }); - return Math.max(...indices, 1) + 1; -}; - export const StepSelectHosts: React.FunctionComponent = ({ agentPolicy, updateAgentPolicy, @@ -84,7 +75,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ if (agentPolicies.length > 0) { updateNewAgentPolicy({ ...newAgentPolicy, - name: `Agent policy ${getLatestPolicyIndex(agentPolicies)}`, + name: incrementPolicyName(agentPolicies), }); } }, [agentPolicies.length]); // eslint-disable-line react-hooks/exhaustive-deps diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.test.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.test.ts new file mode 100644 index 0000000000000..a518e9825add6 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.test.ts @@ -0,0 +1,33 @@ +/* + * 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 { incrementPolicyName } from './increment_policy_name'; +describe('increment policy name', () => { + it('should return index 1 when no policies', () => { + const name = incrementPolicyName([]); + expect(name).toEqual('Agent policy 1'); + }); + + it('should return index 1 when policies with other name', () => { + const name = incrementPolicyName([{ name: 'policy' } as any]); + expect(name).toEqual('Agent policy 1'); + }); + + it('should return index 2 when policy 1 exists', () => { + const name = incrementPolicyName([{ name: 'Agent policy 1' } as any]); + expect(name).toEqual('Agent policy 2'); + }); + + it('should return index 11 when policy 10 is max', () => { + const name = incrementPolicyName([ + { name: 'Agent policy 10' } as any, + { name: 'Agent policy 9' } as any, + { name: 'policy' } as any, + ]); + expect(name).toEqual('Agent policy 11'); + }); +}); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.ts new file mode 100644 index 0000000000000..aa6554d2ce1b2 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.ts @@ -0,0 +1,18 @@ +/* + * 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 type { AgentPolicy } from '../../../../types'; + +export function incrementPolicyName(policies: AgentPolicy[]): string { + const indices = policies + .map((pol: AgentPolicy) => pol.name) + .map((name) => { + const match = name.match(/Agent policy (\d+)/); + return match ? parseInt(match[1], 10) : 0; + }); + return `Agent policy ${Math.max(...indices, 0) + 1}`; +} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/index.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/index.ts index 15de46e1dc588..a687ea01deef4 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/index.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/index.ts @@ -6,3 +6,5 @@ */ export { appendOnSaveQueryParamsToPath } from './append_on_save_query_params'; + +export { incrementPolicyName } from './increment_policy_name'; From 3d34f05607d8992a8c0c57027fa0e26847ca768d Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 6 Jan 2022 17:21:50 +0100 Subject: [PATCH 33/99] fix checks --- x-pack/plugins/fleet/server/services/agent_policy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index 89a2a037934a3..79e1964e5287d 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -144,7 +144,7 @@ class AgentPolicyService { if (!searchParams) throw new Error('Missing ID'); - return await this.ensureAgentPolicy(soClient, esClient, newAgentPolicy, searchParams, id); + return await this.ensureAgentPolicy(soClient, esClient, newAgentPolicy, searchParams); } private async ensureAgentPolicy( From d75d554219d8fad7db858d174c48c9b1ec2ad3f5 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 10 Jan 2022 10:25:12 +0100 Subject: [PATCH 34/99] fix jest --- .../agent_enrollment_flyout.test.mocks.ts | 1 + .../agent_enrollment_flyout.test.tsx | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts index 5c292187982dc..d078461b4ed9b 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts @@ -12,6 +12,7 @@ jest.mock('../../hooks/use_request', () => { useGetSettings: jest.fn(), sendGetFleetStatus: jest.fn(), sendGetOneAgentPolicy: jest.fn(), + useGetAgents: jest.fn(), }; }); diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx index 18296134ee1a7..68032b09bce89 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx @@ -16,7 +16,12 @@ import { coreMock } from 'src/core/public/mocks'; import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; import type { AgentPolicy } from '../../../common'; -import { useGetSettings, sendGetFleetStatus, sendGetOneAgentPolicy } from '../../hooks/use_request'; +import { + useGetSettings, + sendGetFleetStatus, + sendGetOneAgentPolicy, + useGetAgents, +} from '../../hooks/use_request'; import { FleetStatusProvider, ConfigContext } from '../../hooks'; import { useFleetServerInstructions } from '../../applications/fleet/sections/agents/agent_requirements_page/components'; @@ -92,6 +97,10 @@ describe('', () => { setPlatform: jest.fn(), }); + (useGetAgents as jest.Mock).mockReturnValue({ + data: { items: [{}] }, + }); + await act(async () => { testBed = await setup({ agentPolicies: [], From d25eb2a4810fbe6b8e4947bb51809a2cc37c8e2d Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 10 Jan 2022 13:12:55 +0100 Subject: [PATCH 35/99] fix tests --- .../cypress/integration/fleet_startup.spec.ts | 2 +- x-pack/plugins/fleet/cypress/support/index.ts | 2 +- .../fleet/server/services/agent_policy.ts | 18 ++++--------- .../fleet/server/services/package_policy.ts | 12 ++++++++- .../apis/fleet_telemetry.ts | 25 ++++++++++--------- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index b795b9537d909..7efaa51c8e724 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -81,7 +81,7 @@ describe('Fleet startup', () => { cy.getBySel('toastCloseButton').click(); cy.getBySel('standaloneTab').click(); cy.getBySel('createPolicyBtn').click(); - cy.getBySel('euiToastHeader'); + cy.getBySel('euiToastHeader', { timeout: 180000 }); cy.get('.euiLoadingSpinner').should('not.exist'); cy.getBySel('euiFlyoutCloseButton').click(); diff --git a/x-pack/plugins/fleet/cypress/support/index.ts b/x-pack/plugins/fleet/cypress/support/index.ts index 3fe732a027a65..a967b40e2345c 100644 --- a/x-pack/plugins/fleet/cypress/support/index.ts +++ b/x-pack/plugins/fleet/cypress/support/index.ts @@ -29,7 +29,7 @@ declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace Cypress { interface Chainable { - getBySel(value: string): Chainable; + getBySel(value: string, ...args: any[]): Chainable; } } } diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index 79e1964e5287d..62f04ce7aac64 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -134,24 +134,16 @@ class AgentPolicyService { is_preconfigured: true, }; - let searchParams; + if (!id) throw new Error('Missing ID'); - if (id) { - searchParams = { - id: String(id), - }; - } - - if (!searchParams) throw new Error('Missing ID'); - - return await this.ensureAgentPolicy(soClient, esClient, newAgentPolicy, searchParams); + return await this.ensureAgentPolicy(soClient, esClient, newAgentPolicy, id as string); } private async ensureAgentPolicy( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, newAgentPolicy: NewAgentPolicy, - searchParams: { id: string } + id: string ): Promise<{ created: boolean; policy: AgentPolicy; @@ -160,7 +152,7 @@ class AgentPolicyService { try { const agentPolicy = await soClient.get( AGENT_POLICY_SAVED_OBJECT_TYPE, - searchParams.id + id ); return { created: false, @@ -173,7 +165,7 @@ class AgentPolicyService { if (SavedObjectsErrorHelpers.isNotFoundError(e)) { return { created: true, - policy: await this.create(soClient, esClient, newAgentPolicy, { id: searchParams.id }), + policy: await this.create(soClient, esClient, newAgentPolicy, { id }), }; } else throw e; } diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index 91375f52a655b..1ee7f25391c9a 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -727,13 +727,23 @@ class PackagePolicyService { })), } as NewPackagePolicyInput; }); + let agentPolicyId; + // fallback to first agent policy id in case no policy_id is specified, BWC with 8.0 + if (!newPolicy.policy_id) { + const { items: agentPolicies } = await agentPolicyService.list(soClient, { + perPage: 1, + }); + if (agentPolicies.length > 0) { + agentPolicyId = agentPolicies[0].id; + } + } newPackagePolicy = { ...newPP, name: newPolicy.name, namespace: newPolicy.namespace ?? 'default', description: newPolicy.description ?? '', enabled: newPolicy.enabled ?? true, - policy_id: newPolicy.policy_id, // TODO BWC previously optional + policy_id: newPolicy.policy_id ?? agentPolicyId, output_id: newPolicy.output_id ?? '', inputs: newPolicy.inputs[0]?.streams ? newPolicy.inputs : inputs, vars: newPolicy.vars || newPP.vars, diff --git a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts index 8a40c643553b0..16350114358c4 100644 --- a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts +++ b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts @@ -77,9 +77,10 @@ export default function (providerContext: FtrProviderContext) { .send({ name: 'Fleet Server policy 1', namespace: 'default', + has_fleet_server: true, }) .expect(200); - const defaultFleetServerPolicy = apiResponse.item; + const fleetServerPolicy = apiResponse.item; ({ body: apiResponse } = await supertest .post(`/api/fleet/agent_policies`) @@ -90,13 +91,13 @@ export default function (providerContext: FtrProviderContext) { }) .expect(200)); - const defaultServerPolicy = apiResponse.item; + const agentPolicy = apiResponse.item; - if (!defaultFleetServerPolicy) { + if (!fleetServerPolicy) { throw new Error('No Fleet server policy'); } - if (!defaultServerPolicy) { + if (!agentPolicy) { throw new Error('No agent policy'); } @@ -107,16 +108,16 @@ export default function (providerContext: FtrProviderContext) { .expect(200); // Default Fleet Server - await generateAgent('healthy', defaultFleetServerPolicy.id); - await generateAgent('healthy', defaultFleetServerPolicy.id); - await generateAgent('error', defaultFleetServerPolicy.id); + await generateAgent('healthy', fleetServerPolicy.id); + await generateAgent('healthy', fleetServerPolicy.id); + await generateAgent('error', fleetServerPolicy.id); // Default policy - await generateAgent('healthy', defaultServerPolicy.id); - await generateAgent('offline', defaultServerPolicy.id); - await generateAgent('error', defaultServerPolicy.id); - await generateAgent('degraded', defaultServerPolicy.id); - await generateAgent('error-unenrolling', defaultServerPolicy.id); + await generateAgent('healthy', agentPolicy.id); + await generateAgent('offline', agentPolicy.id); + await generateAgent('error', agentPolicy.id); + await generateAgent('degraded', agentPolicy.id); + await generateAgent('error-unenrolling', agentPolicy.id); }); it('should return the correct telemetry values for fleet', async () => { From eb3ca36d57f9fe668e4262f96dc3831fde3a3ee0 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 10 Jan 2022 14:30:55 +0100 Subject: [PATCH 36/99] using fleet-server-policy id for first --- .../cypress/integration/fleet_startup.spec.ts | 11 +++++++--- .../components/agent_policy_create_inline.tsx | 6 +---- .../server/routes/agent_policy/handlers.ts | 22 +++++++++++++++++++ .../server/services/agent_policy_update.ts | 1 + 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 7efaa51c8e724..abe7ea46853cc 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -87,10 +87,15 @@ describe('Fleet startup', () => { verifyFleetServerPolicy('Agent policy 1', 'System'); - // TODO might take longer to install elastic agent async - cy.visit('/app/integrations/installed'); - cy.getBySel('integration-card:epr:elastic_agent'); + // wait for elastic-agent if not visible at first + cy.get('.euiCard').then((els) => { + if (els.length === 2) { + cy.wait(5000); + cy.visit('/app/integrations/installed'); + } + cy.getBySel('integration-card:epr:elastic_agent'); + }); }); it('should create Fleet Server policy', () => { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index d3a2912152ede..661ba7700ba75 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -49,16 +49,12 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ }) => { const [touchedFields, setTouchedFields] = useState<{ [key: string]: boolean }>({}); - const defaultPolicy = { + const [newAgentPolicy, setNewAgentPolicy] = useState({ name: isFleetServerPolicy ? 'Fleet Server policy 1' : 'Agent policy 1', description: '', namespace: 'default', monitoring_enabled: Object.values(dataTypes), has_fleet_server: isFleetServerPolicy, - }; - - const [newAgentPolicy, setNewAgentPolicy] = useState({ - ...defaultPolicy, }); const updateNewAgentPolicy = useCallback( diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index 942db6bb6db91..84807b22611c9 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -114,6 +114,24 @@ export const getOneAgentPolicyHandler: RequestHandler< } }; +async function getAgentPolicyId(soClient: SavedObjectsClientContract): Promise { + let agentPolicyId; + // creating first fleet server policy with id 'fleet-server-policy' + const FLEET_SERVER_POLICY_ID = 'fleet-server-policy'; + let agentPolicy; + try { + agentPolicy = await agentPolicyService.get(soClient, FLEET_SERVER_POLICY_ID, false); + } catch (err) { + if (!err.isBoom || err.output.statusCode !== 404) { + throw err; + } + } + if (!agentPolicy) { + agentPolicyId = FLEET_SERVER_POLICY_ID; + } + return agentPolicyId; +} + export const createAgentPolicyHandler: FleetRequestHandler< undefined, TypeOf, @@ -126,6 +144,7 @@ export const createAgentPolicyHandler: FleetRequestHandler< const { has_fleet_server: hasFleetServer, ...newPolicy } = request.body; const spaceId = context.fleet.spaceId; try { + let agentPolicyId; if (hasFleetServer) { // install fleet server package if not yet installed await ensureInstalledPackage({ @@ -133,6 +152,8 @@ export const createAgentPolicyHandler: FleetRequestHandler< pkgName: FLEET_SERVER_PACKAGE, esClient, }); + + agentPolicyId = await getAgentPolicyId(soClient); } if (withSysMonitoring) { // install system package if not yet installed @@ -152,6 +173,7 @@ export const createAgentPolicyHandler: FleetRequestHandler< } const agentPolicy = await agentPolicyService.create(soClient, esClient, newPolicy, { user, + id: agentPolicyId, }); // Create the fleet server package policy and add it to agent policy. diff --git a/x-pack/plugins/fleet/server/services/agent_policy_update.ts b/x-pack/plugins/fleet/server/services/agent_policy_update.ts index 51bf068b8b111..699a8ed161974 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy_update.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy_update.ts @@ -42,6 +42,7 @@ export async function agentPolicyUpdateEventHandler( await generateEnrollmentAPIKey(soClient, esClient, { name: 'Default', agentPolicyId, + forceRecreate: true, }); await agentPolicyService.createFleetServerPolicy(internalSoClient, agentPolicyId); } From cb87b567b34d5a35612ee617c1e6482a26c0a07b Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 10 Jan 2022 15:21:10 +0100 Subject: [PATCH 37/99] fixed refresh after policy created, removed toast --- .../components/agent_policy_create_inline.tsx | 6 ++-- .../create_package_policy_page/index.tsx | 6 ---- .../fleet_server_on_prem_instructions.tsx | 14 ++++++++-- .../agents/services/has_fleet_server.ts | 2 +- .../agent_enrollment_flyout/steps.tsx | 28 +++++++++++++------ 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index 661ba7700ba75..38e011e01f880 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -25,7 +25,7 @@ import { i18n } from '@kbn/i18n'; import { dataTypes } from '../../../../../../common'; import { agentPolicyFormValidation } from '../components'; -import type { NewAgentPolicy } from '../../../types'; +import type { AgentPolicy, NewAgentPolicy } from '../../../types'; import { sendCreateAgentPolicy, useStartServices } from '../../../hooks'; @@ -39,7 +39,7 @@ const StyledEuiAccordion = styled(EuiAccordion)` `; interface Props { - updateAgentPolicy: (u: string) => void; + updateAgentPolicy: (u: AgentPolicy) => void; isFleetServerPolicy?: boolean; } @@ -86,7 +86,7 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ values: { name: newAgentPolicy.name }, }) ); - updateAgentPolicy(resp.data.item.id); + updateAgentPolicy(resp.data.item); } } catch (e) { notifications.toasts.addDanger( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index 52a622a42d63f..55b1bde1331eb 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -392,12 +392,6 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { setFormState('VALID'); if (resp.error) throw resp.error; if (resp.data) { - notifications.toasts.addSuccess( - i18n.translate('xpack.fleet.createAgentPolicy.successNotificationTitle', { - defaultMessage: "Agent policy '{name}' created", - values: { name: newAgentPolicy.name }, - }) - ); policyId = resp.data.item.id; setAgentPolicy(resp.data.item); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index b54718caafc51..ff59ea5ef6378 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -44,7 +44,7 @@ import { useLink, } from '../../../../hooks'; import type { PLATFORM_TYPE } from '../../../../hooks'; -import type { PackagePolicy } from '../../../../types'; +import type { AgentPolicy, PackagePolicy } from '../../../../types'; import { FLEET_SERVER_PACKAGE } from '../../../../constants'; import { FleetServerOnPremRequiredCallout } from '../../components'; @@ -330,7 +330,7 @@ const AgentPolicySelectionStep = ({ policyId?: string; setPolicyId: (v: string) => void; }): EuiStepProps => { - const { data } = useGetAgentPolicies({ full: true }); + const { data, resendRequest: refreshAgentPolicies } = useGetAgentPolicies({ full: true }); const agentPolicies = useMemo( () => @@ -364,6 +364,14 @@ const AgentPolicySelectionStep = ({ [setPolicyId] ); + const onAgentPolicyCreated = useCallback( + (policy: AgentPolicy) => { + setPolicyId(policy.id); + refreshAgentPolicies(); + }, + [setPolicyId, refreshAgentPolicies] + ); + if (agentPolicies.length === 0) { return { title: i18n.translate('xpack.fleet.fleetServerSetup.stepCreateAgentPolicyTitle', { @@ -372,7 +380,7 @@ const AgentPolicySelectionStep = ({ status: undefined, children: ( setPolicyId(value)} + updateAgentPolicy={onAgentPolicyCreated} isFleetServerPolicy={true} /> ), diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts index 8efee0953d4c1..c10049303234c 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts @@ -9,7 +9,7 @@ import type { AgentPolicy, PackagePolicy } from '../../../types'; import { FLEET_SERVER_PACKAGE } from '../../../constants'; export function policyHasFleetServer(agentPolicy: AgentPolicy) { - return agentPolicy.package_policies.some( + return agentPolicy.package_policies?.some( (ap: string | PackagePolicy) => typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE ); diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx index bb67f8d3eb0c1..776f6a6c96a8e 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { EuiText, EuiButton, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; @@ -90,14 +90,14 @@ export const AgentPolicySelectionStep = ({ setSelectedAPIKeyId?: (key?: string) => void; excludeFleetServer?: boolean; }) => { + const [agentPolicyList, setAgentPolicyList] = useState(agentPolicies || []); + const regularAgentPolicies = useMemo(() => { - return Array.isArray(agentPolicies) - ? agentPolicies.filter( - (policy) => - policy && !policy.is_managed && (!excludeFleetServer || !policyHasFleetServer(policy)) - ) - : []; - }, [agentPolicies, excludeFleetServer]); + return agentPolicyList.filter( + (policy) => + policy && !policy.is_managed && (!excludeFleetServer || !policyHasFleetServer(policy)) + ); + }, [agentPolicyList, excludeFleetServer]); const onAgentPolicyChange = useCallback( async (policyId?: string) => { @@ -108,6 +108,16 @@ export const AgentPolicySelectionStep = ({ [setSelectedPolicyId] ); + const onAgentPolicyCreated = useCallback( + async (policy: AgentPolicy) => { + setAgentPolicyList([...agentPolicyList, policy]); + if (setSelectedPolicyId) { + setSelectedPolicyId(policy.id); + } + }, + [agentPolicyList, setAgentPolicyList, setSelectedPolicyId] + ); + return { title: i18n.translate('xpack.fleet.agentEnrollment.stepChooseAgentPolicyTitle', { defaultMessage: 'What type of host are you adding?', @@ -123,7 +133,7 @@ export const AgentPolicySelectionStep = ({ excludeFleetServer={excludeFleetServer} /> ) : ( - + ), }; }; From 633693d2fdd4f28b8d52375aa02b2feca91aee04 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 10 Jan 2022 15:50:10 +0100 Subject: [PATCH 38/99] fixed smaller review comments --- x-pack/plugins/fleet/common/constants/epm.ts | 4 --- x-pack/plugins/fleet/server/index.ts | 3 ++ .../server/routes/agent_policy/handlers.ts | 4 +-- .../saved_objects/migrations/to_v7_16_0.ts | 18 ++++++++-- .../server/services/agent_policy.test.ts | 6 ++-- .../fleet/server/services/agent_policy.ts | 34 ++++++------------- .../server/services/agent_policy_update.ts | 4 +-- .../fleet/server/services/agents/setup.ts | 2 +- .../server/types/models/preconfiguration.ts | 2 -- 9 files changed, 37 insertions(+), 40 deletions(-) diff --git a/x-pack/plugins/fleet/common/constants/epm.ts b/x-pack/plugins/fleet/common/constants/epm.ts index b162cfddf6cff..12885be5a8aea 100644 --- a/x-pack/plugins/fleet/common/constants/epm.ts +++ b/x-pack/plugins/fleet/common/constants/epm.ts @@ -25,7 +25,6 @@ export const STANDALONE_RUN_INSTRUCTIONS_WINDOWS = '.\\elastic-agent.exe install Package rules: | | autoUpdatePackages | |---------------|:------------------:| -| Auto-installs | ❌ | | Auto-updates | ✔️ | @@ -37,9 +36,6 @@ in their custom policy editor implementations. */ export const autoUpdatePackages = [ - FLEET_SYSTEM_PACKAGE, - FLEET_ELASTIC_AGENT_PACKAGE, - FLEET_SERVER_PACKAGE, FLEET_ENDPOINT_PACKAGE, FLEET_APM_PACKAGE, FLEET_SYNTHETICS_PACKAGE, diff --git a/x-pack/plugins/fleet/server/index.ts b/x-pack/plugins/fleet/server/index.ts index 8cbfa311081d2..46b837c2d234c 100644 --- a/x-pack/plugins/fleet/server/index.ts +++ b/x-pack/plugins/fleet/server/index.ts @@ -53,6 +53,9 @@ export const config: PluginConfigDescriptor = { unused('agents.pollingRequestTimeout', { level: 'critical' }), unused('agents.tlsCheckDisabled', { level: 'critical' }), unused('agents.fleetServerEnabled', { level: 'critical' }), + // Removed default policies + unused('agentPolicies.is_default', { level: 'critical' }), + unused('agentPolicies.is_default_fleet_server', { level: 'critical' }), // Renaming elasticsearch.host => elasticsearch.hosts (fullConfig, fromPath, addDeprecation) => { const oldValue = fullConfig?.xpack?.fleet?.agents?.elasticsearch?.host; diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index 84807b22611c9..70b4a8ea8b1a4 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -192,8 +192,8 @@ export const createAgentPolicyHandler: FleetRequestHandler< }); } - await agentPolicyService.createFleetServerPolicy(soClient, agentPolicy.id); - ensureDefaultEnrollmentAPIKeysExists(soClient, esClient); + await ensureDefaultEnrollmentAPIKeysExists(soClient, esClient); + await agentPolicyService.deployPolicy(soClient, agentPolicy.id); const body: CreateAgentPolicyResponse = { item: agentPolicy, diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_16_0.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_16_0.ts index 33ea56c538616..66331dab47cc8 100644 --- a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_16_0.ts +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_16_0.ts @@ -8,7 +8,12 @@ import type { SavedObjectMigrationFn } from 'kibana/server'; import type { Installation, PackagePolicy } from '../../../common'; -import { AUTO_UPDATE_PACKAGES } from '../../../common'; +import { + FLEET_ELASTIC_AGENT_PACKAGE, + FLEET_SERVER_PACKAGE, + FLEET_SYSTEM_PACKAGE, +} from '../../../common'; +import { PRECONFIGURATION_LATEST_KEYWORD } from '../../constants'; import { migratePackagePolicyToV7160 as SecSolMigratePackagePolicyToV7160 } from './security_solution'; @@ -18,7 +23,16 @@ export const migrateInstallationToV7160: SavedObjectMigrationFn { const updatedInstallationDoc = installationDoc; - if (AUTO_UPDATE_PACKAGES.some((pkg) => pkg.name === updatedInstallationDoc.attributes.name)) { + const DEFAULT_PACKAGES = [ + FLEET_SYSTEM_PACKAGE, + FLEET_ELASTIC_AGENT_PACKAGE, + FLEET_SERVER_PACKAGE, + ].map((name) => ({ + name, + version: PRECONFIGURATION_LATEST_KEYWORD, + })); + + if (DEFAULT_PACKAGES.some((pkg) => pkg.name === updatedInstallationDoc.attributes.name)) { updatedInstallationDoc.attributes.keep_policies_up_to_date = true; } diff --git a/x-pack/plugins/fleet/server/services/agent_policy.test.ts b/x-pack/plugins/fleet/server/services/agent_policy.test.ts index fad8fbf4a1a56..77bd67a63512b 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.test.ts @@ -237,7 +237,7 @@ describe('agent policy', () => { }); }); - describe('createFleetServerPolicy', () => { + describe('deployPolicy', () => { beforeEach(() => { mockedGetFullAgentPolicy.mockReset(); }); @@ -254,7 +254,7 @@ describe('agent policy', () => { type: 'mocked', references: [], }); - await agentPolicyService.createFleetServerPolicy(soClient, 'policy123'); + await agentPolicyService.deployPolicy(soClient, 'policy123'); expect(esClient.create).not.toBeCalled(); }); @@ -280,7 +280,7 @@ describe('agent policy', () => { type: 'mocked', references: [], }); - await agentPolicyService.createFleetServerPolicy(soClient, 'policy123'); + await agentPolicyService.deployPolicy(soClient, 'policy123'); expect(esClient.create).toBeCalledWith( expect.objectContaining({ diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index 62f04ce7aac64..b1f4cc2a45812 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -16,8 +16,6 @@ import type { SavedObjectsBulkUpdateResponse, } from 'src/core/server'; -import { SavedObjectsErrorHelpers } from '../../../../../src/core/server'; - import type { AuthenticatedUser } from '../../../security/server'; import { AGENT_POLICY_SAVED_OBJECT_TYPE, @@ -149,26 +147,17 @@ class AgentPolicyService { policy: AgentPolicy; }> { // For preconfigured policies with a specified ID - try { - const agentPolicy = await soClient.get( - AGENT_POLICY_SAVED_OBJECT_TYPE, - id - ); + const agentPolicy = await this.get(soClient, id); + if (!agentPolicy) { return { - created: false, - policy: { - id: agentPolicy.id, - ...agentPolicy.attributes, - }, + created: true, + policy: await this.create(soClient, esClient, newAgentPolicy, { id }), }; - } catch (e) { - if (SavedObjectsErrorHelpers.isNotFoundError(e)) { - return { - created: true, - policy: await this.create(soClient, esClient, newAgentPolicy, { id }), - }; - } else throw e; } + return { + created: false, + policy: agentPolicy, + }; } public async create( @@ -401,7 +390,7 @@ class AgentPolicyService { throw new Error('Copied agent policy not found'); } - await this.createFleetServerPolicy(soClient, newAgentPolicy.id); + await this.deployPolicy(soClient, newAgentPolicy.id); return updatedAgentPolicy; } @@ -606,10 +595,7 @@ class AgentPolicyService { }; } - public async createFleetServerPolicy( - soClient: SavedObjectsClientContract, - agentPolicyId: string - ) { + public async deployPolicy(soClient: SavedObjectsClientContract, agentPolicyId: string) { // Use internal ES client so we have permissions to write to .fleet* indices const esClient = appContextService.getInternalUserESClient(); const defaultOutputId = await outputService.getDefaultDataOutputId(soClient); diff --git a/x-pack/plugins/fleet/server/services/agent_policy_update.ts b/x-pack/plugins/fleet/server/services/agent_policy_update.ts index 699a8ed161974..30472c242ba45 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy_update.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy_update.ts @@ -44,11 +44,11 @@ export async function agentPolicyUpdateEventHandler( agentPolicyId, forceRecreate: true, }); - await agentPolicyService.createFleetServerPolicy(internalSoClient, agentPolicyId); + await agentPolicyService.deployPolicy(internalSoClient, agentPolicyId); } if (action === 'updated') { - await agentPolicyService.createFleetServerPolicy(internalSoClient, agentPolicyId); + await agentPolicyService.deployPolicy(internalSoClient, agentPolicyId); } if (action === 'deleted') { diff --git a/x-pack/plugins/fleet/server/services/agents/setup.ts b/x-pack/plugins/fleet/server/services/agents/setup.ts index 2b680dee1146e..ffbfb589b10f2 100644 --- a/x-pack/plugins/fleet/server/services/agents/setup.ts +++ b/x-pack/plugins/fleet/server/services/agents/setup.ts @@ -29,7 +29,7 @@ export async function ensureFleetServerAgentPoliciesExists( )); if (!policyChangeActionExist) { - return agentPolicyService.createFleetServerPolicy(soClient, agentPolicy.id); + return agentPolicyService.deployPolicy(soClient, agentPolicy.id); } }) ); diff --git a/x-pack/plugins/fleet/server/types/models/preconfiguration.ts b/x-pack/plugins/fleet/server/types/models/preconfiguration.ts index 960ecbe67d593..a706f5eebb299 100644 --- a/x-pack/plugins/fleet/server/types/models/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/types/models/preconfiguration.ts @@ -96,8 +96,6 @@ export const PreconfiguredAgentPoliciesSchema = schema.arrayOf( ...AgentPolicyBaseSchema, namespace: schema.maybe(NamespaceSchema), id: schema.maybe(schema.oneOf([schema.string(), schema.number()])), - is_default: schema.maybe(schema.boolean()), - is_default_fleet_server: schema.maybe(schema.boolean()), has_fleet_server: schema.maybe(schema.boolean()), data_output_id: schema.maybe(schema.string()), monitoring_output_id: schema.maybe(schema.string()), From a7aa263888b3836b4d810d19c96e5a98fbaa1395 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 10 Jan 2022 16:28:35 +0100 Subject: [PATCH 39/99] added missing catch --- x-pack/plugins/fleet/server/services/agent_policy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index b1f4cc2a45812..f4674d9ee0b2b 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -147,7 +147,7 @@ class AgentPolicyService { policy: AgentPolicy; }> { // For preconfigured policies with a specified ID - const agentPolicy = await this.get(soClient, id); + const agentPolicy = await this.get(soClient, id, false).catch(() => null); if (!agentPolicy) { return { created: true, From 5ac31c10708d2e5ff754c4b2094409f0c867dc28 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 10 Jan 2022 17:13:13 +0100 Subject: [PATCH 40/99] changed to bulk install --- .../cypress/integration/fleet_startup.spec.ts | 8 +----- .../server/routes/agent_policy/handlers.ts | 27 ++++++++----------- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index abe7ea46853cc..2a62751eb93b9 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -89,13 +89,7 @@ describe('Fleet startup', () => { cy.visit('/app/integrations/installed'); // wait for elastic-agent if not visible at first - cy.get('.euiCard').then((els) => { - if (els.length === 2) { - cy.wait(5000); - cy.visit('/app/integrations/installed'); - } - cy.getBySel('integration-card:epr:elastic_agent'); - }); + cy.getBySel('integration-card:epr:elastic_agent'); }); it('should create Fleet Server policy', () => { diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index 70b4a8ea8b1a4..3f0cf6a54137d 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -50,7 +50,7 @@ import type { } from '../../../common'; import { defaultIngestErrorHandler } from '../../errors'; import { incrementPackageName } from '../../services/package_policy'; -import { ensureInstalledPackage } from '../../services/epm/packages'; +import { bulkInstallPackages } from '../../services/epm/packages'; import { ensureDefaultEnrollmentAPIKeysExists } from '../../services/setup'; export const getAgentPoliciesHandler: FleetRequestHandler< @@ -145,32 +145,27 @@ export const createAgentPolicyHandler: FleetRequestHandler< const spaceId = context.fleet.spaceId; try { let agentPolicyId; + const packagesToInstall = []; if (hasFleetServer) { - // install fleet server package if not yet installed - await ensureInstalledPackage({ - savedObjectsClient: soClient, - pkgName: FLEET_SERVER_PACKAGE, - esClient, - }); + packagesToInstall.push(FLEET_SERVER_PACKAGE); agentPolicyId = await getAgentPolicyId(soClient); } if (withSysMonitoring) { - // install system package if not yet installed - await ensureInstalledPackage({ - savedObjectsClient: soClient, - pkgName: FLEET_SYSTEM_PACKAGE, - esClient, - }); + packagesToInstall.push(FLEET_SYSTEM_PACKAGE); } if (request.body.monitoring_enabled?.length) { - // install elastic agent package if not yet installed - ensureInstalledPackage({ + packagesToInstall.push(FLEET_ELASTIC_AGENT_PACKAGE); + } + if (packagesToInstall.length > 0) { + await bulkInstallPackages({ savedObjectsClient: soClient, - pkgName: FLEET_ELASTIC_AGENT_PACKAGE, esClient, + packagesToInstall, + spaceId, }); } + const agentPolicy = await agentPolicyService.create(soClient, esClient, newPolicy, { user, id: agentPolicyId, From 95b7dfbb44a839f8d4ea6c227f663d06ef61a14f Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 10 Jan 2022 17:53:42 +0100 Subject: [PATCH 41/99] moved service logic from handler, measuring time in cypress --- .../cypress/integration/fleet_startup.spec.ts | 12 +- .../server/routes/agent_policy/handlers.ts | 121 ++------------- .../server/services/agent_policy_create.ts | 138 ++++++++++++++++++ 3 files changed, 162 insertions(+), 109 deletions(-) create mode 100644 x-pack/plugins/fleet/server/services/agent_policy_create.ts diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 2a62751eb93b9..3eb7f2c1dae57 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -80,9 +80,19 @@ describe('Fleet startup', () => { cy.getBySel('addAgentButton').click(); cy.getBySel('toastCloseButton').click(); cy.getBySel('standaloneTab').click(); + + cy.intercept('POST', '/api/fleet/agent_policies?sys_monitoring=true').as('createAgentPolicy'); + cy.getBySel('createPolicyBtn').click(); - cy.getBySel('euiToastHeader', { timeout: 180000 }); + + const startTime = Date.now(); + cy.wait('@createAgentPolicy', { timeout: 180000 }).then((xhr: any) => { + cy.log('Create agent policy took: ' + (Date.now() - startTime) / 1000 + ' s'); + }); + + cy.getBySel('euiToastHeader'); cy.get('.euiLoadingSpinner').should('not.exist'); + cy.getBySel('euiFlyoutCloseButton').click(); verifyFleetServerPolicy('Agent policy 1', 'System'); diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index 3f0cf6a54137d..4e32ce1bf33b9 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -6,23 +6,15 @@ */ import type { TypeOf } from '@kbn/config-schema'; -import type { - ElasticsearchClient, - RequestHandler, - ResponseHeaders, - SavedObjectsClientContract, -} from 'src/core/server'; +import type { RequestHandler, ResponseHeaders } from 'src/core/server'; import pMap from 'p-map'; import { safeDump } from 'js-yaml'; -import type { AuthenticatedUser } from '../../../../security/common/model'; - import { fullAgentPolicyToYaml } from '../../../common/services'; -import { appContextService, agentPolicyService, packagePolicyService } from '../../services'; +import { appContextService, agentPolicyService } from '../../services'; import { getAgentsByKuery } from '../../services/agents'; import { AGENTS_PREFIX } from '../../constants'; import type { - AgentPolicy, GetAgentPoliciesRequestSchema, GetOneAgentPolicyRequestSchema, CreateAgentPolicyRequestSchema, @@ -32,11 +24,7 @@ import type { GetFullAgentPolicyRequestSchema, FleetRequestHandler, } from '../../types'; -import { - FLEET_ELASTIC_AGENT_PACKAGE, - FLEET_SERVER_PACKAGE, - FLEET_SYSTEM_PACKAGE, -} from '../../../common'; + import type { GetAgentPoliciesResponse, GetAgentPoliciesResponseItem, @@ -49,9 +37,7 @@ import type { GetFullAgentConfigMapResponse, } from '../../../common'; import { defaultIngestErrorHandler } from '../../errors'; -import { incrementPackageName } from '../../services/package_policy'; -import { bulkInstallPackages } from '../../services/epm/packages'; -import { ensureDefaultEnrollmentAPIKeysExists } from '../../services/setup'; +import { createAgentPolicyWithPackages } from '../../services/agent_policy_create'; export const getAgentPoliciesHandler: FleetRequestHandler< undefined, @@ -114,24 +100,6 @@ export const getOneAgentPolicyHandler: RequestHandler< } }; -async function getAgentPolicyId(soClient: SavedObjectsClientContract): Promise { - let agentPolicyId; - // creating first fleet server policy with id 'fleet-server-policy' - const FLEET_SERVER_POLICY_ID = 'fleet-server-policy'; - let agentPolicy; - try { - agentPolicy = await agentPolicyService.get(soClient, FLEET_SERVER_POLICY_ID, false); - } catch (err) { - if (!err.isBoom || err.output.statusCode !== 404) { - throw err; - } - } - if (!agentPolicy) { - agentPolicyId = FLEET_SERVER_POLICY_ID; - } - return agentPolicyId; -} - export const createAgentPolicyHandler: FleetRequestHandler< undefined, TypeOf, @@ -141,57 +109,21 @@ export const createAgentPolicyHandler: FleetRequestHandler< const esClient = context.core.elasticsearch.client.asInternalUser; const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined; const withSysMonitoring = request.query.sys_monitoring ?? false; + const monitoringEnabled = request.body.monitoring_enabled; const { has_fleet_server: hasFleetServer, ...newPolicy } = request.body; const spaceId = context.fleet.spaceId; try { - let agentPolicyId; - const packagesToInstall = []; - if (hasFleetServer) { - packagesToInstall.push(FLEET_SERVER_PACKAGE); - - agentPolicyId = await getAgentPolicyId(soClient); - } - if (withSysMonitoring) { - packagesToInstall.push(FLEET_SYSTEM_PACKAGE); - } - if (request.body.monitoring_enabled?.length) { - packagesToInstall.push(FLEET_ELASTIC_AGENT_PACKAGE); - } - if (packagesToInstall.length > 0) { - await bulkInstallPackages({ - savedObjectsClient: soClient, + const body: CreateAgentPolicyResponse = { + item: await createAgentPolicyWithPackages({ + soClient, esClient, - packagesToInstall, - spaceId, - }); - } - - const agentPolicy = await agentPolicyService.create(soClient, esClient, newPolicy, { - user, - id: agentPolicyId, - }); - - // Create the fleet server package policy and add it to agent policy. - if (hasFleetServer) { - await createPackagePolicy(soClient, esClient, agentPolicy, FLEET_SERVER_PACKAGE, { + newPolicy, + hasFleetServer, + withSysMonitoring, + monitoringEnabled, spaceId, user, - }); - } - - // Create the system monitoring package policy and add it to agent policy. - if (withSysMonitoring) { - await createPackagePolicy(soClient, esClient, agentPolicy, FLEET_SYSTEM_PACKAGE, { - spaceId, - user, - }); - } - - await ensureDefaultEnrollmentAPIKeysExists(soClient, esClient); - await agentPolicyService.deployPolicy(soClient, agentPolicy.id); - - const body: CreateAgentPolicyResponse = { - item: agentPolicy, + }), }; return response.ok({ @@ -202,33 +134,6 @@ export const createAgentPolicyHandler: FleetRequestHandler< } }; -async function createPackagePolicy( - soClient: SavedObjectsClientContract, - esClient: ElasticsearchClient, - agentPolicy: AgentPolicy, - packageToInstall: string, - options: { spaceId: string; user: AuthenticatedUser | undefined } -) { - // If needed, retrieve package information and build a new package policy for the package - // NOTE: we ignore failures in attempting to create package policy, since agent policy might have been created - // successfully - const newPackagePolicy = await packagePolicyService - .buildPackagePolicyFromPackage(soClient, packageToInstall) - .catch(() => undefined); - - if (!newPackagePolicy) return; - - newPackagePolicy.policy_id = agentPolicy.id; - newPackagePolicy.namespace = agentPolicy.namespace; - newPackagePolicy.name = await incrementPackageName(soClient, packageToInstall); - - await packagePolicyService.create(soClient, esClient, newPackagePolicy, { - spaceId: options.spaceId, - user: options.user, - bumpRevision: false, - }); -} - export const updateAgentPolicyHandler: RequestHandler< TypeOf, unknown, diff --git a/x-pack/plugins/fleet/server/services/agent_policy_create.ts b/x-pack/plugins/fleet/server/services/agent_policy_create.ts new file mode 100644 index 0000000000000..177c851c91fc2 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/agent_policy_create.ts @@ -0,0 +1,138 @@ +/* + * 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 type { ElasticsearchClient, SavedObjectsClientContract } from 'src/core/server'; + +import type { AuthenticatedUser } from '../../../security/common/model'; + +import { + FLEET_ELASTIC_AGENT_PACKAGE, + FLEET_SERVER_PACKAGE, + FLEET_SYSTEM_PACKAGE, +} from '../../common'; + +import type { AgentPolicy, NewAgentPolicy } from '../types'; + +import { agentPolicyService, packagePolicyService } from '.'; +import { incrementPackageName } from './package_policy'; +import { bulkInstallPackages } from './epm/packages'; +import { ensureDefaultEnrollmentAPIKeysExists } from './setup'; + +async function getAgentPolicyId(soClient: SavedObjectsClientContract): Promise { + let agentPolicyId; + // creating first fleet server policy with id 'fleet-server-policy' + const FLEET_SERVER_POLICY_ID = 'fleet-server-policy'; + let agentPolicy; + try { + agentPolicy = await agentPolicyService.get(soClient, FLEET_SERVER_POLICY_ID, false); + } catch (err) { + if (!err.isBoom || err.output.statusCode !== 404) { + throw err; + } + } + if (!agentPolicy) { + agentPolicyId = FLEET_SERVER_POLICY_ID; + } + return agentPolicyId; +} + +async function createPackagePolicy( + soClient: SavedObjectsClientContract, + esClient: ElasticsearchClient, + agentPolicy: AgentPolicy, + packageToInstall: string, + options: { spaceId: string; user: AuthenticatedUser | undefined } +) { + // If needed, retrieve package information and build a new package policy for the package + // NOTE: we ignore failures in attempting to create package policy, since agent policy might have been created + // successfully + const newPackagePolicy = await packagePolicyService + .buildPackagePolicyFromPackage(soClient, packageToInstall) + .catch(() => undefined); + + if (!newPackagePolicy) return; + + newPackagePolicy.policy_id = agentPolicy.id; + newPackagePolicy.namespace = agentPolicy.namespace; + newPackagePolicy.name = await incrementPackageName(soClient, packageToInstall); + + await packagePolicyService.create(soClient, esClient, newPackagePolicy, { + spaceId: options.spaceId, + user: options.user, + bumpRevision: false, + }); +} + +interface CreateAgentPolicyParams { + soClient: SavedObjectsClientContract; + esClient: ElasticsearchClient; + newPolicy: NewAgentPolicy; + hasFleetServer?: boolean; + withSysMonitoring: boolean; + monitoringEnabled?: string[]; + spaceId: string; + user?: AuthenticatedUser; +} + +export async function createAgentPolicyWithPackages({ + soClient, + esClient, + newPolicy, + hasFleetServer, + withSysMonitoring, + monitoringEnabled, + spaceId, + user, +}: CreateAgentPolicyParams) { + let agentPolicyId; + const packagesToInstall = []; + if (hasFleetServer) { + packagesToInstall.push(FLEET_SERVER_PACKAGE); + + agentPolicyId = await getAgentPolicyId(soClient); + } + if (withSysMonitoring) { + packagesToInstall.push(FLEET_SYSTEM_PACKAGE); + } + if (monitoringEnabled?.length) { + packagesToInstall.push(FLEET_ELASTIC_AGENT_PACKAGE); + } + if (packagesToInstall.length > 0) { + await bulkInstallPackages({ + savedObjectsClient: soClient, + esClient, + packagesToInstall, + spaceId, + }); + } + + const agentPolicy = await agentPolicyService.create(soClient, esClient, newPolicy, { + user, + id: agentPolicyId, + }); + + // Create the fleet server package policy and add it to agent policy. + if (hasFleetServer) { + await createPackagePolicy(soClient, esClient, agentPolicy, FLEET_SERVER_PACKAGE, { + spaceId, + user, + }); + } + + // Create the system monitoring package policy and add it to agent policy. + if (withSysMonitoring) { + await createPackagePolicy(soClient, esClient, agentPolicy, FLEET_SYSTEM_PACKAGE, { + spaceId, + user, + }); + } + + await ensureDefaultEnrollmentAPIKeysExists(soClient, esClient); + await agentPolicyService.deployPolicy(soClient, agentPolicy.id); + + return agentPolicy; +} From fb730103597f3f0fe5154caa607734b62b6a5801 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 11 Jan 2022 10:02:47 +0100 Subject: [PATCH 42/99] fcypress comment out fleet server enroll --- .../plugins/fleet/cypress/integration/fleet_startup.spec.ts | 4 +++- x-pack/plugins/fleet/cypress/integration/integrations.spec.ts | 4 +++- x-pack/plugins/fleet/cypress/screens/integrations.ts | 1 + x-pack/plugins/fleet/public/components/link_and_revision.tsx | 1 + x-pack/test/fleet_cypress/runner.ts | 3 +++ 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 3eb7f2c1dae57..f1bb4de064977 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -43,7 +43,8 @@ describe('Fleet startup', () => { cy.get('.euiTableCellContent').contains(name); } - describe('Fleet Server', () => { + // skipping Fleet Server enroll, to enable, comment out runner.ts line 23 + describe.skip('Fleet Server', () => { it('should display Add agent button and Healthy agent once Fleet Agent page loaded', () => { cy.get('.euiBadge').contains('Healthy'); @@ -62,6 +63,7 @@ describe('Fleet startup', () => { }); before(() => { + // hosts needed to be set so that UI shows fleet server instructions cy.request({ method: 'PUT', url: '/api/fleet/settings', diff --git a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts index 7eb7f8aab454e..e489a8c7b14db 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts @@ -13,6 +13,7 @@ import { clickIfVisible, } from '../tasks/integrations'; import { + AGENT_POLICY_NAME_LINK, CONFIRM_MODAL_BTN, FLYOUT_CLOSE_BTN_SEL, INTEGRATIONS_CARD, @@ -38,6 +39,7 @@ describe('Add Integration', () => { }); it('should display Apache integration in the Policies list once installed ', () => { addAndVerifyIntegration(); + cy.getBySel(AGENT_POLICY_NAME_LINK).contains('Agent policy 1'); }); it('should upgrade policies with integration update', () => { @@ -74,6 +76,6 @@ describe('Add Integration', () => { cy.get('input[placeholder="Search for integrations"]').type('Apache'); cy.get(INTEGRATIONS_CARD).contains(integration).click(); addIntegration(); - cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-'); + cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-1'); } }); diff --git a/x-pack/plugins/fleet/cypress/screens/integrations.ts b/x-pack/plugins/fleet/cypress/screens/integrations.ts index d42fb904b3224..3c980723cc4df 100644 --- a/x-pack/plugins/fleet/cypress/screens/integrations.ts +++ b/x-pack/plugins/fleet/cypress/screens/integrations.ts @@ -10,6 +10,7 @@ export const CREATE_PACKAGE_POLICY_SAVE_BTN = 'createPackagePolicySaveButton'; export const INTEGRATIONS_CARD = '.euiCard__titleAnchor'; export const INTEGRATION_NAME_LINK = 'integrationNameLink'; +export const AGENT_POLICY_NAME_LINK = 'agentPolicyNameLink'; export const CONFIRM_MODAL_BTN = 'confirmModalConfirmButton'; export const CONFIRM_MODAL_BTN_SEL = `[data-test-subj=${CONFIRM_MODAL_BTN}]`; diff --git a/x-pack/plugins/fleet/public/components/link_and_revision.tsx b/x-pack/plugins/fleet/public/components/link_and_revision.tsx index 99f85a09356c8..b56787fbb399c 100644 --- a/x-pack/plugins/fleet/public/components/link_and_revision.tsx +++ b/x-pack/plugins/fleet/public/components/link_and_revision.tsx @@ -26,6 +26,7 @@ export const AgentPolicySummaryLine = memo<{ policy: AgentPolicy }>(({ policy }) className={`eui-textTruncate`} href={getHref('policy_details', { policyId: id })} title={name || id} + data-test-subj="agentPolicyNameLink" > {name || id} diff --git a/x-pack/test/fleet_cypress/runner.ts b/x-pack/test/fleet_cypress/runner.ts index ccc5827c860c9..bcd54fa568368 100644 --- a/x-pack/test/fleet_cypress/runner.ts +++ b/x-pack/test/fleet_cypress/runner.ts @@ -19,6 +19,9 @@ async function withFleetAgent( { getService }: FtrProviderContext, runner: (runnerEnv: Record) => Promise ) { + // skipping fleet server enroll for now, as it is not a functionality of Fleet UI itself. are there any existing e2e tests for enroll? + return await runner({}); + const log = getService('log'); const config = getService('config'); From 89a1d6b67cbb32347fd284bbb450ac3184b7102a Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 11 Jan 2022 11:10:49 +0100 Subject: [PATCH 43/99] cypress fix --- .../cypress/integration/fleet_startup.spec.ts | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index f1bb4de064977..f86449a64982f 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -30,11 +30,13 @@ describe('Fleet startup', () => { cy.get('.euiButtonIcon--danger'); // wait for trash icon } - function verifyFleetServerPolicy(name: string, integration: string) { + function verifyPolicy(name: string, integrations: string[]) { navigateToAgentPolicies(); navigateToAgentPolicy(name); - cy.get('.euiLink').contains(integration); + integrations.forEach((integration) => { + cy.get('.euiLink').contains(integration); + }); cy.get('.euiButtonEmpty').contains('View all agent policies').click(); @@ -43,12 +45,17 @@ describe('Fleet startup', () => { cy.get('.euiTableCellContent').contains(name); } + function verifyAgentPackage() { + cy.visit('/app/integrations/installed'); + cy.getBySel('integration-card:epr:elastic_agent'); + } + // skipping Fleet Server enroll, to enable, comment out runner.ts line 23 describe.skip('Fleet Server', () => { it('should display Add agent button and Healthy agent once Fleet Agent page loaded', () => { cy.get('.euiBadge').contains('Healthy'); - verifyFleetServerPolicy('Fleet Server policy', 'Fleet Server'); + verifyPolicy('Fleet Server policy', ['Fleet Server']); }); after(() => { @@ -79,7 +86,7 @@ describe('Fleet startup', () => { }); it('should create agent policy', () => { - cy.getBySel('addAgentButton').click(); + cy.getBySel('addAgentBtnTop').click(); cy.getBySel('toastCloseButton').click(); cy.getBySel('standaloneTab').click(); @@ -97,24 +104,18 @@ describe('Fleet startup', () => { cy.getBySel('euiFlyoutCloseButton').click(); - verifyFleetServerPolicy('Agent policy 1', 'System'); + verifyPolicy('Agent policy 1', ['System']); - cy.visit('/app/integrations/installed'); - // wait for elastic-agent if not visible at first - cy.getBySel('integration-card:epr:elastic_agent'); + verifyAgentPackage(); }); it('should create Fleet Server policy', () => { - cy.getBySel(AGENTS_TAB).click(); - cy.getBySel('addAgentButton').click(); cy.getBySel('toastCloseButton').click(); cy.getBySel('createFleetServerPolicyBtn').click(); cy.getBySel('euiToastHeader'); - cy.getBySel('euiFlyoutCloseButton').click(); - - verifyFleetServerPolicy('Fleet Server policy 1', 'Fleet Server'); + verifyPolicy('Fleet Server policy 1', ['Fleet Server', 'System']); }); }); }); From b2beb39c3628dd40317b463f58e5699c36a21eb3 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 11 Jan 2022 12:29:31 +0100 Subject: [PATCH 44/99] cypress fix --- x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index f86449a64982f..c64d7f7e35b52 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { AGENTS_TAB, AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; +import { AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; import { cleanupAgentPolicies, unenrollAgent } from '../tasks/cleanup'; import { FLEET, navigateTo } from '../tasks/navigation'; From c4a81abe9269139efc45711f2ab7b66e22bff236 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 11 Jan 2022 13:30:56 +0100 Subject: [PATCH 45/99] changed toast to callout --- .../cypress/integration/fleet_startup.spec.ts | 7 +-- .../components/agent_policy_create_inline.tsx | 20 ++------- .../fleet_server_on_prem_instructions.tsx | 18 +++++++- .../agent_policy_created_callout.tsx | 45 +++++++++++++++++++ .../sections/agents/components/index.tsx | 1 + .../agent_enrollment_flyout/steps.tsx | 35 +++++++++++---- 6 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_policy_created_callout.tsx diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index c64d7f7e35b52..59c7838538103 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -87,7 +87,6 @@ describe('Fleet startup', () => { it('should create agent policy', () => { cy.getBySel('addAgentBtnTop').click(); - cy.getBySel('toastCloseButton').click(); cy.getBySel('standaloneTab').click(); cy.intercept('POST', '/api/fleet/agent_policies?sys_monitoring=true').as('createAgentPolicy'); @@ -99,7 +98,7 @@ describe('Fleet startup', () => { cy.log('Create agent policy took: ' + (Date.now() - startTime) / 1000 + ' s'); }); - cy.getBySel('euiToastHeader'); + cy.getBySel('agentPolicyCreateStatusCallOut').contains('Agent policy created'); cy.get('.euiLoadingSpinner').should('not.exist'); cy.getBySel('euiFlyoutCloseButton').click(); @@ -110,10 +109,8 @@ describe('Fleet startup', () => { }); it('should create Fleet Server policy', () => { - cy.getBySel('toastCloseButton').click(); - cy.getBySel('createFleetServerPolicyBtn').click(); - cy.getBySel('euiToastHeader'); + cy.getBySel('agentPolicyCreateStatusCallOut').contains('Agent policy created'); verifyPolicy('Fleet Server policy 1', ['Fleet Server', 'System']); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index 38e011e01f880..2910b6a5e132f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -27,7 +27,7 @@ import { agentPolicyFormValidation } from '../components'; import type { AgentPolicy, NewAgentPolicy } from '../../../types'; -import { sendCreateAgentPolicy, useStartServices } from '../../../hooks'; +import { sendCreateAgentPolicy } from '../../../hooks'; import { AgentPolicyAdvancedOptionsContent } from './agent_policy_advanced_fields'; import { AgentPolicyFormSystemMonitoringCheckbox } from './agent_policy_system_monitoring_field'; @@ -39,7 +39,7 @@ const StyledEuiAccordion = styled(EuiAccordion)` `; interface Props { - updateAgentPolicy: (u: AgentPolicy) => void; + updateAgentPolicy: (u: AgentPolicy | null) => void; isFleetServerPolicy?: boolean; } @@ -72,32 +72,20 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ const [isLoading, setIsLoading] = useState(false); - const { notifications } = useStartServices(); - const createAgentPolicy = useCallback(async () => { try { setIsLoading(true); const resp = await sendCreateAgentPolicy(newAgentPolicy, { withSysMonitoring }); if (resp.error) throw resp.error; if (resp.data) { - notifications.toasts.addSuccess( - i18n.translate('xpack.fleet.createAgentPolicy.successNotificationTitle', { - defaultMessage: "Agent policy '{name}' created", - values: { name: newAgentPolicy.name }, - }) - ); updateAgentPolicy(resp.data.item); } } catch (e) { - notifications.toasts.addDanger( - i18n.translate('xpack.fleet.createAgentPolicy.errorNotificationTitle', { - defaultMessage: 'Unable to create agent policy', - }) - ); + updateAgentPolicy(null); } finally { setIsLoading(false); } - }, [newAgentPolicy, withSysMonitoring, notifications, updateAgentPolicy]); + }, [newAgentPolicy, withSysMonitoring, updateAgentPolicy]); return ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index ff59ea5ef6378..32d5d905358d6 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -46,7 +46,11 @@ import { import type { PLATFORM_TYPE } from '../../../../hooks'; import type { AgentPolicy, PackagePolicy } from '../../../../types'; import { FLEET_SERVER_PACKAGE } from '../../../../constants'; -import { FleetServerOnPremRequiredCallout } from '../../components'; +import { + AgentPolicyCreatedCallOut, + CREATE_STATUS, + FleetServerOnPremRequiredCallout, +} from '../../components'; import { AgentPolicyCreateInlineForm } from '../../../agent_policy/components'; @@ -364,8 +368,15 @@ const AgentPolicySelectionStep = ({ [setPolicyId] ); + const [createStatus, setCreateStatus] = useState(CREATE_STATUS.INITIAL); + const onAgentPolicyCreated = useCallback( - (policy: AgentPolicy) => { + (policy: AgentPolicy | null) => { + if (!policy) { + setCreateStatus(CREATE_STATUS.FAILED); + return; + } + setCreateStatus(CREATE_STATUS.CREATED); setPolicyId(policy.id); refreshAgentPolicies(); }, @@ -417,6 +428,9 @@ const AgentPolicySelectionStep = ({ defaultMessage: 'Agent policy', })} /> + {createStatus !== CREATE_STATUS.INITIAL && ( + + )} ), }; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_policy_created_callout.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_policy_created_callout.tsx new file mode 100644 index 0000000000000..014f68168f140 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_policy_created_callout.tsx @@ -0,0 +1,45 @@ +/* + * 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 React from 'react'; +import { EuiSpacer, EuiCallOut } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +export enum CREATE_STATUS { + INITIAL = 'initial', + CREATED = 'created', + FAILED = 'failed', +} + +interface Props { + createStatus: CREATE_STATUS; +} + +export const AgentPolicyCreatedCallOut: React.FunctionComponent = ({ createStatus }) => { + return ( + <> + + + ) : ( + + ) + } + color={createStatus === CREATE_STATUS.CREATED ? 'success' : 'danger'} + iconType={createStatus === CREATE_STATUS.CREATED ? 'check' : 'cross'} + /> + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/index.tsx index 27fcc06045314..cbae2c93221aa 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/index.tsx @@ -11,3 +11,4 @@ export * from './agent_health'; export * from './agent_unenroll_modal'; export * from './agent_upgrade_modal'; export * from './fleet_server_callouts'; +export * from './agent_policy_created_callout'; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx index 776f6a6c96a8e..e0fbb7266fb5f 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx @@ -20,6 +20,11 @@ import { AgentPolicyCreateInlineForm } from '../../applications/fleet/sections/a import { policyHasFleetServer } from '../../applications/fleet/sections/agents/services/has_fleet_server'; +import { + AgentPolicyCreatedCallOut, + CREATE_STATUS, +} from '../../applications/fleet/sections/agents/components'; + import { EnrollmentStepAgentPolicy } from './agent_policy_selection'; import { AdvancedAgentAuthenticationSettings } from './advanced_agent_authentication_settings'; @@ -108,8 +113,15 @@ export const AgentPolicySelectionStep = ({ [setSelectedPolicyId] ); + const [createStatus, setCreateStatus] = useState(CREATE_STATUS.INITIAL); + const onAgentPolicyCreated = useCallback( - async (policy: AgentPolicy) => { + async (policy: AgentPolicy | null) => { + if (!policy) { + setCreateStatus(CREATE_STATUS.FAILED); + return; + } + setCreateStatus(CREATE_STATUS.CREATED); setAgentPolicyList([...agentPolicyList, policy]); if (setSelectedPolicyId) { setSelectedPolicyId(policy.id); @@ -124,14 +136,19 @@ export const AgentPolicySelectionStep = ({ }), children: regularAgentPolicies.length > 0 ? ( - + <> + + {createStatus !== CREATE_STATUS.INITIAL && ( + + )} + ) : ( ), From 45e69948b7dcfad34911674477c0ed7be8d10244 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 11 Jan 2022 14:14:24 +0100 Subject: [PATCH 46/99] changed toast to callout --- .../agent_policy_created_callout.tsx | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_policy_created_callout.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_policy_created_callout.tsx index 014f68168f140..ba3af7716d985 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_policy_created_callout.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_policy_created_callout.tsx @@ -22,24 +22,31 @@ export const AgentPolicyCreatedCallOut: React.FunctionComponent = ({ crea return ( <> - - ) : ( + } + color="success" + iconType="check" + /> + ) : ( + - ) - } - color={createStatus === CREATE_STATUS.CREATED ? 'success' : 'danger'} - iconType={createStatus === CREATE_STATUS.CREATED ? 'check' : 'cross'} - /> + } + color="danger" + iconType="cross" + /> + )} ); }; From 52edebce6d72c0ee16eb7a25b2b767066fbb731a Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 11 Jan 2022 16:31:02 +0100 Subject: [PATCH 47/99] removed label --- .../agent_enrollment_flyout/agent_policy_selection.tsx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx index 1c2464e1abfa3..4b7b7de66e562 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx @@ -17,7 +17,6 @@ import { EuiPortal, EuiSelect, EuiSpacer, - EuiText, } from '@elastic/eui'; import type { AgentPolicy } from '../../types'; @@ -134,14 +133,6 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => { > - - - } isLoading={!agentPolicies} options={agentPolicyList.map((agentPolicy: AgentPolicy) => ({ value: agentPolicy.id, From cdcbef9c1068d00f314369ccc891e70b0e1afe64 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 11 Jan 2022 17:55:26 +0100 Subject: [PATCH 48/99] fix checks, added more tests --- .../fleet/cypress/integration/integrations.spec.ts | 8 ++++++++ x-pack/plugins/fleet/cypress/tasks/integrations.ts | 6 +++++- .../agent_policy/create_package_policy_page/index.tsx | 2 +- x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts index e489a8c7b14db..9124b6a8aa36e 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts @@ -40,6 +40,14 @@ describe('Add Integration', () => { it('should display Apache integration in the Policies list once installed ', () => { addAndVerifyIntegration(); cy.getBySel(AGENT_POLICY_NAME_LINK).contains('Agent policy 1'); + + clickIfVisible(FLYOUT_CLOSE_BTN_SEL); + // test add integration using existing policy + addIntegration({ useExistingPolicy: true }); + cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-2'); + cy.getBySel(AGENT_POLICY_NAME_LINK) + .should('have.length', 2) + .each((el) => el.text().includes('Agent policy 1')); }); it('should upgrade policies with integration update', () => { diff --git a/x-pack/plugins/fleet/cypress/tasks/integrations.ts b/x-pack/plugins/fleet/cypress/tasks/integrations.ts index e9e3f2613c3e8..e13cea1af59d7 100644 --- a/x-pack/plugins/fleet/cypress/tasks/integrations.ts +++ b/x-pack/plugins/fleet/cypress/tasks/integrations.ts @@ -13,8 +13,12 @@ import { INTEGRATION_NAME_LINK, } from '../screens/integrations'; -export const addIntegration = () => { +export const addIntegration = ({ useExistingPolicy } = { useExistingPolicy: false }) => { cy.getBySel(ADD_POLICY_BTN).click(); + cy.getBySel('toastCloseButton').click(); + if (useExistingPolicy) { + cy.get('#existing').click(); + } cy.getBySel(CREATE_PACKAGE_POLICY_SAVE_BTN).click(); // sometimes agent is assigned to default policy, sometimes not cy.getBySel(CONFIRM_MODAL_BTN).click(); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index 55b1bde1331eb..2df366fba9591 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -656,7 +656,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { Date: Tue, 11 Jan 2022 18:01:36 +0100 Subject: [PATCH 49/99] fix test --- x-pack/plugins/fleet/cypress/tasks/integrations.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/fleet/cypress/tasks/integrations.ts b/x-pack/plugins/fleet/cypress/tasks/integrations.ts index e13cea1af59d7..23f16b33d0303 100644 --- a/x-pack/plugins/fleet/cypress/tasks/integrations.ts +++ b/x-pack/plugins/fleet/cypress/tasks/integrations.ts @@ -15,7 +15,6 @@ import { export const addIntegration = ({ useExistingPolicy } = { useExistingPolicy: false }) => { cy.getBySel(ADD_POLICY_BTN).click(); - cy.getBySel('toastCloseButton').click(); if (useExistingPolicy) { cy.get('#existing').click(); } From 50bd3a0e74504895a28fc0d99d9c6a74673f6adb Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 12 Jan 2022 10:12:14 +0100 Subject: [PATCH 50/99] fix checks --- .../create_package_policy_page/step_select_hosts.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx index 873da56277568..2ecba56ace16c 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -103,6 +103,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ agentPolicy={agentPolicy} updateAgentPolicy={updateAgentPolicy} setHasAgentPolicyError={setHasAgentPolicyError} + onNewAgentPolicyCreate={() => {}} /> ), }, From 8a5aea2646ca7c7bac1ef5270048e06bab707ee9 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 12 Jan 2022 11:27:03 +0100 Subject: [PATCH 51/99] added more cypress asserts --- .../cypress/integration/fleet_startup.spec.ts | 48 +++++++++++-------- .../fleet_server_on_prem_instructions.tsx | 9 +++- .../agent_policy_selection.tsx | 1 + 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 59c7838538103..68bc5e6669d49 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; +import { AGENTS_TAB, AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; import { cleanupAgentPolicies, unenrollAgent } from '../tasks/cleanup'; import { FLEET, navigateTo } from '../tasks/navigation'; @@ -14,8 +14,8 @@ describe('Fleet startup', () => { navigateTo(FLEET); }); - function navigateToAgentPolicies() { - cy.getBySel(AGENT_POLICIES_TAB).click(); + function navigateToTab(tab: string) { + cy.getBySel(tab).click(); cy.get('.euiBasicTable-loading').should('not.exist'); } @@ -31,7 +31,7 @@ describe('Fleet startup', () => { } function verifyPolicy(name: string, integrations: string[]) { - navigateToAgentPolicies(); + navigateToTab(AGENT_POLICIES_TAB); navigateToAgentPolicy(name); integrations.forEach((integration) => { @@ -69,15 +69,7 @@ describe('Fleet startup', () => { cleanupAgentPolicies(); }); - before(() => { - // hosts needed to be set so that UI shows fleet server instructions - cy.request({ - method: 'PUT', - url: '/api/fleet/settings', - body: { fleet_server_hosts: ['http://localhost:8220'] }, - headers: { 'kbn-xsrf': 'kibana' }, - }); - }); + before(() => {}); it('should have no agent policy by default', () => { cy.request('/api/fleet/agent_policies?full=true').then((response: any) => { @@ -93,26 +85,44 @@ describe('Fleet startup', () => { cy.getBySel('createPolicyBtn').click(); + let agentPolicyId; const startTime = Date.now(); cy.wait('@createAgentPolicy', { timeout: 180000 }).then((xhr: any) => { cy.log('Create agent policy took: ' + (Date.now() - startTime) / 1000 + ' s'); - }); + agentPolicyId = xhr.response.body.item.id; - cy.getBySel('agentPolicyCreateStatusCallOut').contains('Agent policy created'); - cy.get('.euiLoadingSpinner').should('not.exist'); + cy.getBySel('agentPolicyCreateStatusCallOut').contains('Agent policy created'); - cy.getBySel('euiFlyoutCloseButton').click(); + // verify create button changed to dropdown + cy.getBySel('agentPolicyDropdown'); + // verify agent.yml code block has new policy id + cy.get('.euiCodeBlock__code').contains(`id: ${agentPolicyId}`); - verifyPolicy('Agent policy 1', ['System']); + cy.getBySel('euiFlyoutCloseButton').click(); - verifyAgentPackage(); + // verify policy is created and has system package + verifyPolicy('Agent policy 1', ['System']); + + verifyAgentPackage(); + }); }); it('should create Fleet Server policy', () => { cy.getBySel('createFleetServerPolicyBtn').click(); cy.getBySel('agentPolicyCreateStatusCallOut').contains('Agent policy created'); + // verify policy is created and has fleet server and system package verifyPolicy('Fleet Server policy 1', ['Fleet Server', 'System']); + + navigateToTab(AGENTS_TAB); + // verify create button changed to dropdown + cy.getBySel('agentPolicyDropdown'); + + // verify fleet server enroll command contains created policy id + cy.getBySel('fleetServerHostInput').type('http://localhost:8220'); + cy.getBySel('fleetServerAddHostBtn').click(); + cy.getBySel('fleetServerGenerateServiceTokenBtn').click(); + cy.get('.euiCodeBlock__code').contains('--fleet-server-policy=fleet-server-policy'); }); }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index 32d5d905358d6..ce972e53dffc7 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -116,6 +116,7 @@ export const ServiceTokenStep = ({ onClick={() => { getServiceToken(); }} + data-test-subj="fleetServerGenerateServiceTokenBtn" > {createStatus !== CREATE_STATUS.INITIAL && ( @@ -538,11 +540,16 @@ export const AddFleetServerHostStepContent = ({ /> } + data-test-subj="fleetServerHostInput" /> {error && {error}} - + = (props) => { } )} hasNoInitialSelection={agentPolicyList.length > 1} + data-test-subj="agentPolicyDropdown" /> From e90f55f27406545fc64872522a9da712330128e9 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 12 Jan 2022 11:30:28 +0100 Subject: [PATCH 52/99] fix checks --- .../create_package_policy_page/step_select_hosts.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx index 2ecba56ace16c..55dcd68a90807 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -40,6 +40,7 @@ interface Props { packageInfo?: PackageInfo; setHasAgentPolicyError: (hasError: boolean) => void; updateSelectedTab: (tab: SelectedPolicyTab) => void; + onNewAgentPolicyCreate: () => void; } export const StepSelectHosts: React.FunctionComponent = ({ @@ -53,6 +54,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ packageInfo, setHasAgentPolicyError, updateSelectedTab, + onNewAgentPolicyCreate, }) => { let agentPolicies: AgentPolicy[] = []; const { data: agentPoliciesData, error: err } = useGetAgentPolicies({ @@ -103,7 +105,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ agentPolicy={agentPolicy} updateAgentPolicy={updateAgentPolicy} setHasAgentPolicyError={setHasAgentPolicyError} - onNewAgentPolicyCreate={() => {}} + onNewAgentPolicyCreate={onNewAgentPolicyCreate} /> ), }, From 343e5c2fce0b29f73b1fcac03f8d7230f27569f7 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 12 Jan 2022 16:47:14 +0100 Subject: [PATCH 53/99] refactored agent policy create and select --- .../components/agent_policy_create_inline.tsx | 4 +- .../step_select_hosts.tsx | 3 +- .../utils/increment_policy_name.ts | 18 ---- .../create_package_policy_page/utils/index.ts | 2 - .../fleet_server_on_prem_instructions.tsx | 82 +++------------- .../agent_policy_select_create.tsx | 93 +++++++++++++++++++ .../agent_policy_selection.tsx | 63 +++++-------- .../agent_enrollment_flyout/index.tsx | 1 + .../agent_enrollment_flyout/steps.tsx | 63 ++++--------- .../increment_policy_name.test.ts | 5 + .../public/services/increment_policy_name.ts | 21 +++++ x-pack/plugins/fleet/public/services/index.ts | 1 + .../server/types/models/preconfiguration.ts | 2 + 13 files changed, 180 insertions(+), 178 deletions(-) delete mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.ts create mode 100644 x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx rename x-pack/plugins/fleet/public/{applications/fleet/sections/agent_policy/create_package_policy_page/utils => services}/increment_policy_name.test.ts (84%) create mode 100644 x-pack/plugins/fleet/public/services/increment_policy_name.ts diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index 2910b6a5e132f..0f8915fc7fe2f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -41,16 +41,18 @@ const StyledEuiAccordion = styled(EuiAccordion)` interface Props { updateAgentPolicy: (u: AgentPolicy | null) => void; isFleetServerPolicy?: boolean; + agentPolicyName: string; } export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ updateAgentPolicy, isFleetServerPolicy, + agentPolicyName, }) => { const [touchedFields, setTouchedFields] = useState<{ [key: string]: boolean }>({}); const [newAgentPolicy, setNewAgentPolicy] = useState({ - name: isFleetServerPolicy ? 'Fleet Server policy 1' : 'Agent policy 1', + name: agentPolicyName, description: '', namespace: 'default', monitoring_enabled: Object.values(dataTypes), diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx index 55dcd68a90807..b08190f0ef771 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -15,8 +15,9 @@ import type { AgentPolicy, NewAgentPolicy, PackageInfo } from '../../../types'; import { AgentPolicyIntegrationForm } from '../components'; import type { ValidationResults } from '../components/agent_policy_validation'; +import { incrementPolicyName } from '../../../services'; + import { StepSelectAgentPolicy } from './step_select_agent_policy'; -import { incrementPolicyName } from './utils'; export enum SelectedPolicyTab { NEW = 'new', diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.ts deleted file mode 100644 index aa6554d2ce1b2..0000000000000 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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 type { AgentPolicy } from '../../../../types'; - -export function incrementPolicyName(policies: AgentPolicy[]): string { - const indices = policies - .map((pol: AgentPolicy) => pol.name) - .map((name) => { - const match = name.match(/Agent policy (\d+)/); - return match ? parseInt(match[1], 10) : 0; - }); - return `Agent policy ${Math.max(...indices, 0) + 1}`; -} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/index.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/index.ts index a687ea01deef4..15de46e1dc588 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/index.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/index.ts @@ -6,5 +6,3 @@ */ export { appendOnSaveQueryParamsToPath } from './append_on_save_query_params'; - -export { incrementPolicyName } from './increment_policy_name'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index ce972e53dffc7..25b3f3bceabab 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -17,7 +17,6 @@ import { EuiCode, EuiCodeBlock, EuiCallOut, - EuiSelect, EuiRadioGroup, EuiFieldText, EuiForm, @@ -29,7 +28,7 @@ import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { DownloadStep } from '../../../../components'; +import { DownloadStep, SelectCreateAgentPolicy } from '../../../../components'; import { useStartServices, useDefaultOutput, @@ -46,13 +45,7 @@ import { import type { PLATFORM_TYPE } from '../../../../hooks'; import type { AgentPolicy, PackagePolicy } from '../../../../types'; import { FLEET_SERVER_PACKAGE } from '../../../../constants'; -import { - AgentPolicyCreatedCallOut, - CREATE_STATUS, - FleetServerOnPremRequiredCallout, -} from '../../components'; - -import { AgentPolicyCreateInlineForm } from '../../../agent_policy/components'; +import { FleetServerOnPremRequiredCallout } from '../../components'; import { getInstallCommandForPlatform } from './install_command_utils'; @@ -351,10 +344,6 @@ const AgentPolicySelectionStep = ({ [data] ); - const options = useMemo(() => { - return agentPolicies.map((policy) => ({ text: policy.name, value: policy.id })); - }, [agentPolicies]); - useEffect(() => { // Select default value if (agentPolicies.length && !policyId) { @@ -363,42 +352,15 @@ const AgentPolicySelectionStep = ({ }, [agentPolicies, policyId, setPolicyId]); const onChangeCallback = useCallback( - (e: React.ChangeEvent) => { - setPolicyId(e.target.value); - }, - [setPolicyId] - ); - - const [createStatus, setCreateStatus] = useState(CREATE_STATUS.INITIAL); - - const onAgentPolicyCreated = useCallback( - (policy: AgentPolicy | null) => { - if (!policy) { - setCreateStatus(CREATE_STATUS.FAILED); - return; + (key: string | undefined, policy?: AgentPolicy) => { + if (policy) { + refreshAgentPolicies(); } - setCreateStatus(CREATE_STATUS.CREATED); - setPolicyId(policy.id); - refreshAgentPolicies(); + setPolicyId(key!); }, [setPolicyId, refreshAgentPolicies] ); - if (agentPolicies.length === 0) { - return { - title: i18n.translate('xpack.fleet.fleetServerSetup.stepCreateAgentPolicyTitle', { - defaultMessage: 'Create a Fleet Server agent policy', - }), - status: undefined, - children: ( - - ), - }; - } - return { title: i18n.translate('xpack.fleet.fleetServerSetup.stepSelectAgentPolicyTitle', { defaultMessage: 'Select an Agent policy', @@ -406,33 +368,13 @@ const AgentPolicySelectionStep = ({ status: undefined, children: ( <> - - - - - - - - } - options={options} - value={policyId} - onChange={onChangeCallback} - aria-label={i18n.translate('xpack.fleet.fleetServerSetup.agentPolicySelectAraiLabel', { - defaultMessage: 'Agent policy', - })} - data-test-subj="agentPolicyDropdown" + - {createStatus !== CREATE_STATUS.INITIAL && ( - - )} ), }; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx new file mode 100644 index 0000000000000..8fd9602f18bf8 --- /dev/null +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx @@ -0,0 +1,93 @@ +/* + * 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 React, { useState, useCallback, useEffect } from 'react'; + +import { + AgentPolicyCreatedCallOut, + CREATE_STATUS, +} from '../../applications/fleet/sections/agents/components'; +import { AgentPolicyCreateInlineForm } from '../../applications/fleet/sections/agent_policy/components'; +import type { AgentPolicy } from '../../types'; +import { incrementPolicyName } from '../../services'; + +import { EnrollmentStepAgentPolicy } from '.'; + +interface Props { + agentPolicies: AgentPolicy[]; + excludeFleetServer?: boolean; + onAgentPolicyChange: (key?: string, policy?: AgentPolicy) => void; + withKeySelection: boolean; + selectedApiKeyId?: string; + onKeyChange?: (key?: string) => void; + isFleetServerPolicy?: boolean; +} + +export const SelectCreateAgentPolicy: React.FC = ({ + agentPolicies, + excludeFleetServer, + onAgentPolicyChange, + withKeySelection, + selectedApiKeyId, + onKeyChange, + isFleetServerPolicy, +}) => { + const [showCreatePolicy, setShowCreatePolicy] = useState(agentPolicies.length === 0); + + const [createStatus, setCreateStatus] = useState(CREATE_STATUS.INITIAL); + + const [newName, setNewName] = useState(incrementPolicyName(agentPolicies, isFleetServerPolicy)); + + const [selectedAgentPolicy, setSelectedAgentPolicy] = useState(undefined); + + useEffect(() => { + setShowCreatePolicy(agentPolicies.length === 0); + setNewName(incrementPolicyName(agentPolicies, isFleetServerPolicy)); + }, [agentPolicies, isFleetServerPolicy]); + + const onAgentPolicyCreated = useCallback( + async (policy: AgentPolicy | null) => { + if (!policy) { + setCreateStatus(CREATE_STATUS.FAILED); + return; + } + setShowCreatePolicy(false); + setCreateStatus(CREATE_STATUS.CREATED); + if (onAgentPolicyChange) { + onAgentPolicyChange(policy.id, policy!); + } + setSelectedAgentPolicy(policy.id); + }, + [onAgentPolicyChange] + ); + + return ( + <> + {showCreatePolicy ? ( + + ) : ( + setShowCreatePolicy(true)} + selectedAgentPolicy={selectedAgentPolicy} + /> + )} + {createStatus !== CREATE_STATUS.INITIAL && ( + + )} + + ); +}; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx index 230fc5c8eb35e..e177db0e46a1a 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx @@ -9,21 +9,12 @@ import React, { useState, useEffect } from 'react'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, - EuiLink, - EuiPortal, - EuiSelect, - EuiSpacer, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiLink, EuiSelect, EuiSpacer } from '@elastic/eui'; import type { AgentPolicy } from '../../types'; import { AgentPolicyPackageBadges } from '../agent_policy_package_badges'; import { useCapabilities } from '../../hooks'; -import { CreateAgentPolicyFlyout } from '../../applications/fleet/sections/agent_policy/list_page/components'; import { AdvancedAgentAuthenticationSettings } from './advanced_agent_authentication_settings'; @@ -34,9 +25,11 @@ const AgentPolicyFormRow = styled(EuiFormRow)` `; type Props = { - agentPolicies?: AgentPolicy[]; - onAgentPolicyChange?: (key?: string) => void; + agentPolicies: AgentPolicy[]; + onAgentPolicyChange: (key?: string, policy?: AgentPolicy) => void; excludeFleetServer?: boolean; + onClickCreatePolicy: () => void; + selectedAgentPolicy?: string; } & ( | { withKeySelection: true; @@ -62,18 +55,20 @@ const resolveAgentId = ( }; export const EnrollmentStepAgentPolicy: React.FC = (props) => { - const { agentPolicies, onAgentPolicyChange, excludeFleetServer } = props; - - const [agentPolicyList, setAgentPolicyList] = useState(agentPolicies || []); + const { + agentPolicies, + onAgentPolicyChange, + excludeFleetServer, + onClickCreatePolicy, + selectedAgentPolicy, + } = props; const [selectedAgentPolicyId, setSelectedAgentPolicyId] = useState( - () => resolveAgentId(agentPolicyList, undefined) // no agent id selected yet + () => resolveAgentId(agentPolicies, undefined) // no agent id selected yet ); // Create new agent policy flyout state const hasWriteCapabilites = useCapabilities().write; - const [isCreateAgentPolicyFlyoutOpen, setIsCreateAgentPolicyFlyoutOpen] = - useState(false); useEffect( function triggerOnAgentPolicyChangeEffect() { @@ -86,41 +81,27 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => { useEffect( function useDefaultAgentPolicyEffect() { - const resolvedId = resolveAgentId(agentPolicyList, selectedAgentPolicyId); + const resolvedId = resolveAgentId(agentPolicies, selectedAgentPolicyId); if (resolvedId !== selectedAgentPolicyId) { setSelectedAgentPolicyId(resolvedId); } }, - [agentPolicyList, selectedAgentPolicyId] + [agentPolicies, selectedAgentPolicyId] ); + useEffect(() => { + if (selectedAgentPolicy) setSelectedAgentPolicyId(selectedAgentPolicy); + }, [selectedAgentPolicy]); + return ( <> - {isCreateAgentPolicyFlyoutOpen ? ( - - { - setIsCreateAgentPolicyFlyoutOpen(false); - if (newAgentPolicy) { - setAgentPolicyList([...agentPolicyList, newAgentPolicy]); - - setSelectedAgentPolicyId(newAgentPolicy.id); - } - }} - ownFocus={true} - /> - - ) : null}
- setIsCreateAgentPolicyFlyoutOpen(true)} - > + = (props) => { ({ + options={agentPolicies.map((agentPolicy: AgentPolicy) => ({ value: agentPolicy.id, text: agentPolicy.name, }))} @@ -146,7 +127,7 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => { defaultMessage: 'Agent policy', } )} - hasNoInitialSelection={agentPolicyList.length > 1} + hasNoInitialSelection={agentPolicies.length > 1} data-test-subj="agentPolicyDropdown" /> diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/index.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/index.tsx index 5c9c20329699b..b740d0ea62f0a 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/index.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/index.tsx @@ -39,6 +39,7 @@ export interface Props extends BaseProps { } export * from './agent_policy_selection'; +export * from './agent_policy_select_create'; export * from './managed_instructions'; export * from './standalone_instructions'; export * from './steps'; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx index e0fbb7266fb5f..953918a10f157 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx @@ -16,17 +16,10 @@ import semverPatch from 'semver/functions/patch'; import type { AgentPolicy } from '../../types'; import { useKibanaVersion } from '../../hooks'; -import { AgentPolicyCreateInlineForm } from '../../applications/fleet/sections/agent_policy/components'; - import { policyHasFleetServer } from '../../applications/fleet/sections/agents/services/has_fleet_server'; -import { - AgentPolicyCreatedCallOut, - CREATE_STATUS, -} from '../../applications/fleet/sections/agents/components'; - -import { EnrollmentStepAgentPolicy } from './agent_policy_selection'; import { AdvancedAgentAuthenticationSettings } from './advanced_agent_authentication_settings'; +import { SelectCreateAgentPolicy } from './agent_policy_select_create'; export const DownloadStep = (hasFleetServer: boolean) => { const kibanaVersion = useKibanaVersion(); @@ -105,53 +98,33 @@ export const AgentPolicySelectionStep = ({ }, [agentPolicyList, excludeFleetServer]); const onAgentPolicyChange = useCallback( - async (policyId?: string) => { - if (setSelectedPolicyId) { - setSelectedPolicyId(policyId); - } - }, - [setSelectedPolicyId] - ); - - const [createStatus, setCreateStatus] = useState(CREATE_STATUS.INITIAL); - - const onAgentPolicyCreated = useCallback( - async (policy: AgentPolicy | null) => { - if (!policy) { - setCreateStatus(CREATE_STATUS.FAILED); - return; + async (key?: string, policy?: AgentPolicy) => { + if (policy) { + setAgentPolicyList([...agentPolicyList, policy]); } - setCreateStatus(CREATE_STATUS.CREATED); - setAgentPolicyList([...agentPolicyList, policy]); if (setSelectedPolicyId) { - setSelectedPolicyId(policy.id); + setSelectedPolicyId(key); } }, - [agentPolicyList, setAgentPolicyList, setSelectedPolicyId] + [setSelectedPolicyId, setAgentPolicyList, agentPolicyList] ); return { title: i18n.translate('xpack.fleet.agentEnrollment.stepChooseAgentPolicyTitle', { defaultMessage: 'What type of host are you adding?', }), - children: - regularAgentPolicies.length > 0 ? ( - <> - - {createStatus !== CREATE_STATUS.INITIAL && ( - - )} - - ) : ( - - ), + children: ( + <> + + + ), }; }; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.test.ts b/x-pack/plugins/fleet/public/services/increment_policy_name.test.ts similarity index 84% rename from x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.test.ts rename to x-pack/plugins/fleet/public/services/increment_policy_name.test.ts index a518e9825add6..363ff26a6fe51 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/utils/increment_policy_name.test.ts +++ b/x-pack/plugins/fleet/public/services/increment_policy_name.test.ts @@ -30,4 +30,9 @@ describe('increment policy name', () => { ]); expect(name).toEqual('Agent policy 11'); }); + + it('should return index 2 when policy 1 exists - fleet server', () => { + const name = incrementPolicyName([{ name: 'Fleet Server policy 1' } as any], true); + expect(name).toEqual('Fleet Server policy 2'); + }); }); diff --git a/x-pack/plugins/fleet/public/services/increment_policy_name.ts b/x-pack/plugins/fleet/public/services/increment_policy_name.ts new file mode 100644 index 0000000000000..77a9baff1805d --- /dev/null +++ b/x-pack/plugins/fleet/public/services/increment_policy_name.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +export function incrementPolicyName( + policies: Array<{ name: string }>, + isFleetServerPolicy?: boolean +): string { + const indices = policies + .map((pol: { name: string }) => pol.name) + .map((name) => { + const match = name.match( + isFleetServerPolicy ? /Fleet Server policy (\d+)/ : /Agent policy (\d+)/ + ); + return match ? parseInt(match[1], 10) : 0; + }); + return `${isFleetServerPolicy ? 'Fleet Server' : 'Agent'} policy ${Math.max(...indices, 0) + 1}`; +} diff --git a/x-pack/plugins/fleet/public/services/index.ts b/x-pack/plugins/fleet/public/services/index.ts index 10dfe6b59d6ba..ad108e3f97ca9 100644 --- a/x-pack/plugins/fleet/public/services/index.ts +++ b/x-pack/plugins/fleet/public/services/index.ts @@ -44,3 +44,4 @@ export { export * from './pkg_key_from_package_info'; export * from './ui_extensions'; +export * from './increment_policy_name'; diff --git a/x-pack/plugins/fleet/server/types/models/preconfiguration.ts b/x-pack/plugins/fleet/server/types/models/preconfiguration.ts index a706f5eebb299..960ecbe67d593 100644 --- a/x-pack/plugins/fleet/server/types/models/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/types/models/preconfiguration.ts @@ -96,6 +96,8 @@ export const PreconfiguredAgentPoliciesSchema = schema.arrayOf( ...AgentPolicyBaseSchema, namespace: schema.maybe(NamespaceSchema), id: schema.maybe(schema.oneOf([schema.string(), schema.number()])), + is_default: schema.maybe(schema.boolean()), + is_default_fleet_server: schema.maybe(schema.boolean()), has_fleet_server: schema.maybe(schema.boolean()), data_output_id: schema.maybe(schema.string()), monitoring_output_id: schema.maybe(schema.string()), From 6cfbab262e02cb35fc56b21b708627b9b585ef77 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 12 Jan 2022 16:52:42 +0100 Subject: [PATCH 54/99] update label --- .../components/fleet_server_on_prem_instructions.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index 25b3f3bceabab..c569adee10595 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -362,9 +362,14 @@ const AgentPolicySelectionStep = ({ ); return { - title: i18n.translate('xpack.fleet.fleetServerSetup.stepSelectAgentPolicyTitle', { - defaultMessage: 'Select an Agent policy', - }), + title: + agentPolicies.length === 0 + ? i18n.translate('xpack.fleet.fleetServerSetup.stepCreateAgentPolicyTitle', { + defaultMessage: 'Create an agent policy to host Fleet Server', + }) + : i18n.translate('xpack.fleet.fleetServerSetup.stepSelectAgentPolicyTitle', { + defaultMessage: 'Select an agent policy to host Fleet Server', + }), status: undefined, children: ( <> From ec66136439a483401ed99dc866d8126c4da16d2d Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 13 Jan 2022 10:08:39 +0100 Subject: [PATCH 55/99] fix checks, hide badges for fleet server policy --- .../agent_enrollment_flyout/agent_policy_select_create.tsx | 1 + .../agent_enrollment_flyout/agent_policy_selection.tsx | 4 +++- x-pack/plugins/translations/translations/ja-JP.json | 3 --- x-pack/plugins/translations/translations/zh-CN.json | 3 --- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx index 8fd9602f18bf8..80ab845aaa49c 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx @@ -83,6 +83,7 @@ export const SelectCreateAgentPolicy: React.FC = ({ excludeFleetServer={excludeFleetServer} onClickCreatePolicy={() => setShowCreatePolicy(true)} selectedAgentPolicy={selectedAgentPolicy} + isFleetServerPolicy={isFleetServerPolicy} /> )} {createStatus !== CREATE_STATUS.INITIAL && ( diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx index e177db0e46a1a..54de3cb27e46e 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx @@ -30,6 +30,7 @@ type Props = { excludeFleetServer?: boolean; onClickCreatePolicy: () => void; selectedAgentPolicy?: string; + isFleetServerPolicy?: boolean; } & ( | { withKeySelection: true; @@ -61,6 +62,7 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => { excludeFleetServer, onClickCreatePolicy, selectedAgentPolicy, + isFleetServerPolicy, } = props; const [selectedAgentPolicyId, setSelectedAgentPolicyId] = useState( @@ -132,7 +134,7 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => { /> - {selectedAgentPolicyId && ( + {selectedAgentPolicyId && !isFleetServerPolicy && ( Date: Thu, 13 Jan 2022 12:17:04 +0100 Subject: [PATCH 56/99] added back is_default flags --- .../fleet/common/types/models/agent_policy.ts | 4 ++++ .../agent_policy_selection.tsx | 12 +++++++----- .../fleet/server/saved_objects/index.ts | 4 ++-- .../saved_objects/migrations/to_v8_1_0.ts | 19 ------------------- .../server/services/agent_policy.test.ts | 1 + .../fleet/server/services/agent_policy.ts | 1 + .../server/services/agent_policy_create.ts | 7 ++++++- .../fleet/server/services/preconfiguration.ts | 8 ++++++-- .../fleet/server/types/models/agent_policy.ts | 2 ++ .../es_archives/fleet/agents/mappings.json | 3 +++ .../fleet/empty_fleet_server/mappings.json | 3 +++ 11 files changed, 35 insertions(+), 29 deletions(-) delete mode 100644 x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_1_0.ts diff --git a/x-pack/plugins/fleet/common/types/models/agent_policy.ts b/x-pack/plugins/fleet/common/types/models/agent_policy.ts index bb778e9c90d1b..6e59cf0d50006 100644 --- a/x-pack/plugins/fleet/common/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/common/types/models/agent_policy.ts @@ -140,6 +140,10 @@ export interface FleetServerPolicy { data: { [k: string]: unknown; }; + /** + * True when this policy is the default policy to start Fleet Server + */ + default_fleet_server: boolean; /** * Auto unenroll any Elastic Agents which have not checked in for this many seconds */ diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx index 54de3cb27e46e..84f4dd9a9aff6 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx @@ -133,12 +133,14 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => { data-test-subj="agentPolicyDropdown" /> - {selectedAgentPolicyId && !isFleetServerPolicy && ( - + <> + + + )} {props.withKeySelection && props.onKeyChange && ( <> diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index 5a485af1300c3..e91eaf0bb0569 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -36,7 +36,6 @@ import { migratePackagePolicyToV7140, migrateInstallationToV7140 } from './migra import { migratePackagePolicyToV7150 } from './migrations/to_v7_15_0'; import { migrateInstallationToV7160, migratePackagePolicyToV7160 } from './migrations/to_v7_16_0'; import { migrateInstallationToV800, migrateOutputToV800 } from './migrations/to_v8_0_0'; -import { migrateAgentPolicyToV810 } from './migrations/to_v8_1_0'; /* * Saved object types and mappings @@ -79,6 +78,8 @@ const getSavedObjectTypes = ( description: { type: 'text' }, namespace: { type: 'keyword' }, is_managed: { type: 'boolean' }, + is_default: { type: 'boolean' }, + is_default_fleet_server: { type: 'boolean' }, status: { type: 'keyword' }, package_policies: { type: 'keyword' }, unenroll_timeout: { type: 'integer' }, @@ -94,7 +95,6 @@ const getSavedObjectTypes = ( migrations: { '7.10.0': migrateAgentPolicyToV7100, '7.12.0': migrateAgentPolicyToV7120, - '8.1.0': migrateAgentPolicyToV810, }, }, [OUTPUT_SAVED_OBJECT_TYPE]: { diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_1_0.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_1_0.ts deleted file mode 100644 index 42ce665c3d788..0000000000000 --- a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_1_0.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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 type { SavedObjectMigrationFn } from 'kibana/server'; - -import type { AgentPolicy } from '../../types'; - -export const migrateAgentPolicyToV810: SavedObjectMigrationFn = ( - agentPolicyDoc -) => { - delete agentPolicyDoc.attributes.is_default; - delete agentPolicyDoc.attributes.is_default_fleet_server; - - return agentPolicyDoc; -}; diff --git a/x-pack/plugins/fleet/server/services/agent_policy.test.ts b/x-pack/plugins/fleet/server/services/agent_policy.test.ts index 77bd67a63512b..11d710e9e2b3d 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.test.ts @@ -288,6 +288,7 @@ describe('agent policy', () => { body: expect.objectContaining({ '@timestamp': expect.anything(), data: { id: 'policy123', inputs: [{ id: 'input-123' }], revision: 1 }, + default_fleet_server: false, policy_id: 'policy123', revision_idx: 1, }), diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index f4674d9ee0b2b..2f7607490a753 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -616,6 +616,7 @@ class AgentPolicyService { coordinator_idx: 0, data: fullPolicy as unknown as FleetServerPolicy['data'], policy_id: fullPolicy.id, + default_fleet_server: policy.is_default_fleet_server === true, }; if (policy.unenroll_timeout) { diff --git a/x-pack/plugins/fleet/server/services/agent_policy_create.ts b/x-pack/plugins/fleet/server/services/agent_policy_create.ts index 177c851c91fc2..e6b464ff94cef 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy_create.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy_create.ts @@ -22,10 +22,11 @@ import { incrementPackageName } from './package_policy'; import { bulkInstallPackages } from './epm/packages'; import { ensureDefaultEnrollmentAPIKeysExists } from './setup'; +const FLEET_SERVER_POLICY_ID = 'fleet-server-policy'; + async function getAgentPolicyId(soClient: SavedObjectsClientContract): Promise { let agentPolicyId; // creating first fleet server policy with id 'fleet-server-policy' - const FLEET_SERVER_POLICY_ID = 'fleet-server-policy'; let agentPolicy; try { agentPolicy = await agentPolicyService.get(soClient, FLEET_SERVER_POLICY_ID, false); @@ -94,6 +95,10 @@ export async function createAgentPolicyWithPackages({ packagesToInstall.push(FLEET_SERVER_PACKAGE); agentPolicyId = await getAgentPolicyId(soClient); + if (agentPolicyId === FLEET_SERVER_POLICY_ID) { + // setting first fleet server policy to default, so that fleet server can enroll without setting policy_id + newPolicy.is_default_fleet_server = true; + } } if (withSysMonitoring) { packagesToInstall.push(FLEET_SYSTEM_PACKAGE); diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.ts b/x-pack/plugins/fleet/server/services/preconfiguration.ts index d0f828995f550..8593f753de738 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.ts @@ -226,10 +226,14 @@ export async function ensurePreconfiguredPackagesAndPolicies( if (wasDeleted) { return { created: false, deleted: preconfigurationId }; } - } else { + } else if ( + !preconfiguredAgentPolicy.is_default && + !preconfiguredAgentPolicy.is_default_fleet_server + ) { throw new Error( i18n.translate('xpack.fleet.preconfiguration.missingIDError', { - defaultMessage: '{agentPolicyName} is missing an `id` field. `id` is required.', + defaultMessage: + '{agentPolicyName} is missing an `id` field. `id` is required, except for policies marked is_default or is_default_fleet_server.', values: { agentPolicyName: preconfiguredAgentPolicy.name }, }) ); diff --git a/x-pack/plugins/fleet/server/types/models/agent_policy.ts b/x-pack/plugins/fleet/server/types/models/agent_policy.ts index 07cf439d62f9f..1aece7852d909 100644 --- a/x-pack/plugins/fleet/server/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/server/types/models/agent_policy.ts @@ -17,6 +17,8 @@ export const AgentPolicyBaseSchema = { description: schema.maybe(schema.string()), is_managed: schema.maybe(schema.boolean()), has_fleet_server: schema.maybe(schema.boolean()), + is_default: schema.maybe(schema.boolean()), + is_default_fleet_server: schema.maybe(schema.boolean()), unenroll_timeout: schema.maybe(schema.number({ min: 0 })), monitoring_enabled: schema.maybe( schema.arrayOf( diff --git a/x-pack/test/functional/es_archives/fleet/agents/mappings.json b/x-pack/test/functional/es_archives/fleet/agents/mappings.json index bf0ecb43232fc..1f2df04713c4b 100644 --- a/x-pack/test/functional/es_archives/fleet/agents/mappings.json +++ b/x-pack/test/functional/es_archives/fleet/agents/mappings.json @@ -3393,6 +3393,9 @@ "enabled": false, "type": "object" }, + "default_fleet_server": { + "type": "boolean" + }, "policy_id": { "type": "keyword" }, diff --git a/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json b/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json index 9f7103ac42165..a04b7a7dc21c7 100644 --- a/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json +++ b/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json @@ -355,6 +355,9 @@ "enabled": false, "type": "object" }, + "default_fleet_server": { + "type": "boolean" + }, "policy_id": { "type": "keyword" }, From 0e5750fd8362210070237f9a7f2cffabfc6df6de Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 13 Jan 2022 13:13:46 +0100 Subject: [PATCH 57/99] added fleet server specific confirm message to delete policy modal --- .../components/agent_policy_advanced_fields.tsx | 6 +++++- .../components/agent_policy_delete_provider.tsx | 11 ++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx index 933cbc7e566c3..d26dc83084a20 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields.tsx @@ -27,6 +27,8 @@ import { useStartServices } from '../../../hooks'; import { AgentPolicyPackageBadge } from '../../../components'; +import { policyHasFleetServer } from '../../agents/services/has_fleet_server'; + import { AgentPolicyDeleteProvider } from './agent_policy_delete_provider'; import type { ValidationResults } from './agent_policy_validation'; @@ -290,7 +292,9 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent = defaultMessage="Existing data will not be deleted." /> - + {(deleteAgentPolicyPrompt) => { return ( React.ReactElement; + hasFleetServer: boolean; } export type DeleteAgentPolicy = (agentPolicy: string, onSuccess?: OnSuccessCallback) => void; type OnSuccessCallback = (agentPolicyDeleted: string) => void; -export const AgentPolicyDeleteProvider: React.FunctionComponent = ({ children }) => { +export const AgentPolicyDeleteProvider: React.FunctionComponent = ({ + children, + hasFleetServer, +}) => { const { notifications } = useStartServices(); const { agents: { enabled: isFleetEnabled }, @@ -165,6 +169,11 @@ export const AgentPolicyDeleteProvider: React.FunctionComponent = ({ chil }} /> + ) : hasFleetServer ? ( + ) : ( Date: Thu, 13 Jan 2022 15:32:01 +0100 Subject: [PATCH 58/99] added unit tests for agent_policy_create logic --- .../services/agent_policy_create.test.ts | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 x-pack/plugins/fleet/server/services/agent_policy_create.test.ts diff --git a/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts b/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts new file mode 100644 index 0000000000000..ce428948f352b --- /dev/null +++ b/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts @@ -0,0 +1,183 @@ +/* + * 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 { elasticsearchServiceMock, savedObjectsClientMock } from 'src/core/server/mocks'; + +import type { AgentPolicy, PackagePolicy } from '../types'; + +import { agentPolicyService, packagePolicyService } from '.'; +import { createAgentPolicyWithPackages } from './agent_policy_create'; +import { bulkInstallPackages } from './epm/packages'; +import { incrementPackageName } from './package_policy'; + +const mockedAgentPolicyService = agentPolicyService as jest.Mocked; +const mockedPackagePolicyService = packagePolicyService as jest.Mocked; +const mockIncrementPackageName = incrementPackageName as jest.MockedFunction< + typeof incrementPackageName +>; + +jest.mock('./epm/packages', () => { + return { + bulkInstallPackages: jest.fn(), + }; +}); + +const mockedBulkInstallPackages = bulkInstallPackages as jest.Mocked; + +jest.mock('./setup', () => { + return { + ensureDefaultEnrollmentAPIKeysExists: jest.fn(), + }; +}); + +jest.mock('./agent_policy'); +jest.mock('./package_policy'); + +function getPackagePolicy(name: string, policyId = '') { + return { + name, + namespace: 'default', + enabled: true, + policy_id: policyId, + output_id: '', + inputs: [], + }; +} + +describe('createAgentPolicyWithPackages', () => { + const esClientMock = elasticsearchServiceMock.createElasticsearchClient(); + const soClientMock = savedObjectsClientMock.create(); + + beforeEach(() => { + mockedAgentPolicyService.get.mockRejectedValue({ output: { statusCode: 404 }, isBoom: true }); + mockedAgentPolicyService.create.mockImplementation((soClient, esClient, newPolicy, options) => + Promise.resolve({ + ...newPolicy, + id: options?.id || 'new_id', + } as AgentPolicy) + ); + mockedAgentPolicyService.deployPolicy.mockResolvedValue(); + + mockedPackagePolicyService.buildPackagePolicyFromPackage.mockImplementation( + (soClient, packageToInstall) => Promise.resolve(getPackagePolicy(packageToInstall)) + ); + mockIncrementPackageName.mockImplementation((soClient: any, pkg: string) => + Promise.resolve(`${pkg}-1`) + ); + mockedPackagePolicyService.create.mockImplementation((soClient, esClient, newPolicy) => + Promise.resolve({ + ...newPolicy, + } as PackagePolicy) + ); + }); + it('should create policy with fleet_server, system and elastic_agent package - first one', async () => { + const response = await createAgentPolicyWithPackages({ + esClient: esClientMock, + soClient: soClientMock, + newPolicy: { name: 'Fleet Server policy', namespace: 'default' }, + hasFleetServer: true, + withSysMonitoring: true, + monitoringEnabled: ['logs', 'metrics'], + spaceId: 'default', + }); + + expect(response.id).toEqual('fleet-server-policy'); + expect(response.is_default_fleet_server).toBe(true); + expect(mockedBulkInstallPackages).toHaveBeenCalledWith({ + savedObjectsClient: soClientMock, + esClient: esClientMock, + packagesToInstall: ['fleet_server', 'system', 'elastic_agent'], + spaceId: 'default', + }); + expect(mockedPackagePolicyService.create).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + getPackagePolicy('system-1', 'fleet-server-policy'), + expect.anything() + ); + expect(mockedPackagePolicyService.create).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + getPackagePolicy('fleet_server-1', 'fleet-server-policy'), + expect.anything() + ); + }); + it('should create policy with fleet_server package', async () => { + mockedAgentPolicyService.get.mockResolvedValueOnce({} as AgentPolicy); + const response = await createAgentPolicyWithPackages({ + esClient: esClientMock, + soClient: soClientMock, + newPolicy: { name: 'Fleet Server policy 2', namespace: 'default' }, + hasFleetServer: true, + withSysMonitoring: false, + monitoringEnabled: [], + spaceId: 'default', + }); + + expect(response.id).toEqual('new_id'); + expect(mockedBulkInstallPackages).toHaveBeenCalledWith({ + savedObjectsClient: soClientMock, + esClient: esClientMock, + packagesToInstall: ['fleet_server'], + spaceId: 'default', + }); + expect(mockedPackagePolicyService.create).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + getPackagePolicy('fleet_server-1', 'new_id'), + expect.anything() + ); + }); + it('should create policy with system package', async () => { + const response = await createAgentPolicyWithPackages({ + esClient: esClientMock, + soClient: soClientMock, + newPolicy: { name: 'Agent policy 1', namespace: 'default' }, + withSysMonitoring: true, + spaceId: 'default', + }); + + expect(response.id).toEqual('new_id'); + expect(mockedBulkInstallPackages).toHaveBeenCalledWith({ + savedObjectsClient: soClientMock, + esClient: esClientMock, + packagesToInstall: ['system'], + spaceId: 'default', + }); + expect(mockedPackagePolicyService.create).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + getPackagePolicy('system-1', 'new_id'), + expect.anything() + ); + }); + + it('should create policy with system and elastic_agent package', async () => { + const response = await createAgentPolicyWithPackages({ + esClient: esClientMock, + soClient: soClientMock, + newPolicy: { name: 'Agent policy 1', namespace: 'default' }, + withSysMonitoring: true, + spaceId: 'default', + monitoringEnabled: ['logs'], + }); + + expect(response.id).toEqual('new_id'); + expect(mockedBulkInstallPackages).toHaveBeenCalledWith({ + savedObjectsClient: soClientMock, + esClient: esClientMock, + packagesToInstall: ['system', 'elastic_agent'], + spaceId: 'default', + }); + expect(mockedPackagePolicyService.create).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + getPackagePolicy('system-1', 'new_id'), + expect.anything() + ); + }); +}); From d1c5539b9adbd6c78e0af707ca13e84aae381181 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 13 Jan 2022 16:15:19 +0100 Subject: [PATCH 59/99] fixed condition to show fleet server instructions --- .../managed_instructions.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx index 51258325043f1..2f0aa744c8097 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx @@ -23,6 +23,8 @@ import { } from '../../applications/fleet/sections/agents/agent_requirements_page/components'; import { FleetServerRequirementPage } from '../../applications/fleet/sections/agents/agent_requirements_page'; +import { policyHasFleetServer } from '../../applications/fleet/sections/agents/services/has_fleet_server'; + import { DownloadStep, AgentPolicySelectionStep, AgentEnrollmentKeySelectionStep } from './steps'; import type { BaseProps } from './types'; @@ -77,6 +79,15 @@ export const ManagedInstructions = React.memo( showInactive: false, }); + const fleetServers = useMemo(() => { + const fleetServerAgentPolicies: string[] = (agentPolicies || []) + .filter((pol) => policyHasFleetServer(pol)) + .map((pol) => pol.id); + return (agents?.items || []).filter((agent) => + fleetServerAgentPolicies.includes(agent.policy_id || '') + ); + }, [agents, agentPolicies]); + const fleetServerSteps = useMemo(() => { const { serviceToken, @@ -147,7 +158,7 @@ export const ManagedInstructions = React.memo( return null; } - if (fleetStatus.isReady && agents && agents.items.length > 0) { + if (fleetStatus.isReady && fleetServers.length > 0) { return ( <> @@ -166,8 +177,7 @@ export const ManagedInstructions = React.memo( <> {(fleetStatus.missingRequirements?.length === 1 && fleetStatus.missingRequirements[0] === 'fleet_server') || - !agents || - agents.items.length === 0 ? ( + fleetServers.length === 0 ? ( ) : ( From 41a4c4d8f055f916ba77bdab38dd61e1ab24e09f Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 13 Jan 2022 17:34:18 +0100 Subject: [PATCH 60/99] fixed tests --- .../components/fleet_server_on_prem_instructions.tsx | 7 +------ .../agent_enrollment_flyout.test.mocks.ts | 4 ++++ .../agent_enrollment_flyout.test.tsx | 10 ++++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index c569adee10595..220ebbd0d340a 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -236,7 +236,7 @@ export const FleetServerCommandStep = ({ }; export const useFleetServerInstructions = (policyId?: string) => { - const { output, refresh: refreshOutputs } = useDefaultOutput(); + const { output } = useDefaultOutput(); const { notifications } = useStartServices(); const [serviceToken, setServiceToken] = useState(); const [isLoadingServiceToken, setIsLoadingServiceToken] = useState(false); @@ -289,10 +289,6 @@ export const useFleetServerInstructions = (policyId?: string) => { setIsLoadingServiceToken(false); }, [notifications.toasts]); - const refresh = useCallback(() => { - return Promise.all([refreshOutputs(), refreshSettings()]); - }, [refreshOutputs, refreshSettings]); - const addFleetServerHost = useCallback( async (host: string) => { const res = await sendPutSettings({ @@ -317,7 +313,6 @@ export const useFleetServerInstructions = (policyId?: string) => { installCommand, platform, setPlatform, - refresh, }; }; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts index d078461b4ed9b..79cfb7ff2b2d1 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts @@ -63,3 +63,7 @@ jest.mock('@elastic/eui', () => { EuiSteps: 'eui-steps', }; }); + +jest.mock('../../applications/fleet/sections/agents/services/has_fleet_server', () => { + return { policyHasFleetServer: jest.fn().mockReturnValue(true) }; +}); diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx index 68032b09bce89..0e6138aea7cb4 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx @@ -98,12 +98,12 @@ describe('', () => { }); (useGetAgents as jest.Mock).mockReturnValue({ - data: { items: [{}] }, + data: { items: [{ policy_id: 'fleet-server-policy' }] }, }); await act(async () => { testBed = await setup({ - agentPolicies: [], + agentPolicies: [{ id: 'fleet-server-policy' } as AgentPolicy], onClose: jest.fn(), }); testBed.component.update(); @@ -127,6 +127,7 @@ describe('', () => { jest.clearAllMocks(); await act(async () => { testBed = await setup({ + agentPolicies: [{ id: 'fleet-server-policy' } as AgentPolicy], agentPolicy: testAgentPolicy, onClose: jest.fn(), }); @@ -148,7 +149,7 @@ describe('', () => { jest.clearAllMocks(); await act(async () => { testBed = await setup({ - agentPolicies: [], + agentPolicies: [{ id: 'fleet-server-policy' } as AgentPolicy], onClose: jest.fn(), viewDataStep: { title: 'View Data', children:
}, }); @@ -168,7 +169,7 @@ describe('', () => { jest.clearAllMocks(); await act(async () => { testBed = await setup({ - agentPolicies: [], + agentPolicies: [{ id: 'fleet-server-policy' } as AgentPolicy], onClose: jest.fn(), viewDataStep: undefined, }); @@ -199,6 +200,7 @@ describe('', () => { jest.clearAllMocks(); await act(async () => { testBed = await setup({ + agentPolicies: [{ id: 'fleet-server-policy' } as AgentPolicy], agentPolicy: testAgentPolicy, onClose: jest.fn(), }); From 5d318adf9e8653b84a8c0d12c63e365799ec2713 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 13 Jan 2022 17:58:27 +0100 Subject: [PATCH 61/99] fixed jumping --- .../agent_enrollment_flyout/managed_instructions.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx index 2f0aa744c8097..a150ac258c692 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx @@ -73,7 +73,7 @@ export const ManagedInstructions = React.memo( const apiKey = useGetOneEnrollmentAPIKey(selectedApiKeyId); const fleetServerInstructions = useFleetServerInstructions(apiKey?.data?.item?.policy_id); - const { data: agents } = useGetAgents({ + const { data: agents, isLoading: isLoadingAgents } = useGetAgents({ page: 1, perPage: 1000, showInactive: false, @@ -158,7 +158,7 @@ export const ManagedInstructions = React.memo( return null; } - if (fleetStatus.isReady && fleetServers.length > 0) { + if (fleetStatus.isReady && (isLoadingAgents || fleetServers.length > 0)) { return ( <> From fdf99198d648623e6bf7ae2ebf02165894e55fd3 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 14 Jan 2022 11:20:13 +0100 Subject: [PATCH 62/99] fixed bug where add integration stayed invalid when going back to new hosts tab --- .../sections/agent_policy/create_package_policy_page/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index e60c4c1feb34e..079bfd2d96bbc 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -193,7 +193,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { setFormState('VALID'); } } else { - setFormState('INVALID'); + setHasAgentPolicyError(true); setAgentPolicy(undefined); } From d08c0fc89be9587d9cf3919cb0f844eb8f6aa9d0 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 14 Jan 2022 11:37:46 +0100 Subject: [PATCH 63/99] fix tests --- .../server/integration_tests/reset_preconfiguration.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts b/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts index 4096035f840e0..53fd7b5fae6b1 100644 --- a/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts @@ -32,7 +32,7 @@ const waitForFleetSetup = async (root: Root) => { } }; -describe('Fleet preconfiguration rest', () => { +describe('Fleet preconfiguration reset', () => { let esServer: kbnTestServer.TestElasticsearchUtils; let kbnServer: kbnTestServer.TestKibanaUtils; @@ -53,6 +53,10 @@ describe('Fleet preconfiguration rest', () => { { xpack: { fleet: { + packages: { + name: 'fleet-server', + version: 'latest', + }, agentPolicies: [ { name: 'Elastic Cloud agent policy 0001', From f4ed7272fe918780ff45ab487168ed70234ec93e Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 14 Jan 2022 12:47:46 +0100 Subject: [PATCH 64/99] fix tests --- .../integration_tests/reset_preconfiguration.test.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts b/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts index 53fd7b5fae6b1..68a28bc859acc 100644 --- a/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts @@ -53,10 +53,12 @@ describe('Fleet preconfiguration reset', () => { { xpack: { fleet: { - packages: { - name: 'fleet-server', - version: 'latest', - }, + packages: [ + { + name: 'fleet-server', + version: 'latest', + }, + ], agentPolicies: [ { name: 'Elastic Cloud agent policy 0001', From e39794a5d0ad9f1f7f04819c2b8e1da20bcbd1ee Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 14 Jan 2022 13:03:33 +0100 Subject: [PATCH 65/99] show invalid if policy not selected --- .../agent_enrollment_flyout/agent_policy_selection.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx index 84f4dd9a9aff6..5aba299d7dd61 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx @@ -131,6 +131,7 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => { )} hasNoInitialSelection={agentPolicies.length > 1} data-test-subj="agentPolicyDropdown" + isInvalid={!selectedAgentPolicyId} /> {selectedAgentPolicyId && !isFleetServerPolicy && ( From d1f67a21e0812a4cc39ffcd7929ed7c214b0ce62 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 14 Jan 2022 13:27:40 +0100 Subject: [PATCH 66/99] add missing texts --- .../components/agent_policy_create_inline.tsx | 2 +- .../agent_policy_selection.tsx | 36 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index 0f8915fc7fe2f..0ca39c522bc0f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -95,7 +95,7 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ {isFleetServerPolicy ? ( ) : ( = (props) => { return ( <> + + {isFleetServerPolicy ? ( + + ) : ( + + + + ), + }} + /> + )} + Date: Fri, 14 Jan 2022 14:08:46 +0100 Subject: [PATCH 67/99] fix radio groups when fleet server instructions are rendered twice --- .../fleet_server_on_prem_instructions.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index 220ebbd0d340a..4b23e1233884d 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -565,13 +565,17 @@ const DeploymentModeStepContent = ({ }) => { const onChangeCallback = useCallback( (v: string) => { - if (v === 'production' || v === 'quickstart') { - setDeploymentMode(v); + const value = v.split('_')[0]; + if (value === 'production' || value === 'quickstart') { + setDeploymentMode(value); } }, [setDeploymentMode] ); + // radio id has to be unique so that the component works even if appears twice in DOM (Agents tab, Add agent flyout) + const radioSuffix = useMemo(() => Date.now(), []); + return ( <> @@ -584,7 +588,7 @@ const DeploymentModeStepContent = ({ ); From cf2444cd66cde847297e49542681389913ed552e Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 14 Jan 2022 15:25:20 +0100 Subject: [PATCH 68/99] fix test, fixed bug where fleet server policy was not filtered out --- .../fleet_server_on_prem_instructions.tsx | 16 ++++------------ .../applications/fleet/sections/agents/index.tsx | 1 + .../reset_preconfiguration.test.ts | 2 +- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index 4b23e1233884d..c3f532da862ed 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -43,10 +43,11 @@ import { useLink, } from '../../../../hooks'; import type { PLATFORM_TYPE } from '../../../../hooks'; -import type { AgentPolicy, PackagePolicy } from '../../../../types'; -import { FLEET_SERVER_PACKAGE } from '../../../../constants'; +import type { AgentPolicy } from '../../../../types'; import { FleetServerOnPremRequiredCallout } from '../../components'; +import { policyHasFleetServer } from '../../services/has_fleet_server'; + import { getInstallCommandForPlatform } from './install_command_utils'; const URL_REGEX = /^(https?):\/\/[^\s$.?#].[^\s]*$/gm; @@ -326,16 +327,7 @@ const AgentPolicySelectionStep = ({ const { data, resendRequest: refreshAgentPolicies } = useGetAgentPolicies({ full: true }); const agentPolicies = useMemo( - () => - data - ? data.items.filter((item) => { - return item.package_policies.some( - (p: string | PackagePolicy) => - (p as PackagePolicy).package?.name === FLEET_SERVER_PACKAGE - ); - return false; - }) - : [], + () => (data ? data.items.filter((item) => policyHasFleetServer(item)) : []), [data] ); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/index.tsx index 5c6de6e25609e..2ae60faf3c994 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/index.tsx @@ -37,6 +37,7 @@ export const AgentsApp: React.FunctionComponent = () => { const agentPoliciesRequest = useGetAgentPolicies({ page: 1, perPage: 1000, + full: true, }); const agentPolicies = useMemo( diff --git a/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts b/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts index fb171d0246835..7f881a7f2afe2 100644 --- a/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts @@ -55,7 +55,7 @@ describe('Fleet preconfiguration reset', () => { fleet: { packages: [ { - name: 'fleet-server', + name: 'fleet_server', version: 'latest', }, ], From 34caeddc15653a949d2e8e951d1a2e98b096076e Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 14 Jan 2022 16:02:33 +0100 Subject: [PATCH 69/99] fixed add integration from agent policy --- .../agent_policy/create_package_policy_page/index.tsx | 2 ++ .../create_package_policy_page/step_select_agent_policy.tsx | 5 ++++- .../create_package_policy_page/step_select_hosts.tsx | 5 ++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index 079bfd2d96bbc..9b77d5c8d739e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -506,6 +506,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { setHasAgentPolicyError={setHasAgentPolicyError} updateSelectedTab={updateSelectedPolicy} onNewAgentPolicyCreate={handleInlineAgentPolicyCreate} + selectedAgentPolicyId={queryParamsPolicyId} /> ), [ @@ -518,6 +519,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { withSysMonitoring, updateSelectedPolicy, handleInlineAgentPolicyCreate, + queryParamsPolicyId, ] ); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx index b701fc28f83b4..270f8404ffd7f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx @@ -45,12 +45,14 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ updateAgentPolicy: (agentPolicy: AgentPolicy | undefined) => void; setHasAgentPolicyError: (hasError: boolean) => void; onNewAgentPolicyCreate: () => void; + selectedAgentPolicyId?: string; }> = ({ packageInfo, agentPolicy, updateAgentPolicy, setHasAgentPolicyError, onNewAgentPolicyCreate, + selectedAgentPolicyId, }) => { const { isReady: isFleetReady } = useFleetStatus(); @@ -88,7 +90,8 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ // Selected agent policy state const [selectedPolicyId, setSelectedPolicyId] = useState( - agentPolicy?.id ?? (agentPolicies.length === 1 ? agentPolicies[0].id : undefined) + agentPolicy?.id ?? + (selectedAgentPolicyId || (agentPolicies.length === 1 ? agentPolicies[0].id : undefined)) ); const doesAgentPolicyHaveLimitedPackage = useCallback( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx index b08190f0ef771..c04289a9d6262 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -42,6 +42,7 @@ interface Props { setHasAgentPolicyError: (hasError: boolean) => void; updateSelectedTab: (tab: SelectedPolicyTab) => void; onNewAgentPolicyCreate: () => void; + selectedAgentPolicyId?: string; } export const StepSelectHosts: React.FunctionComponent = ({ @@ -56,6 +57,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ setHasAgentPolicyError, updateSelectedTab, onNewAgentPolicyCreate, + selectedAgentPolicyId, }) => { let agentPolicies: AgentPolicy[] = []; const { data: agentPoliciesData, error: err } = useGetAgentPolicies({ @@ -107,6 +109,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ updateAgentPolicy={updateAgentPolicy} setHasAgentPolicyError={setHasAgentPolicyError} onNewAgentPolicyCreate={onNewAgentPolicyCreate} + selectedAgentPolicyId={selectedAgentPolicyId} /> ), }, @@ -117,7 +120,7 @@ export const StepSelectHosts: React.FunctionComponent = ({ return agentPolicies.length > 0 ? ( From 8bae9a5c85ba11df29f80d8d4b8be36ea8b12be9 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Fri, 14 Jan 2022 16:26:21 +0100 Subject: [PATCH 70/99] fixed add integration to agent policy navigation --- .../agent_policy/create_package_policy_page/index.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index 9b77d5c8d739e..dbb328144c575 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -162,7 +162,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { inputs: [], }); - const [wasNewAgentPolicyCreated, setWasNewAgentPolicyCreated] = useState(false); + const [wasAgentPolicyChanged, setWasAgentPolicyChanged] = useState(false); // Validation state const [validationResults, setValidationResults] = useState(); @@ -189,6 +189,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { (updatedAgentPolicy: AgentPolicy | undefined) => { if (updatedAgentPolicy) { setAgentPolicy(updatedAgentPolicy); + setWasAgentPolicyChanged(true); if (packageInfo) { setFormState('VALID'); } @@ -337,7 +338,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { const doOnSaveNavigation = useRef(true); const handleInlineAgentPolicyCreate = useCallback(() => { - setWasNewAgentPolicyCreated(true); + setWasAgentPolicyChanged(true); }, []); // Detect if user left page @@ -368,7 +369,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { const pathWithQueryString = appendOnSaveQueryParamsToPath({ // In cases where we created a new agent policy inline, we need to override the initial `path` // value and navigate to the newly-created agent policy instead - path: wasNewAgentPolicyCreated ? packagePolicyPath : options.path, + path: wasAgentPolicyChanged ? packagePolicyPath : options.path, policy, mappingOptions: routeState.onSaveQueryParams, paramsToApply, @@ -381,7 +382,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { history.push(packagePolicyPath); } }, - [packagePolicy.policy_id, getPath, navigateToApp, history, routeState, wasNewAgentPolicyCreated] + [packagePolicy.policy_id, getPath, navigateToApp, history, routeState, wasAgentPolicyChanged] ); const onSubmit = useCallback(async () => { From 601d0ec50c15b85897bcb17f8ee79c70e6de0634 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 17 Jan 2022 10:06:35 +0100 Subject: [PATCH 71/99] fixed cypress --- .../create_package_policy_page/index.tsx | 26 +++++++------------ .../step_select_agent_policy.tsx | 3 --- .../step_select_hosts.tsx | 3 --- 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index dbb328144c575..d68765bfb734e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -148,7 +148,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { const [agentCount, setAgentCount] = useState(0); const [selectedPolicyTab, setSelectedPolicyTab] = useState( - SelectedPolicyTab.NEW + queryParamsPolicyId ? SelectedPolicyTab.EXISTING : SelectedPolicyTab.NEW ); // New package policy state @@ -162,8 +162,6 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { inputs: [], }); - const [wasAgentPolicyChanged, setWasAgentPolicyChanged] = useState(false); - // Validation state const [validationResults, setValidationResults] = useState(); const [hasAgentPolicyError, setHasAgentPolicyError] = useState(false); @@ -189,7 +187,6 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { (updatedAgentPolicy: AgentPolicy | undefined) => { if (updatedAgentPolicy) { setAgentPolicy(updatedAgentPolicy); - setWasAgentPolicyChanged(true); if (packageInfo) { setFormState('VALID'); } @@ -337,10 +334,6 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { ); const doOnSaveNavigation = useRef(true); - const handleInlineAgentPolicyCreate = useCallback(() => { - setWasAgentPolicyChanged(true); - }, []); - // Detect if user left page useEffect(() => { return () => { @@ -367,9 +360,9 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { if (options?.path) { const pathWithQueryString = appendOnSaveQueryParamsToPath({ - // In cases where we created a new agent policy inline, we need to override the initial `path` - // value and navigate to the newly-created agent policy instead - path: wasAgentPolicyChanged ? packagePolicyPath : options.path, + // In cases where we want to navigate back to a new/existing policy, we need to override the initial `path` + // value and navigate to the actual agent policy instead + path: queryParamsPolicyId ? packagePolicyPath : options.path, policy, mappingOptions: routeState.onSaveQueryParams, paramsToApply, @@ -382,7 +375,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { history.push(packagePolicyPath); } }, - [packagePolicy.policy_id, getPath, navigateToApp, history, routeState, wasAgentPolicyChanged] + [packagePolicy.policy_id, getPath, navigateToApp, history, routeState, queryParamsPolicyId] ); const onSubmit = useCallback(async () => { @@ -400,8 +393,10 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { try { setFormState('LOADING'); const resp = await sendCreateAgentPolicy(newAgentPolicy, { withSysMonitoring }); - setFormState('VALID'); - if (resp.error) throw resp.error; + if (resp.error) { + setFormState('VALID'); + throw resp.error; + } if (resp.data) { policyId = resp.data.item.id; setAgentPolicy(resp.data.item); @@ -418,6 +413,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { } } + setFormState('LOADING'); // passing pkgPolicy with policy_id here as setPackagePolicy doesn't propagate immediately const { error, data } = await savePackagePolicy({ ...packagePolicy, @@ -506,7 +502,6 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { packageInfo={packageInfo} setHasAgentPolicyError={setHasAgentPolicyError} updateSelectedTab={updateSelectedPolicy} - onNewAgentPolicyCreate={handleInlineAgentPolicyCreate} selectedAgentPolicyId={queryParamsPolicyId} /> ), @@ -519,7 +514,6 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { validation, withSysMonitoring, updateSelectedPolicy, - handleInlineAgentPolicyCreate, queryParamsPolicyId, ] ); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx index 270f8404ffd7f..0874b026f0b27 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx @@ -44,14 +44,12 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ agentPolicy: AgentPolicy | undefined; updateAgentPolicy: (agentPolicy: AgentPolicy | undefined) => void; setHasAgentPolicyError: (hasError: boolean) => void; - onNewAgentPolicyCreate: () => void; selectedAgentPolicyId?: string; }> = ({ packageInfo, agentPolicy, updateAgentPolicy, setHasAgentPolicyError, - onNewAgentPolicyCreate, selectedAgentPolicyId, }) => { const { isReady: isFleetReady } = useFleetStatus(); @@ -180,7 +178,6 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ onClose={(newAgentPolicy?: AgentPolicy) => { setIsCreateAgentPolicyFlyoutOpen(false); if (newAgentPolicy) { - onNewAgentPolicyCreate(); refreshAgentPolicies(); setSelectedPolicyId(newAgentPolicy.id); } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx index c04289a9d6262..5e454a51ea3a8 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_hosts.tsx @@ -41,7 +41,6 @@ interface Props { packageInfo?: PackageInfo; setHasAgentPolicyError: (hasError: boolean) => void; updateSelectedTab: (tab: SelectedPolicyTab) => void; - onNewAgentPolicyCreate: () => void; selectedAgentPolicyId?: string; } @@ -56,7 +55,6 @@ export const StepSelectHosts: React.FunctionComponent = ({ packageInfo, setHasAgentPolicyError, updateSelectedTab, - onNewAgentPolicyCreate, selectedAgentPolicyId, }) => { let agentPolicies: AgentPolicy[] = []; @@ -108,7 +106,6 @@ export const StepSelectHosts: React.FunctionComponent = ({ agentPolicy={agentPolicy} updateAgentPolicy={updateAgentPolicy} setHasAgentPolicyError={setHasAgentPolicyError} - onNewAgentPolicyCreate={onNewAgentPolicyCreate} selectedAgentPolicyId={selectedAgentPolicyId} /> ), From 3d9c044d57beaa0f2ae3a994f61a38c974d33550 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 17 Jan 2022 11:03:28 +0100 Subject: [PATCH 72/99] added cypress test for policy add integration --- .../cypress/integration/fleet_startup.spec.ts | 2 +- .../cypress/integration/integrations.spec.ts | 21 +++++++++++++++++++ .../fleet/cypress/tasks/integrations.ts | 21 +++++++------------ .../package_policies/no_package_policies.tsx | 1 + .../package_policies_table.tsx | 1 + 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 68bc5e6669d49..608af9e47ab12 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -85,7 +85,7 @@ describe('Fleet startup', () => { cy.getBySel('createPolicyBtn').click(); - let agentPolicyId; + let agentPolicyId: string; const startTime = Date.now(); cy.wait('@createAgentPolicy', { timeout: 180000 }).then((xhr: any) => { cy.log('Create agent policy took: ' + (Date.now() - startTime) / 1000 + ' s'); diff --git a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts index 9124b6a8aa36e..022ed66089648 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts @@ -50,6 +50,27 @@ describe('Add Integration', () => { .each((el) => el.text().includes('Agent policy 1')); }); + it('should add integration to policy', () => { + cy.request('/api/fleet/agent_policies').then((response: any) => { + const agentPolicyId = response.body.items + .filter((policy: any) => policy.name === 'Agent policy 1') + .map((policy: any) => policy.id); + + cy.visit(`/app/fleet/policies/${agentPolicyId}`); + cy.intercept('GET', '/api/fleet/epm/packages?*').as('packages'); + cy.getBySel('addPackagePolicyButton').click(); + cy.wait('@packages'); + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.get('input[placeholder="Search for integrations"]').type('Apache'); + cy.get(INTEGRATIONS_CARD).contains(integration).click(); + addIntegration(); + cy.get('.euiBasicTable-loading').should('not.exist'); + cy.get('.euiTitle').contains('Agent policy 1'); + clickIfVisible(FLYOUT_CLOSE_BTN_SEL); + cy.get('.euiLink').contains('apache-1'); + }); + }); + it('should upgrade policies with integration update', () => { const oldVersion = '0.3.3'; installPackageWithVersion('apache', oldVersion); diff --git a/x-pack/plugins/fleet/cypress/tasks/integrations.ts b/x-pack/plugins/fleet/cypress/tasks/integrations.ts index 23f16b33d0303..665117bb8090e 100644 --- a/x-pack/plugins/fleet/cypress/tasks/integrations.ts +++ b/x-pack/plugins/fleet/cypress/tasks/integrations.ts @@ -10,7 +10,6 @@ import { CONFIRM_MODAL_BTN, CREATE_PACKAGE_POLICY_SAVE_BTN, FLYOUT_CLOSE_BTN_SEL, - INTEGRATION_NAME_LINK, } from '../screens/integrations'; export const addIntegration = ({ useExistingPolicy } = { useExistingPolicy: false }) => { @@ -36,19 +35,15 @@ export function clickIfVisible(selector: string) { export const deleteIntegrations = async (integration: string) => { const ids: string[] = []; - cy.getBySel(INTEGRATION_NAME_LINK) - .each(($a) => { - const href = $a.attr('href') as string; - ids.push(href.substr(href.lastIndexOf('/') + 1)); - }) - .then(() => { - cy.request({ - url: `/api/fleet/package_policies/delete`, - headers: { 'kbn-xsrf': 'cypress' }, - body: `{ "packagePolicyIds": ${JSON.stringify(ids)} }`, - method: 'POST', - }); + cy.request('/api/fleet/package_policies').then((response: any) => { + response.body.items.forEach((policy: any) => ids.push(policy.id)); + cy.request({ + url: `/api/fleet/package_policies/delete`, + headers: { 'kbn-xsrf': 'cypress' }, + body: `{ "packagePolicyIds": ${JSON.stringify(ids)} }`, + method: 'POST', }); + }); }; export const installPackageWithVersion = (integration: string, version: string) => { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/no_package_policies.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/no_package_policies.tsx index dede1dc905f85..98017d0c98b9d 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/no_package_policies.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/no_package_policies.tsx @@ -43,6 +43,7 @@ export const NoPackagePolicies = memo<{ policyId: string }>(({ policyId }) => { state: { forAgentPolicyId: policyId }, }) } + data-test-subj="addPackagePolicyButton" > = ({ state: { forAgentPolicyId: agentPolicy.id }, }); }} + data-test-subj="addPackagePolicyButton" > Date: Mon, 17 Jan 2022 14:48:38 +0100 Subject: [PATCH 73/99] added cypress test for upgrade integration without policy and upgrade integration policy --- .../cypress/integration/integrations.spec.ts | 54 +++++++++++++++---- .../components/package_policy_input_panel.tsx | 2 +- .../package_policy_input_stream.tsx | 2 + .../detail/policies/package_policies.tsx | 1 + 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts index 022ed66089648..57701c98cb21f 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts @@ -33,6 +33,17 @@ describe('Add Integration', () => { cleanupAgentPolicies(); }); + function addAndVerifyIntegration() { + cy.intercept('GET', '/api/fleet/epm/packages?*').as('packages'); + navigateTo(INTEGRATIONS); + cy.wait('@packages'); + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.get('input[placeholder="Search for integrations"]').type('Apache'); + cy.get(INTEGRATIONS_CARD).contains(integration).click(); + addIntegration(); + cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-1'); + } + describe('Real API', () => { afterEach(() => { deleteIntegrations(integration); @@ -95,16 +106,37 @@ describe('Add Integration', () => { cy.getBySel(PACKAGE_VERSION).contains(newVersion); }); }); - }); - function addAndVerifyIntegration() { - cy.intercept('GET', '/api/fleet/epm/packages?*').as('packages'); - navigateTo(INTEGRATIONS); - cy.wait('@packages'); - cy.get('.euiLoadingSpinner').should('not.exist'); - cy.get('input[placeholder="Search for integrations"]').type('Apache'); - cy.get(INTEGRATIONS_CARD).contains(integration).click(); - addIntegration(); - cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-1'); - } + it('should upgrade policies without integration update', () => { + const oldVersion = '0.3.3'; + installPackageWithVersion('apache', oldVersion); + navigateTo(`app/integrations/detail/apache-${oldVersion}/policies`); + + addIntegration(); + + cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-'); + cy.getBySel(PACKAGE_VERSION).contains(oldVersion); + + clickIfVisible(FLYOUT_CLOSE_BTN_SEL); + + cy.getBySel(SETTINGS_TAB).click(); + cy.get('#upgradePoliciesCheckbox').uncheck({ force: true }); + + cy.getBySel(UPDATE_PACKAGE_BTN).click(); + + cy.getBySel(LATEST_VERSION).then(($title) => { + const newVersion = $title.text(); + cy.get('#upgradePoliciesCheckbox').should('not.exist'); + cy.getBySel('installedVersion').contains(newVersion); + cy.getBySel(POLICIES_TAB).click(); + cy.getBySel(PACKAGE_VERSION).contains(oldVersion); + + // upgrade integration policy + cy.getBySel('integrationPolicyUpgradeBtn').click(); + cy.getBySel('saveIntegration').click(); + cy.getBySel('saveIntegration').should('not.exist'); + cy.getBySel(PACKAGE_VERSION).contains(newVersion); + }); + }); + }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/package_policy_input_panel.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/package_policy_input_panel.tsx index e8366a38c0c60..4883972c455d5 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/package_policy_input_panel.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/package_policy_input_panel.tsx @@ -83,7 +83,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{ ); // Errors state - const errorCount = countValidationErrors(inputValidationResults); + const errorCount = inputValidationResults && countValidationErrors(inputValidationResults); const hasErrors = forceShowErrors && errorCount; const hasInputStreams = useMemo( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/package_policy_input_stream.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/package_policy_input_stream.tsx index 8e7dda174f363..a428c43cedd0e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/package_policy_input_stream.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/package_policy_input_stream.tsx @@ -106,6 +106,7 @@ export const PackagePolicyInputStreamConfig: React.FunctionComponent<{ {requiredVars.map((varDef) => { + if (!packagePolicyInputStream.vars) return null; const { name: varName, type: varType } = varDef; const { value, frozen } = packagePolicyInputStream.vars![varName]; return ( @@ -163,6 +164,7 @@ export const PackagePolicyInputStreamConfig: React.FunctionComponent<{ {isShowingAdvanced ? advancedVars.map((varDef) => { + if (!packagePolicyInputStream.vars) return null; const { name: varName, type: varType } = varDef; const value = packagePolicyInputStream.vars![varName].value; return ( diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx index c4f06d4d7d5ab..ca09c7075fbab 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx @@ -244,6 +244,7 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps policyId: agentPolicy.id, packagePolicyId: packagePolicy.id, })}?from=integrations-policy-list`} + data-test-subj="integrationPolicyUpgradeBtn" > Date: Tue, 18 Jan 2022 14:05:29 +0100 Subject: [PATCH 74/99] added unit test for policy select empty default --- .../public/applications/fleet/hooks/index.ts | 2 +- .../step_select_agent_policy.test.tsx | 91 +++++++++++++++++++ .../step_select_agent_policy.tsx | 1 + .../agent_policy_selection.test.tsx | 64 +++++++++++++ 4 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.test.tsx create mode 100644 x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.test.tsx diff --git a/x-pack/plugins/fleet/public/applications/fleet/hooks/index.ts b/x-pack/plugins/fleet/public/applications/fleet/hooks/index.ts index 7cf16b1b7ae90..63438170c7faf 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/hooks/index.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/hooks/index.ts @@ -7,4 +7,4 @@ export * from '../../../hooks'; -export { useBreadcrumbs } from './use_breadcrumbs'; +export * from './use_breadcrumbs'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.test.tsx new file mode 100644 index 0000000000000..9ef31b596e652 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.test.tsx @@ -0,0 +1,91 @@ +/* + * 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 React from 'react'; +import { act } from '@testing-library/react'; + +import type { TestRenderer } from '../../../../../mock'; +import { createFleetTestRendererMock } from '../../../../../mock'; + +import { useGetAgentPolicies } from '../../../hooks'; + +import { StepSelectAgentPolicy } from './step_select_agent_policy'; + +jest.mock('../../../hooks', () => { + return { + ...jest.requireActual('../../../hooks'), + useGetAgentPolicies: jest.fn(), + useFleetStatus: jest.fn().mockReturnValue({ isReady: true } as any), + sendGetFleetStatus: jest + .fn() + .mockResolvedValue({ data: { isReady: true, missing_requirements: [] } }), + }; +}); + +const useGetAgentPoliciesMock = useGetAgentPolicies as jest.MockedFunction< + typeof useGetAgentPolicies +>; + +describe('step select agent policy', () => { + let testRenderer: TestRenderer; + let renderResult: ReturnType; + const mockSetHasAgentPolicyError = jest.fn(); + const render = () => + (renderResult = testRenderer.render( + + )); + + beforeEach(() => { + testRenderer = createFleetTestRendererMock(); + }); + + test('should not select agent policy by default if multiple exists', async () => { + useGetAgentPoliciesMock.mockReturnValueOnce({ + data: { + items: [ + { id: 'policy-1', name: 'Policy 1' }, + { id: 'policy-2', name: 'Policy 2' }, + ], + }, + error: undefined, + isLoading: false, + resendRequest: jest.fn(), + } as any); + + render(); + + await act(async () => { + const select = renderResult.container.querySelector('[data-test-subj="agentPolicySelect"]'); + expect((select as any)?.value).toEqual(''); + + expect(renderResult.getAllByRole('option').length).toBe(2); + expect(renderResult.getByText('An agent policy is required.')).toBeVisible(); + }); + }); + + test('should select agent policy by default if one exists', async () => { + useGetAgentPoliciesMock.mockReturnValueOnce({ + data: { items: [{ id: 'policy-1', name: 'Policy 1' }] }, + error: undefined, + isLoading: false, + resendRequest: jest.fn(), + } as any); + + render(); + + await act(async () => { + const select = renderResult.container.querySelector('[data-test-subj="agentPolicySelect"]'); + expect((select as any)?.value).toEqual('policy-1'); + }); + }); +}); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx index 0874b026f0b27..bf6639b1c4674 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx @@ -281,6 +281,7 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ options={agentPolicyOptions} value={selectedPolicyId || undefined} onChange={(e) => setSelectedPolicyId(e.target.value)} + data-test-subj="agentPolicySelect" /> diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.test.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.test.tsx new file mode 100644 index 0000000000000..b84d101fdef5f --- /dev/null +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.test.tsx @@ -0,0 +1,64 @@ +/* + * 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 React from 'react'; +import { act } from '@testing-library/react'; + +import type { TestRenderer } from '../../mock'; +import { createFleetTestRendererMock } from '../../mock'; + +import type { AgentPolicy } from '../../types'; + +import { EnrollmentStepAgentPolicy } from '.'; + +describe('step select agent policy', () => { + let testRenderer: TestRenderer; + let renderResult: ReturnType; + let agentPolicies: AgentPolicy[] = []; + const render = () => + (renderResult = testRenderer.render( + + )); + + beforeEach(() => { + testRenderer = createFleetTestRendererMock(); + }); + + test('should not select agent policy by default if multiple exists', async () => { + agentPolicies = [ + { id: 'policy-1', name: 'Policy 1' } as AgentPolicy, + { id: 'policy-2', name: 'Policy 2' } as AgentPolicy, + ]; + + render(); + + await act(async () => { + const select = renderResult.container.querySelector('[data-test-subj="agentPolicyDropdown"]'); + expect((select as any)?.value).toEqual(''); + + expect(renderResult.getAllByRole('option').length).toBe(2); + }); + }); + + test('should select agent policy by default if one exists', async () => { + agentPolicies = [{ id: 'policy-1', name: 'Policy 1' } as AgentPolicy]; + + render(); + + await act(async () => { + const select = renderResult.container.querySelector('[data-test-subj="agentPolicyDropdown"]'); + expect((select as any)?.value).toEqual('policy-1'); + }); + }); +}); From 643d4aac64e2652647a1a746a0eda9d3867bd050 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 18 Jan 2022 14:57:12 +0100 Subject: [PATCH 75/99] added cypress test for update outputs, settings --- .../cypress/integration/fleet_startup.spec.ts | 81 +++++++++++++++++-- .../components/edit_output_flyout/index.tsx | 1 + .../fleet_server_hosts_flyout/index.tsx | 1 + .../components/outputs_table/index.tsx | 1 + .../settings_page/settings_section.tsx | 6 +- 5 files changed, 84 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 608af9e47ab12..f05b007fbabe8 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -6,14 +6,11 @@ */ import { AGENTS_TAB, AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; +import { CONFIRM_MODAL_BTN } from '../screens/integrations'; import { cleanupAgentPolicies, unenrollAgent } from '../tasks/cleanup'; import { FLEET, navigateTo } from '../tasks/navigation'; describe('Fleet startup', () => { - beforeEach(() => { - navigateTo(FLEET); - }); - function navigateToTab(tab: string) { cy.getBySel(tab).click(); cy.get('.euiBasicTable-loading').should('not.exist'); @@ -53,6 +50,7 @@ describe('Fleet startup', () => { // skipping Fleet Server enroll, to enable, comment out runner.ts line 23 describe.skip('Fleet Server', () => { it('should display Add agent button and Healthy agent once Fleet Agent page loaded', () => { + navigateTo(FLEET); cy.get('.euiBadge').contains('Healthy'); verifyPolicy('Fleet Server policy', ['Fleet Server']); @@ -69,7 +67,9 @@ describe('Fleet startup', () => { cleanupAgentPolicies(); }); - before(() => {}); + beforeEach(() => { + navigateTo(FLEET); + }); it('should have no agent policy by default', () => { cy.request('/api/fleet/agent_policies?full=true').then((response: any) => { @@ -125,4 +125,75 @@ describe('Fleet startup', () => { cy.get('.euiCodeBlock__code').contains('--fleet-server-policy=fleet-server-policy'); }); }); + + describe('Edit settings', () => { + beforeEach(() => { + cy.intercept('/api/fleet/settings', { + item: { id: 'fleet-default-settings', fleet_server_hosts: [] }, + }); + cy.intercept('/api/fleet/outputs', { + items: [ + { + id: 'fleet-default-output', + name: 'default', + type: 'elasticsearch', + is_default: true, + is_default_monitoring: true, + }, + ], + }); + + cy.visit('/app/fleet/settings'); + cy.getBySel('toastCloseButton').click(); + }); + + it('should update hosts', () => { + cy.getBySel('editHostsBtn').click(); + cy.get('[placeholder="Specify host URL"').type('http://localhost:8220'); + + cy.intercept('/api/fleet/settings', { + item: { id: 'fleet-default-settings', fleet_server_hosts: ['http://localhost:8220'] }, + }); + cy.intercept('PUT', '/api/fleet/settings', { + fleet_server_hosts: ['http://localhost:8220'], + }).as('updateSettings'); + + cy.getBySel('saveApplySettingsBtn').click(); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + + cy.wait('@updateSettings').then((interception) => { + expect(interception.request.body.fleet_server_hosts[0]).to.equal('http://localhost:8220'); + }); + }); + + it('should update outputs', () => { + cy.getBySel('editOutputBtn').click(); + cy.get('[placeholder="Specify name"').clear().type('output-1'); + + cy.intercept('/api/fleet/outputs', { + items: [ + { + id: 'fleet-default-output', + name: 'output-1', + type: 'elasticsearch', + is_default: true, + is_default_monitoring: true, + }, + ], + }); + cy.intercept('PUT', '/api/fleet/outputs/fleet-default-output', { + name: 'output-1', + type: 'elasticsearch', + is_default: true, + is_default_monitoring: true, + }).as('updateOutputs'); + + cy.getBySel('saveApplySettingsBtn').click(); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + + cy.wait('@updateOutputs').then((interception) => { + expect(interception.request.body.name).to.equal('output-1'); + }); + }); + }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx index 62b22d0bdffc6..6190d2b13c8fe 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx @@ -236,6 +236,7 @@ export const EditOutputFlyout: React.FunctionComponent = isLoading={form.isLoading} isDisabled={form.isDisabled} onClick={form.submit} + data-test-subj="saveApplySettingsBtn" > = ({ title={i18n.translate('xpack.fleet.settings.outputSection.editButtonTitle', { defaultMessage: 'Edit', })} + data-test-subj="editOutputBtn" /> diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/settings_section.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/settings_section.tsx index 8129943e0e6c0..13d3657276335 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/settings_section.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/settings_section.tsx @@ -64,7 +64,11 @@ export const SettingsSection: React.FunctionComponent = ({ - + Date: Tue, 18 Jan 2022 15:26:59 +0100 Subject: [PATCH 76/99] added cypress test for update agent policy --- .../cypress/integration/agent_policy.spec.ts | 61 ++++++++++++++ .../integration/fleet_settings.spec.ts | 79 +++++++++++++++++++ .../cypress/integration/fleet_startup.spec.ts | 71 ----------------- 3 files changed, 140 insertions(+), 71 deletions(-) create mode 100644 x-pack/plugins/fleet/cypress/integration/agent_policy.spec.ts create mode 100644 x-pack/plugins/fleet/cypress/integration/fleet_settings.spec.ts diff --git a/x-pack/plugins/fleet/cypress/integration/agent_policy.spec.ts b/x-pack/plugins/fleet/cypress/integration/agent_policy.spec.ts new file mode 100644 index 0000000000000..694cf6c1527ae --- /dev/null +++ b/x-pack/plugins/fleet/cypress/integration/agent_policy.spec.ts @@ -0,0 +1,61 @@ +/* + * 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. + */ + +describe('Edit agent policy', () => { + beforeEach(() => { + cy.intercept('/api/fleet/agent_policies/policy-1', { + item: { + id: 'policy-1', + name: 'Agent policy 1', + description: '', + namespace: 'default', + monitoring_enabled: ['logs', 'metrics'], + status: 'active', + }, + }); + cy.intercept('/api/fleet/agent_status?policyId=policy-1', { + results: { + total: 0, + inactive: 0, + online: 0, + error: 0, + offline: 0, + updating: 0, + other: 0, + events: 0, + }, + }); + }); + + it('should edit agent policy', () => { + cy.visit('/app/fleet/policies/policy-1/settings'); + cy.getBySel('toastCloseButton').click(); + cy.get('[placeholder="Optional description"').clear().type('desc'); + + cy.intercept('/api/fleet/agent_policies/policy-1', { + item: { + id: 'policy-1', + name: 'Agent policy 1', + description: 'desc', + namespace: 'default', + monitoring_enabled: ['logs', 'metrics'], + status: 'active', + }, + }); + cy.intercept('PUT', '/api/fleet/agent_policies/policy-1', { + name: 'Agent policy 1', + description: 'desc', + namespace: 'default', + monitoring_enabled: ['logs', 'metrics'], + }).as('updateAgentPolicy'); + cy.get('.euiButton').contains('Save changes').click(); + + cy.wait('@updateAgentPolicy').then((interception) => { + expect(interception.request.body.description).to.equal('desc'); + }); + }); +}); diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_settings.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_settings.spec.ts new file mode 100644 index 0000000000000..ab4bf6b4a66a9 --- /dev/null +++ b/x-pack/plugins/fleet/cypress/integration/fleet_settings.spec.ts @@ -0,0 +1,79 @@ +/* + * 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 { CONFIRM_MODAL_BTN } from '../screens/integrations'; + +describe('Edit settings', () => { + beforeEach(() => { + cy.intercept('/api/fleet/settings', { + item: { id: 'fleet-default-settings', fleet_server_hosts: [] }, + }); + cy.intercept('/api/fleet/outputs', { + items: [ + { + id: 'fleet-default-output', + name: 'default', + type: 'elasticsearch', + is_default: true, + is_default_monitoring: true, + }, + ], + }); + + cy.visit('/app/fleet/settings'); + cy.getBySel('toastCloseButton').click(); + }); + + it('should update hosts', () => { + cy.getBySel('editHostsBtn').click(); + cy.get('[placeholder="Specify host URL"').type('http://localhost:8220'); + + cy.intercept('/api/fleet/settings', { + item: { id: 'fleet-default-settings', fleet_server_hosts: ['http://localhost:8220'] }, + }); + cy.intercept('PUT', '/api/fleet/settings', { + fleet_server_hosts: ['http://localhost:8220'], + }).as('updateSettings'); + + cy.getBySel('saveApplySettingsBtn').click(); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + + cy.wait('@updateSettings').then((interception) => { + expect(interception.request.body.fleet_server_hosts[0]).to.equal('http://localhost:8220'); + }); + }); + + it('should update outputs', () => { + cy.getBySel('editOutputBtn').click(); + cy.get('[placeholder="Specify name"').clear().type('output-1'); + + cy.intercept('/api/fleet/outputs', { + items: [ + { + id: 'fleet-default-output', + name: 'output-1', + type: 'elasticsearch', + is_default: true, + is_default_monitoring: true, + }, + ], + }); + cy.intercept('PUT', '/api/fleet/outputs/fleet-default-output', { + name: 'output-1', + type: 'elasticsearch', + is_default: true, + is_default_monitoring: true, + }).as('updateOutputs'); + + cy.getBySel('saveApplySettingsBtn').click(); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + + cy.wait('@updateOutputs').then((interception) => { + expect(interception.request.body.name).to.equal('output-1'); + }); + }); +}); diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index f05b007fbabe8..59a8df2a0b999 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -125,75 +125,4 @@ describe('Fleet startup', () => { cy.get('.euiCodeBlock__code').contains('--fleet-server-policy=fleet-server-policy'); }); }); - - describe('Edit settings', () => { - beforeEach(() => { - cy.intercept('/api/fleet/settings', { - item: { id: 'fleet-default-settings', fleet_server_hosts: [] }, - }); - cy.intercept('/api/fleet/outputs', { - items: [ - { - id: 'fleet-default-output', - name: 'default', - type: 'elasticsearch', - is_default: true, - is_default_monitoring: true, - }, - ], - }); - - cy.visit('/app/fleet/settings'); - cy.getBySel('toastCloseButton').click(); - }); - - it('should update hosts', () => { - cy.getBySel('editHostsBtn').click(); - cy.get('[placeholder="Specify host URL"').type('http://localhost:8220'); - - cy.intercept('/api/fleet/settings', { - item: { id: 'fleet-default-settings', fleet_server_hosts: ['http://localhost:8220'] }, - }); - cy.intercept('PUT', '/api/fleet/settings', { - fleet_server_hosts: ['http://localhost:8220'], - }).as('updateSettings'); - - cy.getBySel('saveApplySettingsBtn').click(); - cy.getBySel(CONFIRM_MODAL_BTN).click(); - - cy.wait('@updateSettings').then((interception) => { - expect(interception.request.body.fleet_server_hosts[0]).to.equal('http://localhost:8220'); - }); - }); - - it('should update outputs', () => { - cy.getBySel('editOutputBtn').click(); - cy.get('[placeholder="Specify name"').clear().type('output-1'); - - cy.intercept('/api/fleet/outputs', { - items: [ - { - id: 'fleet-default-output', - name: 'output-1', - type: 'elasticsearch', - is_default: true, - is_default_monitoring: true, - }, - ], - }); - cy.intercept('PUT', '/api/fleet/outputs/fleet-default-output', { - name: 'output-1', - type: 'elasticsearch', - is_default: true, - is_default_monitoring: true, - }).as('updateOutputs'); - - cy.getBySel('saveApplySettingsBtn').click(); - cy.getBySel(CONFIRM_MODAL_BTN).click(); - - cy.wait('@updateOutputs').then((interception) => { - expect(interception.request.body.name).to.equal('output-1'); - }); - }); - }); }); From cbebb62be5dc1b1dfefe8205437a517b7b6217b8 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 18 Jan 2022 15:43:36 +0100 Subject: [PATCH 77/99] added cypress test for update package policy --- .../integration/package_policy.spec.ts | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 x-pack/plugins/fleet/cypress/integration/package_policy.spec.ts diff --git a/x-pack/plugins/fleet/cypress/integration/package_policy.spec.ts b/x-pack/plugins/fleet/cypress/integration/package_policy.spec.ts new file mode 100644 index 0000000000000..93d04457e72ec --- /dev/null +++ b/x-pack/plugins/fleet/cypress/integration/package_policy.spec.ts @@ -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. + */ + +describe('Edit package policy', () => { + const policyConfig = { + id: 'policy-1', + name: 'fleet_server-1', + namespace: 'default', + package: { name: 'fleet_server', title: 'Fleet Server', version: '1.1.1' }, + enabled: true, + policy_id: 'fleet-server-policy', + output_id: 'fleet-default-output', + inputs: [ + { + type: 'fleet-server', + policy_template: 'fleet_server', + enabled: true, + streams: [], + vars: { + host: { value: ['0.0.0.0'], type: 'text' }, + port: { value: [8220], type: 'integer' }, + max_connections: { type: 'integer' }, + custom: { value: '', type: 'yaml' }, + }, + compiled_input: { server: { port: 8220, host: '0.0.0.0' } }, + }, + ], + }; + beforeEach(() => { + cy.intercept('/api/fleet/package_policies/policy-1', { + item: policyConfig, + }); + cy.intercept('/api/fleet/agent_status?policyId=fleet-server-policy', { + results: { + total: 0, + inactive: 0, + online: 0, + error: 0, + offline: 0, + updating: 0, + other: 0, + events: 0, + }, + }); + cy.intercept('POST', '/api/fleet/package_policies/upgrade/dryrun', [ + { + name: 'fleet_server-1', + diff: [policyConfig, policyConfig], + hasErrors: false, + }, + ]); + }); + + it('should edit package policy', () => { + cy.visit('/app/fleet/policies/fleet-server-policy/edit-integration/policy-1'); + cy.getBySel('toastCloseButton').click(); + cy.getBySel('packagePolicyDescriptionInput').clear().type('desc'); + + cy.intercept('PUT', '/api/fleet/package_policies/policy-1', { + name: 'fleet_server-1', + description: 'desc', + namespace: 'default', + }).as('updatePackagePolicy'); + cy.get('.euiButton').contains('Save integration').click(); + + cy.wait('@updatePackagePolicy').then((interception) => { + expect(interception.request.body.description).to.equal('desc'); + }); + }); +}); From 0767d35d335a30eccee4437dcef913e96c1041a9 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 18 Jan 2022 15:54:38 +0100 Subject: [PATCH 78/99] added cypress test for install package without policy --- .../cypress/integration/integrations.spec.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts index 57701c98cb21f..84f8b47e79df3 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts @@ -139,4 +139,20 @@ describe('Add Integration', () => { }); }); }); + + it('should install integration without policy', () => { + cy.visit('/app/integrations/detail/tomcat-1.2.1/settings'); + + cy.get('.euiButton').contains('Install Apache Tomcat assets').click(); + cy.get('.euiCallOut').contains('This action will install 1 assets'); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.getBySel('installedVersion').contains('1.2.1'); + + cy.get('.euiButton').contains('Uninstall Apache Tomcat').click(); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.get('.euiButton').contains('Install Apache Tomcat assets'); + }); }); From 12dca7de7a800ed4a523eed34b6723ada697f88b Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 18 Jan 2022 16:44:44 +0100 Subject: [PATCH 79/99] fix checks and test --- .../fleet/cypress/integration/fleet_startup.spec.ts | 1 - .../fleet/cypress/integration/package_policy.spec.ts | 11 +++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 59a8df2a0b999..83423d62e2a43 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -6,7 +6,6 @@ */ import { AGENTS_TAB, AGENT_POLICIES_TAB, ENROLLMENT_TOKENS_TAB } from '../screens/fleet'; -import { CONFIRM_MODAL_BTN } from '../screens/integrations'; import { cleanupAgentPolicies, unenrollAgent } from '../tasks/cleanup'; import { FLEET, navigateTo } from '../tasks/navigation'; diff --git a/x-pack/plugins/fleet/cypress/integration/package_policy.spec.ts b/x-pack/plugins/fleet/cypress/integration/package_policy.spec.ts index 93d04457e72ec..507b4edbcfc70 100644 --- a/x-pack/plugins/fleet/cypress/integration/package_policy.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/package_policy.spec.ts @@ -53,6 +53,17 @@ describe('Edit package policy', () => { hasErrors: false, }, ]); + cy.intercept('/api/fleet/agent_policies/fleet-server-policy', { + item: { + id: 'fleet-server-policy', + name: 'Fleet server policy 1', + description: '', + namespace: 'default', + monitoring_enabled: ['logs', 'metrics'], + status: 'active', + package_policies: [{ id: 'policy-1', name: 'fleet_server-1' }], + }, + }); }); it('should edit package policy', () => { From ee7baa87867d2c57ad0e681d50717224e4c2827e Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 19 Jan 2022 09:27:00 +0100 Subject: [PATCH 80/99] removed create link from existing hosts tab --- .../step_select_agent_policy.tsx | 43 +------------------ 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx index bf6639b1c4674..0ad736a9446d9 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx @@ -14,24 +14,16 @@ import { EuiSelect } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, - EuiPortal, EuiFormRow, EuiDescribedFormGroup, EuiTitle, EuiText, - EuiLink, } from '@elastic/eui'; import { Error } from '../../../components'; import type { AgentPolicy, PackageInfo, GetAgentPoliciesResponseItem } from '../../../types'; import { isPackageLimited, doesAgentPolicyAlreadyIncludePackage } from '../../../services'; -import { - useGetAgentPolicies, - sendGetOneAgentPolicy, - useCapabilities, - useFleetStatus, -} from '../../../hooks'; -import { CreateAgentPolicyFlyout } from '../list_page/components'; +import { useGetAgentPolicies, sendGetOneAgentPolicy, useFleetStatus } from '../../../hooks'; const AgentPolicyFormRow = styled(EuiFormRow)` .euiFormRow__label { @@ -56,17 +48,11 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ const [selectedAgentPolicyError, setSelectedAgentPolicyError] = useState(); - // Create new agent policy flyout state - const hasWriteCapabilites = useCapabilities().write; - const [isCreateAgentPolicyFlyoutOpen, setIsCreateAgentPolicyFlyoutOpen] = - useState(false); - // Fetch agent policies info const { data: agentPoliciesData, error: agentPoliciesError, isLoading: isAgentPoliciesLoading, - resendRequest: refreshAgentPolicies, } = useGetAgentPolicies({ page: 1, perPage: 1000, @@ -172,20 +158,6 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ return ( <> - {isCreateAgentPolicyFlyoutOpen ? ( - - { - setIsCreateAgentPolicyFlyoutOpen(false); - if (newAgentPolicy) { - refreshAgentPolicies(); - setSelectedPolicyId(newAgentPolicy.id); - } - }} - ownFocus={true} - /> - - ) : null} - -
- setIsCreateAgentPolicyFlyoutOpen(true)} - > - - -
-
} helpText={ From 979d374a108eb5eb8e592d66eb16f01137dfc057 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 19 Jan 2022 10:57:55 +0100 Subject: [PATCH 81/99] fixed checks --- x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - 2 files changed, 2 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index a97ebbf14af09..89f7b1b6988eb 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10239,7 +10239,6 @@ "xpack.fleet.createPackagePolicy.stepConfigure.toggleAdvancedOptionsButtonText": "高度なオプション", "xpack.fleet.createPackagePolicy.stepConfigurePackagePolicyTitle": "統合の構成", "xpack.fleet.createPackagePolicy.stepSelectAgentPolicyTitle": "エージェントポリシーに適用", - "xpack.fleet.createPackagePolicy.StepSelectPolicy.addButton": "エージェントポリシーを作成", "xpack.fleet.createPackagePolicy.StepSelectPolicy.agentPolicyFormGroupDescription": "エージェントポリシーは、エージェントのセットで統合のグループを管理するために使用されます", "xpack.fleet.createPackagePolicy.StepSelectPolicy.agentPolicyFormGroupTitle": "エージェントポリシー", "xpack.fleet.createPackagePolicy.StepSelectPolicy.agentPolicyLabel": "エージェントポリシー", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 079cfcc780217..380fce5e63971 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -10335,7 +10335,6 @@ "xpack.fleet.createPackagePolicy.stepConfigure.toggleAdvancedOptionsButtonText": "高级选项", "xpack.fleet.createPackagePolicy.stepConfigurePackagePolicyTitle": "配置集成", "xpack.fleet.createPackagePolicy.stepSelectAgentPolicyTitle": "应用到代理策略", - "xpack.fleet.createPackagePolicy.StepSelectPolicy.addButton": "创建代理策略", "xpack.fleet.createPackagePolicy.StepSelectPolicy.agentPolicyAgentsDescriptionText": "{count, plural, other {# 个代理}}已注册到选定代理策略。", "xpack.fleet.createPackagePolicy.StepSelectPolicy.agentPolicyFormGroupDescription": "代理策略用于管理一个代理集的一组集成", "xpack.fleet.createPackagePolicy.StepSelectPolicy.agentPolicyFormGroupTitle": "代理策略", From b3a3fb101143d331ed6ca99fb4617ea8155d8017 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 19 Jan 2022 14:34:07 +0100 Subject: [PATCH 82/99] updated deprecation, throw error and rollback if package policy failed --- x-pack/plugins/fleet/server/index.ts | 36 +++++++++++++++++-- .../services/agent_policy_create.test.ts | 28 +++++++++++++++ .../server/services/agent_policy_create.ts | 11 +++--- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/fleet/server/index.ts b/x-pack/plugins/fleet/server/index.ts index 630c3ef4ad0b3..b7c7898097481 100644 --- a/x-pack/plugins/fleet/server/index.ts +++ b/x-pack/plugins/fleet/server/index.ts @@ -54,9 +54,39 @@ export const config: PluginConfigDescriptor = { unused('agents.pollingRequestTimeout', { level: 'critical' }), unused('agents.tlsCheckDisabled', { level: 'critical' }), unused('agents.fleetServerEnabled', { level: 'critical' }), - // Removed default policies - unused('agentPolicies.is_default', { level: 'critical' }), - unused('agentPolicies.is_default_fleet_server', { level: 'critical' }), + // Deprecate default policy flags + (fullConfig, fromPath, addDeprecation) => { + if ( + (fullConfig?.xpack?.fleet?.agentPolicies || []).find((policy: any) => policy.is_default) + ) { + addDeprecation({ + configPath: 'xpack.fleet.agentPolicies.is_default', + message: `Config key [xpack.fleet.agentPolicies.is_default] is deprecated.`, + correctiveActions: { + manualSteps: [`Create a dedicated policy instead through the UI or API.`], + }, + level: 'warning', + }); + } + return fullConfig; + }, + (fullConfig, fromPath, addDeprecation) => { + if ( + (fullConfig?.xpack?.fleet?.agentPolicies || []).find( + (policy: any) => policy.is_default_fleet_server + ) + ) { + addDeprecation({ + configPath: 'xpack.fleet.agentPolicies.is_default_fleet_server', + message: `Config key [xpack.fleet.agentPolicies.is_default_fleet_server] is deprecated.`, + correctiveActions: { + manualSteps: [`Create a dedicated fleet server policy instead through the UI or API.`], + }, + level: 'warning', + }); + } + return fullConfig; + }, // Renaming elasticsearch.host => elasticsearch.hosts (fullConfig, fromPath, addDeprecation) => { const oldValue = fullConfig?.xpack?.fleet?.agents?.elasticsearch?.host; diff --git a/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts b/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts index ce428948f352b..57398f053b269 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts @@ -74,6 +74,34 @@ describe('createAgentPolicyWithPackages', () => { } as PackagePolicy) ); }); + + it('should roll back agent policy if package policy creation failed', async () => { + mockedPackagePolicyService.buildPackagePolicyFromPackage.mockImplementationOnce( + (soClient, packageToInstall) => Promise.reject(new Error('error')) + ); + let error; + try { + await createAgentPolicyWithPackages({ + esClient: esClientMock, + soClient: soClientMock, + newPolicy: { name: 'Agent policy 1', namespace: 'default' }, + withSysMonitoring: true, + spaceId: 'default', + }); + } catch (err) { + error = err; + } + + expect(error.message).toEqual('error'); + + expect(mockedAgentPolicyService.delete).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + 'new_id', + expect.anything() + ); + }); + it('should create policy with fleet_server, system and elastic_agent package - first one', async () => { const response = await createAgentPolicyWithPackages({ esClient: esClientMock, diff --git a/x-pack/plugins/fleet/server/services/agent_policy_create.ts b/x-pack/plugins/fleet/server/services/agent_policy_create.ts index e6b464ff94cef..280cef9d820fe 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy_create.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy_create.ts @@ -48,12 +48,15 @@ async function createPackagePolicy( packageToInstall: string, options: { spaceId: string; user: AuthenticatedUser | undefined } ) { - // If needed, retrieve package information and build a new package policy for the package - // NOTE: we ignore failures in attempting to create package policy, since agent policy might have been created - // successfully const newPackagePolicy = await packagePolicyService .buildPackagePolicyFromPackage(soClient, packageToInstall) - .catch(() => undefined); + .catch(async (error) => { + // rollback agent policy on error + await agentPolicyService.delete(soClient, esClient, agentPolicy.id, { + force: true, + }); + throw error; + }); if (!newPackagePolicy) return; From 2faa0131721f72c6b5a8faabf179729536a282fa Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 20 Jan 2022 09:44:41 +0100 Subject: [PATCH 83/99] fix formatting --- .../fleet/public/components/new_enrollment_key_modal.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/x-pack/plugins/fleet/public/components/new_enrollment_key_modal.tsx b/x-pack/plugins/fleet/public/components/new_enrollment_key_modal.tsx index 6e0504d948ba3..9d71a50ce026c 100644 --- a/x-pack/plugins/fleet/public/components/new_enrollment_key_modal.tsx +++ b/x-pack/plugins/fleet/public/components/new_enrollment_key_modal.tsx @@ -77,9 +77,7 @@ export const NewEnrollmentTokenModal: React.FunctionComponent = ({ }) => { const { notifications } = useStartServices(); const form = useCreateApiKeyForm( - agentPolicies.length > 0 - ? agentPolicies[0].id - : undefined, + agentPolicies.length > 0 ? agentPolicies[0].id : undefined, (key: EnrollmentAPIKey) => { onClose(key); notifications.toasts.addSuccess( From f676146fa69c5369238848117ec9808d42e207a8 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 20 Jan 2022 11:49:01 +0100 Subject: [PATCH 84/99] fix test --- x-pack/test/fleet_api_integration/apis/epm/setup.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/x-pack/test/fleet_api_integration/apis/epm/setup.ts b/x-pack/test/fleet_api_integration/apis/epm/setup.ts index 351ec27c3abe3..1e828cf63cfd5 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/setup.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/setup.ts @@ -82,6 +82,13 @@ export default function (providerContext: FtrProviderContext) { .set('Authorization', `Bearer ${token.value}`) .set('kbn-xsrf', 'xxx') .expect(200); + const resp = await supertest + .post('/api/fleet/agent_policies') + .set('Authorization', `Bearer ${token.value}`) + .set('kbn-xsrf', 'xxx') + .send({ name: 'Agent policy', namespace: 'default' }) + .expect(200); + const agentPolicyId = resp.body.item.id; await supertestWithoutAuth .get('/api/fleet/enrollment_api_keys') .set('Authorization', `Bearer ${token.value}`) @@ -91,7 +98,7 @@ export default function (providerContext: FtrProviderContext) { .post('/api/fleet/enrollment_api_keys') .set('Authorization', `Bearer ${token.value}`) .set('kbn-xsrf', 'xxx') - .send({ policy_id: '' }) + .send({ policy_id: agentPolicyId }) .expect(200); const enrollmentApiKeyId = response.body.item.id; await supertestWithoutAuth From eccf4b7ab5002c35b9d783fd83c49769ccfc3ace Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 20 Jan 2022 16:28:50 +0100 Subject: [PATCH 85/99] documented dependent projects --- x-pack/plugins/fleet/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/x-pack/plugins/fleet/README.md b/x-pack/plugins/fleet/README.md index 29436440fac8b..6c26cb29fc541 100644 --- a/x-pack/plugins/fleet/README.md +++ b/x-pack/plugins/fleet/README.md @@ -129,3 +129,15 @@ $ yarn storybook fleet ``` Write stories by creating `.stories.tsx` files colocated with the components you're working on. Consult the [Storybook docs](https://storybook.js.org/docs/react/get-started/introduction) for more information. + +## Dependent applications using Fleet + +The projects below are dependent on Fleet, most using Fleet API as well. In case of breaking changes in Fleet functionality/API, the project owners have to be notified to make sure they can plan for the necessary changes on their end to avoid unexpected break in functionality. + + * [Elastic Agent](https://github.com/elastic/beats/blob/master/x-pack/elastic-agent): uses Fleet API to enroll agents. [See here](https://github.com/elastic/beats/blob/master/x-pack/elastic-agent/pkg/agent/cmd/container.go) + * [Fleet Server](https://github.com/elastic/fleet-server): uses Fleet API to enroll fleet server [See here](https://github.com/elastic/fleet-server/blob/master/cmd/fleet/router.go) + * [elastic-package](https://github.com/elastic/elastic-package): command line tool, uses Fleet with docker compose and Fleet API [See here](https://github.com/elastic/elastic-package/tree/master/internal/kibana) + * [Azure VM extension](https://github.com/elastic/azure-vm-extension): automation tool for Azure VMs, uses Fleet API to enroll agents [See here](https://github.com/elastic/azure-vm-extension/blob/main/src/handler/windows/scripts/enable.ps1) + * [e2e-testing](https://github.com/elastic/e2e-testing): internal project that runs Fleet and tests Fleet API [See here](https://github.com/elastic/e2e-testing/tree/main/internal/kibana) + * [observability-test-environments](https://github.com/elastic/observability-test-environments): internal project, uses Fleet API [See here](https://github.com/elastic/observability-test-environments/blob/master/ansible/tasks-fleet-config.yml) + * [ECK](https://github.com/elastic/cloud-on-k8s): Elastic Cloud on Kubernetes, orchestrates Elastic Stack applications, including Kibana with Fleet (no direct dependency, has examples that include Fleet config) [See here](https://github.com/elastic/cloud-on-k8s/blob/main/docs/orchestrating-elastic-stack-applications/agent-fleet.asciidoc) \ No newline at end of file From 5219ea1a05e1ae1d90034a23762b0ae74b121c23 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 24 Jan 2022 11:31:03 +0100 Subject: [PATCH 86/99] cypress speed up --- .../cypress/integration/integrations.spec.ts | 33 ++++++++----------- .../fleet/cypress/tasks/integrations.ts | 6 ++++ .../components/agent_policy_integration.tsx | 1 + .../agent_policy_system_monitoring_field.tsx | 1 + 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts index 84f8b47e79df3..f3e869385acf4 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts @@ -44,6 +44,17 @@ describe('Add Integration', () => { cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-1'); } + it('should install integration without policy', () => { + cy.visit('/app/integrations/detail/tomcat-1.2.1/settings'); + + cy.get('.euiButton').contains('Install Apache Tomcat assets').click(); + cy.get('.euiCallOut').contains('This action will install 1 assets'); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.getBySel('installedVersion').contains('1.2.1'); + }); + describe('Real API', () => { afterEach(() => { deleteIntegrations(integration); @@ -74,7 +85,7 @@ describe('Add Integration', () => { cy.get('.euiLoadingSpinner').should('not.exist'); cy.get('input[placeholder="Search for integrations"]').type('Apache'); cy.get(INTEGRATIONS_CARD).contains(integration).click(); - addIntegration(); + addIntegration({ useExistingPolicy: true }); cy.get('.euiBasicTable-loading').should('not.exist'); cy.get('.euiTitle').contains('Agent policy 1'); clickIfVisible(FLYOUT_CLOSE_BTN_SEL); @@ -87,7 +98,7 @@ describe('Add Integration', () => { installPackageWithVersion('apache', oldVersion); navigateTo(`app/integrations/detail/apache-${oldVersion}/policies`); - addIntegration(); + addIntegration({ useExistingPolicy: true }); cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-'); cy.getBySel(PACKAGE_VERSION).contains(oldVersion); @@ -112,7 +123,7 @@ describe('Add Integration', () => { installPackageWithVersion('apache', oldVersion); navigateTo(`app/integrations/detail/apache-${oldVersion}/policies`); - addIntegration(); + addIntegration({ useExistingPolicy: true }); cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-'); cy.getBySel(PACKAGE_VERSION).contains(oldVersion); @@ -139,20 +150,4 @@ describe('Add Integration', () => { }); }); }); - - it('should install integration without policy', () => { - cy.visit('/app/integrations/detail/tomcat-1.2.1/settings'); - - cy.get('.euiButton').contains('Install Apache Tomcat assets').click(); - cy.get('.euiCallOut').contains('This action will install 1 assets'); - cy.getBySel(CONFIRM_MODAL_BTN).click(); - - cy.get('.euiLoadingSpinner').should('not.exist'); - cy.getBySel('installedVersion').contains('1.2.1'); - - cy.get('.euiButton').contains('Uninstall Apache Tomcat').click(); - cy.getBySel(CONFIRM_MODAL_BTN).click(); - cy.get('.euiLoadingSpinner').should('not.exist'); - cy.get('.euiButton').contains('Install Apache Tomcat assets'); - }); }); diff --git a/x-pack/plugins/fleet/cypress/tasks/integrations.ts b/x-pack/plugins/fleet/cypress/tasks/integrations.ts index 665117bb8090e..6058a7cc399bd 100644 --- a/x-pack/plugins/fleet/cypress/tasks/integrations.ts +++ b/x-pack/plugins/fleet/cypress/tasks/integrations.ts @@ -16,6 +16,12 @@ export const addIntegration = ({ useExistingPolicy } = { useExistingPolicy: fals cy.getBySel(ADD_POLICY_BTN).click(); if (useExistingPolicy) { cy.get('#existing').click(); + } else { + // speeding up creating with unchecking system and agent integration + cy.getBySel('agentPolicyFormSystemMonitoringCheckbox').uncheck({ force: true }); + cy.getBySel('advancedOptionsBtn').find('.euiAccordion__button').click(); + cy.get('*[id^="logs_"]').uncheck({ force: true }); + cy.get('*[id^="metrics_"]').uncheck({ force: true }); } cy.getBySel(CREATE_PACKAGE_POLICY_SAVE_BTN).click(); // sometimes agent is assigned to default policy, sometimes not diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx index da7ca2f3e18ec..07b4d59c9a258 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_integration.tsx @@ -95,6 +95,7 @@ export const AgentPolicyIntegrationForm: React.FunctionComponent = ({ /> } buttonClassName="ingest-active-button" + data-test-subj="advancedOptionsBtn" > { updateSysMonitoring(!withSysMonitoring); }} + data-test-subj="agentPolicyFormSystemMonitoringCheckbox" /> ); From 520aba7a1b8c69f8ff3b6d46622fddb635134eb8 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 24 Jan 2022 11:43:32 +0100 Subject: [PATCH 87/99] added back integration uninstall --- .../plugins/fleet/cypress/integration/integrations.spec.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts index f3e869385acf4..6b1148780702a 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts @@ -53,6 +53,11 @@ describe('Add Integration', () => { cy.get('.euiLoadingSpinner').should('not.exist'); cy.getBySel('installedVersion').contains('1.2.1'); + + cy.get('.euiButton').contains('Uninstall Apache Tomcat').click(); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.get('.euiButton').contains('Install Apache Tomcat assets'); }); describe('Real API', () => { From 986f4f8eab876f44e58b35e5bbc9dfea6faa09e4 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 24 Jan 2022 15:49:53 +0100 Subject: [PATCH 88/99] cypress further speed up --- .../cypress/integration/integrations.spec.ts | 158 ------------------ .../integration/integrations_mock.spec.ts | 148 ++++++++++++++++ .../integration/integrations_real.spec.ts | 116 +++++++++++++ .../fleet/cypress/tasks/integrations.ts | 1 + 4 files changed, 265 insertions(+), 158 deletions(-) delete mode 100644 x-pack/plugins/fleet/cypress/integration/integrations.spec.ts create mode 100644 x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts create mode 100644 x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts diff --git a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts deleted file mode 100644 index 6b1148780702a..0000000000000 --- a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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 { INTEGRATIONS, navigateTo } from '../tasks/navigation'; -import { - addIntegration, - installPackageWithVersion, - deleteIntegrations, - clickIfVisible, -} from '../tasks/integrations'; -import { - AGENT_POLICY_NAME_LINK, - CONFIRM_MODAL_BTN, - FLYOUT_CLOSE_BTN_SEL, - INTEGRATIONS_CARD, - INTEGRATION_NAME_LINK, - LATEST_VERSION, - PACKAGE_VERSION, - POLICIES_TAB, - SETTINGS_TAB, - UPDATE_PACKAGE_BTN, -} from '../screens/integrations'; -import { cleanupAgentPolicies } from '../tasks/cleanup'; - -describe('Add Integration', () => { - const integration = 'Apache'; - - after(() => { - cleanupAgentPolicies(); - }); - - function addAndVerifyIntegration() { - cy.intercept('GET', '/api/fleet/epm/packages?*').as('packages'); - navigateTo(INTEGRATIONS); - cy.wait('@packages'); - cy.get('.euiLoadingSpinner').should('not.exist'); - cy.get('input[placeholder="Search for integrations"]').type('Apache'); - cy.get(INTEGRATIONS_CARD).contains(integration).click(); - addIntegration(); - cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-1'); - } - - it('should install integration without policy', () => { - cy.visit('/app/integrations/detail/tomcat-1.2.1/settings'); - - cy.get('.euiButton').contains('Install Apache Tomcat assets').click(); - cy.get('.euiCallOut').contains('This action will install 1 assets'); - cy.getBySel(CONFIRM_MODAL_BTN).click(); - - cy.get('.euiLoadingSpinner').should('not.exist'); - cy.getBySel('installedVersion').contains('1.2.1'); - - cy.get('.euiButton').contains('Uninstall Apache Tomcat').click(); - cy.getBySel(CONFIRM_MODAL_BTN).click(); - cy.get('.euiLoadingSpinner').should('not.exist'); - cy.get('.euiButton').contains('Install Apache Tomcat assets'); - }); - - describe('Real API', () => { - afterEach(() => { - deleteIntegrations(integration); - }); - it('should display Apache integration in the Policies list once installed ', () => { - addAndVerifyIntegration(); - cy.getBySel(AGENT_POLICY_NAME_LINK).contains('Agent policy 1'); - - clickIfVisible(FLYOUT_CLOSE_BTN_SEL); - // test add integration using existing policy - addIntegration({ useExistingPolicy: true }); - cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-2'); - cy.getBySel(AGENT_POLICY_NAME_LINK) - .should('have.length', 2) - .each((el) => el.text().includes('Agent policy 1')); - }); - - it('should add integration to policy', () => { - cy.request('/api/fleet/agent_policies').then((response: any) => { - const agentPolicyId = response.body.items - .filter((policy: any) => policy.name === 'Agent policy 1') - .map((policy: any) => policy.id); - - cy.visit(`/app/fleet/policies/${agentPolicyId}`); - cy.intercept('GET', '/api/fleet/epm/packages?*').as('packages'); - cy.getBySel('addPackagePolicyButton').click(); - cy.wait('@packages'); - cy.get('.euiLoadingSpinner').should('not.exist'); - cy.get('input[placeholder="Search for integrations"]').type('Apache'); - cy.get(INTEGRATIONS_CARD).contains(integration).click(); - addIntegration({ useExistingPolicy: true }); - cy.get('.euiBasicTable-loading').should('not.exist'); - cy.get('.euiTitle').contains('Agent policy 1'); - clickIfVisible(FLYOUT_CLOSE_BTN_SEL); - cy.get('.euiLink').contains('apache-1'); - }); - }); - - it('should upgrade policies with integration update', () => { - const oldVersion = '0.3.3'; - installPackageWithVersion('apache', oldVersion); - navigateTo(`app/integrations/detail/apache-${oldVersion}/policies`); - - addIntegration({ useExistingPolicy: true }); - - cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-'); - cy.getBySel(PACKAGE_VERSION).contains(oldVersion); - - clickIfVisible(FLYOUT_CLOSE_BTN_SEL); - - cy.getBySel(SETTINGS_TAB).click(); - cy.getBySel(UPDATE_PACKAGE_BTN).click(); - cy.getBySel(CONFIRM_MODAL_BTN).click(); - - cy.getBySel(LATEST_VERSION).then(($title) => { - const newVersion = $title.text(); - cy.get('#upgradePoliciesCheckbox').should('not.exist'); - cy.getBySel(POLICIES_TAB).click(); - cy.getBySel(PACKAGE_VERSION).contains(oldVersion).should('not.exist'); - cy.getBySel(PACKAGE_VERSION).contains(newVersion); - }); - }); - - it('should upgrade policies without integration update', () => { - const oldVersion = '0.3.3'; - installPackageWithVersion('apache', oldVersion); - navigateTo(`app/integrations/detail/apache-${oldVersion}/policies`); - - addIntegration({ useExistingPolicy: true }); - - cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-'); - cy.getBySel(PACKAGE_VERSION).contains(oldVersion); - - clickIfVisible(FLYOUT_CLOSE_BTN_SEL); - - cy.getBySel(SETTINGS_TAB).click(); - cy.get('#upgradePoliciesCheckbox').uncheck({ force: true }); - - cy.getBySel(UPDATE_PACKAGE_BTN).click(); - - cy.getBySel(LATEST_VERSION).then(($title) => { - const newVersion = $title.text(); - cy.get('#upgradePoliciesCheckbox').should('not.exist'); - cy.getBySel('installedVersion').contains(newVersion); - cy.getBySel(POLICIES_TAB).click(); - cy.getBySel(PACKAGE_VERSION).contains(oldVersion); - - // upgrade integration policy - cy.getBySel('integrationPolicyUpgradeBtn').click(); - cy.getBySel('saveIntegration').click(); - cy.getBySel('saveIntegration').should('not.exist'); - cy.getBySel(PACKAGE_VERSION).contains(newVersion); - }); - }); - }); -}); diff --git a/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts new file mode 100644 index 0000000000000..23f894136368b --- /dev/null +++ b/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts @@ -0,0 +1,148 @@ +/* + * 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 { navigateTo } from '../tasks/navigation'; +import { PACKAGE_VERSION, POLICIES_TAB, UPDATE_PACKAGE_BTN } from '../screens/integrations'; + +describe('Add Integration - Mock API', () => { + describe('upgrade package and upgrade package policy', () => { + const oldVersion = '0.3.3'; + const newVersion = '1.3.4'; + beforeEach(() => { + cy.intercept('/api/fleet/epm/packages?experimental=true', { + items: [ + { + name: 'apache', + id: 'apache', + version: newVersion, + savedObject: { attributes: { version: oldVersion } }, + status: 'installed', + }, + ], + }); + + cy.intercept(`/api/fleet/epm/packages/apache/${oldVersion}`, { + item: { + name: 'apache', + version: oldVersion, + latestVersion: newVersion, + status: 'installed', + assets: [], + savedObject: { attributes: { version: oldVersion } }, + }, + }); + cy.intercept('/api/fleet/epm/packages/apache/stats', { response: { agent_policy_count: 1 } }); + cy.intercept('/api/fleet/package_policies?*', { + items: [ + { + name: 'apache-2', + description: '', + namespace: 'default', + policy_id: 'policy-1', + package: { + name: 'apache', + version: oldVersion, + }, + updated_by: 'elastic', + }, + ], + }); + const policyConfig = { + id: 'apache-2', + name: 'apache-2', + namespace: 'default', + package: { name: 'apache', version: oldVersion }, + enabled: true, + policy_id: 'policy-1', + inputs: [], + }; + cy.intercept('/api/fleet/package_policies/apache-2', { + item: policyConfig, + }); + cy.intercept('POST', '/api/fleet/package_policies/upgrade/dryrun', [ + { + name: 'apache-2', + diff: [policyConfig, policyConfig], + hasErrors: false, + }, + ]); + cy.intercept('POST', `/api/fleet/epm/packages/apache/${newVersion}`, { items: [] }); + const agentPolicy = { + id: 'policy-1', + name: 'Agent policy 1', + description: '', + namespace: 'default', + monitoring_enabled: [], + status: 'active', + package_policies: [{ id: 'apache-2', name: 'apache-2', policy_id: 'policy-1', inputs: [] }], + }; + cy.intercept('/api/fleet/agent_policies?*', { items: [agentPolicy] }); + cy.intercept('/api/fleet/agent_policies/policy-1', { + item: agentPolicy, + }); + }); + + it('should upgrade policies without integration update', () => { + navigateTo(`app/integrations/detail/apache-${oldVersion}/settings`); + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.getBySel('installedVersion').contains(oldVersion); + + cy.get('#upgradePoliciesCheckbox').uncheck({ force: true }); + + cy.intercept(`/api/fleet/epm/packages/apache/${newVersion}`, { + item: { + name: 'apache', + version: newVersion, + latestVersion: newVersion, + status: 'installed', + assets: [], + savedObject: { attributes: { version: newVersion } }, + }, + }).as('updatePackage'); + cy.getBySel(UPDATE_PACKAGE_BTN).click(); + cy.wait('@updatePackage'); + cy.get('#upgradePoliciesCheckbox').should('not.exist'); + cy.getBySel('installedVersion').contains(newVersion); + }); + + it('should upgrade integration policy', () => { + cy.intercept('/api/fleet/epm/packages/apache/*', { + item: { + name: 'apache', + version: newVersion, + latestVersion: newVersion, + status: 'installed', + assets: [], + savedObject: { attributes: { version: newVersion } }, + }, + }); + cy.intercept('/api/fleet/epm/packages/apache/stats', { response: { agent_policy_count: 1 } }); + cy.intercept('PUT', '/api/fleet/package_policies/apache-2', { + item: { + id: 'apache-2', + name: 'apache-2', + namespace: 'default', + package: { name: 'apache', version: newVersion }, + enabled: true, + policy_id: 'policy-1', + inputs: [], + }, + }).as('updateApachePolicy'); + + navigateTo( + '/app/fleet/policies/package-1/upgrade-package-policy/apache-2?from=integrations-policy-list' + ); + + cy.getBySel('toastCloseButton').click(); + cy.getBySel('saveIntegration').click(); + + cy.wait('@updateApachePolicy').then((interception) => { + expect(interception.request.body.package.version).to.equal(newVersion); + }); + }); + }); +}); diff --git a/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts new file mode 100644 index 0000000000000..9994b5e61575d --- /dev/null +++ b/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts @@ -0,0 +1,116 @@ +/* + * 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 { INTEGRATIONS, navigateTo } from '../tasks/navigation'; +import { + addIntegration, + installPackageWithVersion, + deleteIntegrations, + clickIfVisible, +} from '../tasks/integrations'; +import { + AGENT_POLICY_NAME_LINK, + CONFIRM_MODAL_BTN, + FLYOUT_CLOSE_BTN_SEL, + INTEGRATIONS_CARD, + INTEGRATION_NAME_LINK, + LATEST_VERSION, + PACKAGE_VERSION, + POLICIES_TAB, + SETTINGS_TAB, + UPDATE_PACKAGE_BTN, +} from '../screens/integrations'; +import { cleanupAgentPolicies } from '../tasks/cleanup'; + +describe('Add Integration - Real API', () => { + const integration = 'Apache'; + + after(() => { + cleanupAgentPolicies(); + }); + + it('should install integration without policy', () => { + cy.visit('/app/integrations/detail/tomcat-1.2.1/settings'); + + cy.get('.euiButton').contains('Install Apache Tomcat assets').click(); + cy.get('.euiCallOut').contains('This action will install 1 assets'); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.getBySel('installedVersion').contains('1.2.1'); + + cy.get('.euiButton').contains('Uninstall Apache Tomcat').click(); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.get('.euiButton').contains('Install Apache Tomcat assets'); + }); + + function addAndVerifyIntegration() { + cy.intercept('GET', '/api/fleet/epm/packages?*').as('packages'); + navigateTo(INTEGRATIONS); + cy.wait('@packages'); + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.get('input[placeholder="Search for integrations"]').type('Apache'); + cy.get(INTEGRATIONS_CARD).contains(integration).click(); + addIntegration(); + cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-1'); + } + + afterEach(() => { + deleteIntegrations(integration); + }); + it('should display Apache integration in the Policies list once installed ', () => { + addAndVerifyIntegration(); + cy.getBySel(AGENT_POLICY_NAME_LINK).contains('Agent policy 1'); + }); + + it('should add integration to policy', () => { + cy.request('/api/fleet/agent_policies').then((response: any) => { + const agentPolicyId = response.body.items + .filter((policy: any) => policy.name === 'Agent policy 1') + .map((policy: any) => policy.id); + + cy.visit(`/app/fleet/policies/${agentPolicyId}`); + cy.intercept('GET', '/api/fleet/epm/packages?*').as('packages'); + cy.getBySel('addPackagePolicyButton').click(); + cy.wait('@packages'); + cy.get('.euiLoadingSpinner').should('not.exist'); + cy.get('input[placeholder="Search for integrations"]').type('Apache'); + cy.get(INTEGRATIONS_CARD).contains(integration).click(); + addIntegration({ useExistingPolicy: true }); + cy.get('.euiBasicTable-loading').should('not.exist'); + cy.get('.euiTitle').contains('Agent policy 1'); + clickIfVisible(FLYOUT_CLOSE_BTN_SEL); + cy.get('.euiLink').contains('apache-1'); + }); + }); + + it('should upgrade policies with integration update', () => { + const oldVersion = '0.3.3'; + installPackageWithVersion('apache', oldVersion); + navigateTo(`app/integrations/detail/apache-${oldVersion}/policies`); + + addIntegration({ useExistingPolicy: true }); + + cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-'); + cy.getBySel(PACKAGE_VERSION).contains(oldVersion); + + clickIfVisible(FLYOUT_CLOSE_BTN_SEL); + + cy.getBySel(SETTINGS_TAB).click(); + cy.getBySel(UPDATE_PACKAGE_BTN).click(); + cy.getBySel(CONFIRM_MODAL_BTN).click(); + + cy.getBySel(LATEST_VERSION).then(($title) => { + const newVersion = $title.text(); + cy.get('#upgradePoliciesCheckbox').should('not.exist'); + cy.getBySel(POLICIES_TAB).click(); + cy.getBySel(PACKAGE_VERSION).contains(oldVersion).should('not.exist'); + cy.getBySel(PACKAGE_VERSION).contains(newVersion); + }); + }); +}); diff --git a/x-pack/plugins/fleet/cypress/tasks/integrations.ts b/x-pack/plugins/fleet/cypress/tasks/integrations.ts index 6058a7cc399bd..7e266dce523d5 100644 --- a/x-pack/plugins/fleet/cypress/tasks/integrations.ts +++ b/x-pack/plugins/fleet/cypress/tasks/integrations.ts @@ -23,6 +23,7 @@ export const addIntegration = ({ useExistingPolicy } = { useExistingPolicy: fals cy.get('*[id^="logs_"]').uncheck({ force: true }); cy.get('*[id^="metrics_"]').uncheck({ force: true }); } + cy.getBySel('toastCloseButton').click(); cy.getBySel(CREATE_PACKAGE_POLICY_SAVE_BTN).click(); // sometimes agent is assigned to default policy, sometimes not cy.getBySel(CONFIRM_MODAL_BTN).click(); From 33fd8980dcbd91da07c7bba3912c140476ee76c6 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 24 Jan 2022 16:31:08 +0100 Subject: [PATCH 89/99] fix checks --- .../plugins/fleet/cypress/integration/integrations_mock.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts index 23f894136368b..aa8d4f14f4027 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts @@ -6,7 +6,7 @@ */ import { navigateTo } from '../tasks/navigation'; -import { PACKAGE_VERSION, POLICIES_TAB, UPDATE_PACKAGE_BTN } from '../screens/integrations'; +import { UPDATE_PACKAGE_BTN } from '../screens/integrations'; describe('Add Integration - Mock API', () => { describe('upgrade package and upgrade package policy', () => { From ffc15971e57acf05ca3bfc8e370dc81a3c055bd9 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Wed, 26 Jan 2022 10:21:02 +0100 Subject: [PATCH 90/99] Update x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx Co-authored-by: Josh Dover <1813008+joshdover@users.noreply.github.com> --- .../agent_enrollment_flyout/managed_instructions.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx index a150ac258c692..455bcb85df2a0 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx @@ -80,11 +80,11 @@ export const ManagedInstructions = React.memo( }); const fleetServers = useMemo(() => { - const fleetServerAgentPolicies: string[] = (agentPolicies || []) + const fleetServerAgentPolicies: string[] = (agentPolicies ?? []) .filter((pol) => policyHasFleetServer(pol)) .map((pol) => pol.id); - return (agents?.items || []).filter((agent) => - fleetServerAgentPolicies.includes(agent.policy_id || '') + return (agents?.items ?? []).filter((agent) => + fleetServerAgentPolicies.includes(agent.policy_id ?? '') ); }, [agents, agentPolicies]); From 2f9f7e8c519735e5f5be13bf9a7c0c92644e2c97 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 26 Jan 2022 10:51:01 +0100 Subject: [PATCH 91/99] review fixes --- .../components/agent_policy_create_inline.tsx | 7 ++++--- .../agent_policy/create_package_policy_page/index.tsx | 8 ++++---- .../agent_enrollment_flyout/managed_instructions.tsx | 10 +++++++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index 0ca39c522bc0f..afab3980c1f56 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -51,6 +51,10 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ }) => { const [touchedFields, setTouchedFields] = useState<{ [key: string]: boolean }>({}); + const [withSysMonitoring, setWithSysMonitoring] = useState(true); + + const [isLoading, setIsLoading] = useState(false); + const [newAgentPolicy, setNewAgentPolicy] = useState({ name: agentPolicyName, description: '', @@ -69,11 +73,8 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ [setNewAgentPolicy, newAgentPolicy] ); - const [withSysMonitoring, setWithSysMonitoring] = useState(true); const validation = agentPolicyFormValidation(newAgentPolicy); - const [isLoading, setIsLoading] = useState(false); - const createAgentPolicy = useCallback(async () => { try { setIsLoading(true); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index d68765bfb734e..09c24b7e09472 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -404,11 +404,11 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { updatePackagePolicy({ policy_id: policyId }); } } catch (e) { - notifications.toasts.addDanger( - i18n.translate('xpack.fleet.createAgentPolicy.errorNotificationTitle', { + notifications.toasts.addError(e, { + title: i18n.translate('xpack.fleet.createAgentPolicy.errorNotificationTitle', { defaultMessage: 'Unable to create agent policy', - }) - ); + }), + }); return; } } diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx index 455bcb85df2a0..6d65476e3641f 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx @@ -25,6 +25,8 @@ import { FleetServerRequirementPage } from '../../applications/fleet/sections/ag import { policyHasFleetServer } from '../../applications/fleet/sections/agents/services/has_fleet_server'; +import { FLEET_SERVER_PACKAGE } from '../../constants'; + import { DownloadStep, AgentPolicySelectionStep, AgentEnrollmentKeySelectionStep } from './steps'; import type { BaseProps } from './types'; @@ -173,11 +175,13 @@ export const ManagedInstructions = React.memo( ); } + const showFleetMissingRequirements = + fleetServers.length === 0 || + (fleetStatus.missingRequirements ?? []).some((r) => r === FLEET_SERVER_PACKAGE); + return ( <> - {(fleetStatus.missingRequirements?.length === 1 && - fleetStatus.missingRequirements[0] === 'fleet_server') || - fleetServers.length === 0 ? ( + {showFleetMissingRequirements ? ( ) : ( From e82240cfa8b1d8683869d683d9d8fa2eaaa3d850 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 26 Jan 2022 13:07:53 +0100 Subject: [PATCH 92/99] aria label and onSubmit refactor --- .../create_package_policy_page/index.tsx | 39 ++++++++++--------- .../step_select_agent_policy.tsx | 1 + 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index 09c24b7e09472..9d0daf00e5ecd 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -378,6 +378,23 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { [packagePolicy.policy_id, getPath, navigateToApp, history, routeState, queryParamsPolicyId] ); + const createAgentPolicy = useCallback(async (): Promise => { + let policyId; + setFormState('LOADING'); + const resp = await sendCreateAgentPolicy(newAgentPolicy, { withSysMonitoring }); + if (resp.error) { + setFormState('VALID'); + throw resp.error; + } + if (resp.data) { + policyId = resp.data.item.id; + setAgentPolicy(resp.data.item); + + updatePackagePolicy({ policy_id: policyId }); + } + return policyId; + }, [newAgentPolicy, updatePackagePolicy, withSysMonitoring]); + const onSubmit = useCallback(async () => { if (formState === 'VALID' && hasErrors) { setFormState('INVALID'); @@ -387,22 +404,10 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { setFormState('CONFIRM'); return; } - let policyId = ''; - // save agent policy + let policyId; if (selectedPolicyTab === SelectedPolicyTab.NEW) { try { - setFormState('LOADING'); - const resp = await sendCreateAgentPolicy(newAgentPolicy, { withSysMonitoring }); - if (resp.error) { - setFormState('VALID'); - throw resp.error; - } - if (resp.data) { - policyId = resp.data.item.id; - setAgentPolicy(resp.data.item); - - updatePackagePolicy({ policy_id: policyId }); - } + policyId = await createAgentPolicy(); } catch (e) { notifications.toasts.addError(e, { title: i18n.translate('xpack.fleet.createAgentPolicy.errorNotificationTitle', { @@ -417,7 +422,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { // passing pkgPolicy with policy_id here as setPackagePolicy doesn't propagate immediately const { error, data } = await savePackagePolicy({ ...packagePolicy, - policy_id: policyId || packagePolicy.policy_id, + policy_id: policyId ?? packagePolicy.policy_id, }); if (!error) { setSavedPackagePolicy(data!.item); @@ -460,11 +465,9 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { onSaveNavigate, agentPolicy, notifications.toasts, - newAgentPolicy, packagePolicy, - updatePackagePolicy, - withSysMonitoring, selectedPolicyTab, + createAgentPolicy, ]); const integrationInfo = useMemo( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx index 0ad736a9446d9..8558fbecbde0f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx @@ -241,6 +241,7 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ value={selectedPolicyId || undefined} onChange={(e) => setSelectedPolicyId(e.target.value)} data-test-subj="agentPolicySelect" + aria-label="Select Agent Policy" /> From 62c5f2346abc20df2230b568bab0ba6cf221a60d Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 26 Jan 2022 13:54:48 +0100 Subject: [PATCH 93/99] agent policy validation test --- .../agent_policy_validation.test.tsx | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.test.tsx diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.test.tsx new file mode 100644 index 0000000000000..961a0c7ca899d --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.test.tsx @@ -0,0 +1,42 @@ +/* + * 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 { agentPolicyFormValidation } from './agent_policy_validation'; +describe('Agent Policy form validation', () => { + it('should not return errors when agentPolicy is valid', () => { + const result = agentPolicyFormValidation({ + namespace: 'default', + name: 'policy', + }); + expect(result).toEqual({}); + }); + + it('should return error when agentPolicy has empty name', () => { + const result = agentPolicyFormValidation({ + namespace: 'default', + name: '', + }); + expect(result.name).toBeDefined(); + }); + + it('should return error when agentPolicy has empty namespace', () => { + const result = agentPolicyFormValidation({ + namespace: 'Default', + name: 'policy', + }); + expect(result.namespace).toBeDefined(); + }); + + it('should return error when agentPolicy has negative unenroll timeout', () => { + const result = agentPolicyFormValidation({ + namespace: 'Default', + name: 'policy', + unenroll_timeout: -1, + }); + expect(result.unenroll_timeout).toBeDefined(); + }); +}); From f2c373a6ebbd7223b790c2efc721798f19ccc3f7 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 27 Jan 2022 10:40:19 +0100 Subject: [PATCH 94/99] renamed to getFleetServerAgentPolicyId --- x-pack/plugins/fleet/server/services/agent_policy_create.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/agent_policy_create.ts b/x-pack/plugins/fleet/server/services/agent_policy_create.ts index 280cef9d820fe..9bbf2889357a3 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy_create.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy_create.ts @@ -24,7 +24,9 @@ import { ensureDefaultEnrollmentAPIKeysExists } from './setup'; const FLEET_SERVER_POLICY_ID = 'fleet-server-policy'; -async function getAgentPolicyId(soClient: SavedObjectsClientContract): Promise { +async function getFleetServerAgentPolicyId( + soClient: SavedObjectsClientContract +): Promise { let agentPolicyId; // creating first fleet server policy with id 'fleet-server-policy' let agentPolicy; @@ -97,7 +99,7 @@ export async function createAgentPolicyWithPackages({ if (hasFleetServer) { packagesToInstall.push(FLEET_SERVER_PACKAGE); - agentPolicyId = await getAgentPolicyId(soClient); + agentPolicyId = await getFleetServerAgentPolicyId(soClient); if (agentPolicyId === FLEET_SERVER_POLICY_ID) { // setting first fleet server policy to default, so that fleet server can enroll without setting policy_id newPolicy.is_default_fleet_server = true; From 68bd12a1350774397dd1b91e9a38523eb1867bd6 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 27 Jan 2022 15:09:02 +0100 Subject: [PATCH 95/99] fixed cypress test --- .../fleet/cypress/integration/integrations_mock.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts index aa8d4f14f4027..080b01458e18f 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations_mock.spec.ts @@ -66,7 +66,10 @@ describe('Add Integration - Mock API', () => { cy.intercept('POST', '/api/fleet/package_policies/upgrade/dryrun', [ { name: 'apache-2', - diff: [policyConfig, policyConfig], + diff: [ + policyConfig, + { ...policyConfig, package: { ...policyConfig.package, version: newVersion } }, + ], hasErrors: false, }, ]); From 247c279faf7b04b4592482af70caf882dfa97e11 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Mon, 31 Jan 2022 13:06:32 +0100 Subject: [PATCH 96/99] fixed package policy error message condition --- .../sections/agent_policy/create_package_policy_page/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index 1fbc202528933..743ff40ecf5e6 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -641,7 +641,7 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { - {agentPolicy && packageInfo && formState === 'INVALID' ? ( + {packageInfo && (formState === 'INVALID' || hasAgentPolicyError) ? ( Date: Tue, 1 Feb 2022 08:47:12 +0100 Subject: [PATCH 97/99] fixed import --- .../step_select_agent_policy.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx index 835bd473e3bdf..8558fbecbde0f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx @@ -23,12 +23,7 @@ import { import { Error } from '../../../components'; import type { AgentPolicy, PackageInfo, GetAgentPoliciesResponseItem } from '../../../types'; import { isPackageLimited, doesAgentPolicyAlreadyIncludePackage } from '../../../services'; -import { - useGetAgentPolicies, - sendGetOneAgentPolicy, - useAuthz, - useFleetStatus, -} from '../../../hooks'; +import { useGetAgentPolicies, sendGetOneAgentPolicy, useFleetStatus } from '../../../hooks'; const AgentPolicyFormRow = styled(EuiFormRow)` .euiFormRow__label { From 511c236206c926ba5bf83871883872569a9aca05 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Tue, 1 Feb 2022 08:51:35 +0100 Subject: [PATCH 98/99] fixed authz --- .../agent_enrollment_flyout/agent_policy_selection.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx index a83938471f9ea..539f9f990262c 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.tsx @@ -22,7 +22,7 @@ import { import type { AgentPolicy } from '../../types'; import { AgentPolicyPackageBadges } from '../agent_policy_package_badges'; -import { useCapabilities } from '../../hooks'; +import { useAuthz } from '../../hooks'; import { AdvancedAgentAuthenticationSettings } from './advanced_agent_authentication_settings'; @@ -77,8 +77,7 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => { () => resolveAgentId(agentPolicies, undefined) // no agent id selected yet ); - // Create new agent policy flyout state - const hasWriteCapabilites = useCapabilities().write; + const hasFleetAllPrivileges = useAuthz().fleet.all; useEffect( function triggerOnAgentPolicyChangeEffect() { @@ -137,7 +136,7 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => {
- + Date: Tue, 1 Feb 2022 10:26:26 +0100 Subject: [PATCH 99/99] fix cypress --- .../fleet/cypress/integration/integrations_real.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts index 9994b5e61575d..0a35dff62c8db 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts @@ -34,14 +34,14 @@ describe('Add Integration - Real API', () => { }); it('should install integration without policy', () => { - cy.visit('/app/integrations/detail/tomcat-1.2.1/settings'); + cy.visit('/app/integrations/detail/tomcat-1.3.0/settings'); cy.get('.euiButton').contains('Install Apache Tomcat assets').click(); cy.get('.euiCallOut').contains('This action will install 1 assets'); cy.getBySel(CONFIRM_MODAL_BTN).click(); cy.get('.euiLoadingSpinner').should('not.exist'); - cy.getBySel('installedVersion').contains('1.2.1'); + cy.getBySel('installedVersion').contains('1.3.0'); cy.get('.euiButton').contains('Uninstall Apache Tomcat').click(); cy.getBySel(CONFIRM_MODAL_BTN).click();