From 41bbab06e890b0fab0dc4c51e0ab4fb4900c55f0 Mon Sep 17 00:00:00 2001
From: Michelle Bergquist <11967646+michellescripts@users.noreply.github.com>
Date: Mon, 25 Nov 2024 11:42:25 -0700
Subject: [PATCH] Add route and header for aws oidc dash (#49163)
---
web/packages/design/src/Label/Label.tsx | 7 +-
.../design/src/Label/{index.js => index.ts} | 4 +-
.../src/Integrations/IntegrationList.tsx | 41 ++------
.../src/Integrations/IntegrationStatus.tsx | 5 +
.../teleport/src/Integrations/helpers.test.ts | 93 +++++++++++++++++++
.../teleport/src/Integrations/helpers.ts | 74 +++++++++++++++
.../status/AwsOidc/AwsOidcDashboard.story.tsx | 51 ++++++++++
.../status/AwsOidc/AwsOidcDashboard.test.tsx | 56 +++++++++++
.../status/AwsOidc/AwsOidcDashboard.tsx | 35 +++++++
.../status/AwsOidc/AwsOidcHeader.tsx | 55 +++++++++++
.../status/AwsOidc/AwsOidcRoutes.tsx | 41 ++++++++
.../testHelpers/mockAwsOidcStatusProvider.tsx | 48 ++++++++++
.../status/AwsOidc/useAwsOidcStatus.tsx | 76 +++++++++++++++
13 files changed, 552 insertions(+), 34 deletions(-)
rename web/packages/design/src/Label/{index.js => index.ts} (88%)
create mode 100644 web/packages/teleport/src/Integrations/helpers.test.ts
create mode 100644 web/packages/teleport/src/Integrations/helpers.ts
create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.story.tsx
create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.test.tsx
create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.tsx
create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx
create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcRoutes.tsx
create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider.tsx
create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/useAwsOidcStatus.tsx
diff --git a/web/packages/design/src/Label/Label.tsx b/web/packages/design/src/Label/Label.tsx
index bc1a865dd1ef2..d18066cce632c 100644
--- a/web/packages/design/src/Label/Label.tsx
+++ b/web/packages/design/src/Label/Label.tsx
@@ -58,7 +58,12 @@ const kind = ({ kind, theme }) => {
};
};
-type LabelKind = 'primary' | 'secondary' | 'warning' | 'danger' | 'success';
+export type LabelKind =
+ | 'primary'
+ | 'secondary'
+ | 'warning'
+ | 'danger'
+ | 'success';
interface LabelProps extends SpaceProps {
kind?: LabelKind;
diff --git a/web/packages/design/src/Label/index.js b/web/packages/design/src/Label/index.ts
similarity index 88%
rename from web/packages/design/src/Label/index.js
rename to web/packages/design/src/Label/index.ts
index e7c934c6f4029..500af263e629f 100644
--- a/web/packages/design/src/Label/index.js
+++ b/web/packages/design/src/Label/index.ts
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
-import Label, { Primary, Secondary, Warning, Danger } from './Label';
+import Label, { Danger, Primary, Secondary, Warning } from './Label';
+
export default Label;
export { Primary, Secondary, Warning, Danger };
+export type { LabelKind } from './Label';
diff --git a/web/packages/teleport/src/Integrations/IntegrationList.tsx b/web/packages/teleport/src/Integrations/IntegrationList.tsx
index 26a0e376af26f..958fe4bc8635c 100644
--- a/web/packages/teleport/src/Integrations/IntegrationList.tsx
+++ b/web/packages/teleport/src/Integrations/IntegrationList.tsx
@@ -28,16 +28,18 @@ import { ToolTipInfo } from 'shared/components/ToolTip';
import { ResourceIcon } from 'design/ResourceIcon';
import {
+ ExternalAuditStorageIntegration,
getStatusCodeDescription,
getStatusCodeTitle,
Integration,
- IntegrationStatusCode,
IntegrationKind,
+ IntegrationStatusCode,
Plugin,
- ExternalAuditStorageIntegration,
} from 'teleport/services/integrations';
import cfg from 'teleport/config';
+import { getStatus } from 'teleport/Integrations/helpers';
+
import { ExternalAuditStorageOpType } from './Operations/useIntegrationOperation';
type Props = {
@@ -50,7 +52,10 @@ type Props = {
onDeleteExternalAuditStorage?(opType: ExternalAuditStorageOpType): void;
};
-type IntegrationLike = Integration | Plugin | ExternalAuditStorageIntegration;
+export type IntegrationLike =
+ | Integration
+ | Plugin
+ | ExternalAuditStorageIntegration;
export function IntegrationList(props: Props) {
const history = useHistory();
@@ -229,40 +234,12 @@ const StatusCell = ({ item }: { item: IntegrationLike }) => {
);
};
-enum Status {
+export enum Status {
Success,
Warning,
Error,
}
-function getStatus(item: IntegrationLike): Status | null {
- if (item.resourceType === 'integration') {
- return Status.Success;
- }
-
- if (item.resourceType === 'external-audit-storage') {
- switch (item.statusCode) {
- case IntegrationStatusCode.Draft:
- return Status.Warning;
- default:
- return Status.Success;
- }
- }
-
- switch (item.statusCode) {
- case IntegrationStatusCode.Unknown:
- return null;
- case IntegrationStatusCode.Running:
- return Status.Success;
- case IntegrationStatusCode.SlackNotInChannel:
- return Status.Warning;
- case IntegrationStatusCode.Draft:
- return Status.Warning;
- default:
- return Status.Error;
- }
-}
-
const StatusLight = styled(Box)<{ status: Status }>`
border-radius: 50%;
margin-right: 4px;
diff --git a/web/packages/teleport/src/Integrations/IntegrationStatus.tsx b/web/packages/teleport/src/Integrations/IntegrationStatus.tsx
index 836fe97cfcec7..500067a68d86c 100644
--- a/web/packages/teleport/src/Integrations/IntegrationStatus.tsx
+++ b/web/packages/teleport/src/Integrations/IntegrationStatus.tsx
@@ -20,11 +20,16 @@ import React from 'react';
import { useParams } from 'react-router';
import { IntegrationKind, PluginKind } from 'teleport/services/integrations';
+import { AwsOidcRoutes } from 'teleport/Integrations/status/AwsOidc/AwsOidcRoutes';
export function IntegrationStatus() {
const { type: integrationType } = useParams<{
type: PluginKind | IntegrationKind;
}>();
+ if (integrationType === 'aws-oidc') {
+ return ;
+ }
+
return <>Status for integration type {integrationType} is not supported>;
}
diff --git a/web/packages/teleport/src/Integrations/helpers.test.ts b/web/packages/teleport/src/Integrations/helpers.test.ts
new file mode 100644
index 0000000000000..86668ee0d5fe9
--- /dev/null
+++ b/web/packages/teleport/src/Integrations/helpers.test.ts
@@ -0,0 +1,93 @@
+/**
+ * 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 .
+ */
+
+import {
+ Integration,
+ IntegrationStatusCode,
+} from 'teleport/services/integrations';
+import { getStatus, getStatusAndLabel } from 'teleport/Integrations/helpers';
+import { IntegrationLike, Status } from 'teleport/Integrations/IntegrationList';
+
+test.each`
+ type | code | expected
+ ${'integration'} | ${IntegrationStatusCode.Draft} | ${Status.Success}
+ ${'integration'} | ${IntegrationStatusCode.Running} | ${Status.Success}
+ ${'integration'} | ${IntegrationStatusCode.Unauthorized} | ${Status.Success}
+ ${'integration'} | ${IntegrationStatusCode.SlackNotInChannel} | ${Status.Success}
+ ${'integration'} | ${IntegrationStatusCode.Unknown} | ${Status.Success}
+ ${'integration'} | ${IntegrationStatusCode.OtherError} | ${Status.Success}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.Draft} | ${Status.Warning}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.Running} | ${Status.Success}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.Unauthorized} | ${Status.Success}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.SlackNotInChannel} | ${Status.Success}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.Unknown} | ${Status.Success}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.OtherError} | ${Status.Success}
+ ${'any'} | ${IntegrationStatusCode.Draft} | ${Status.Warning}
+ ${'any'} | ${IntegrationStatusCode.Running} | ${Status.Success}
+ ${'any'} | ${IntegrationStatusCode.Unauthorized} | ${Status.Error}
+ ${'any'} | ${IntegrationStatusCode.SlackNotInChannel} | ${Status.Warning}
+ ${'any'} | ${IntegrationStatusCode.Unknown} | ${null}
+ ${'any'} | ${IntegrationStatusCode.OtherError} | ${Status.Error}
+`(
+ 'getStatus type $type with code $code returns $expected',
+ async ({ type, code, expected }) => {
+ const item: IntegrationLike = {
+ name: '',
+ kind: undefined,
+ resourceType: type,
+ statusCode: code,
+ };
+ const status = getStatus(item);
+ expect(status).toBe(expected);
+ }
+);
+
+test.each`
+ type | code | expectedLabelKind | expectedTitle
+ ${'integration'} | ${IntegrationStatusCode.Draft} | ${'success'} | ${'Draft'}
+ ${'integration'} | ${IntegrationStatusCode.Running} | ${'success'} | ${'Running'}
+ ${'integration'} | ${IntegrationStatusCode.Unauthorized} | ${'success'} | ${'Unauthorized'}
+ ${'integration'} | ${IntegrationStatusCode.SlackNotInChannel} | ${'success'} | ${'Bot not invited to channel'}
+ ${'integration'} | ${IntegrationStatusCode.Unknown} | ${'success'} | ${'Unknown'}
+ ${'integration'} | ${IntegrationStatusCode.OtherError} | ${'success'} | ${'Unknown error'}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.Draft} | ${'warning'} | ${'Draft'}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.Running} | ${'success'} | ${'Running'}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.Unauthorized} | ${'success'} | ${'Unauthorized'}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.SlackNotInChannel} | ${'success'} | ${'Bot not invited to channel'}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.Unknown} | ${'success'} | ${'Unknown'}
+ ${'external-audit-storage'} | ${IntegrationStatusCode.OtherError} | ${'success'} | ${'Unknown error'}
+ ${'any'} | ${IntegrationStatusCode.Draft} | ${'warning'} | ${'Draft'}
+ ${'any'} | ${IntegrationStatusCode.Running} | ${'success'} | ${'Running'}
+ ${'any'} | ${IntegrationStatusCode.Unauthorized} | ${'danger'} | ${'Unauthorized'}
+ ${'any'} | ${IntegrationStatusCode.SlackNotInChannel} | ${'warning'} | ${'Bot not invited to channel'}
+ ${'any'} | ${IntegrationStatusCode.Unknown} | ${'secondary'} | ${'Unknown'}
+ ${'any'} | ${IntegrationStatusCode.OtherError} | ${'danger'} | ${'Unknown error'}
+`(
+ 'getStatusAndLabel type $type with code $code returns expected',
+ async ({ type, code, expectedLabelKind, expectedTitle }) => {
+ const item: Integration = {
+ name: '',
+ kind: undefined,
+ resourceType: type,
+ statusCode: code,
+ };
+ const status = getStatusAndLabel(item);
+ expect(status.status).toBe(expectedTitle);
+ expect(status.labelKind).toBe(expectedLabelKind);
+ }
+);
diff --git a/web/packages/teleport/src/Integrations/helpers.ts b/web/packages/teleport/src/Integrations/helpers.ts
new file mode 100644
index 0000000000000..87690be4a421f
--- /dev/null
+++ b/web/packages/teleport/src/Integrations/helpers.ts
@@ -0,0 +1,74 @@
+/**
+ * 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 .
+ */
+
+import { LabelKind } from 'design/Label';
+
+import {
+ getStatusCodeTitle,
+ Integration,
+ IntegrationStatusCode,
+} from 'teleport/services/integrations';
+import { IntegrationLike, Status } from 'teleport/Integrations/IntegrationList';
+
+export function getStatus(item: IntegrationLike): Status {
+ if (item.resourceType === 'integration') {
+ return Status.Success;
+ }
+
+ if (item.resourceType === 'external-audit-storage') {
+ switch (item.statusCode) {
+ case IntegrationStatusCode.Draft:
+ return Status.Warning;
+ default:
+ return Status.Success;
+ }
+ }
+
+ switch (item.statusCode) {
+ case IntegrationStatusCode.Unknown:
+ return null;
+ case IntegrationStatusCode.Running:
+ return Status.Success;
+ case IntegrationStatusCode.SlackNotInChannel:
+ return Status.Warning;
+ case IntegrationStatusCode.Draft:
+ return Status.Warning;
+ default:
+ return Status.Error;
+ }
+}
+
+export function getStatusAndLabel(integration: Integration): {
+ labelKind: LabelKind;
+ status: string;
+} {
+ const modifiedStatus = getStatus(integration);
+ const statusCode = integration.statusCode;
+ const title = getStatusCodeTitle(statusCode);
+
+ switch (modifiedStatus) {
+ case Status.Success:
+ return { labelKind: 'success', status: title };
+ case Status.Error:
+ return { labelKind: 'danger', status: title };
+ case Status.Warning:
+ return { labelKind: 'warning', status: title };
+ default:
+ return { labelKind: 'secondary', status: title };
+ }
+}
diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.story.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.story.tsx
new file mode 100644
index 0000000000000..662b5b5206af5
--- /dev/null
+++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.story.tsx
@@ -0,0 +1,51 @@
+/**
+ * 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 .
+ */
+
+import React from 'react';
+
+import { AwsOidcDashboard } from 'teleport/Integrations/status/AwsOidc/AwsOidcDashboard';
+import { MockAwsOidcStatusProvider } from 'teleport/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider';
+import { IntegrationKind } from 'teleport/services/integrations';
+
+export default {
+ title: 'Teleport/Integrations/AwsOidc',
+};
+
+export function Dashboard() {
+ return (
+
+
+
+ );
+}
diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.test.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.test.tsx
new file mode 100644
index 0000000000000..3a1a20866a359
--- /dev/null
+++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.test.tsx
@@ -0,0 +1,56 @@
+/**
+ * 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 .
+ */
+
+import React from 'react';
+import { render, screen } from 'design/utils/testing';
+
+import { AwsOidcDashboard } from 'teleport/Integrations/status/AwsOidc/AwsOidcDashboard';
+import { MockAwsOidcStatusProvider } from 'teleport/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider';
+import { IntegrationKind } from 'teleport/services/integrations';
+
+test('renders header', () => {
+ render(
+
+
+
+ );
+
+ expect(screen.getByRole('link', { name: 'back' })).toHaveAttribute(
+ 'href',
+ '/web/integrations'
+ );
+ expect(screen.getByText('integration-one')).toBeInTheDocument();
+ expect(screen.getByLabelText('status')).toHaveAttribute('kind', 'success');
+ expect(screen.getByLabelText('status')).toHaveTextContent('Running');
+});
diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.tsx
new file mode 100644
index 0000000000000..45779ea05ed70
--- /dev/null
+++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.tsx
@@ -0,0 +1,35 @@
+/**
+ * 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 .
+ */
+
+import React from 'react';
+
+import { AwsOidcHeader } from 'teleport/Integrations/status/AwsOidc/AwsOidcHeader';
+import { useAwsOidcStatus } from 'teleport/Integrations/status/AwsOidc/useAwsOidcStatus';
+import { FeatureBox } from 'teleport/components/Layout';
+
+// todo (michellescripts) after routing, ensure this view can be sticky
+export function AwsOidcDashboard() {
+ const { attempt } = useAwsOidcStatus();
+
+ return (
+
+
+ Status for integration type aws-oidc is not supported
+
+ );
+}
diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx
new file mode 100644
index 0000000000000..136e3ee354e09
--- /dev/null
+++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx
@@ -0,0 +1,55 @@
+/**
+ * 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 .
+ */
+
+import React from 'react';
+import { Link as InternalLink } from 'react-router-dom';
+
+import { ButtonIcon, Flex, Label, Text } from 'design';
+import { ArrowLeft } from 'design/Icon';
+import { HoverTooltip } from 'shared/components/ToolTip';
+
+import cfg from 'teleport/config';
+import { getStatusAndLabel } from 'teleport/Integrations/helpers';
+import { Integration } from 'teleport/services/integrations';
+
+export function AwsOidcHeader({
+ integration,
+}: {
+ integration: Integration | null;
+}) {
+ const { status, labelKind } = getStatusAndLabel(integration);
+ return (
+
+
+
+
+
+
+
+ {integration?.name}
+
+
+
+ );
+}
diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcRoutes.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcRoutes.tsx
new file mode 100644
index 0000000000000..b218fc905706d
--- /dev/null
+++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcRoutes.tsx
@@ -0,0 +1,41 @@
+/**
+ * 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 .
+ */
+
+import React from 'react';
+
+import { Route, Switch } from 'teleport/components/Router';
+import cfg from 'teleport/config';
+
+import { AwsOidcStatusProvider } from 'teleport/Integrations/status/AwsOidc/useAwsOidcStatus';
+
+import { AwsOidcDashboard } from './AwsOidcDashboard';
+
+export function AwsOidcRoutes() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider.tsx
new file mode 100644
index 0000000000000..4d29af57d0422
--- /dev/null
+++ b/web/packages/teleport/src/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider.tsx
@@ -0,0 +1,48 @@
+/**
+ * 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 .
+ */
+
+import React from 'react';
+
+import { MemoryRouter } from 'react-router';
+
+import {
+ awsOidcStatusContext,
+ AwsOidcStatusContextState,
+} from 'teleport/Integrations/status/AwsOidc/useAwsOidcStatus';
+import { ContextProvider } from 'teleport';
+import { createTeleportContext } from 'teleport/mocks/contexts';
+
+export const MockAwsOidcStatusProvider = ({
+ children,
+ value,
+}: {
+ children?: React.ReactNode;
+ value: AwsOidcStatusContextState;
+}) => {
+ const ctx = createTeleportContext();
+
+ return (
+
+
+
+ {children}
+
+
+
+ );
+};
diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/useAwsOidcStatus.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/useAwsOidcStatus.tsx
new file mode 100644
index 0000000000000..fc060328adc0b
--- /dev/null
+++ b/web/packages/teleport/src/Integrations/status/AwsOidc/useAwsOidcStatus.tsx
@@ -0,0 +1,76 @@
+/**
+ * Teleport
+ * Copyright (C) 2023 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 .
+ */
+
+import React, { createContext, useContext, useEffect } from 'react';
+import { useParams } from 'react-router';
+import { Attempt, useAsync } from 'shared/hooks/useAsync';
+
+import {
+ Integration,
+ IntegrationKind,
+ integrationService,
+} from 'teleport/services/integrations';
+
+import useTeleport from 'teleport/useTeleport';
+
+export interface AwsOidcStatusContextState {
+ attempt: Attempt;
+}
+
+export const awsOidcStatusContext =
+ createContext(null);
+
+export function AwsOidcStatusProvider({ children }: React.PropsWithChildren) {
+ const { name } = useParams<{
+ type: IntegrationKind;
+ name: string;
+ }>();
+ const ctx = useTeleport();
+ const integrationAccess = ctx.storeUser.getIntegrationsAccess();
+ const hasIntegrationReadAccess = integrationAccess.read;
+
+ const [attempt, fetchIntegration] = useAsync(() =>
+ integrationService.fetchIntegration(name)
+ );
+
+ useEffect(() => {
+ if (hasIntegrationReadAccess) {
+ fetchIntegration();
+ }
+ }, []);
+
+ const value: AwsOidcStatusContextState = {
+ attempt,
+ };
+
+ return (
+
+ {children}
+
+ );
+}
+
+export function useAwsOidcStatus(): AwsOidcStatusContextState {
+ const context = useContext(awsOidcStatusContext);
+ if (!context) {
+ throw new Error(
+ 'useAwsOidcStatus must be used within a AwsOidcStatusProvider'
+ );
+ }
+ return context;
+}