Skip to content

Commit

Permalink
[Fleet] Fix agent dashboard link accross multiple space (#201280)
Browse files Browse the repository at this point in the history
  • Loading branch information
nchaulet authored Nov 22, 2024
1 parent 62b191c commit 8e6698f
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jest.mock('../../../../../../hooks/use_fleet_status', () => ({
FleetStatusProvider: (props: any) => {
return props.children;
},
useFleetStatus: jest.fn().mockReturnValue({ spaceId: 'default' }),
}));

jest.mock('../../../../../../hooks/use_request/epm');
Expand All @@ -30,7 +31,7 @@ jest.mock('../../../../../../hooks/use_locator', () => {
useDashboardLocator: jest.fn().mockImplementation(() => {
return {
id: 'DASHBOARD_APP_LOCATOR',
getRedirectUrl: jest.fn().mockResolvedValue('app/dashboards#/view/elastic_agent-a0001'),
getRedirectUrl: jest.fn().mockReturnValue('app/dashboards#/view/elastic_agent-a0001'),
};
}),
};
Expand All @@ -43,6 +44,10 @@ describe('AgentDashboardLink', () => {
data: {
item: {
status: 'installed',
installationInfo: {
install_status: 'installed',
installed_kibana_space_id: 'default',
},
},
},
} as ReturnType<typeof useGetPackageInfoByKeyQuery>);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,49 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { EuiButton, EuiToolTip } from '@elastic/eui';
import styled from 'styled-components';

import { useGetPackageInfoByKeyQuery, useLink, useDashboardLocator } from '../../../../hooks';
import type { GetInfoResponse } from '../../../../../../../common/types';
import {
useGetPackageInfoByKeyQuery,
useLink,
useDashboardLocator,
useFleetStatus,
} from '../../../../hooks';
import type { Agent, AgentPolicy } from '../../../../types';
import {
FLEET_ELASTIC_AGENT_PACKAGE,
DASHBOARD_LOCATORS_IDS,
} from '../../../../../../../common/constants';
import { getDashboardIdForSpace } from '../../services/dashboard_helpers';

function isKibanaAssetsInstalledInSpace(spaceId: string | undefined, res?: GetInfoResponse) {
if (res?.item?.status !== 'installed') {
return false;
}

const installationInfo = res.item.installationInfo;

if (!installationInfo || installationInfo.install_status !== 'installed') {
return false;
}
return (
installationInfo.installed_kibana_space_id === spaceId ||
(spaceId && installationInfo.additional_spaces_installed_kibana?.[spaceId])
);
}

function useAgentDashboardLink(agent: Agent) {
const { isLoading, data } = useGetPackageInfoByKeyQuery(FLEET_ELASTIC_AGENT_PACKAGE);
const { spaceId } = useFleetStatus();

const isInstalled = data?.item.status === 'installed';
const isInstalled = isKibanaAssetsInstalledInSpace(spaceId, data);
const dashboardLocator = useDashboardLocator();

const link = dashboardLocator?.getRedirectUrl({
dashboardId: DASHBOARD_LOCATORS_IDS.ELASTIC_AGENT_AGENT_METRICS,
dashboardId: getDashboardIdForSpace(
spaceId,
data,
DASHBOARD_LOCATORS_IDS.ELASTIC_AGENT_AGENT_METRICS
),
query: {
language: 'kuery',
query: `elastic_agent.id:${agent.id}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,69 @@
* 2.0.
*/

import React, { useEffect } from 'react';
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { useQuery } from '@tanstack/react-query';

import { DASHBOARD_LOCATORS_IDS } from '../../../../../../../common/constants';
import {
DASHBOARD_LOCATORS_IDS,
FLEET_ELASTIC_AGENT_PACKAGE,
} from '../../../../../../../common/constants';

import { useDashboardLocator, useStartServices } from '../../../../hooks';
import {
useDashboardLocator,
useFleetStatus,
useGetPackageInfoByKeyQuery,
useStartServices,
} from '../../../../hooks';

import { getDashboardIdForSpace } from '../../services/dashboard_helpers';

const useDashboardExists = (dashboardId: string) => {
const [dashboardExists, setDashboardExists] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const { dashboard: dashboardPlugin } = useStartServices();

useEffect(() => {
const fetchDashboard = async () => {
const { data, isLoading } = useQuery({
queryKey: ['dashboard_exists', dashboardId],
queryFn: async () => {
try {
const findDashboardsService = await dashboardPlugin.findDashboardsService();
const [dashboard] = await findDashboardsService.findByIds([dashboardId]);
setLoading(false);
setDashboardExists(dashboard?.status === 'success');
return dashboard?.status === 'success';
} catch (e) {
setLoading(false);
setDashboardExists(false);
return false;
}
};

fetchDashboard();
}, [dashboardId, dashboardPlugin]);

return { dashboardExists, loading };
},
});
return { dashboardExists: data ?? false, loading: isLoading };
};

export const DashboardsButtons: React.FunctionComponent = () => {
const { data } = useGetPackageInfoByKeyQuery(FLEET_ELASTIC_AGENT_PACKAGE);
const { spaceId } = useFleetStatus();

const dashboardLocator = useDashboardLocator();

const getDashboardHref = (dashboardId: string) => {
return dashboardLocator?.getRedirectUrl({ dashboardId }) || '';
};

const { dashboardExists, loading: dashboardLoading } = useDashboardExists(
const elasticAgentOverviewDashboardId = getDashboardIdForSpace(
spaceId,
data,
DASHBOARD_LOCATORS_IDS.ELASTIC_AGENT_OVERVIEW
);

const elasticAgentInfoDashboardId = getDashboardIdForSpace(
spaceId,
data,
DASHBOARD_LOCATORS_IDS.ELASTIC_AGENT_AGENT_INFO
);

const { dashboardExists, loading: dashboardLoading } = useDashboardExists(
elasticAgentOverviewDashboardId
);

if (dashboardLoading || !dashboardExists) {
return null;
}
Expand All @@ -58,7 +78,7 @@ export const DashboardsButtons: React.FunctionComponent = () => {
<EuiFlexItem grow={false}>
<EuiButtonEmpty
iconType="dashboardApp"
href={getDashboardHref(DASHBOARD_LOCATORS_IDS.ELASTIC_AGENT_OVERVIEW)}
href={getDashboardHref(elasticAgentOverviewDashboardId)}
data-test-subj="ingestOverviewLinkButton"
>
<FormattedMessage
Expand All @@ -70,7 +90,7 @@ export const DashboardsButtons: React.FunctionComponent = () => {
<EuiFlexItem grow={false}>
<EuiButtonEmpty
iconType="dashboardApp"
href={getDashboardHref(DASHBOARD_LOCATORS_IDS.ELASTIC_AGENT_AGENT_INFO)}
href={getDashboardHref(elasticAgentInfoDashboardId)}
data-test-subj="agentInfoLinkButton"
>
<FormattedMessage
Expand Down
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 type { GetInfoResponse } from '../../../../../../common';

import { getDashboardIdForSpace } from './dashboard_helpers';

const PKG_INFO = {
item: {
status: 'installed',
installationInfo: {
install_status: 'installed',
installed_kibana_space_id: 'default',
additional_spaces_installed_kibana: {
test: [
{
id: 'test-destination-1',
originId: 'test-id-1',
},
],
},
},
},
} as unknown as GetInfoResponse;

describe('getDashboardIdForSpace', () => {
it('return the same id if package is installed in the same space', () => {
expect(() => getDashboardIdForSpace('default', PKG_INFO, 'test-id-1'));
});

it('return the destination ID if package is installed in an additionnal space', () => {
expect(() => getDashboardIdForSpace('test', PKG_INFO, 'test-id-1'));
});
});
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 { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common';

import type { GetInfoResponse } from '../../../../../../common';

export function getDashboardIdForSpace(
spaceId: string = DEFAULT_SPACE_ID,
res: GetInfoResponse | undefined,
dashboardId: string
) {
if (res?.item?.status !== 'installed') {
return dashboardId;
}

const installationInfo = res.item.installationInfo;

if (!installationInfo || installationInfo?.installed_kibana_space_id === spaceId) {
return dashboardId;
}

return (
installationInfo.additional_spaces_installed_kibana?.[spaceId]?.find(
({ originId }) => originId === dashboardId
)?.id ?? dashboardId
);
}

0 comments on commit 8e6698f

Please sign in to comment.