Skip to content

Commit

Permalink
Do not cache the service account token in the devWorkspace client
Browse files Browse the repository at this point in the history
  • Loading branch information
vinokurig committed Dec 25, 2024
1 parent 1790beb commit 05fafa6
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 149 deletions.
7 changes: 4 additions & 3 deletions packages/dashboard-backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ import { registerEditorsRoutes } from '@/routes/api/editors';
import { registerEventsRoutes } from '@/routes/api/events';
import { registerGettingStartedSamplesRoutes } from '@/routes/api/gettingStartedSample';
import { registerGitConfigRoutes } from '@/routes/api/gitConfig';
import { getDevWorkspaceSingletonClient } from '@/routes/api/helpers/getDevWorkspaceClient';
import { getDevWorkspaceClient } from '@/routes/api/helpers/getDevWorkspaceClient';
import { getServiceAccountToken } from '@/routes/api/helpers/getServiceAccountToken';
import { registerKubeConfigRoute } from '@/routes/api/kubeConfig';
import { registerPersonalAccessTokenRoutes } from '@/routes/api/personalAccessToken';
import { registerPodmanLoginRoute } from '@/routes/api/podmanLogin';
Expand Down Expand Up @@ -71,8 +72,8 @@ export default async function buildApp(server: FastifyInstance): Promise<unknown
},
);

const { devWorkspaceClusterServiceApi } = getDevWorkspaceSingletonClient();
await devWorkspaceClusterServiceApi.watchInAllNamespaces();
const devWorkspaceClient = getDevWorkspaceClient(getServiceAccountToken());
await devWorkspaceClient.devWorkspaceClusterApi.watchInAllNamespaces();

server.register(import('@fastify/rate-limit'));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { ServerConfigApiService } from '@/devworkspaceClient/services/serverConf
import { SshKeysService } from '@/devworkspaceClient/services/sshKeysApi';
import { UserProfileApiService } from '@/devworkspaceClient/services/userProfileApi';

import { DevWorkspaceClient, DevWorkspaceSingletonClient } from '..';
import { DevWorkspaceClient } from '..';

jest.mock('../services/devWorkspaceApi.ts');

Expand All @@ -50,6 +50,7 @@ describe('DevWorkspace client', () => {
expect(client.devworkspaceApi).toBeInstanceOf(DevWorkspaceApiService);
expect(client.dockerConfigApi).toBeInstanceOf(DockerConfigApiService);
expect(client.eventApi).toBeInstanceOf(EventApiService);
expect(client.devWorkspaceClusterApi).toBeInstanceOf(DevWorkspaceClusterApiService);
expect(client.kubeConfigApi).toBeInstanceOf(KubeConfigApiService);
expect(client.logsApi).toBeInstanceOf(LogsApiService);
expect(client.podApi).toBeInstanceOf(PodApiService);
Expand All @@ -60,28 +61,3 @@ describe('DevWorkspace client', () => {
expect(client.sshKeysApi).toBeInstanceOf(SshKeysService);
});
});

describe('DevWorkspace singleton client', () => {
let config: KubeConfig;
beforeEach(() => {
const { KubeConfig } = mockClientNode;
config = new KubeConfig();
config.makeApiClient = jest.fn().mockImplementation(() => ({}));
});

afterEach(() => {
jest.clearAllMocks();
});

test('client', () => {
const client = DevWorkspaceSingletonClient.getInstance(config);

expect(client.devWorkspaceClusterServiceApi).toBeInstanceOf(DevWorkspaceClusterApiService);
});

test('return same instance', () => {
const client = DevWorkspaceSingletonClient.getInstance(config);

expect(client.devWorkspaceClusterServiceApi).toEqual(client.devWorkspaceClusterServiceApi);
});
});
24 changes: 4 additions & 20 deletions packages/dashboard-backend/src/devworkspaceClient/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import {
IDevWorkspaceApi,
IDevWorkspaceClient,
IDevWorkspaceClusterApi,
IDevWorkspaceSingletonClient,
IDevWorkspaceTemplateApi,
IDockerConfigApi,
IEditorsApi,
Expand Down Expand Up @@ -110,6 +109,10 @@ export class DevWorkspaceClient implements IDevWorkspaceClient {
return new GitConfigApiService(this.kubeConfig);
}

get devWorkspaceClusterApi(): IDevWorkspaceClusterApi {
return new DevWorkspaceClusterApiService(this.kubeConfig);
}

get gettingStartedSampleApi(): IGettingStartedSampleApi {
return new GettingStartedSamplesApiService(this.kubeConfig);
}
Expand All @@ -130,22 +133,3 @@ export class DevWorkspaceClient implements IDevWorkspaceClient {
return new WorkspacePreferencesApiService(this.kubeConfig);
}
}

