Skip to content

Commit

Permalink
Add user tasks tables for aws resources
Browse files Browse the repository at this point in the history
  • Loading branch information
michellescripts committed Dec 30, 2024
1 parent ace89fd commit a1b38f1
Show file tree
Hide file tree
Showing 12 changed files with 278 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ export function DashboardMissingData() {
state.statsAttempt.data.awseks = undefined;
state.statsAttempt.data.awsrds = undefined;
state.statsAttempt.data.awsec2 = undefined;
state.tasksAttempt.data.items = [
{
name: '',
taskType: 'ec2',
state: '',
issueType: 'lost-connection',
integration: '',
lastStateChange: '',
},
];
return (
<MockAwsOidcStatusProvider value={state}>
<AwsOidcDashboard />
Expand Down Expand Up @@ -174,6 +184,11 @@ function makeAwsOidcStatusContextState(
awseks: makeResourceTypeSummary(),
},
},
tasksAttempt: {
status: 'success',
statusText: '',
data: {},
},
},
overrides
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ import {
StatCard,
} from 'teleport/Integrations/status/AwsOidc/StatCard';
import { AwsOidcTitle } from 'teleport/Integrations/status/AwsOidc/AwsOidcTitle';
import { TaskAlert } from 'teleport/Integrations/status/AwsOidc/Tasks/TaskAlert';

