mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[APM] Make fleet plugin dependency optional (#104967)
* fixing tutorial when fleet plugin is disabled * addressing PR comments
This commit is contained in:
parent
5b207d8484
commit
d2ce8d5223
12 changed files with 401 additions and 166 deletions
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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-<version>.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-<version>.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-<version>.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-<version>.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-<version>.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-<version>.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-<version>.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-<version>.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-<version>.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-<version>.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"
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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}>
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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` }
|
||||
|
|
|
@ -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: [
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue