-
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.
[Fleet] [Feature Branch] Create Fleet
_debug
UI (#131322)
* Bootstrap Fleet /_debug route + React Query * [Fleet] [Debug UI] Implement "Agent Policy Debugger" UI (#131335) * Add initial agent policy debugger module * Fix clear button in agent policy select * Implement deletion of selected policy * Fix layout of combo-box/button * Add searchable ID to agent policy labels * Add description text to debugger module * Fixup loading/error logic * [Fleet] Saved Objects Debugger (#131370) * saved objects debugger * converted so names to combobox * types fix * extracted combo box component * fixed error display * [Fleet] [Debug UI] Implement "Integration Debugger" UI (#131354) * Implement integrations debugger UI * Clean up + add link to integration settings * Add divider below integration debugger * Clean up loading states * Fix flex spacing for saved objects debugger * [Fleet] Added fleet indices query to debug UI (#131395) * fleet indices * keeping the type and name combo close in saved objects * fixed prettier * removed useEffects, simplified use of useQuery (#131482) * using different query for saved objects (#131491) * [Fleet] [Debug UI] Implement "Preconfiguration debugger" UI (#131436) * Implement preconfiguration debugger UI * Add code block view * Added missing newline Co-authored-by: Julia Bardi <[email protected]> * Prevent flicker in saved objects code block * added links including health check report (#131503) * added links including health check report * experiment with accordion Co-authored-by: Kibana Machine <[email protected]> * Refactor panel rendering + danger zone callout * Convert panels to all singular * confirm modal for reset preconfig (#131596) * Add icons to useful links + fix reset all -> title case * Fix disabled health check link * added orphaned policies api and to debug page (#131697) * Language fixes around orphaned policy module * Add some basic dev docs around the debugger * increasing page load bundle limit slightly (#132690) * Remove health check link as it's not implemented * Fix agents link + disable reset all button when no preconfigured policies * Update doc title on debug page * Translate everything * Remove delete orphaned endpoint + fix force flag in existing delete endpoint * Fix type * Add API integration tests for orphaned policies Co-authored-by: Julia Bardi <[email protected]> Co-authored-by: Kibana Machine <[email protected]>
- Loading branch information
1 parent
e1eb3db
commit d8558fc
Showing
27 changed files
with
2,007 additions
and
76 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
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,27 @@ | ||
# Fleet Debugger | ||
|
||
Fleet includes a "debug" interface that provides some insight and data management capabilities around Fleet's underlying data. This interface can be used to diagnose issues, assist support engineers, and restore functionality to broken Fleet installations. | ||
|
||
![Fleet Debugger UI Screenshot](https://user-images.githubusercontent.com/6766512/167193984-fcb100c4-729d-4a0b-ae64-2b280272da96.png) | ||
|
||
## Accessing the Fleet debugger | ||
|
||
The debugger is served at `<kibana>/app/fleet/_debug`. This page shares the same permissions requirement as other `/fleet` pages, so you'll need a user with the `fleet.all` permission. | ||
|
||
## Using the Fleet debugger | ||
|
||
The Fleet debugger provides debugger modules for the following Fleet data: | ||
|
||
- Agent Policies | ||
- Installed Integrations | ||
- Saved Objects | ||
- System Indices | ||
- Preconfiguration | ||
- "Orphaned" Integration Policies | ||
|
||
Each module contains an explanation of its functionality and behavior, but generally the goal of each module is to | ||
|
||
1. Provide visibility into the underlying data for the given object | ||
1. Provide cleanup/reset functionality in order to recover from malformed data that may be preventing normal usage of Fleet | ||
|
||
The debugger should be used when possible to assist with SDH's when we request things like a copy/paste of a given policy object or for some cleanup operation to be run via `cURL`. As common SDH tasks are identified, the debugger should be expanded to suit the Fleet UI team's and the support team's needs. |
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
172 changes: 172 additions & 0 deletions
172
...ugins/fleet/public/applications/fleet/sections/debug/components/agent_policy_debugger.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,172 @@ | ||
/* | ||
* 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 { | ||
EuiButton, | ||
EuiCallOut, | ||
EuiCode, | ||
EuiComboBox, | ||
EuiFlexGroup, | ||
EuiFlexItem, | ||
EuiLink, | ||
EuiSpacer, | ||
EuiText, | ||
} from '@elastic/eui'; | ||
import { useQuery } from 'react-query'; | ||
|
||
import { FormattedMessage } from '@kbn/i18n-react'; | ||
import { i18n } from '@kbn/i18n'; | ||
|
||
import { sendGetAgentPolicies, useLink } from '../../../hooks'; | ||
import { SO_SEARCH_LIMIT } from '../../../constants'; | ||
|
||
import { policyHasFleetServer } from '../../../services'; | ||
import type { AgentPolicy } from '../../../types'; | ||
import { AgentPolicyDeleteProvider } from '../../agent_policy/components'; | ||
|
||
import { queryClient } from '..'; | ||
|
||
import { CodeBlock } from './code_block'; | ||
|
||
const fetchAgentPolicies = async () => { | ||
const response = await sendGetAgentPolicies({ | ||
full: true, | ||
perPage: SO_SEARCH_LIMIT, | ||
sortOrder: 'asc', | ||
}); | ||
|
||
if (response.error) { | ||
throw new Error(response.error.message); | ||
} | ||
|
||
return response; | ||
}; | ||
|
||
export const AgentPolicyDebugger: React.FunctionComponent = () => { | ||
const { getHref } = useLink(); | ||
const [selectedPolicyId, setSelectedPolicyId] = useState<string>(); | ||
|
||
// TODO: Depending on the number of agent policies, this might need to be switched to | ||
// `useInfinite` query with an infinite scrolling approach in the dropdown options. | ||
const { data, status } = useQuery('debug-agent-policies', fetchAgentPolicies); | ||
|
||
const agentPolicies = data?.data?.items ?? []; | ||
const comboBoxOptions = agentPolicies.map((policy) => ({ | ||
label: `${policy.name} - ${policy.id}`, | ||
value: policy.id, | ||
})); | ||
|
||
const selectedOptions = selectedPolicyId | ||
? [comboBoxOptions.find((option) => option.value === selectedPolicyId)!] | ||
: []; | ||
|
||
const selectedAgentPolicy = agentPolicies.find((policy) => policy.id === selectedPolicyId); | ||
|
||
const onDelete = () => { | ||
setSelectedPolicyId(undefined); | ||
queryClient.invalidateQueries('debug-agent-policies'); | ||
}; | ||
|
||
if (status === 'error') { | ||
return ( | ||
<EuiCallOut title="Error" color="danger"> | ||
<FormattedMessage | ||
id="xpack.fleet.debug.agentPolicyDebugger.fetchError" | ||
defaultMessage="Error fetching Agent Policies" | ||
/> | ||
</EuiCallOut> | ||
); | ||
} | ||
|
||
return ( | ||
<> | ||
<EuiText grow={false}> | ||
<p> | ||
<FormattedMessage | ||
id="xpack.fleet.debug.agentPolicyDebugger.description" | ||
defaultMessage="Search for an Agent Policy using its name or {codeId} value. Use the code block below to diagnose any potential issues with the policy's configuration." | ||
values={{ codeId: <EuiCode>id</EuiCode> }} | ||
/> | ||
</p> | ||
</EuiText> | ||
|
||
<EuiSpacer size="m" /> | ||
|
||
<EuiFlexGroup alignItems="center" justifyContent="flexStart"> | ||
<EuiFlexItem | ||
grow={false} | ||
css={` | ||
min-width: 600px; | ||
`} | ||
> | ||
<EuiComboBox | ||
aria-label={i18n.translate('xpack.fleet.debug.agentPolicyDebugger.selectLabel', { | ||
defaultMessage: 'Select an Agent Policy', | ||
})} | ||
placeholder={i18n.translate('xpack.fleet.debug.agentPolicyDebugger.selectLabel', { | ||
defaultMessage: 'Select an Agent Policy', | ||
})} | ||
fullWidth | ||
options={comboBoxOptions} | ||
singleSelection={{ asPlainText: true }} | ||
selectedOptions={selectedOptions} | ||
isLoading={status === 'loading'} | ||
onChange={(newSelectedOptions) => { | ||
// Handle "clear" action | ||
if (!newSelectedOptions.length) { | ||
setSelectedPolicyId(undefined); | ||
} else { | ||
setSelectedPolicyId(newSelectedOptions[0].value); | ||
} | ||
}} | ||
/> | ||
</EuiFlexItem> | ||
|
||
{selectedPolicyId && ( | ||
<AgentPolicyDeleteProvider | ||
hasFleetServer={policyHasFleetServer(selectedAgentPolicy as AgentPolicy)} | ||
> | ||
{(deleteAgentPolicyPrompt) => { | ||
return ( | ||
<EuiFlexItem grow={false}> | ||
<div> | ||
<EuiButton | ||
color="danger" | ||
onClick={() => deleteAgentPolicyPrompt(selectedPolicyId, onDelete)} | ||
> | ||
<FormattedMessage | ||
id="xpack.fleet.policyForm.deletePolicyActionText" | ||
defaultMessage="Delete policy" | ||
/> | ||
</EuiButton> | ||
</div> | ||
</EuiFlexItem> | ||
); | ||
}} | ||
</AgentPolicyDeleteProvider> | ||
)} | ||
</EuiFlexGroup> | ||
|
||
{selectedPolicyId && ( | ||
<> | ||
<EuiSpacer size="m" /> | ||
|
||
<EuiLink target="_blank" href={getHref('policy_details', { policyId: selectedPolicyId })}> | ||
<FormattedMessage | ||
id="xpack.fleet.debug.agentPolicyDebugger.viewAgentPolicyLink" | ||
defaultMessage="View Agent Policy in Fleet UI" | ||
/> | ||
</EuiLink> | ||
|
||
<EuiSpacer size="m" /> | ||
|
||
<CodeBlock value={JSON.stringify(selectedAgentPolicy, null, 2)} /> | ||
</> | ||
)} | ||
</> | ||
); | ||
}; |
38 changes: 38 additions & 0 deletions
38
x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/code_block.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,38 @@ | ||
/* | ||
* 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 { CodeEditor } from '@kbn/kibana-react-plugin/public'; | ||
|
||
/** | ||
* A read-only code block with various default settings suitable for displaying API responses, etc | ||
*/ | ||
export const CodeBlock: React.FunctionComponent<{ value: string }> = ({ value }) => { | ||
return ( | ||
<CodeEditor | ||
isCopyable | ||
languageId="" | ||
height="600px" | ||
width="100%" | ||
options={{ | ||
minimap: { | ||
enabled: false, | ||
}, | ||
scrollBeyondLastLine: false, | ||
readOnly: true, | ||
tabSize: 2, | ||
lineNumbers: 'off', | ||
lineNumbersMinChars: 0, | ||
glyphMargin: false, | ||
lineDecorationsWidth: 0, | ||
overviewRulerBorder: false, | ||
}} | ||
value={value} | ||
/> | ||
); | ||
}; |
Oops, something went wrong.