From e61e7319c4cf51ab1dc19fd2aeade3d394cd19ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Cie=C5=9Blak?= Date: Thu, 28 Mar 2024 12:56:02 +0100 Subject: [PATCH 1/3] Reuse single transport for gRPC clients v15 doesn't have VnetClient, but we're backporting this for the sake of consistency. --- .../teleterm/src/mainProcess/mainProcess.ts | 9 ++++++++- web/packages/teleterm/src/preload.ts | 9 ++++++++- .../teleterm/src/services/tshd/createClient.ts | 15 +-------------- .../teleterm/src/services/tshd/types.test.ts | 9 ++++++++- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/web/packages/teleterm/src/mainProcess/mainProcess.ts b/web/packages/teleterm/src/mainProcess/mainProcess.ts index 89564516c178d..b4278d998fda0 100644 --- a/web/packages/teleterm/src/mainProcess/mainProcess.ts +++ b/web/packages/teleterm/src/mainProcess/mainProcess.ts @@ -31,6 +31,7 @@ import { shell, } from 'electron'; import { ChannelCredentials } from '@grpc/grpc-js'; +import { GrpcTransport } from '@protobuf-ts/grpc-transport'; import { FileStorage, RuntimeSettings } from 'teleterm/types'; import { subscribeToFileStorageEvents } from 'teleterm/services/fileStorage'; @@ -50,6 +51,7 @@ import Logger from 'teleterm/logger'; import * as grpcCreds from 'teleterm/services/grpcCredentials'; import { createTshdClient } from 'teleterm/services/tshd/createClient'; import { TshdClient } from 'teleterm/services/tshd/types'; +import { loggingInterceptor } from 'teleterm/services/tshd/interceptors'; import { ConfigService, @@ -629,7 +631,12 @@ async function setUpTshdClient({ tshdAddress: string; }): Promise { const creds = await createGrpcCredentials(runtimeSettings); - return createTshdClient(tshdAddress, creds); + const transport = new GrpcTransport({ + host: tshdAddress, + channelCredentials: creds, + interceptors: [loggingInterceptor(new Logger('tshd'))], + }); + return createTshdClient(transport); } async function createGrpcCredentials( diff --git a/web/packages/teleterm/src/preload.ts b/web/packages/teleterm/src/preload.ts index 56d1f5ad54621..9e20e1d29dbd5 100644 --- a/web/packages/teleterm/src/preload.ts +++ b/web/packages/teleterm/src/preload.ts @@ -18,8 +18,10 @@ import { contextBridge } from 'electron'; import { ChannelCredentials, ServerCredentials } from '@grpc/grpc-js'; +import { GrpcTransport } from '@protobuf-ts/grpc-transport'; import { createTshdClient } from 'teleterm/services/tshd/createClient'; +import { loggingInterceptor } from 'teleterm/services/tshd/interceptors'; import createMainProcessClient from 'teleterm/mainProcess/mainProcessClient'; import { createFileLoggerService } from 'teleterm/services/logger'; import Logger from 'teleterm/logger'; @@ -60,7 +62,12 @@ async function getElectronGlobals(): Promise { mainProcessClient.getResolvedChildProcessAddresses(), createGrpcCredentials(runtimeSettings), ]); - const tshClient = createTshdClient(addresses.tsh, credentials.tshd); + const tshdTransport = new GrpcTransport({ + host: addresses.tsh, + channelCredentials: credentials.tshd, + interceptors: [loggingInterceptor(new Logger('tshd'))], + }); + const tshClient = createTshdClient(tshdTransport); const ptyServiceClient = createPtyService( addresses.shared, credentials.shared, diff --git a/web/packages/teleterm/src/services/tshd/createClient.ts b/web/packages/teleterm/src/services/tshd/createClient.ts index 231d67faf55e1..b1167afcf45f5 100644 --- a/web/packages/teleterm/src/services/tshd/createClient.ts +++ b/web/packages/teleterm/src/services/tshd/createClient.ts @@ -16,25 +16,12 @@ * along with this program. If not, see . */ -import grpc from '@grpc/grpc-js'; import { GrpcTransport } from '@protobuf-ts/grpc-transport'; import { TerminalServiceClient } from 'gen-proto-ts/teleport/lib/teleterm/v1/service_pb.client'; -import Logger from 'teleterm/logger'; - import { cloneClient } from './cloneableClient'; import * as types from './types'; -import { loggingInterceptor } from './interceptors'; -export function createTshdClient( - addr: string, - credentials: grpc.ChannelCredentials -): types.TshdClient { - const logger = new Logger('tshd'); - const transport = new GrpcTransport({ - host: addr, - channelCredentials: credentials, - interceptors: [loggingInterceptor(logger)], - }); +export function createTshdClient(transport: GrpcTransport): types.TshdClient { return cloneClient(new TerminalServiceClient(transport)); } diff --git a/web/packages/teleterm/src/services/tshd/types.test.ts b/web/packages/teleterm/src/services/tshd/types.test.ts index 9879a7cfd9f48..0c58e1daef927 100644 --- a/web/packages/teleterm/src/services/tshd/types.test.ts +++ b/web/packages/teleterm/src/services/tshd/types.test.ts @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +import { GrpcTransport } from '@protobuf-ts/grpc-transport'; + import { createInsecureClientCredentials } from 'teleterm/services/grpcCredentials'; import { createTshdClient } from './createClient'; @@ -24,6 +26,11 @@ import { createTshdClient } from './createClient'; // Dependencies must be provided as `--path` values to `buf generate` in build.assets/genproto.sh. test('generated protos import necessary dependencies', () => { expect(() => { - createTshdClient('localhost:0', createInsecureClientCredentials()); + createTshdClient( + new GrpcTransport({ + host: 'localhost:1337', + channelCredentials: createInsecureClientCredentials(), + }) + ); }).not.toThrow(); }); From 2be7d5237e9f6bd95594c6bb92deb55e70dad450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Cie=C5=9Blak?= Date: Thu, 28 Mar 2024 13:49:19 +0100 Subject: [PATCH 2/3] Log service name --- .../src/services/tshd/interceptors.test.ts | 33 +++++++++++++++++-- .../src/services/tshd/interceptors.ts | 22 ++++++++----- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/web/packages/teleterm/src/services/tshd/interceptors.test.ts b/web/packages/teleterm/src/services/tshd/interceptors.test.ts index 0b368e7bb7af7..52d7e0b9adfb8 100644 --- a/web/packages/teleterm/src/services/tshd/interceptors.test.ts +++ b/web/packages/teleterm/src/services/tshd/interceptors.test.ts @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { UnaryCall, MethodInfo } from '@protobuf-ts/runtime-rpc'; +import { UnaryCall, MethodInfo, ServiceInfo } from '@protobuf-ts/runtime-rpc'; import Logger from 'teleterm/logger'; @@ -35,7 +35,10 @@ it('do not log sensitive info like password', () => { interceptor.interceptUnary( () => ({ then: () => Promise.resolve({ response: '' }) }) as UnaryCall, - { name: 'LogIn' } as MethodInfo, + { + name: 'LogIn', + service: { typeName: 'FooService' } as ServiceInfo, + } as MethodInfo, { passw: {}, userData: { @@ -46,8 +49,32 @@ it('do not log sensitive info like password', () => { {} ); - expect(infoLogger).toHaveBeenCalledWith('LogIn request:', { + expect(infoLogger).toHaveBeenCalledWith(expect.any(String), { passw: '~FILTERED~', userData: { login: 'admin', password: '~FILTERED~' }, }); }); + +it('includes service and method name', () => { + const infoLogger = jest.fn(); + Logger.init({ + createLogger: () => ({ + info: infoLogger, + error: () => {}, + warn: () => {}, + }), + }); + const interceptor = loggingInterceptor(new Logger()); + + interceptor.interceptUnary( + () => ({ then: () => Promise.resolve({ response: '' }) }) as UnaryCall, + { + name: 'Foo', + service: { typeName: 'FooService' } as ServiceInfo, + } as MethodInfo, + {}, + {} + ); + + expect(infoLogger).toHaveBeenCalledWith('send FooService Foo', {}); +}); diff --git a/web/packages/teleterm/src/services/tshd/interceptors.ts b/web/packages/teleterm/src/services/tshd/interceptors.ts index bed80c9760744..3608039462fb9 100644 --- a/web/packages/teleterm/src/services/tshd/interceptors.ts +++ b/web/packages/teleterm/src/services/tshd/interceptors.ts @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { RpcInterceptor } from '@protobuf-ts/runtime-rpc'; +import { MethodInfo, RpcInterceptor } from '@protobuf-ts/runtime-rpc'; import { isObject } from 'shared/utils/highbar'; @@ -30,7 +30,7 @@ export function loggingInterceptor(logger: Logger): RpcInterceptor { const output = next(method, input, options); const { logRequest, logResponse, logError } = makeMethodLogger( logger, - method.name + method ); logRequest(input); @@ -44,7 +44,7 @@ export function loggingInterceptor(logger: Logger): RpcInterceptor { const output = next(method, options); const { logRequest, logResponse, logError } = makeMethodLogger( logger, - method.name + method ); const originalSend = output.requests.send.bind(output.requests); @@ -62,7 +62,7 @@ export function loggingInterceptor(logger: Logger): RpcInterceptor { const output = next(method, input, options); const { logRequest, logResponse, logError } = makeMethodLogger( logger, - method.name + method ); logRequest(input); @@ -81,7 +81,7 @@ export function loggingInterceptor(logger: Logger): RpcInterceptor { const output = next(method, options); const { logRequest, logResponse, logError } = makeMethodLogger( logger, - method.name + method ); const originalSend = output.requests.send.bind(output.requests); @@ -127,17 +127,21 @@ export function filterSensitiveProperties(toFilter: object): object { return acc; } -function makeMethodLogger(logger: Logger, methodName: string) { +function makeMethodLogger(logger: Logger, method: MethodInfo) { + // Service name and method name are separated with a space and not a slash on purpose. + // This way the Chromium console can break down the log message more easily on narrower widths. + const methodDesc = `${method.service.typeName} ${method.name}`; + return { logRequest: (input: object) => { - logger.info(`${methodName} request:`, filterSensitiveProperties(input)); + logger.info(`send ${methodDesc}`, filterSensitiveProperties(input)); }, logResponse: (output: object) => { const toLog = output ? filterSensitiveProperties(output) : null; - logger.info(`${methodName} response:`, toLog); + logger.info(`receive ${methodDesc}`, toLog); }, logError: (error: unknown) => { - logger.error(`${methodName} response:`, `${error}`); + logger.error(`receive ${methodDesc}`, `${error}`); }, }; } From 99676f6e3a20ac2a3cf98b3cf28fb41b642f51df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Cie=C5=9Blak?= Date: Tue, 2 Apr 2024 11:50:44 +0200 Subject: [PATCH 3/3] Clean up TypeScript types related to tsh daemon --- .../teleterm/src/mainProcess/mainProcess.ts | 3 +- .../rootClusterProxyHostAllowList.ts | 2 +- .../src/services/tshd/createClient.ts | 14 ++- .../src/services/tshd/fixtures/mocks.ts | 6 +- .../teleterm/src/services/tshd/index.ts | 21 ++++ .../teleterm/src/services/tshd/types.ts | 109 ++++++++++++++---- web/packages/teleterm/src/types.ts | 2 +- web/packages/teleterm/src/ui/appContext.ts | 2 +- .../services/clusters/clustersService.test.ts | 8 +- .../ui/services/clusters/clustersService.ts | 9 +- .../connectMyComputerService.ts | 3 +- .../fileTransferClient/fileTransferService.ts | 3 +- .../headlessAuthn/headlessAuthnService.ts | 5 +- .../resources/resourcesService.test.ts | 19 +-- .../ui/services/resources/resourcesService.ts | 3 +- .../src/ui/services/usage/usageService.ts | 3 +- web/packages/teleterm/src/ui/types.ts | 2 +- 17 files changed, 155 insertions(+), 59 deletions(-) create mode 100644 web/packages/teleterm/src/services/tshd/index.ts diff --git a/web/packages/teleterm/src/mainProcess/mainProcess.ts b/web/packages/teleterm/src/mainProcess/mainProcess.ts index b4278d998fda0..42dcb2f7b44b6 100644 --- a/web/packages/teleterm/src/mainProcess/mainProcess.ts +++ b/web/packages/teleterm/src/mainProcess/mainProcess.ts @@ -49,8 +49,7 @@ import { getAssetPath } from 'teleterm/mainProcess/runtimeSettings'; import { RootClusterUri } from 'teleterm/ui/uri'; import Logger from 'teleterm/logger'; import * as grpcCreds from 'teleterm/services/grpcCredentials'; -import { createTshdClient } from 'teleterm/services/tshd/createClient'; -import { TshdClient } from 'teleterm/services/tshd/types'; +import { createTshdClient, TshdClient } from 'teleterm/services/tshd'; import { loggingInterceptor } from 'teleterm/services/tshd/interceptors'; import { diff --git a/web/packages/teleterm/src/mainProcess/rootClusterProxyHostAllowList.ts b/web/packages/teleterm/src/mainProcess/rootClusterProxyHostAllowList.ts index ba1635dae669b..979adc3b96545 100644 --- a/web/packages/teleterm/src/mainProcess/rootClusterProxyHostAllowList.ts +++ b/web/packages/teleterm/src/mainProcess/rootClusterProxyHostAllowList.ts @@ -21,7 +21,7 @@ import { ipcMain } from 'electron'; import { isAbortError } from 'shared/utils/abortError'; import { proxyHostToBrowserProxyHost } from 'teleterm/services/tshd/cluster'; -import { TshdClient } from 'teleterm/services/tshd/types'; +import { TshdClient } from 'teleterm/services/tshd'; import { Logger } from 'teleterm/types'; import { MainProcessIpc } from 'teleterm/mainProcess/types'; import * as tshd from 'teleterm/services/tshd/types'; diff --git a/web/packages/teleterm/src/services/tshd/createClient.ts b/web/packages/teleterm/src/services/tshd/createClient.ts index b1167afcf45f5..2815bc90924da 100644 --- a/web/packages/teleterm/src/services/tshd/createClient.ts +++ b/web/packages/teleterm/src/services/tshd/createClient.ts @@ -17,11 +17,17 @@ */ import { GrpcTransport } from '@protobuf-ts/grpc-transport'; -import { TerminalServiceClient } from 'gen-proto-ts/teleport/lib/teleterm/v1/service_pb.client'; +import { + ITerminalServiceClient, + TerminalServiceClient, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/service_pb.client'; -import { cloneClient } from './cloneableClient'; -import * as types from './types'; +import { CloneableClient, cloneClient } from './cloneableClient'; -export function createTshdClient(transport: GrpcTransport): types.TshdClient { +// Creating the client type based on the interface (ITerminalServiceClient) and not the class +// (TerminalServiceClient) lets us omit a bunch of properties when mocking a client. +export type TshdClient = CloneableClient; + +export function createTshdClient(transport: GrpcTransport): TshdClient { return cloneClient(new TerminalServiceClient(transport)); } diff --git a/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts b/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts index ca14d8a05e997..9467f05442856 100644 --- a/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts +++ b/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts @@ -20,11 +20,11 @@ import { makeRootCluster, makeAppGateway, } from 'teleterm/services/tshd/testHelpers'; -import { MockedUnaryCall } from 'teleterm/services/tshd/cloneableClient'; -import * as types from '../types'; +import { TshdClient } from '../createClient'; +import { MockedUnaryCall } from '../cloneableClient'; -export class MockTshClient implements types.TshdClient { +export class MockTshClient implements TshdClient { listRootClusters = () => new MockedUnaryCall({ clusters: [] }); listLeafClusters = () => new MockedUnaryCall({ clusters: [] }); getKubes = () => diff --git a/web/packages/teleterm/src/services/tshd/index.ts b/web/packages/teleterm/src/services/tshd/index.ts new file mode 100644 index 0000000000000..225cf8d0465da --- /dev/null +++ b/web/packages/teleterm/src/services/tshd/index.ts @@ -0,0 +1,21 @@ +/** + * 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 . + */ + +export * from './createClient'; +export { cloneAbortSignal, isTshdRpcError } from './cloneableClient'; +export type { CloneableAbortSignal } from './cloneableClient'; diff --git a/web/packages/teleterm/src/services/tshd/types.ts b/web/packages/teleterm/src/services/tshd/types.ts index 828d09addd187..44d8c273d6970 100644 --- a/web/packages/teleterm/src/services/tshd/types.ts +++ b/web/packages/teleterm/src/services/tshd/types.ts @@ -16,34 +16,99 @@ * along with this program. If not, see . */ -import { ITerminalServiceClient } from 'gen-proto-ts/teleport/lib/teleterm/v1/service_pb.client'; - import { SortType } from 'design/DataTable/types'; -import { CloneableClient } from './cloneableClient'; - import type * as uri from 'teleterm/ui/uri'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/database_pb'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/gateway_pb'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/server_pb'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/kube_pb'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/app_pb'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/label_pb'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/service_pb'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/auth_settings_pb'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/access_request_pb'; -export * from 'gen-proto-ts/teleport/lib/teleterm/v1/usage_events_pb'; -export * from 'gen-proto-ts/teleport/accesslist/v1/accesslist_pb'; +/* + * + * Do not add new imports to this file, we're trying to get rid of types.ts files. + * + */ -export type { - CloneableAbortSignal, - CloneableRpcOptions, - CloneableClient, -} from './cloneableClient'; +export { + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + Cluster, + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + LoggedInUser, + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + LoggedInUser_UserType, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; +export { + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + Database, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/database_pb'; +export { + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + Gateway, + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + GatewayCLICommand, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/gateway_pb'; +export { + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + Server, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/server_pb'; +export { + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + Kube, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/kube_pb'; +export { + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + App, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/app_pb'; +export { + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + Label, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/label_pb'; +export { + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + AuthSettings, + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + AuthProvider, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/auth_settings_pb'; +export { + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + AccessRequest, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/access_request_pb'; +export { + /** + * @deprecated Import directly from gen-proto-ts instead. + */ + AccessList, +} from 'gen-proto-ts/teleport/accesslist/v1/accesslist_pb'; -export type TshdClient = CloneableClient; +// There's too many re-exports from this file to list them individually. +// A @deprecated annotation like this Unfortunately has no effect on the language server. +/** + * @deprecated Import directly from gen-proto-ts instead. + */ +export * from 'gen-proto-ts/teleport/lib/teleterm/v1/service_pb'; /** * Available types are listed here: diff --git a/web/packages/teleterm/src/types.ts b/web/packages/teleterm/src/types.ts index 28adaa7991d84..c88a28c986ac7 100644 --- a/web/packages/teleterm/src/types.ts +++ b/web/packages/teleterm/src/types.ts @@ -24,7 +24,7 @@ import { Logger, LoggerService } from 'teleterm/services/logger/types'; import { FileStorage } from 'teleterm/services/fileStorage'; import { MainProcessClient, RuntimeSettings } from 'teleterm/mainProcess/types'; import { PtyServiceClient } from 'teleterm/services/pty'; -import { TshdClient } from 'teleterm/services/tshd/types'; +import { TshdClient } from 'teleterm/services/tshd/createClient'; export type { Logger, diff --git a/web/packages/teleterm/src/ui/appContext.ts b/web/packages/teleterm/src/ui/appContext.ts index e67d07ea4b8e4..5d305ded45b47 100644 --- a/web/packages/teleterm/src/ui/appContext.ts +++ b/web/packages/teleterm/src/ui/appContext.ts @@ -40,7 +40,7 @@ import { UsageService } from 'teleterm/ui/services/usage'; import { ResourcesService } from 'teleterm/ui/services/resources'; import { ConnectMyComputerService } from 'teleterm/ui/services/connectMyComputer'; import { ConfigService } from 'teleterm/services/config'; -import { TshdClient } from 'teleterm/services/tshd/types'; +import { TshdClient } from 'teleterm/services/tshd/createClient'; import { IAppContext } from 'teleterm/ui/types'; import { DeepLinksService } from 'teleterm/ui/services/deepLinks'; import { parseDeepLink } from 'teleterm/deepLinks'; diff --git a/web/packages/teleterm/src/ui/services/clusters/clustersService.test.ts b/web/packages/teleterm/src/ui/services/clusters/clustersService.test.ts index 50dad09d43850..d41ae1a1ed001 100644 --- a/web/packages/teleterm/src/ui/services/clusters/clustersService.test.ts +++ b/web/packages/teleterm/src/ui/services/clusters/clustersService.test.ts @@ -30,7 +30,7 @@ import { MockedUnaryCall } from 'teleterm/services/tshd/cloneableClient'; import { ClustersService } from './clustersService'; import type * as uri from 'teleterm/ui/uri'; -import type * as tsh from 'teleterm/services/tshd/types'; +import type { TshdClient } from 'teleterm/services/tshd'; jest.mock('teleterm/ui/services/notifications'); jest.mock('teleterm/ui/services/usage'); @@ -58,9 +58,9 @@ const NotificationsServiceMock = NotificationsService as jest.MockedClass< >; const UsageServiceMock = UsageService as jest.MockedClass; -function createService(client: Partial): ClustersService { +function createService(client: Partial): ClustersService { return new ClustersService( - client as tsh.TshdClient, + client as TshdClient, { removeKubeConfig: jest.fn().mockResolvedValueOnce(undefined), } as unknown as MainProcessClient, @@ -69,7 +69,7 @@ function createService(client: Partial): ClustersService { ); } -function getClientMocks(): Partial { +function getClientMocks(): Partial { return { login: jest.fn().mockReturnValueOnce(new MockedUnaryCall({})), logout: jest.fn().mockReturnValueOnce(new MockedUnaryCall({})), diff --git a/web/packages/teleterm/src/ui/services/clusters/clustersService.ts b/web/packages/teleterm/src/ui/services/clusters/clustersService.ts index 1dcaf2f0aaad5..2be68c77409b8 100644 --- a/web/packages/teleterm/src/ui/services/clusters/clustersService.ts +++ b/web/packages/teleterm/src/ui/services/clusters/clustersService.ts @@ -41,6 +41,7 @@ import { UsageService } from 'teleterm/ui/services/usage'; import { ImmutableStore } from '../immutableStore'; import type * as types from './types'; +import type { TshdClient, CloneableAbortSignal } from 'teleterm/services/tshd'; import type * as tsh from 'teleterm/services/tshd/types'; const { routing } = uri; @@ -56,7 +57,7 @@ export class ClustersService extends ImmutableStore state: types.ClustersServiceState = createClusterServiceState(); constructor( - public client: tsh.TshdClient, + public client: TshdClient, private mainProcessClient: MainProcessClient, private notificationsService: NotificationsService, private usageService: UsageService @@ -101,7 +102,7 @@ export class ClustersService extends ImmutableStore async loginLocal( params: types.LoginLocalParams, - abortSignal: tsh.CloneableAbortSignal + abortSignal: CloneableAbortSignal ) { await this.client.login( { @@ -126,7 +127,7 @@ export class ClustersService extends ImmutableStore async loginSso( params: types.LoginSsoParams, - abortSignal: tsh.CloneableAbortSignal + abortSignal: CloneableAbortSignal ) { await this.client.login( { @@ -147,7 +148,7 @@ export class ClustersService extends ImmutableStore async loginPasswordless( params: types.LoginPasswordlessParams, - abortSignal: tsh.CloneableAbortSignal + abortSignal: CloneableAbortSignal ) { await new Promise((resolve, reject) => { const stream = this.client.loginPasswordless({ diff --git a/web/packages/teleterm/src/ui/services/connectMyComputer/connectMyComputerService.ts b/web/packages/teleterm/src/ui/services/connectMyComputer/connectMyComputerService.ts index 0dcb5dcab7411..f938bc8642b39 100644 --- a/web/packages/teleterm/src/ui/services/connectMyComputer/connectMyComputerService.ts +++ b/web/packages/teleterm/src/ui/services/connectMyComputer/connectMyComputerService.ts @@ -21,9 +21,8 @@ import { Cluster, CreateConnectMyComputerRoleResponse, Server, - CloneableAbortSignal, - TshdClient, } from 'teleterm/services/tshd/types'; +import { TshdClient, CloneableAbortSignal } from 'teleterm/services/tshd'; import type * as uri from 'teleterm/ui/uri'; diff --git a/web/packages/teleterm/src/ui/services/fileTransferClient/fileTransferService.ts b/web/packages/teleterm/src/ui/services/fileTransferClient/fileTransferService.ts index 6582dfac33aed..68e0049ddc94f 100644 --- a/web/packages/teleterm/src/ui/services/fileTransferClient/fileTransferService.ts +++ b/web/packages/teleterm/src/ui/services/fileTransferClient/fileTransferService.ts @@ -20,7 +20,8 @@ import { FileTransferListeners } from 'shared/components/FileTransfer'; import { FileTransferDirection } from 'gen-proto-ts/teleport/lib/teleterm/v1/service_pb'; -import { FileTransferRequest, TshdClient } from 'teleterm/services/tshd/types'; +import { FileTransferRequest } from 'teleterm/services/tshd/types'; +import { TshdClient } from 'teleterm/services/tshd'; import { UsageService } from 'teleterm/ui/services/usage'; import { cloneAbortSignal } from 'teleterm/services/tshd/cloneableClient'; diff --git a/web/packages/teleterm/src/ui/services/headlessAuthn/headlessAuthnService.ts b/web/packages/teleterm/src/ui/services/headlessAuthn/headlessAuthnService.ts index de55e9688e1c4..fa5dc997e08e7 100644 --- a/web/packages/teleterm/src/ui/services/headlessAuthn/headlessAuthnService.ts +++ b/web/packages/teleterm/src/ui/services/headlessAuthn/headlessAuthnService.ts @@ -21,13 +21,14 @@ import { MainProcessClient } from 'teleterm/types'; import { ModalsService } from 'teleterm/ui/services/modals'; import { ConfigService } from 'teleterm/services/config'; +import type { TshdClient, CloneableAbortSignal } from 'teleterm/services/tshd'; import type * as types from 'teleterm/services/tshd/types'; export class HeadlessAuthenticationService { constructor( private mainProcessClient: MainProcessClient, private modalsService: ModalsService, - private tshClient: types.TshdClient, + private tshClient: TshdClient, private configService: ConfigService ) {} @@ -60,7 +61,7 @@ export class HeadlessAuthenticationService { async updateHeadlessAuthenticationState( params: types.UpdateHeadlessAuthenticationStateRequest, - abortSignal: types.CloneableAbortSignal + abortSignal: CloneableAbortSignal ): Promise { await this.tshClient.updateHeadlessAuthenticationState(params, { abort: abortSignal, diff --git a/web/packages/teleterm/src/ui/services/resources/resourcesService.test.ts b/web/packages/teleterm/src/ui/services/resources/resourcesService.test.ts index 9a9b42086c2c1..201c95c9f8a35 100644 --- a/web/packages/teleterm/src/ui/services/resources/resourcesService.test.ts +++ b/web/packages/teleterm/src/ui/services/resources/resourcesService.test.ts @@ -30,6 +30,7 @@ import { ResourcesService, } from './resourcesService'; +import type { TshdClient } from 'teleterm/services/tshd'; import type * as tsh from 'teleterm/services/tshd/types'; describe('getServerByHostname', () => { @@ -37,7 +38,7 @@ describe('getServerByHostname', () => { const getServerByHostnameTests: Array< { name: string; - getServersMockedValue: ReturnType; + getServersMockedValue: ReturnType; } & ( | { expectedServer: tsh.Server; expectedErr?: never } | { expectedErr: any; expectedServer?: never } @@ -74,10 +75,10 @@ describe('getServerByHostname', () => { test.each(getServerByHostnameTests)( '$name', async ({ getServersMockedValue, expectedServer, expectedErr }) => { - const tshClient: Partial = { + const tshClient: Partial = { getServers: jest.fn().mockResolvedValueOnce(getServersMockedValue), }; - const service = new ResourcesService(tshClient as tsh.TshdClient); + const service = new ResourcesService(tshClient as TshdClient); const promise = service.getServerByHostname('/clusters/bar', 'foo'); @@ -110,7 +111,7 @@ describe('searchResources', () => { const kube = makeKube(); const app = makeApp(); - const tshClient: Partial = { + const tshClient: Partial = { getServers: jest.fn().mockResolvedValueOnce( new MockedUnaryCall({ agents: [server], @@ -140,7 +141,7 @@ describe('searchResources', () => { }) ), }; - const service = new ResourcesService(tshClient as tsh.TshdClient); + const service = new ResourcesService(tshClient as TshdClient); const searchResults = await service.searchResources({ clusterUri: '/clusters/foo', @@ -172,7 +173,7 @@ describe('searchResources', () => { it('returns a single item if a filter is supplied', async () => { const server = makeServer(); - const tshClient: Partial = { + const tshClient: Partial = { getServers: jest.fn().mockResolvedValueOnce( new MockedUnaryCall({ agents: [server], @@ -181,7 +182,7 @@ describe('searchResources', () => { }) ), }; - const service = new ResourcesService(tshClient as tsh.TshdClient); + const service = new ResourcesService(tshClient as TshdClient); const searchResults = await service.searchResources({ clusterUri: '/clusters/foo', @@ -200,13 +201,13 @@ describe('searchResources', () => { it('returns a custom error pointing at resource kind and cluster when an underlying promise gets rejected', async () => { const expectedCause = new Error('oops'); - const tshClient: Partial = { + const tshClient: Partial = { getServers: jest.fn().mockRejectedValueOnce(expectedCause), getDatabases: jest.fn().mockRejectedValueOnce(expectedCause), getKubes: jest.fn().mockRejectedValueOnce(expectedCause), getApps: jest.fn().mockRejectedValueOnce(expectedCause), }; - const service = new ResourcesService(tshClient as tsh.TshdClient); + const service = new ResourcesService(tshClient as TshdClient); const searchResults = await service.searchResources({ clusterUri: '/clusters/foo', diff --git a/web/packages/teleterm/src/ui/services/resources/resourcesService.ts b/web/packages/teleterm/src/ui/services/resources/resourcesService.ts index 60b3fbb3ccc5f..35fd224dbc18c 100644 --- a/web/packages/teleterm/src/ui/services/resources/resourcesService.ts +++ b/web/packages/teleterm/src/ui/services/resources/resourcesService.ts @@ -34,6 +34,7 @@ import { import Logger from 'teleterm/logger'; +import type { TshdClient } from 'teleterm/services/tshd'; import type * as types from 'teleterm/services/tshd/types'; import type * as uri from 'teleterm/ui/uri'; import type { ResourceTypeFilter } from 'teleterm/ui/Search/searchResult'; @@ -41,7 +42,7 @@ import type { ResourceTypeFilter } from 'teleterm/ui/Search/searchResult'; export class ResourcesService { private logger = new Logger('ResourcesService'); - constructor(private tshClient: types.TshdClient) {} + constructor(private tshClient: TshdClient) {} async fetchServers(params: types.GetResourcesParams) { const { response } = await this.tshClient.getServers( diff --git a/web/packages/teleterm/src/ui/services/usage/usageService.ts b/web/packages/teleterm/src/ui/services/usage/usageService.ts index e2092f590283d..950ae27747e3c 100644 --- a/web/packages/teleterm/src/ui/services/usage/usageService.ts +++ b/web/packages/teleterm/src/ui/services/usage/usageService.ts @@ -21,7 +21,8 @@ import { SubmitConnectEventRequest } from 'gen-proto-ts/prehog/v1alpha/connect_p import { Timestamp } from 'gen-proto-ts/google/protobuf/timestamp_pb'; import { ClusterOrResourceUri, ClusterUri, routing } from 'teleterm/ui/uri'; -import { Cluster, TshdClient } from 'teleterm/services/tshd/types'; +import { Cluster } from 'teleterm/services/tshd/types'; +import { TshdClient } from 'teleterm/services/tshd'; import { RuntimeSettings } from 'teleterm/mainProcess/types'; import { ConfigService } from 'teleterm/services/config'; import Logger from 'teleterm/logger'; diff --git a/web/packages/teleterm/src/ui/types.ts b/web/packages/teleterm/src/ui/types.ts index 15b0842f7c69e..07e1c107977e8 100644 --- a/web/packages/teleterm/src/ui/types.ts +++ b/web/packages/teleterm/src/ui/types.ts @@ -37,7 +37,7 @@ import { UsageService } from 'teleterm/ui/services/usage'; import { ConfigService } from 'teleterm/services/config'; import { ConnectMyComputerService } from 'teleterm/ui/services/connectMyComputer'; import { HeadlessAuthenticationService } from 'teleterm/ui/services/headlessAuthn/headlessAuthnService'; -import { TshdClient } from 'teleterm/services/tshd/types'; +import { TshdClient } from 'teleterm/services/tshd'; export interface IAppContext { clustersService: ClustersService;