diff --git a/x-pack/plugins/fleet/common/services/agent_status.ts b/x-pack/plugins/fleet/common/services/agent_status.ts index a7a5257c603b8..78726667f3b13 100644 --- a/x-pack/plugins/fleet/common/services/agent_status.ts +++ b/x-pack/plugins/fleet/common/services/agent_status.ts @@ -61,10 +61,15 @@ export const AGENT_UPDATING_TIMEOUT_HOURS = 2; export function isStuckInUpdating(agent: Agent): boolean { return ( - agent.status === 'updating' && - !!agent.upgrade_started_at && - !agent.upgraded_at && - Date.now() - Date.parse(agent.upgrade_started_at) > - AGENT_UPDATING_TIMEOUT_HOURS * 60 * 60 * 1000 + (agent.status !== 'offline' && agent.active && isAgentInFailedUpgradeState(agent)) || + (agent.status === 'updating' && + !!agent.upgrade_started_at && + !agent.upgraded_at && + Date.now() - Date.parse(agent.upgrade_started_at) > + AGENT_UPDATING_TIMEOUT_HOURS * 60 * 60 * 1000) ); } + +export function isAgentInFailedUpgradeState(agent: Agent): boolean { + return agent.upgrade_details?.state === 'UPG_FAILED'; +} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.test.tsx index 93646a544bebb..b55190d848f8a 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.test.tsx @@ -40,6 +40,8 @@ describe('AgentHealth', () => { true ); + utils.getByText('Agent may be stuck updating.'); + act(() => { fireEvent.click(utils.getByTestId('restartUpgradeBtn')); }); @@ -47,6 +49,56 @@ describe('AgentHealth', () => { utils.findByText('Upgrade Modal'); }); + it('should render agent health with callout when agent has upgrade state failed', () => { + const { utils } = renderAgentHealth( + { + active: true, + status: 'online', + upgrade_started_at: '2022-11-21T12:27:24Z', + upgrade_details: { + state: 'UPG_FAILED', + }, + } as any, + true + ); + + utils.getByText('Agent upgrade is stuck in failed state.'); + + utils.getByTestId('restartUpgradeBtn'); + }); + + it('should not render agent health with callout when agent has upgrade state failed but offline', () => { + const { utils } = renderAgentHealth( + { + active: true, + status: 'offline', + upgrade_started_at: '2022-11-21T12:27:24Z', + upgrade_details: { + state: 'UPG_FAILED', + }, + } as any, + true + ); + + expect(utils.queryByTestId('restartUpgradeBtn')).not.toBeInTheDocument(); + }); + + it('should not render agent health with callout when agent has upgrade state failed but inactive', () => { + const { utils } = renderAgentHealth( + { + active: false, + status: 'unenrolled', + upgrade_started_at: '2022-11-21T12:27:24Z', + upgrade_details: { + state: 'UPG_FAILED', + }, + } as any, + true + ); + + expect(utils.queryByTestId('restartUpgradeBtn')).not.toBeInTheDocument(); + }); + it('should not render agent health with callout when agent not stuck updating', () => { const { utils } = renderAgentHealth( { @@ -58,6 +110,7 @@ describe('AgentHealth', () => { ); expect(utils.queryByTestId('restartUpgradeBtn')).not.toBeInTheDocument(); + expect(utils.queryByText('Agent may be stuck updating.')).not.toBeInTheDocument(); }); it('should not render agent health with callout when not from details', () => { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx index 0cb89b06b62d2..fa8e263c16170 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx @@ -23,6 +23,7 @@ import { euiLightVars as euiVars } from '@kbn/ui-theme'; import { getPreviousAgentStatusForOfflineAgents, + isAgentInFailedUpgradeState, isStuckInUpdating, } from '../../../../../../common/services/agent_status'; @@ -152,12 +153,19 @@ export const AgentHealth: React.FunctionComponent = ({ agent, fromDetails

{lastCheckinText}

{lastCheckInMessageText}

{isStuckInUpdating(agent) ? ( -

+ isAgentInFailedUpgradeState(agent) ? ( -

+ ) : ( +

+ +

+ ) ) : null} } @@ -183,17 +191,27 @@ export const AgentHealth: React.FunctionComponent = ({ agent, fromDetails size="m" color="warning" title={ - + isAgentInFailedUpgradeState(agent) ? ( + + ) : ( + + ) } >

diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 99be3d9af2923..79dbb24983d00 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -16577,7 +16577,6 @@ "xpack.fleet.agentFlyout.standaloneRadioOption": "{standaloneMessage} – Exécutez un agent Elastic Agent de façon autonome pour le configurer et le mettre à jour manuellement sur l'hôte sur lequel il est installé.", "xpack.fleet.agentHealth.checkinMessageText": "Dernier message de vérification : {lastCheckinMessage}", "xpack.fleet.agentHealth.checkInTooltipText": "Dernier archivage le {lastCheckIn}", - "xpack.fleet.agentHealth.stuckUpdatingText": "L'agent effectue la mise à jour depuis un certain temps ; il est peut-être bloqué. Envisagez de redémarrer la mise à niveau. {learnMore}", "xpack.fleet.agentList.noFilteredAgentsPrompt": "Aucun agent trouvé. {clearFiltersLink}", "xpack.fleet.agentLogs.logDisabledCallOutDescription": "Mettez à jour la politique de l'agent {settingsLink} pour activer la collecte de logs.", "xpack.fleet.agentLogs.oldAgentWarningTitle": "La vue Logs requiert Elastic Agent 7.11 ou une version ultérieure. Pour mettre à niveau un agent, accédez au menu Actions ou {downloadLink} une version plus récente.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index cf450dbeeb29c..bc275b607f33a 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -16590,7 +16590,6 @@ "xpack.fleet.agentFlyout.standaloneRadioOption": "{standaloneMessage} – Elasticエージェントをスタンドアロンで実行して、エージェントがインストールされているホストで、手動でエージェントを構成および更新します。", "xpack.fleet.agentHealth.checkinMessageText": "前回のチェックインメッセージ:{lastCheckinMessage}", "xpack.fleet.agentHealth.checkInTooltipText": "前回確認日時:{lastCheckIn}", - "xpack.fleet.agentHealth.stuckUpdatingText": "エージェントはしばらく更新が止まっている可能性があります。アップグレードの再開を検討してください。{learnMore}", "xpack.fleet.agentList.noFilteredAgentsPrompt": "エージェントが見つかりません。{clearFiltersLink}", "xpack.fleet.agentLogs.logDisabledCallOutDescription": "エージェントのポリシー{settingsLink}を更新して、ログ収集を有効にします。", "xpack.fleet.agentLogs.oldAgentWarningTitle": "ログの表示には、Elastic Agent 7.11以降が必要です。エージェントをアップグレードするには、[アクション]メニューに移動するか、新しいバージョンを{downloadLink}。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 9cabcd3ccab48..5cce4ff16e0e9 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -16590,7 +16590,6 @@ "xpack.fleet.agentFlyout.standaloneRadioOption": "{standaloneMessage} – 独立运行 Elastic 代理,以在安装代理的主机上手动配置和更新代理。", "xpack.fleet.agentHealth.checkinMessageText": "上次签入消息:{lastCheckinMessage}", "xpack.fleet.agentHealth.checkInTooltipText": "上次签入时间 {lastCheckIn}", - "xpack.fleet.agentHealth.stuckUpdatingText": "代理已更新一段时间,并可能陷入停滞。请考虑重新开始升级。{learnMore}", "xpack.fleet.agentList.noFilteredAgentsPrompt": "找不到代理。{clearFiltersLink}", "xpack.fleet.agentLogs.logDisabledCallOutDescription": "更新代理的策略 {settingsLink} 以启用日志收集。", "xpack.fleet.agentLogs.oldAgentWarningTitle": "“日志”视图需要 Elastic Agent 7.11 或更高版本。要升级代理,请前往“操作”菜单或{downloadLink}更新的版本。",