[APM] Make fleet plugin dependency optional (#104967)

* fixing tutorial when fleet plugin is disabled

* addressing PR comments
This commit is contained in:
Cauê Marcondes 2021-07-09 13:46:52 -04:00 committed by GitHub
parent 5b207d8484
commit d2ce8d5223
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 401 additions and 166 deletions

View file

@ -7,7 +7,6 @@
"data",
"embeddable",
"features",
"fleet",
"infra",
"licensing",
"observability",
@ -24,11 +23,15 @@
"security",
"spaces",
"taskManager",
"usageCollection"
"usageCollection",
"fleet"
],
"server": true,
"ui": true,
"configPath": ["xpack", "apm"],
"configPath": [
"xpack",
"apm"
],
"requiredBundles": [
"fleet",
"home",
@ -38,4 +41,4 @@
"ml",
"observability"
]
}
}

View file

@ -74,7 +74,7 @@ export interface ApmPluginStartDeps {
ml?: MlPluginStart;
triggersActionsUi: TriggersAndActionsUIPublicPluginStart;
observability: ObservabilityPublicStart;
fleet: FleetStart;
fleet?: FleetStart;
}
export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
@ -311,20 +311,21 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
}
public start(core: CoreStart, plugins: ApmPluginStartDeps) {
const { fleet } = plugins;
if (fleet) {
const agentEnrollmentExtensionData = getApmEnrollmentFlyoutData();
const agentEnrollmentExtensionData = getApmEnrollmentFlyoutData();
fleet.registerExtension({
package: 'apm',
view: 'agent-enrollment-flyout',
title: agentEnrollmentExtensionData.title,
Component: agentEnrollmentExtensionData.Component,
});
fleet.registerExtension({
package: 'apm',
view: 'agent-enrollment-flyout',
title: agentEnrollmentExtensionData.title,
Component: agentEnrollmentExtensionData.Component,
});
fleet.registerExtension({
package: 'apm',
view: 'package-detail-assets',
Component: LazyApmCustomAssetsExtension,
});
fleet.registerExtension({
package: 'apm',
view: 'package-detail-assets',
Component: LazyApmCustomAssetsExtension,
});
}
}
}

View file

