Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion web/packages/teleport/src/Bots/Add/AddBotsPicker.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,24 @@
import React from 'react';
import { MemoryRouter } from 'react-router';

import { ContextProvider } from 'teleport';

import { createTeleportContext } from 'teleport/mocks/contexts';

import { AddBotsPicker } from './AddBotsPicker';

export default {
title: 'Teleport/Bots/Add/AddBotsPicker',
};

export const Picker = () => {
const ctx = createTeleportContext();

return (
<MemoryRouter>
<AddBotsPicker />
<ContextProvider ctx={ctx}>
<AddBotsPicker />
</ContextProvider>
</MemoryRouter>
);
};
45 changes: 37 additions & 8 deletions web/packages/teleport/src/Bots/Add/AddBotsPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ import {
import { IntegrationTile } from 'teleport/Integrations';
import { FeatureHeader, FeatureHeaderTitle } from 'teleport/components/Layout';

import useTeleport from 'teleport/useTeleport';
import { ToolTipNoPermBadge } from 'teleport/components/ToolTipNoPermBadge';

import { BotFlowType } from '../types';

type BotIntegration = {
Expand Down Expand Up @@ -136,29 +139,37 @@ const integrations: BotIntegration[] = [
];

export function AddBotsPicker() {
const ctx = useTeleport();
return (
<>
<FeatureHeader>
<FeatureHeaderTitle>Select Bot Type</FeatureHeaderTitle>
</FeatureHeader>

<Text typography="body1">
<Text typography="body1" mb="5">
Set up Teleport Machine ID to allow CI/CD workflows and other machines
to access resources protected by Teleport.
</Text>

<BotTiles />
<BotTiles hasCreateBotPermission={ctx.getFeatureFlags().addBots} />
</>
);
}

export function BotTiles() {
export function BotTiles({
hasCreateBotPermission,
}: {
hasCreateBotPermission: boolean;
}) {
return (
<Flex mt={5} gap={3} flexWrap="wrap">
<Flex gap={3} flexWrap="wrap">
{integrations.map(i => (
<Box key={i.title}>
{i.guided ? (
<GuidedTile integration={i} />
<GuidedTile
integration={i}
hasCreateBotPermission={hasCreateBotPermission}
/>
) : (
<ExternalLinkTile integration={i} />
)}
Expand Down Expand Up @@ -189,12 +200,21 @@ function ExternalLinkTile({ integration }: { integration: BotIntegration }) {
);
}

function GuidedTile({ integration }: { integration: BotIntegration }) {
function GuidedTile({
integration,
hasCreateBotPermission,
}: {
integration: BotIntegration;
hasCreateBotPermission: boolean;
}) {
return (
<IntegrationTile
as={Link}
to={integration.link}
to={hasCreateBotPermission ? integration.link : null}
onClick={() => {
if (!hasCreateBotPermission) {
return;
}
userEventService.captureIntegrationEnrollEvent({
event: IntegrationEnrollEvent.Started,
eventData: {
Expand All @@ -204,7 +224,16 @@ function GuidedTile({ integration }: { integration: BotIntegration }) {
});
}}
>
<BadgeGuided>Guided</BadgeGuided>
{hasCreateBotPermission ? (
<BadgeGuided>Guided</BadgeGuided>
) : (
<ToolTipNoPermBadge>
<div>
You don’t have sufficient permissions to create bots. Reach out to
your Teleport administrator to request additional permissions.
</div>
</ToolTipNoPermBadge>
)}
<TileContent icon={integration.icon} title={integration.title} />
</IntegrationTile>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
import React from 'react';
import { MemoryRouter } from 'react-router';

import { ContextProvider } from 'teleport';

import { createTeleportContext } from 'teleport/mocks/contexts';

import cfg from 'teleport/config';

import { IntegrationEnroll } from './IntegrationEnroll';
Expand All @@ -27,8 +31,14 @@ export default {
title: 'Teleport/Integrations/Enroll',
};

export const Picker = () => (
<MemoryRouter initialEntries={[cfg.routes.integrationEnroll]}>
<IntegrationEnroll />
</MemoryRouter>
);
export const Picker = () => {
const ctx = createTeleportContext();

return (
<MemoryRouter initialEntries={[cfg.routes.integrationEnroll]}>
<ContextProvider ctx={ctx}>
<IntegrationEnroll />
</ContextProvider>
</MemoryRouter>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,107 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import {
AnsibleIcon,
AWSIcon,
AzureIcon,
CircleCIIcon,
GCPIcon,
GitHubIcon,
GitLabIcon,
JenkinsIcon,
KubernetesIcon,
ServersIcon,
SpaceliftIcon,
} from 'design/SVGIcon';
import { Box, Flex, Link as ExternalLink, Text } from 'design';
import React from 'react';

import {
IntegrationEnrollEvent,
IntegrationEnrollKind,
userEventService,
} from 'teleport/services/userEvent';
import { Box, Text } from 'design';

import { IntegrationTile } from './common';

interface Integration {
title: string;
link: string;
icon: JSX.Element;
kind: IntegrationEnrollKind;
}

const integrations: Integration[] = [
{
title: 'GitHub Actions',
link: 'https://goteleport.com/docs/machine-id/deployment/github-actions/',
icon: <GitHubIcon size={80} />,
kind: IntegrationEnrollKind.MachineIDGitHubActions,
},
{
title: 'CircleCI',
link: 'https://goteleport.com/docs/machine-id/deployment/circleci/',
icon: <CircleCIIcon size={80} />,
kind: IntegrationEnrollKind.MachineIDCircleCI,
},
{
title: 'GitLab CI/CD',
link: 'https://goteleport.com/docs/machine-id/deployment/gitlab/',
icon: <GitLabIcon size={80} />,
kind: IntegrationEnrollKind.MachineIDGitLab,
},
{
title: 'Jenkins',
link: 'https://goteleport.com/docs/machine-id/deployment/jenkins/',
icon: <JenkinsIcon size={80} />,
kind: IntegrationEnrollKind.MachineIDJenkins,
},
{
title: 'Ansible',
link: 'https://goteleport.com/docs/machine-id/access-guides/ansible/',
icon: <AnsibleIcon size={80} />,
kind: IntegrationEnrollKind.MachineIDAnsible,
},
{
title: 'Spacelift',
link: 'https://goteleport.com/docs/machine-id/deployment/spacelift/',
icon: <SpaceliftIcon size={80} />,
kind: IntegrationEnrollKind.MachineIDSpacelift,
},
{
title: 'AWS',
link: 'https://goteleport.com/docs/machine-id/deployment/aws/',
icon: <AWSIcon size={80} />,
kind: IntegrationEnrollKind.MachineIDAWS,
},
{
title: 'GCP',
link: 'https://goteleport.com/docs/machine-id/deployment/gcp/',
icon: <GCPIcon size={80} />,
kind: IntegrationEnrollKind.MachineIDGCP,
},
{
title: 'Azure',
link: 'https://goteleport.com/docs/machine-id/deployment/azure/',
icon: <AzureIcon size={80} />,
kind: IntegrationEnrollKind.MachineIDAzure,
},
{
title: 'Kubernetes',
link: 'https://goteleport.com/docs/machine-id/deployment/kubernetes/',
icon: <KubernetesIcon size={80} />,
kind: IntegrationEnrollKind.MachineIDKubernetes,
},
{
title: 'Generic',
link: 'https://goteleport.com/docs/machine-id/getting-started/',
icon: <ServersIcon size={80} />,
kind: IntegrationEnrollKind.MachineID,
},
];
import { BotTiles } from 'teleport/Bots/Add/AddBotsPicker';
import useTeleport from 'teleport/useTeleport';

export const MachineIDIntegrationSection = () => {
const ctx = useTeleport();
return (
<>
<Box mb={3}>
Expand All @@ -128,33 +36,7 @@ export const MachineIDIntegrationSection = () => {
to access resources protected by Teleport.
</Text>
</Box>
{/* TODO(mcbattirola): replace this section with BotTiles and remove Integrations */}
<Flex mb={2} gap={3} flexWrap="wrap">
{integrations.map(i => {
return (
<IntegrationTile
key={i.title}
as={ExternalLink}
href={i.link}
target="_blank"
onClick={() => {
userEventService.captureIntegrationEnrollEvent({
event: IntegrationEnrollEvent.Started,
eventData: {
id: crypto.randomUUID(),
kind: i.kind,
},
});
}}
>
<Box mt={3} mb={2}>
{i.icon}
</Box>
<Text>{i.title}</Text>
</IntegrationTile>
);
})}
</Flex>
<BotTiles hasCreateBotPermission={ctx.getFeatureFlags().addBots} />
</>
);
};