let devWorkspaceSingletonClient: DevWorkspaceSingletonClient;

/**
* Singleton client for devworkspace services.
*/
export class DevWorkspaceSingletonClient implements IDevWorkspaceSingletonClient {
static getInstance(kc: k8s.KubeConfig): DevWorkspaceSingletonClient {
if (!devWorkspaceSingletonClient) {
devWorkspaceSingletonClient = new DevWorkspaceSingletonClient(kc);
}
return devWorkspaceSingletonClient;
}

public readonly devWorkspaceClusterServiceApi: IDevWorkspaceClusterApi;
private constructor(kc: k8s.KubeConfig) {
this.devWorkspaceClusterServiceApi = new DevWorkspaceClusterApiService(kc);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
import { FastifyInstance } from 'fastify';

import { baseApiPath } from '@/constants/config';
import { getDevWorkspaceSingletonClient } from '@/routes/api/helpers/getDevWorkspaceClient';
import { getDevWorkspaceClient } from '@/routes/api/helpers/getDevWorkspaceClient';
import { getServiceAccountToken } from '@/routes/api/helpers/getServiceAccountToken';
import { getSchema } from '@/services/helpers';

const tags = ['Devworkspace Cluster'];
Expand All @@ -24,8 +25,8 @@ export function registerDevWorkspaceClusterRoutes(instance: FastifyInstance) {
`${baseApiPath}/devworkspace/running-workspaces-cluster-limit-exceeded`,
getSchema({ tags }),
async function () {
const { devWorkspaceClusterServiceApi } = getDevWorkspaceSingletonClient();
return await devWorkspaceClusterServiceApi.isRunningWorkspacesClusterLimitExceeded();
const devWorkspaceClient = getDevWorkspaceClient(getServiceAccountToken());
return await devWorkspaceClient.devWorkspaceClusterApi.isRunningWorkspacesClusterLimitExceeded();
},
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { IncomingHttpHeaders } from 'http';

import {
DevWorkspaceClient,
DevWorkspaceSingletonClient,
IDevWorkspaceApi,
IDevWorkspaceClusterApi,
IDevWorkspaceTemplateApi,
Expand Down Expand Up @@ -244,6 +243,13 @@ export const getDevWorkspaceClient = jest.fn(
read: _namespace => Promise.resolve({} as api.IGitConfig),
patch: (_namespace, _gitconfig) => Promise.resolve({} as api.IGitConfig),
} as IGitConfigApi,
devWorkspaceClusterApi: {
isRunningWorkspacesClusterLimitExceeded: () =>
Promise.resolve(stubIsRunningWorkspaceClusterLimitExceeded),
watchInAllNamespaces(): Promise<void> {
return Promise.resolve();
},
} as IDevWorkspaceClusterApi,
sshKeysApi: {
add: (_namespace, _sshKey) => Promise.resolve({} as api.SshKey),
delete: (_namespace, _name) => Promise.resolve(),
Expand All @@ -258,17 +264,3 @@ export const getDevWorkspaceClient = jest.fn(
} as DevWorkspaceClient;
},
);

export const getDevWorkspaceSingletonClient = jest.fn(
(..._args: Parameters<typeof helper>): DevWorkspaceSingletonClient => {
return {
devWorkspaceClusterServiceApi: {
isRunningWorkspacesClusterLimitExceeded: () =>
Promise.resolve(stubIsRunningWorkspaceClusterLimitExceeded),
watchInAllNamespaces(): Promise<void> {
return Promise.resolve();
},
} as IDevWorkspaceClusterApi,
};
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
* Red Hat, Inc. - initial API and implementation
*/

import { DevWorkspaceClient, DevWorkspaceSingletonClient } from '@/devworkspaceClient';
import { DevWorkspaceClient } from '@/devworkspaceClient';
import { DwClientProvider } from '@/services/kubeclient/dwClientProvider';
import { DwSingletonClientProvider } from '@/services/kubeclient/dwSingletonClientProvider';

/**
* Creates DevWorkspace Client depending on the context for the specified request.
Expand All @@ -21,8 +20,3 @@ export function getDevWorkspaceClient(token: string): DevWorkspaceClient {
const dwClientProvider = new DwClientProvider();
return dwClientProvider.getDWClient(token);
}

export function getDevWorkspaceSingletonClient(): DevWorkspaceSingletonClient {
const dwSingletonClientProvider = DwSingletonClientProvider.getInstance();
return dwSingletonClientProvider.getDWSingletonClient();
}

This file was deleted.

This file was deleted.

0 comments on commit 05fafa6

Please sign in to comment.