@ -18,6 +18,7 @@ interface Args {
onPrem: boolean;
hasFleetPoliciesWithApmIntegration: boolean;
hasCloudPolicyWithApmIntegration: boolean;
isFleetEnabled: boolean;
}
const policyElasticAgentOnCloudAgent: APIResponseType['fleetAgents'][0] = {
@ -47,6 +48,7 @@ function Wrapper({
apmAgent,
onPrem,
hasCloudPolicyWithApmIntegration,
isFleetEnabled,
}: Args) {
const http = ({
get: () => ({
@ -56,6 +58,7 @@ function Wrapper({
? [policyElasticAgentOnCloudAgent]
: []),
],
isFleetEnabled,
cloudStandaloneSetup: {
apmServerUrl: 'cloud_url',
secretToken: 'foo',
@ -80,6 +83,7 @@ Integration.args = {
onPrem: true,
hasFleetPoliciesWithApmIntegration: false,
hasCloudPolicyWithApmIntegration: false,
isFleetEnabled: true,
};
export default {
@ -113,5 +117,8 @@ export default {
hasCloudPolicyWithApmIntegration: {
control: { type: 'boolean', options: [true, false] },
},
isFleetEnabled: {
control: { type: 'boolean', options: [true, false], defaultValue: true },
},
},
};

View file

@ -41,6 +41,7 @@ describe('getPolicyOptions', () => {
apmServerUrl: 'cloud_url',
secretToken: 'cloud_token',
},
isFleetEnabled: true,
};
const options = getPolicyOptions({
isCloudEnabled: true,
@ -65,6 +66,7 @@ describe('getPolicyOptions', () => {
apmServerUrl: 'cloud_url',
secretToken: 'cloud_token',
},
isFleetEnabled: true,
};
const options = getPolicyOptions({
isCloudEnabled: true,
@ -109,6 +111,7 @@ describe('getPolicyOptions', () => {
apmServerUrl: 'cloud_url',
secretToken: 'cloud_token',
},
isFleetEnabled: true,
};
const options = getPolicyOptions({
isCloudEnabled: true,
@ -151,6 +154,7 @@ describe('getPolicyOptions', () => {
const data: APIResponseType = {
fleetAgents: [],
cloudStandaloneSetup: undefined,
isFleetEnabled: true,
};
const options = getPolicyOptions({
isCloudEnabled: true,
@ -173,6 +177,7 @@ describe('getPolicyOptions', () => {
const data: APIResponseType = {
fleetAgents,
cloudStandaloneSetup: undefined,
isFleetEnabled: true,
};
const options = getPolicyOptions({
isCloudEnabled: true,
@ -213,6 +218,7 @@ describe('getPolicyOptions', () => {
const data: APIResponseType = {
fleetAgents: [policyElasticAgentOnCloudAgent, ...fleetAgents],
cloudStandaloneSetup: undefined,
isFleetEnabled: true,
};
const options = getPolicyOptions({
isCloudEnabled: true,
@ -256,6 +262,7 @@ describe('getPolicyOptions', () => {
const data: APIResponseType = {
fleetAgents: [],
cloudStandaloneSetup: undefined,
isFleetEnabled: true,
};
const options = getPolicyOptions({
isCloudEnabled: false,
@ -278,6 +285,7 @@ describe('getPolicyOptions', () => {
const data: APIResponseType = {
fleetAgents,
cloudStandaloneSetup: undefined,
isFleetEnabled: true,
};
const options = getPolicyOptions({
isCloudEnabled: false,

View file

@ -7,6 +7,10 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { HttpStart } from 'kibana/public';
import React from 'react';
import {
expectTextsInDocument,
expectTextsNotInDocument,
} from '../../utils/testHelpers';
import TutorialConfigAgent from './';
const policyElasticAgentOnCloudAgent = {
@ -32,68 +36,32 @@ const fleetAgents = [
];
describe('TutorialConfigAgent', () => {
it('renders loading component while API is being called', () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: jest.fn(),
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled
/>
);
expect(component.getByTestId('loading')).toBeInTheDocument();
beforeAll(() => {
// Mocks console.error so it won't polute tests output when testing the api throwing error
jest.spyOn(console, 'error').mockImplementation(() => null);
});
it('updates commands when a different policy is selected', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: jest.fn().mockReturnValue({
cloudStandaloneSetup: undefined,
fleetAgents,
}),
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled={false}
/>
);
expect(
await screen.findByText('Default Standalone configuration')
).toBeInTheDocument();
let commands = component.getByTestId('commands').innerHTML;
expect(commands).not.toEqual('');
expect(commands).toMatchInlineSnapshot(`
"java -javaagent:/path/to/elastic-apm-agent-&lt;version&gt;.jar \\\\
-Delastic.apm.service_name=my-application \\\\
-Delastic.apm.server_urls=http://localhost:8200 \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.environment=production \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-application.jar"
`);
fireEvent.click(component.getByTestId('comboBoxToggleListButton'));
fireEvent.click(component.getByText('agent foo'));
commands = component.getByTestId('commands').innerHTML;
expect(commands).not.toEqual('');
expect(commands).toMatchInlineSnapshot(`
"java -javaagent:/path/to/elastic-apm-agent-&lt;version&gt;.jar \\\\
-Delastic.apm.service_name=my-application \\\\
-Delastic.apm.server_urls=foo \\\\
-Delastic.apm.secret_token=foo \\\\
-Delastic.apm.environment=production \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-application.jar"
`);
afterAll(() => {
jest.restoreAllMocks();
});
describe('running on prem', () => {
it('selects defaul standalone by defauls', async () => {
describe('when fleet plugin is enabled', () => {
it('renders loading component while API is being called', () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: jest.fn(),
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled
/>
);
expect(component.getByTestId('loading')).toBeInTheDocument();
});
it('updates commands when a different policy is selected', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
@ -102,6 +70,7 @@ describe('TutorialConfigAgent', () => {
get: jest.fn().mockReturnValue({
cloudStandaloneSetup: undefined,
fleetAgents,
isFleetEnabled: true,
}),
} as unknown) as HttpStart
}
@ -112,6 +81,259 @@ describe('TutorialConfigAgent', () => {
expect(
await screen.findByText('Default Standalone configuration')
).toBeInTheDocument();
let commands = component.getByTestId('commands').innerHTML;
expect(commands).not.toEqual('');
expect(commands).toMatchInlineSnapshot(`
"java -javaagent:/path/to/elastic-apm-agent-&lt;version&gt;.jar \\\\
-Delastic.apm.service_name=my-application \\\\
-Delastic.apm.server_urls=http://localhost:8200 \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.environment=production \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-application.jar"
`);
fireEvent.click(component.getByTestId('comboBoxToggleListButton'));
fireEvent.click(component.getByText('agent foo'));
commands = component.getByTestId('commands').innerHTML;
expect(commands).not.toEqual('');
expect(commands).toMatchInlineSnapshot(`
"java -javaagent:/path/to/elastic-apm-agent-&lt;version&gt;.jar \\\\
-Delastic.apm.service_name=my-application \\\\
-Delastic.apm.server_urls=foo \\\\
-Delastic.apm.secret_token=foo \\\\
-Delastic.apm.environment=production \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-application.jar"
`);
});
describe('running on prem', () => {
it('selects defaul standalone by defauls', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: jest.fn().mockReturnValue({
cloudStandaloneSetup: undefined,
fleetAgents,
isFleetEnabled: true,
}),
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled={false}
/>
);
expect(
await screen.findByText('Default Standalone configuration')
).toBeInTheDocument();
expect(
component.getByTestId('policySelector_onPrem')
).toBeInTheDocument();
const commands = component.getByTestId('commands').innerHTML;
expect(commands).not.toEqual('');
expect(commands).toMatchInlineSnapshot(`
"java -javaagent:/path/to/elastic-apm-agent-&lt;version&gt;.jar \\\\
-Delastic.apm.service_name=my-application \\\\
-Delastic.apm.server_urls=http://localhost:8200 \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.environment=production \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-application.jar"
`);
});
it('shows get started with fleet link when there are no fleet agents', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: jest.fn().mockReturnValue({
cloudStandaloneSetup: undefined,
fleetAgents: [],
isFleetEnabled: true,
}),
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled
/>
);
expect(
await screen.findByText('Default Standalone configuration')
).toBeInTheDocument();
expect(
component.getByTestId('policySelector_onPrem')
).toBeInTheDocument();
const commands = component.getByTestId('commands').innerHTML;
expect(commands).not.toEqual('');
expect(commands).toMatchInlineSnapshot(`
"java -javaagent:/path/to/elastic-apm-agent-&lt;version&gt;.jar \\\\
-Delastic.apm.service_name=my-application \\\\
-Delastic.apm.server_urls=http://localhost:8200 \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.environment=production \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-application.jar"
`);
expectTextsInDocument(component, ['Get started with fleet']);
});
});
describe('running on cloud', () => {
it('selects defaul standalone by defauls', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: jest.fn().mockReturnValue({
cloudStandaloneSetup: {
apmServerUrl: 'cloud_url',
secretToken: 'cloud_token',
},
fleetAgents,
isFleetEnabled: true,
}),
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled
/>
);
expect(
await screen.findByText('Default Standalone configuration')
).toBeInTheDocument();
expect(
component.getByTestId('policySelector_cloud')
).toBeInTheDocument();
const commands = component.getByTestId('commands').innerHTML;
expect(commands).not.toEqual('');
expect(commands).toMatchInlineSnapshot(`
"java -javaagent:/path/to/elastic-apm-agent-&lt;version&gt;.jar \\\\
-Delastic.apm.service_name=my-application \\\\
-Delastic.apm.server_urls=cloud_url \\\\
-Delastic.apm.secret_token=cloud_token \\\\
-Delastic.apm.environment=production \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-application.jar"
`);
});
it('selects policy elastic agent on cloud when available by default', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: jest.fn().mockReturnValue({
cloudStandaloneSetup: {
apmServerUrl: 'cloud_url',
secretToken: 'cloud_token',
},
fleetAgents: [...fleetAgents, policyElasticAgentOnCloudAgent],
isFleetEnabled: true,
}),
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled
/>
);
expect(
await screen.findByText('Elastic Cloud agent policy')
).toBeInTheDocument();
expect(
component.getByTestId('policySelector_policy-elastic-agent-on-cloud')
).toBeInTheDocument();
const commands = component.getByTestId('commands').innerHTML;
expect(commands).not.toEqual('');
expect(commands).toMatchInlineSnapshot(`
"java -javaagent:/path/to/elastic-apm-agent-&lt;version&gt;.jar \\\\
-Delastic.apm.service_name=my-application \\\\
-Delastic.apm.server_urls=apm_cloud_url \\\\
-Delastic.apm.secret_token=apm_cloud_token \\\\
-Delastic.apm.environment=production \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-application.jar"
`);
});
it('shows default standalone option when api throws an error', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: () => {
throw new Error('Boom');
},
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled
/>
);
expect(
await screen.findByText('Default Standalone configuration')
).toBeInTheDocument();
const commands = component.getByTestId('commands').innerHTML;
expect(commands).not.toEqual('');
expect(commands).toMatchInlineSnapshot(`
"java -javaagent:/path/to/elastic-apm-agent-&lt;version&gt;.jar \\\\
-Delastic.apm.service_name=my-application \\\\
-Delastic.apm.server_urls=http://localhost:8200 \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.environment=production \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-application.jar"
`);
});
});
});
describe('when fleet plugin is disabled', () => {
it('hides fleet links', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: jest.fn().mockReturnValue({
cloudStandaloneSetup: undefined,
fleetAgents: [],
isFleetEnabled: false,
}),
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled
/>
);
expectTextsNotInDocument(component, [
'Get started with fleet',
'Manage fleet policies',
]);
});
it('shows default standalone on prem', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: jest.fn().mockReturnValue({
cloudStandaloneSetup: undefined,
fleetAgents: [],
isFleetEnabled: false,
}),
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled
/>
);
expect(
await screen.findByText('Default Standalone configuration')
).toBeInTheDocument();
expect(
component.getByTestId('policySelector_onPrem')
).toBeInTheDocument();
@ -127,9 +349,7 @@ describe('TutorialConfigAgent', () => {
-jar my-application.jar"
`);
});
});
describe('running on cloud', () => {
it('selects defaul standalone by defauls', async () => {
it('shows default standalone on cloud', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
@ -140,7 +360,8 @@ describe('TutorialConfigAgent', () => {
apmServerUrl: 'cloud_url',
secretToken: 'cloud_token',
},
fleetAgents,
fleetAgents: [],
isFleetEnabled: false,
}),
} as unknown) as HttpStart
}
@ -164,42 +385,5 @@ describe('TutorialConfigAgent', () => {
-jar my-application.jar"
`);
});
it('selects policy elastic agent on cloud when available by default', async () => {
const component = render(
<TutorialConfigAgent
variantId="java"
http={
({
get: jest.fn().mockReturnValue({
cloudStandaloneSetup: {
apmServerUrl: 'cloud_url',
secretToken: 'cloud_token',
},
fleetAgents: [...fleetAgents, policyElasticAgentOnCloudAgent],
}),
} as unknown) as HttpStart
}
basePath="http://localhost:5601"
isCloudEnabled
/>
);
expect(
await screen.findByText('Elastic Cloud agent policy')
).toBeInTheDocument();
expect(
component.getByTestId('policySelector_policy-elastic-agent-on-cloud')
).toBeInTheDocument();
const commands = component.getByTestId('commands').innerHTML;
expect(commands).not.toEqual('');
expect(commands).toMatchInlineSnapshot(`
"java -javaagent:/path/to/elastic-apm-agent-&lt;version&gt;.jar \\\\
-Delastic.apm.service_name=my-application \\\\
-Delastic.apm.server_urls=apm_cloud_url \\\\
-Delastic.apm.secret_token=apm_cloud_token \\\\
-Delastic.apm.environment=production \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-application.jar"
`);
});
});
});

View file

@ -46,16 +46,43 @@ interface Props {
isCloudEnabled: boolean;
}
const INITIAL_STATE = {
fleetAgents: [],
cloudStandaloneSetup: undefined,
isFleetEnabled: false,
};
function getFleetLink({
isFleetEnabled,
hasFleetAgents,
basePath,
}: {
isFleetEnabled: boolean;
hasFleetAgents: boolean;
basePath: string;
}) {
if (!isFleetEnabled) {
return;
}
return hasFleetAgents
? {
label: MANAGE_FLEET_POLICIES_LABEL,
href: `${basePath}/app/fleet#/policies`,
}
: {
label: GET_STARTED_WITH_FLEET_LABEL,
href: `${basePath}/app/integrations#/detail/apm-0.3.0/overview`,
};
}
function TutorialConfigAgent({
variantId,
http,
basePath,
isCloudEnabled,
}: Props) {
const [data, setData] = useState<APIResponseType>({
fleetAgents: [],
cloudStandaloneSetup: undefined,
});
const [data, setData] = useState<APIResponseType>(INITIAL_STATE);
const [isLoading, setIsLoading] = useState(true);
const [selectedOption, setSelectedOption] = useState<PolicyOption>();
@ -68,6 +95,7 @@ function TutorialConfigAgent({
setData(response as APIResponseType);
}
} catch (e) {
setIsLoading(false);
console.error('Error while fetching fleet agents.', e);
}
}
@ -105,15 +133,6 @@ function TutorialConfigAgent({
});
const hasFleetAgents = !!data.fleetAgents.length;
const fleetLink = hasFleetAgents
? {
label: MANAGE_FLEET_POLICIES_LABEL,
href: `${basePath}/app/fleet#/policies`,
}
: {
label: GET_STARTED_WITH_FLEET_LABEL,
href: `${basePath}/app/integrations#/detail/apm-0.3.0/overview`,
};
return (
<>
@ -125,7 +144,11 @@ function TutorialConfigAgent({
onChange={(newSelectedOption) =>
setSelectedOption(newSelectedOption)
}
fleetLink={fleetLink}
fleetLink={getFleetLink({
isFleetEnabled: data.isFleetEnabled,
hasFleetAgents,
basePath,
})}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>

View file

@ -21,7 +21,7 @@ interface Props {
options: PolicyOption[];
selectedOption?: PolicyOption;
onChange: (selectedOption?: PolicyOption) => void;
fleetLink: {
fleetLink?: {
label: string;
href: string;
};
@ -58,9 +58,11 @@ export function PolicySelector({
{ defaultMessage: 'Choose policy' }
)}
labelAppend={
<EuiText size="xs">
<EuiLink href={fleetLink.href}>{fleetLink.label}</EuiLink>
</EuiText>
fleetLink && (
<EuiText size="xs">
<EuiLink href={fleetLink.href}>{fleetLink.label}</EuiLink>
</EuiText>
)
}
helpText={i18n.translate(
'xpack.apm.tutorial.agent_config.choosePolicy.helper',

View file

@ -42,6 +42,7 @@ function TutorialFleetInstructions({ http, basePath, isDarkTheme }: Props) {
const response = await http.get('/api/apm/fleet/has_data');
setData(response as APIResponseType);
} catch (e) {
setIsLoading(false);
console.error('Error while fetching fleet details.', e);
}
setIsLoading(false);

View file

@ -15,7 +15,7 @@ import {
Plugin,
PluginInitializerContext,
} from 'src/core/server';
import { mapValues, once } from 'lodash';
import { isEmpty, mapValues, once } from 'lodash';
import { TECHNICAL_COMPONENT_TEMPLATE_NAME } from '../../rule_registry/common/assets';
import { mappingFromFieldMap } from '../../rule_registry/common/mapping_from_field_map';
import { APMConfig, APMXPackConfig, APM_SERVER_FEATURE_ID } from '.';
@ -104,21 +104,6 @@ export class APMPlugin
});
}
plugins.home?.tutorials.registerTutorial(
tutorialProvider({
isEnabled: this.currentConfig['xpack.apm.ui.enabled'],
indexPatternTitle: this.currentConfig['apm_oss.indexPattern'],
cloud: plugins.cloud,
indices: {
errorIndices: this.currentConfig['apm_oss.errorIndices'],
metricsIndices: this.currentConfig['apm_oss.metricsIndices'],
onboardingIndices: this.currentConfig['apm_oss.onboardingIndices'],
sourcemapIndices: this.currentConfig['apm_oss.sourcemapIndices'],
transactionIndices: this.currentConfig['apm_oss.transactionIndices'],
},
})
);
plugins.features.registerKibanaFeature(APM_FEATURE);
registerFeaturesUsage({ licensingPlugin: plugins.licensing });
@ -206,6 +191,22 @@ export class APMPlugin
};
}) as APMRouteHandlerResources['plugins'];
plugins.home?.tutorials.registerTutorial(
tutorialProvider({
isEnabled: this.currentConfig['xpack.apm.ui.enabled'],
indexPatternTitle: this.currentConfig['apm_oss.indexPattern'],
cloud: plugins.cloud,
isFleetPluginEnabled: !isEmpty(resourcePlugins.fleet),
indices: {
errorIndices: this.currentConfig['apm_oss.errorIndices'],
metricsIndices: this.currentConfig['apm_oss.metricsIndices'],
onboardingIndices: this.currentConfig['apm_oss.onboardingIndices'],
sourcemapIndices: this.currentConfig['apm_oss.sourcemapIndices'],
transactionIndices: this.currentConfig['apm_oss.transactionIndices'],
},
})
);
const telemetryUsageCounter = resourcePlugins.usageCollection?.setup.createUsageCounter(
APM_SERVER_FEATURE_ID
);

View file

@ -32,7 +32,7 @@ const hasFleetDataRoute = createApmServerRoute({
handler: async ({ core, plugins }) => {
const fleetPluginStart = await plugins.fleet?.start();
if (!fleetPluginStart) {
throw Boom.internal(FLEET_REQUIRED_MESSAGE);
return { hasData: false };
}
const packagePolicies = await getApmPackgePolicies({
core,
@ -56,7 +56,7 @@ const fleetAgentsRoute = createApmServerRoute({
const fleetPluginStart = await plugins.fleet?.start();
if (!fleetPluginStart) {
throw Boom.internal(FLEET_REQUIRED_MESSAGE);
return { cloudStandaloneSetup, fleetAgents: [], isFleetEnabled: false };
}
// fetches package policies that contains APM integrations
const packagePolicies = await getApmPackgePolicies({
@ -75,6 +75,7 @@ const fleetAgentsRoute = createApmServerRoute({
return {
cloudStandaloneSetup,
isFleetEnabled: true,
fleetAgents: fleetAgents.map((agent) => {
const packagePolicy = policiesGroupedById[agent.id];
const packagePolicyVars = packagePolicy.inputs[0]?.vars;
@ -190,11 +191,6 @@ export const apmFleetRouteRepository = createApmServerRouteRepository()
.add(getMigrationCheckRoute)
.add(createCloudApmPackagePolicyRoute);
const FLEET_REQUIRED_MESSAGE = i18n.translate(
'xpack.apm.fleet_has_data.fleetRequired',
{ defaultMessage: `Fleet plugin is required` }
);
const FLEET_SECURITY_REQUIRED_MESSAGE = i18n.translate(
'xpack.apm.api.fleet.fleetSecurityRequired',
{ defaultMessage: `Fleet and Security plugins are required` }

View file

@ -38,12 +38,14 @@ export function onPremInstructions({
metricsIndices,
sourcemapIndices,
onboardingIndices,
isFleetPluginEnabled,
}: {
errorIndices: string;
transactionIndices: string;
metricsIndices: string;
sourcemapIndices: string;
onboardingIndices: string;
isFleetPluginEnabled: boolean;
}): InstructionsSchema {
const EDIT_CONFIG = createEditConfig();
const START_SERVER_UNIX = createStartServerUnix();
@ -69,12 +71,17 @@ export function onPremInstructions({
iconType: 'alert',
},
instructionVariants: [
{
id: INSTRUCTION_VARIANT.FLEET,
instructions: [
{ customComponentName: 'TutorialFleetInstructions' },
],
},
// hides fleet section when plugin is disabled
...(isFleetPluginEnabled
? [
{
id: INSTRUCTION_VARIANT.FLEET,
instructions: [
{ customComponentName: 'TutorialFleetInstructions' },
],
},
]
: []),
{
id: INSTRUCTION_VARIANT.OSX,
instructions: [

View file

@ -28,6 +28,7 @@ export const tutorialProvider = ({
indexPatternTitle,
indices,
cloud,
isFleetPluginEnabled,
}: {
isEnabled: boolean;
indexPatternTitle: string;
@ -39,6 +40,7 @@ export const tutorialProvider = ({
sourcemapIndices: string;
onboardingIndices: string;
};
isFleetPluginEnabled: boolean;
}) => () => {
const savedObjects = [
{
@ -104,7 +106,7 @@ It allows you to monitor the performance of thousands of applications in real ti
euiIconType: 'apmApp',
artifacts,
customStatusCheckName: 'apm_fleet_server_status_check',
onPrem: onPremInstructions(indices),
onPrem: onPremInstructions({ ...indices, isFleetPluginEnabled }),
elasticCloud: createElasticCloudInstructions(cloud),
previewImagePath: '/plugins/apm/assets/apm.png',
savedObjects,