From 3dcdc0d1adbe51e600ed1f9d40657526e927ed96 Mon Sep 17 00:00:00 2001 From: Yassine Bounekhla <56373201+rudream@users.noreply.github.com> Date: Thu, 1 Sep 2022 11:32:58 -0400 Subject: [PATCH] [v10] Add `--request-id` flag to connection instructions for Kubes and Databases (#1130) (#1163) --- .../ConnectDialog/ConnectDialog.story.tsx | 14 +++++++++++ .../Databases/ConnectDialog/ConnectDialog.tsx | 17 ++++++++++++- .../Databases/DatabaseList/DatabaseList.tsx | 3 +++ .../src/Databases/Databases.story.tsx | 1 + .../teleport/src/Databases/Databases.tsx | 2 ++ .../teleport/src/Databases/useDatabases.ts | 2 ++ .../ConnectDialog/ConnectDialog.story.tsx | 13 ++++++++++ .../src/Kubes/ConnectDialog/ConnectDialog.tsx | 25 +++++++++++++++++-- .../teleport/src/Kubes/KubeList/KubeList.tsx | 3 +++ .../teleport/src/Kubes/Kubes.story.tsx | 1 + web/packages/teleport/src/Kubes/Kubes.tsx | 2 ++ web/packages/teleport/src/Kubes/useKubes.ts | 2 ++ .../src/services/user/makeUserContext.ts | 2 ++ .../teleport/src/services/user/types.ts | 2 ++ .../teleport/src/stores/storeUserContext.ts | 4 +++ 15 files changed, 90 insertions(+), 3 deletions(-) diff --git a/web/packages/teleport/src/Databases/ConnectDialog/ConnectDialog.story.tsx b/web/packages/teleport/src/Databases/ConnectDialog/ConnectDialog.story.tsx index dde2b59bfb929..6dfa9b7d7c894 100644 --- a/web/packages/teleport/src/Databases/ConnectDialog/ConnectDialog.story.tsx +++ b/web/packages/teleport/src/Databases/ConnectDialog/ConnectDialog.story.tsx @@ -32,3 +32,17 @@ export const Connect = () => ( authType="local" /> ); + +export const ConnectWithRequestId = () => { + return ( + null} + authType="local" + accessRequestId="e1e8072c-1eb8-5df4-a7bd-b6863b19271c" + /> + ); +}; diff --git a/web/packages/teleport/src/Databases/ConnectDialog/ConnectDialog.tsx b/web/packages/teleport/src/Databases/ConnectDialog/ConnectDialog.tsx index 2d4b07cc666ef..2f23dde8d3a29 100644 --- a/web/packages/teleport/src/Databases/ConnectDialog/ConnectDialog.tsx +++ b/web/packages/teleport/src/Databases/ConnectDialog/ConnectDialog.tsx @@ -32,6 +32,7 @@ export default function ConnectDialog({ dbName, onClose, authType, + accessRequestId, }: Props) { const { hostname, port } = window.document.location; const host = `${hostname}:${port || '443'}`; @@ -41,6 +42,10 @@ export default function ConnectDialog({ ? `tsh login --proxy=${host}` : `tsh login --proxy=${host} --auth=local --user=${username}`; + const requestIdFlag = accessRequestId + ? ` --request-id=${accessRequestId}` + : ''; + return ( ({ @@ -60,7 +65,7 @@ export default function ConnectDialog({ Step 1 {' - Login to Teleport'} - + @@ -82,6 +87,15 @@ export default function ConnectDialog({ text={`tsh db connect [--db-user=] [--db-name=] ${dbName}`} /> + {accessRequestId && ( + + + Step 4 (Optional) + + {' - When finished, drop the assumed role'} + + + )} {`* Note: To connect with a GUI database client, see our `} setDbConnectInfo(null)} authType={authType} + accessRequestId={accessRequestId} /> )} @@ -166,6 +168,7 @@ type Props = { pathname: string; replaceHistory: (path: string) => void; onLabelClick: (label: AgentLabel) => void; + accessRequestId?: string; }; export default DatabaseList; diff --git a/web/packages/teleport/src/Databases/Databases.story.tsx b/web/packages/teleport/src/Databases/Databases.story.tsx index 1a74e0a354c06..ecf096a94db13 100644 --- a/web/packages/teleport/src/Databases/Databases.story.tsx +++ b/web/packages/teleport/src/Databases/Databases.story.tsx @@ -85,4 +85,5 @@ export const props: State = { replaceHistory: () => null, isSearchEmpty: false, onLabelClick: () => null, + accessRequestId: null, }; diff --git a/web/packages/teleport/src/Databases/Databases.tsx b/web/packages/teleport/src/Databases/Databases.tsx index 4aa560b8fe0b4..6f8fb9cd33f59 100644 --- a/web/packages/teleport/src/Databases/Databases.tsx +++ b/web/packages/teleport/src/Databases/Databases.tsx @@ -65,6 +65,7 @@ export function Databases(props: State) { fetchStatus, isSearchEmpty, onLabelClick, + accessRequestId, } = props; const hasNoDatabases = results.databases.length === 0 && isSearchEmpty; @@ -110,6 +111,7 @@ export function Databases(props: State) { pathname={pathname} replaceHistory={replaceHistory} onLabelClick={onLabelClick} + accessRequestId={accessRequestId} /> )} diff --git a/web/packages/teleport/src/Databases/useDatabases.ts b/web/packages/teleport/src/Databases/useDatabases.ts index ec468e15461b5..2619ebb8de3b6 100644 --- a/web/packages/teleport/src/Databases/useDatabases.ts +++ b/web/packages/teleport/src/Databases/useDatabases.ts @@ -39,6 +39,7 @@ export default function useDatabases(ctx: Ctx) { const isEnterprise = ctx.isEnterprise; const version = ctx.storeUser.state.cluster.authVersion; const authType = ctx.storeUser.state.authType; + const accessRequestId = ctx.storeUser.getAccessRequestId(); const [isAddDialogVisible, setIsAddDialogVisible] = useState(false); const [fetchStatus, setFetchStatus] = useState(''); const [params, setParams] = useState({ @@ -178,6 +179,7 @@ export default function useDatabases(ctx: Ctx) { fetchStatus, isSearchEmpty, onLabelClick, + accessRequestId, }; } diff --git a/web/packages/teleport/src/Kubes/ConnectDialog/ConnectDialog.story.tsx b/web/packages/teleport/src/Kubes/ConnectDialog/ConnectDialog.story.tsx index c33955ad63574..ea47dda4e822e 100644 --- a/web/packages/teleport/src/Kubes/ConnectDialog/ConnectDialog.story.tsx +++ b/web/packages/teleport/src/Kubes/ConnectDialog/ConnectDialog.story.tsx @@ -34,6 +34,19 @@ export const Local = () => { ); }; +export const LocalWithRequestId = () => { + return ( + null} + username={'sam'} + authType={'local'} + kubeConnectName={'tele.logicoma.dev-prod'} + clusterId={'some-cluster-name'} + accessRequestId={'8289cdb1-385c-5b02-85f1-fa2a934b749f'} + /> + ); +}; + export const Sso = () => { return ( {' - Login to Teleport'} - + @@ -77,6 +88,15 @@ function ConnectDialog(props: Props) { {' - Connect to the Kubernetes cluster'} + {accessRequestId && ( + + + Step 4 (Optional) + + {' - When finished, drop the assumed role'} + + + )} Close @@ -91,6 +111,7 @@ type Props = { authType: AuthType; kubeConnectName: string; clusterId: string; + accessRequestId?: string; }; const dialogCss = () => ` diff --git a/web/packages/teleport/src/Kubes/KubeList/KubeList.tsx b/web/packages/teleport/src/Kubes/KubeList/KubeList.tsx index ac50d47d54c86..2fc16a2492be2 100644 --- a/web/packages/teleport/src/Kubes/KubeList/KubeList.tsx +++ b/web/packages/teleport/src/Kubes/KubeList/KubeList.tsx @@ -47,6 +47,7 @@ function KubeList(props: Props) { pathname, replaceHistory, onLabelClick, + accessRequestId, } = props; const [kubeConnectName, setKubeConnectName] = useState(''); @@ -105,6 +106,7 @@ function KubeList(props: Props) { authType={authType} kubeConnectName={kubeConnectName} clusterId={clusterId} + accessRequestId={accessRequestId} /> )} @@ -143,6 +145,7 @@ type Props = { pathname: string; replaceHistory: (path: string) => void; onLabelClick: (label: AgentLabel) => void; + accessRequestId?: string; }; export default KubeList; diff --git a/web/packages/teleport/src/Kubes/Kubes.story.tsx b/web/packages/teleport/src/Kubes/Kubes.story.tsx index 27d845d680606..ba1c180062279 100644 --- a/web/packages/teleport/src/Kubes/Kubes.story.tsx +++ b/web/packages/teleport/src/Kubes/Kubes.story.tsx @@ -82,4 +82,5 @@ export const props: State = { replaceHistory: () => null, isSearchEmpty: false, onLabelClick: () => null, + accessRequestId: null, }; diff --git a/web/packages/teleport/src/Kubes/Kubes.tsx b/web/packages/teleport/src/Kubes/Kubes.tsx index 74223b73131d1..0a2d4a4813d4b 100644 --- a/web/packages/teleport/src/Kubes/Kubes.tsx +++ b/web/packages/teleport/src/Kubes/Kubes.tsx @@ -63,6 +63,7 @@ export function Kubes(props: State) { fetchStatus, isSearchEmpty, onLabelClick, + accessRequestId, } = props; const [showAddKube, setShowAddKube] = useState(false); @@ -112,6 +113,7 @@ export function Kubes(props: State) { pathname={pathname} replaceHistory={replaceHistory} onLabelClick={onLabelClick} + accessRequestId={accessRequestId} /> )} diff --git a/web/packages/teleport/src/Kubes/useKubes.ts b/web/packages/teleport/src/Kubes/useKubes.ts index 20a9990e29551..bd411bc35d0a5 100644 --- a/web/packages/teleport/src/Kubes/useKubes.ts +++ b/web/packages/teleport/src/Kubes/useKubes.ts @@ -35,6 +35,7 @@ export default function useKubes(ctx: TeleportContext) { const { search, pathname } = useLocation(); const [startKeys, setStartKeys] = useState([]); const canCreate = ctx.storeUser.getTokenAccess().create; + const accessRequestId = ctx.storeUser.getAccessRequestId(); const { attempt, setAttempt } = useAttempt('processing'); const [fetchStatus, setFetchStatus] = useState(''); const [params, setParams] = useState({ @@ -160,6 +161,7 @@ export default function useKubes(ctx: TeleportContext) { fetchStatus, isSearchEmpty, onLabelClick, + accessRequestId, }; } diff --git a/web/packages/teleport/src/services/user/makeUserContext.ts b/web/packages/teleport/src/services/user/makeUserContext.ts index f543cb570b0b4..531a1ad942ff6 100644 --- a/web/packages/teleport/src/services/user/makeUserContext.ts +++ b/web/packages/teleport/src/services/user/makeUserContext.ts @@ -23,6 +23,7 @@ export default function makeUserContext(json: any): UserContext { json = json || {}; const username = json.userName; const authType = json.authType; + const accessRequestId = json.accessRequestId; const cluster = makeCluster(json.cluster); const acl = makeAcl(json.userAcl); @@ -36,6 +37,7 @@ export default function makeUserContext(json: any): UserContext { cluster, accessStrategy, accessCapabilities, + accessRequestId, }; } diff --git a/web/packages/teleport/src/services/user/types.ts b/web/packages/teleport/src/services/user/types.ts index 52ca12e280a7d..dc09721eb3c76 100644 --- a/web/packages/teleport/src/services/user/types.ts +++ b/web/packages/teleport/src/services/user/types.ts @@ -35,6 +35,8 @@ export interface UserContext { cluster: Cluster; accessStrategy: AccessStrategy; accessCapabilities: AccessCapabilities; + // accessRequestId is the ID of the access request from which additional roles to assume were obtained for the current session. + accessRequestId?: string; } export interface Access { diff --git a/web/packages/teleport/src/stores/storeUserContext.ts b/web/packages/teleport/src/stores/storeUserContext.ts index b7de70987f0b9..2f4c8b6b8980a 100644 --- a/web/packages/teleport/src/stores/storeUserContext.ts +++ b/web/packages/teleport/src/stores/storeUserContext.ts @@ -105,4 +105,8 @@ export default class StoreUserContext extends Store { getNodeAccess() { return this.state.acl.nodes; } + + getAccessRequestId() { + return this.state.accessRequestId; + } }