-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[APM] Serverless Onboarding with Custom Tutorials (#158228)
Closes #155371 ## Summary PR adds Serverless Onboarding flow using Custom Integration. This would also lay the foundation for us to complete get rid of Home Tutorial App and move the remaining `onPrem` and `cloud` tutorials which are currently still loaded using Home Tutorial App. 1. Adds new Custom Integration for Serverless Onboarding (Toggling Home AApp Tutorial Integration) 2. Since we are migrating away from the Home App Tutorials, lot of existing code has been duplicated and refactored for the custom implementation. Home App Tutorial would require the Server to register all the steps and the client to only register a custom component which then would be loaded by Home App Tutorial component. We don't need to follow this approach any more. All the UX logic has now been moved to the Public folder with only Custom Integration done on the `server/plugin.ts`. 3. As we are not sure how the solutions will be informed about being running on Serverless or not, I have introduced a new variable in `serverless.oblt.yml` file called `xpack.apm.serverlessOnboarding: true`. With this the development has been done. This can be changed to actual logic once we know more. 4. A new configuration `xpack.apm.managedServiceUrl` for accessing Managed Service URL is also being added by Control Plane team as part of https://elasticco.atlassian.net/browse/CP-2403. Hence this PR expects this property to be present for Serverless. 5. Unit tests to toggle between `secret_token` and `api_key` depending on availability has been added. No API Tests were added as no new API created. Cypress Tests cannot be added due to Serverless ## Need help reviewing the PR ? 1. `config/serverless.oblt.yml` - Adds the new flag which would enable this flow 2. `x-pack/plugins/apm/common/tutorial/tutorials.ts` - Defines the configuration required to register the APM's Tutorial Custom Integration 3. `x-pack/plugins/apm/public/components/app/tutorials/commands` - This directory contains all the agent specific data required to load the TABLE with settings required for configuring APM MIS. 4. `x-pack/plugins/apm/public/components/app/tutorials/instructions` - This folder contains all the individual agent specific instructions in the format used by [EuiSteps](https://eui.elastic.co/#/navigation/steps#complex-steps) 5. `x-pack/plugins/apm/public/components/routing` - Here we register our custom route 6. Changes on the server side a quite small and they only register the custom integration. 7. `x-pack/plugins/apm/public/components/app/tutorials/serverless_instructions.tsx` - This file currently defines all the logic for registering Serverless instructions. We will soon have similar files for `onPrem` and `cloud` instructions ### Risk Matrix | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | The flow depends on presence of a flag in `kibana.yml` file. | Low | High | By default this flow will be disabled and would fallback to traditional onboarding in absence of the flag. | ### Demo https://github.com/elastic/kibana/assets/7416358/d60f0610-1fea-4540-86f5-2d72ab97f640 ### Updated Demo with Create API Button inside the table https://github.com/elastic/kibana/assets/7416358/e84d8d6c-a048-4638-9b63-45080feca90b --------- Co-authored-by: kibanamachine <[email protected]>
- Loading branch information
1 parent
177914b
commit ac2fc4c
Showing
50 changed files
with
3,637 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* 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 { i18n } from '@kbn/i18n'; | ||
import { CustomIntegration } from '@kbn/custom-integrations-plugin/common'; | ||
|
||
const APM_INTEGRATION_CATEGORIES = ['observability', 'apm']; | ||
|
||
export const apmTutorialCustomIntegration: Omit<CustomIntegration, 'type'> = { | ||
id: 'apm', | ||
title: i18n.translate('xpack.apm.tutorial.specProvider.name', { | ||
defaultMessage: 'APM', | ||
}), | ||
categories: APM_INTEGRATION_CATEGORIES, | ||
uiInternalPath: '/app/apm/onboarding', | ||
description: i18n.translate('xpack.apm.tutorial.introduction', { | ||
defaultMessage: | ||
'Collect performance metrics from your applications with Elastic APM.', | ||
}), | ||
icons: [ | ||
{ | ||
type: 'eui', | ||
src: 'apmApp', | ||
}, | ||
], | ||
shipper: 'tutorial', | ||
isBeta: false, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
x-pack/plugins/apm/public/components/app/onboarding/agent_config_instructions.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* 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 { EuiCodeBlock, EuiSpacer } from '@elastic/eui'; | ||
import { | ||
getApmAgentCommands, | ||
getApmAgentVariables, | ||
getApmAgentLineNumbers, | ||
getApmAgentHighlightLang, | ||
} from './commands/get_apm_agent_commands'; | ||
import { AgentConfigurationTable } from './agent_config_table'; | ||
|
||
export function AgentConfigInstructions({ | ||
variantId, | ||
apmServerUrl, | ||
secretToken, | ||
apiKey, | ||
createApiKey, | ||
createApiKeyLoading, | ||
}: { | ||
variantId: string; | ||
apmServerUrl: string; | ||
secretToken?: string; | ||
apiKey?: string | null; | ||
createApiKey?: () => void; | ||
createApiKeyLoading?: boolean; | ||
}) { | ||
const commands = getApmAgentCommands({ | ||
variantId, | ||
apmServerUrl, | ||
secretToken, | ||
apiKey, | ||
}); | ||
|
||
const variables = getApmAgentVariables(variantId, secretToken); | ||
const lineNumbers = getApmAgentLineNumbers(variantId, apiKey); | ||
const highlightLang = getApmAgentHighlightLang(variantId); | ||
|
||
return ( | ||
<> | ||
<EuiSpacer /> | ||
<AgentConfigurationTable | ||
variables={variables} | ||
data={{ apmServerUrl, secretToken, apiKey }} | ||
createApiKey={createApiKey} | ||
createApiKeyLoading={createApiKeyLoading} | ||
/> | ||
<EuiSpacer /> | ||
|
||
<EuiCodeBlock | ||
isCopyable | ||
language={highlightLang || 'bash'} | ||
data-test-subj="commands" | ||
lineNumbers={lineNumbers} | ||
whiteSpace="pre" | ||
> | ||
{commands} | ||
</EuiCodeBlock> | ||
</> | ||
); | ||
} |
106 changes: 106 additions & 0 deletions
106
x-pack/plugins/apm/public/components/app/onboarding/agent_config_table.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/* | ||
* 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 type { ValuesType } from 'utility-types'; | ||
import { get } from 'lodash'; | ||
import { | ||
EuiBasicTable, | ||
EuiText, | ||
EuiBasicTableColumn, | ||
EuiButton, | ||
} from '@elastic/eui'; | ||
import { i18n } from '@kbn/i18n'; | ||
|
||
function ConfigurationValueColumn({ | ||
columnKey, | ||
value, | ||
createApiKey, | ||
createApiKeyLoading, | ||
}: { | ||
columnKey: string; | ||
value: string | null; | ||
createApiKey?: () => void; | ||
createApiKeyLoading?: boolean; | ||
}) { | ||
const shouldRenderCreateApiKeyButton = | ||
columnKey === 'apiKey' && value === null; | ||
|
||
if (shouldRenderCreateApiKeyButton) { | ||
return ( | ||
<EuiButton | ||
data-test-subj="createApiKeyAndId" | ||
fill | ||
onClick={createApiKey} | ||
isLoading={createApiKeyLoading} | ||
> | ||
{i18n.translate('xpack.apm.tutorial.apiKey.create', { | ||
defaultMessage: 'Create API Key', | ||
})} | ||
</EuiButton> | ||
); | ||
} | ||
|
||
return ( | ||
<EuiText size="s" color="accent"> | ||
{value} | ||
</EuiText> | ||
); | ||
} | ||
|
||
export function AgentConfigurationTable({ | ||
variables, | ||
data, | ||
createApiKey, | ||
createApiKeyLoading, | ||
}: { | ||
variables: { [key: string]: string }; | ||
data: { | ||
apmServerUrl?: string; | ||
secretToken?: string; | ||
apiKey?: string | null; | ||
}; | ||
createApiKey?: () => void; | ||
createApiKeyLoading?: boolean; | ||
}) { | ||
if (!variables) return null; | ||
|
||
const defaultValues = { | ||
apmServiceName: 'my-service-name', | ||
apmEnvironment: 'my-environment', | ||
}; | ||
|
||
const columns: Array<EuiBasicTableColumn<ValuesType<typeof items>>> = [ | ||
{ | ||
field: 'setting', | ||
name: i18n.translate('xpack.apm.onboarding.agent.column.configSettings', { | ||
defaultMessage: 'Configuration setting', | ||
}), | ||
}, | ||
{ | ||
field: 'value', | ||
name: i18n.translate('xpack.apm.onboarding.agent.column.configValue', { | ||
defaultMessage: 'Configuration value', | ||
}), | ||
render: (_, { value, key }) => ( | ||
<ConfigurationValueColumn | ||
columnKey={key} | ||
value={value} | ||
createApiKey={createApiKey} | ||
createApiKeyLoading={createApiKeyLoading} | ||
/> | ||
), | ||
}, | ||
]; | ||
|
||
const items = Object.entries(variables).map(([key, value]) => ({ | ||
setting: value, | ||
value: get({ ...data, ...defaultValues }, key), | ||
key, | ||
})); | ||
return <EuiBasicTable items={items} columns={columns} />; | ||
} |
65 changes: 65 additions & 0 deletions
65
x-pack/plugins/apm/public/components/app/onboarding/commands/django.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* 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 { i18n } from '@kbn/i18n'; | ||
|
||
export const djangoVariables = (secretToken?: string) => ({ | ||
apmServiceName: 'SERVICE_NAME', | ||
...(secretToken && { secretToken: 'SECRET_TOKEN' }), | ||
...(!secretToken && { apiKey: 'API_KEY' }), | ||
apmServerUrl: 'SERVER_URL', | ||
apmEnvironment: 'ENVIRONMENT', | ||
}); | ||
|
||
export const djangoHighlightLang = 'py'; | ||
|
||
export const djangoLineNumbers = () => ({ | ||
start: 1, | ||
highlight: '1, 3, 5, 7, 9, 12, 15, 18-19, 21, 23, 25', | ||
}); | ||
|
||
export const django = `INSTALLED_APPS = ( | ||
# ${i18n.translate( | ||
'xpack.apm.onboarding.djangoClient.configure.commands.addAgentComment', | ||
{ | ||
defaultMessage: 'Add the agent to installed apps', | ||
} | ||
)} | ||
'elasticapm.contrib.django', | ||
# ... | ||
) | ||
ELASTIC_APM = { | ||
# {{serviceNameHint}} | ||
'SERVICE_NAME': 'my-service-name', | ||
{{^secretToken}} | ||
# {{apiKeyHint}} | ||
'API_KEY': '{{{apiKey}}}', | ||
{{/secretToken}} | ||
{{#secretToken}} | ||
# {{secretTokenHint}} | ||
'SECRET_TOKEN': '{{{secretToken}}}', | ||
{{/secretToken}} | ||
# {{{serverUrlHint}}} | ||
'SERVER_URL': '{{{apmServerUrl}}}', | ||
# {{{serviceEnvironmentHint}}} | ||
'ENVIRONMENT': 'my-environment', | ||
} | ||
MIDDLEWARE = ( | ||
# ${i18n.translate( | ||
'xpack.apm.onboarding.djangoClient.configure.commands.addTracingMiddlewareComment', | ||
{ | ||
defaultMessage: 'Add our tracing middleware to send performance metrics', | ||
} | ||
)} | ||
'elasticapm.contrib.django.middleware.TracingMiddleware', | ||
#... | ||
)`; |
47 changes: 47 additions & 0 deletions
47
x-pack/plugins/apm/public/components/app/onboarding/commands/dotnet.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* 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 { i18n } from '@kbn/i18n'; | ||
|
||
export const dotnetVariables = (secretToken?: string) => ({ | ||
apmServiceName: 'ServiceName', | ||
...(secretToken && { secretToken: 'SecretToken' }), | ||
...(!secretToken && { apiKey: 'ApiKey' }), | ||
apmServerUrl: 'ServerUrl', | ||
apmEnvironment: 'Environment', | ||
}); | ||
|
||
export const dotnetHighlightLang = 'dotnet'; | ||
|
||
export const dotnetLineNumbers = () => ({ | ||
start: 1, | ||
highlight: '1-2, 4, 6, 8, 10-12', | ||
}); | ||
|
||
export const dotnet = `{ | ||
"ElasticApm": { | ||
/// {{serviceNameHint}} ${i18n.translate( | ||
'xpack.apm.onboarding.dotnetClient.createConfig.commands.defaultServiceName', | ||
{ | ||
defaultMessage: 'Default is the entry assembly of the application.', | ||
} | ||
)} | ||
"ServiceName": "my-service-name", | ||
{{^secretToken}} | ||
/// {{apiKeyHint}} | ||
"ApiKey": "{{{apiKey}}}", | ||
{{/secretToken}} | ||
{{#secretToken}} | ||
/// {{secretTokenHint}} | ||
"SecretToken": "{{{secretToken}}}", | ||
{{/secretToken}} | ||
/// {{{serverUrlHint}}} | ||
"ServerUrl": "{{{apmServerUrl}}}", | ||
/// {{{serviceEnvironmentHint}}} | ||
"Environment": "my-environment", | ||
} | ||
}`; |
Oops, something went wrong.