export function AwsOidcDashboard() {
const { statsAttempt, integrationAttempt } = useAwsOidcStatus();
const { statsAttempt, integrationAttempt, tasksAttempt } = useAwsOidcStatus();

if (
statsAttempt.status == 'processing' ||
Expand All @@ -50,11 +51,15 @@ export function AwsOidcDashboard() {
// todo (michellescripts) after routing, ensure this view can be sticky
const { awsec2, awseks, awsrds } = statsAttempt.data;
const { data: integration } = integrationAttempt;
const { data: tasks } = tasksAttempt;
return (
<>
<AwsOidcHeader integration={integration} />
<FeatureBox css={{ maxWidth: '1400px', paddingTop: '16px' }}>
<FeatureBox css={{ maxWidth: '1400px', paddingTop: '16px', gap: '16px' }}>
{integration && <AwsOidcTitle integration={integration} />}
{tasks && tasks.items.length > 0 && (
<TaskAlert name={integration.name} total={tasks.items.length} />
)}
<H2 my={3}>Auto-Enrollment</H2>
<Flex gap={3}>
<StatCard
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ import { useHistory } from 'react-router';
export function AwsOidcHeader({
integration,
resource = undefined,
tasks = false,
}: {
integration: Integration;
resource?: AwsResource;
tasks?: boolean;
}) {
const history = useHistory();
const divider = (
Expand Down Expand Up @@ -62,7 +64,7 @@ export function AwsOidcHeader({
<Plugs size="small" />
</ButtonIcon>
</HoverTooltip>
{!resource ? (
{!resource && !tasks ? (
<>
{divider}
<Text typography="body3" color="text.slightlyMuted" ml={2}>
Expand All @@ -85,12 +87,24 @@ export function AwsOidcHeader({
>
{integration.name}
</ButtonText>
</>
)}
{resource && (
<>
{divider}
<Text typography="body3" color="text.slightlyMuted" ml={2}>
{resource.toUpperCase()}
</Text>
</>
)}
{tasks && (
<>
{divider}
<Text typography="body3" color="text.slightlyMuted" ml={2}>
Pending Tasks
</Text>
</>
)}
</Flex>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import cfg from 'teleport/config';
import { AwsOidcStatusProvider } from 'teleport/Integrations/status/AwsOidc/useAwsOidcStatus';

import { Details } from 'teleport/Integrations/status/AwsOidc/Details/Details';
import { Tasks } from 'teleport/Integrations/status/AwsOidc/Tasks/Tasks';

import { AwsOidcDashboard } from './AwsOidcDashboard';

Expand All @@ -35,6 +36,12 @@ export function AwsOidcRoutes() {
path={cfg.routes.integrationStatusResources}
component={Details}
/>
<Route
key="aws-oidc-task-table"
exact
path={cfg.routes.integrationTasks}
component={Tasks}
/>
<Route
key="aws-oidc-dashboard"
exact
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { IntegrationKind } from 'teleport/services/integrations';
import { Rds } from 'teleport/Integrations/status/AwsOidc/Details/Rds';
import { Rules } from 'teleport/Integrations/status/AwsOidc/Details/Rules';
import { AwsOidcTitle } from 'teleport/Integrations/status/AwsOidc/AwsOidcTitle';
import { TaskAlert } from 'teleport/Integrations/status/AwsOidc/Tasks/TaskAlert';

export function Details() {
const { resourceKind } = useParams<{
Expand All @@ -34,17 +35,23 @@ export function Details() {
resourceKind: AwsResource;
}>();

const { integrationAttempt } = useAwsOidcStatus();
const { integrationAttempt, tasksAttempt } = useAwsOidcStatus();
const { data: integration } = integrationAttempt;
const { data: tasks } = tasksAttempt;
return (
<>
{integration && (
<AwsOidcHeader integration={integration} resource={resourceKind} />
)}
<FeatureBox css={{ maxWidth: '1400px', paddingTop: '16px', gap: '30px' }}>
<FeatureBox css={{ maxWidth: '1400px', paddingTop: '16px', gap: '16px' }}>
<>
{integration && (
<AwsOidcTitle integration={integration} resource={resourceKind} />
)}
{tasks && tasks.items.length > 0 && (
<TaskAlert name={integration.name} total={tasks.items.length} />
)}
</>
{resourceKind == AwsResource.ec2 && <Rules />}
{resourceKind == AwsResource.eks && <Rules />}
{resourceKind == AwsResource.rds && <Rds />}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Alert } from 'design';
import { ArrowForward, BellRinging } from 'design/Icon';
import cfg from 'teleport/config';
import { IntegrationKind } from 'teleport/services/integrations';
import { useHistory } from 'react-router';

type TaskAlertProps = {
name: string;
total: number;
kind?: IntegrationKind;
};

export function TaskAlert({
name,
total,
kind = IntegrationKind.AwsOidc,
}: TaskAlertProps) {
const history = useHistory();

return (
<Alert
kind="warning"
icon={BellRinging}
primaryAction={{
content: (
<>
Resolve Now
<ArrowForward size={18} ml={2} />
</>
),
onClick: () => history.push(cfg.getIntegrationTasksRoute(kind, name)),
}}
>
{total} Pending Tasks
</Alert>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Teleport
* Copyright (C) 2024 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import Table, { Cell } from 'design/DataTable';

import { Indicator } from 'design';

import { Danger } from 'design/Alert';

import { FeatureBox } from 'teleport/components/Layout';
import { AwsOidcHeader } from 'teleport/Integrations/status/AwsOidc/AwsOidcHeader';
import { useAwsOidcStatus } from 'teleport/Integrations/status/AwsOidc/useAwsOidcStatus';
import { UserTask } from 'teleport/services/integrations';

export function Tasks() {
const { integrationAttempt, tasksAttempt } = useAwsOidcStatus();
const { data: integration } = integrationAttempt;
const { data: tasks } = tasksAttempt;

if (
integrationAttempt.status == 'processing' ||
tasksAttempt.status == 'processing'
) {
return <Indicator />;
}

if (integrationAttempt.status == 'error' || tasksAttempt.status == 'error') {
return (
<Danger>
{integrationAttempt.status == 'error'
? integrationAttempt.statusText
: tasksAttempt.statusText}
</Danger>
);
}

if (!tasks) {
return null;
}

return (
<FeatureBox css={{ maxWidth: '1400px', paddingTop: '16px', gap: '30px' }}>
{integration && <AwsOidcHeader integration={integration} tasks={true} />}
<Table<UserTask>
data={tasks.items}
columns={[
{
key: 'taskType',
headerText: 'Type',
isSortable: true,
},
{
key: 'issueType',
headerText: 'Issue Details',
isSortable: true,
},
{
key: 'lastStateChange',
headerText: 'Timestamp (UTC)',
isSortable: true,
render: (item: UserTask) => (
<Cell>{new Date(item.lastStateChange).toISOString()}</Cell>
),
},
]}
emptyText={`No pending tasks`}
isSearchable
/>
</FeatureBox>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ import {
IntegrationKind,
integrationService,
IntegrationWithSummary,
UserTasksListResponse,
} from 'teleport/services/integrations';

import useTeleport from 'teleport/useTeleport';

export interface AwsOidcStatusContextState {
statsAttempt: Attempt<IntegrationWithSummary>;
integrationAttempt: Attempt<Integration>;
tasksAttempt: Attempt<UserTasksListResponse>;
}

export const awsOidcStatusContext =
Expand All @@ -54,16 +56,22 @@ export function AwsOidcStatusProvider({ children }: React.PropsWithChildren) {
integrationService.fetchIntegration(name)
);

const [tasks, fetchTasks] = useAsync(() =>
integrationService.fetchIntegrationUserTasksList(name)
);

useEffect(() => {
if (hasIntegrationReadAccess) {
fetchIntegrationStats();
fetchIntegration();
fetchTasks();
}
}, []);

const value: AwsOidcStatusContextState = {
statsAttempt: stats,
integrationAttempt: integration,
tasksAttempt: tasks,
};

return (
Expand Down
15 changes: 15 additions & 0 deletions web/packages/teleport/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ const cfg = {
headlessSso: `/web/headless/:requestId`,
integrations: '/web/integrations',
integrationStatus: '/web/integrations/status/:type/:name',
integrationTasks: '/web/integrations/status/:type/:name/tasks',
integrationStatusResources:
'/web/integrations/status/:type/:name/resources/:resourceKind',
integrationEnroll: '/web/integrations/new/:type?',
Expand Down Expand Up @@ -334,6 +335,8 @@ const cfg = {
'/v1/webapi/sites/:clusterId/integrations/:name/stats',
integrationRulesPath:
'/v1/webapi/sites/:clusterId/integrations/:name/discoveryrules?resourceType=:resourceType?&startKey=:startKey?&query=:query?&search=:search?&sort=:sort?&limit=:limit?',
userTaskListByIntegrationPath:
'/v1/webapi/sites/:clusterId/usertask?integration=:name',

thumbprintPath: '/v1/webapi/thumbprint',
pingAwsOidcIntegrationPath:
Expand Down Expand Up @@ -562,6 +565,10 @@ const cfg = {
});
},

getIntegrationTasksRoute(type: PluginKind | IntegrationKind, name: string) {
return generatePath(cfg.routes.integrationTasks, { type, name });
},

getMsTeamsAppZipRoute(clusterId: string, plugin: string) {
return generatePath(cfg.api.msTeamsAppZipPath, { clusterId, plugin });
},
Expand Down Expand Up @@ -1026,6 +1033,14 @@ const cfg = {
});
},

getIntegrationUserTasksListUrl(name: string) {
const clusterId = cfg.proxyCluster;
return generatePath(cfg.api.userTaskListByIntegrationPath, {
clusterId,
name,
});
},

getPingAwsOidcIntegrationUrl({
integrationName,
clusterId,
Expand Down
Loading

0 comments on commit a1b38f1

Please sign in to comment.