Skip to content

Commit

Permalink
fix: certificate injection
Browse files Browse the repository at this point in the history
Signed-off-by: Oleksii Orel <oorel@redhat.com>
  • Loading branch information
olexii4 committed Mar 18, 2023
1 parent 1f53637 commit b64ea5c
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,12 @@ import path from 'path';
import * as axios from 'axios';
import https from 'https';

export interface ICrtConfig {
ssCrtPath?: string;
publicCrtPath?: string;
}

const DEFAULT_CHE_SELF_SIGNED_MOUNT_PATH = '/public-certs/che-self-signed';
const DEFAULT_CHE_SELF_SIGNED_MOUNT_PATH = '/public-certs';
const CHE_SELF_SIGNED_MOUNT_PATH = process.env.CHE_SELF_SIGNED_MOUNT_PATH;

const certificateAuthority = getCertificateAuthority({
publicCrtPath: CHE_SELF_SIGNED_MOUNT_PATH
? CHE_SELF_SIGNED_MOUNT_PATH
: DEFAULT_CHE_SELF_SIGNED_MOUNT_PATH,
});
const certificateAuthority = getCertificateAuthority(
CHE_SELF_SIGNED_MOUNT_PATH ? CHE_SELF_SIGNED_MOUNT_PATH : DEFAULT_CHE_SELF_SIGNED_MOUNT_PATH,
);

export const axiosInstance = certificateAuthority
? axios.default.create({
Expand All @@ -37,21 +30,46 @@ export const axiosInstance = certificateAuthority
})
: axios.default;

function getCertificateAuthority(config: ICrtConfig): Buffer[] | undefined {
const certificateAuthority: Buffer[] = [];
if (config.ssCrtPath && fs.existsSync(config.ssCrtPath)) {
certificateAuthority.push(fs.readFileSync(config.ssCrtPath));
}
function searchCertificate(
certPath: string,
certificateAuthority: Buffer[],
subdirLevel = 1,
): void {
const maxSubdirQuantity = 10;
const maxSubdirLevel = 5;

if (config.publicCrtPath && fs.existsSync(config.publicCrtPath)) {
const publicCertificates = fs.readdirSync(config.publicCrtPath);
const tmpPaths: string[] = [];
try {
const publicCertificates = fs.readdirSync(certPath);
for (const publicCertificate of publicCertificates) {
if (publicCertificate.endsWith('.crt')) {
const certPath = path.join(config.publicCrtPath, publicCertificate);
certificateAuthority.push(fs.readFileSync(certPath));
const newPath = path.join(certPath, publicCertificate);
if (fs.lstatSync(newPath).isDirectory()) {
if (tmpPaths.length < maxSubdirQuantity) {
tmpPaths.push(newPath);
}
} else {
const fullPath = path.join(certPath, publicCertificate);
certificateAuthority.push(fs.readFileSync(fullPath));
}
}
} catch (e) {
// no-op
}

if (subdirLevel < maxSubdirLevel) {
for (const path of tmpPaths) {
searchCertificate(path, certificateAuthority, ++subdirLevel);
}
}
}

function getCertificateAuthority(certPath: string): Buffer[] | undefined {
if (!fs.existsSync(certPath)) {
return undefined;
}

const certificateAuthority: Buffer[] = [];
searchCertificate(certPath, certificateAuthority);

return certificateAuthority.length > 0 ? certificateAuthority : undefined;
}
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,12 @@ class StepApplyDevfile extends AbstractLoaderStep<Props, State> {
}

private async createWorkspaceFromDevfile(devfile: devfileApi.Devfile): Promise<void> {
const params = Object.fromEntries(this.props.searchParams);
const optionalFilesContent = this.props.factoryResolver?.optionalFilesContent || {};
await this.props.createWorkspaceFromDevfile(devfile, params, optionalFilesContent);
await this.props.createWorkspaceFromDevfile(
devfile,
this.state.factoryParams,
optionalFilesContent,
);
}

private handleCreateWorkspaceError(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ describe('Quick Add page', () => {
devfileButton.click();

expect(createWorkspaceFromDevfileMock).toHaveBeenCalledWith(dummyDevfile, {
stackName: 'dummyStackName',
factoryId: 'dummyStackName',
});
});

Expand Down
13 changes: 9 additions & 4 deletions packages/dashboard-frontend/src/pages/GetStarted/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { selectWorkspaceByQualifiedName } from '../../store/Workspaces/selectors
import { selectDefaultNamespace } from '../../store/InfrastructureNamespaces/selectors';
import getRandomString from '../../services/helpers/random';
import devfileApi from '../../services/devfileApi';
import { FactoryParams } from '../../containers/Loader/buildFactoryParams';

const SamplesListTab = React.lazy(() => import('./GetStartedTab'));

Expand Down Expand Up @@ -116,9 +117,9 @@ export class GetStarted extends React.PureComponent<Props, State> {
[fileName: string]: string;
},
): Promise<void> {
const attr: { [key: string]: string } = {};
const attr: Partial<FactoryParams> = {};
if (stackName) {
attr.stackName = stackName;
attr.factoryId = stackName;
}
if (isCheDevfile(devfile) && !devfile.metadata.name && devfile.metadata.generateName) {
const name = devfile.metadata.generateName + getRandomString(4).toLowerCase();
Expand All @@ -130,8 +131,12 @@ export class GetStarted extends React.PureComponent<Props, State> {
: this.props.defaultNamespace.name;
let workspace: Workspace | undefined;
try {
await this.props.createWorkspaceFromDevfile(devfile, attr, optionalFilesContent);
this.props.setWorkspaceQualifiedName(namespace, devfile.metadata.name as string);
await this.props.createWorkspaceFromDevfile(
devfile,
attr as FactoryParams,
optionalFilesContent,
);
this.props.setWorkspaceQualifiedName(namespace, devfile.metadata.name);
workspace = this.props.activeWorkspace;
} catch (e) {
const errorMessage = common.helpers.errors.getMessage(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@
*/

import common from '@eclipse-che/common';
import axios from 'axios';
import devfileApi from '../devfileApi';
import { load, dump } from 'js-yaml';
import { ICheEditorYaml } from './devworkspace/devWorkspaceClient';
import { CHE_EDITOR_YAML_PATH } from './';
import { EDITOR_ATTR } from '../../containers/Loader/const';
import { AppState } from '../../store';
import { ThunkDispatch } from 'redux-thunk';
import { KnownAction } from '../../store/DevfileRegistries';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { DevWorkspaceBuilder } from '../../../__mocks__/devWorkspaceBuilder';
import { FakeStoreBuilder } from '../../../__mocks__/storeBuilder';
import { checkRunningWorkspacesLimit } from '../checkRunningWorkspacesLimit';
import { dump } from 'js-yaml';
import { FactoryParams } from "../../../../containers/Loader/buildFactoryParams";

jest.mock('../../../../services/dashboard-backend-client/serverConfigApi');
jest.mock('../../../../services/helpers/delay', () => ({
Expand Down Expand Up @@ -636,11 +637,14 @@ describe('DevWorkspace store, actions', () => {
namespace: 'user-che',
},
};
const attr: Partial<FactoryParams> = {};

mockCreateDevWorkspace.mockResolvedValueOnce({ devWorkspace, headers: {} });
mockUpdateDevWorkspace.mockResolvedValueOnce({ devWorkspace, headers: {} });

await store.dispatch(testStore.actionCreators.createWorkspaceFromDevfile(devfile, {}, {}));
await store.dispatch(
testStore.actionCreators.createWorkspaceFromDevfile(devfile, attr as FactoryParams, {}),
);

const actions = store.getActions();

Expand Down Expand Up @@ -670,11 +674,14 @@ describe('DevWorkspace store, actions', () => {
namespace: 'user-che',
},
};
const attr: Partial<FactoryParams> = {};

mockCreateDevWorkspace.mockRejectedValueOnce(new Error('Something unexpected happened.'));

try {
await store.dispatch(testStore.actionCreators.createWorkspaceFromDevfile(devfile, {}, {}));
await store.dispatch(
testStore.actionCreators.createWorkspaceFromDevfile(devfile, attr as FactoryParams, {}),
);
} catch (e) {
// no-op
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,15 @@ export type ActionCreators = {
updateWorkspace: (workspace: devfileApi.DevWorkspace) => AppThunk<KnownAction, Promise<void>>;
createWorkspaceFromDevfile: (
devfile: devfileApi.Devfile,
attributes: Partial<FactoryParams>,
attributes: FactoryParams,
optionalFilesContent: {
[fileName: string]: string;
},
) => AppThunk<KnownAction, Promise<void>>;
createWorkspaceFromResources: (
devWorkspace: devfileApi.DevWorkspace,
devWorkspaceTemplate: devfileApi.DevWorkspaceTemplate,
editor?: string,
editorId?: string,
) => AppThunk<KnownAction, Promise<void>>;

handleWebSocketMessage: (
Expand Down Expand Up @@ -574,7 +574,7 @@ export const actionCreators: ActionCreators = {
createWorkspaceFromDevfile:
(
devfile: devfileApi.Devfile,
attributes: Partial<FactoryParams>,
attributes: FactoryParams,
optionalFilesContent: {
[fileName: string]: string;
},
Expand Down
4 changes: 2 additions & 2 deletions packages/dashboard-frontend/src/store/Workspaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export type ActionCreators = {
updateWorkspace: (workspace: Workspace) => AppThunk<KnownAction, Promise<void>>;
createWorkspaceFromDevfile: (
devfile: devfileApi.Devfile,
attributes: Partial<FactoryParams>,
attributes: FactoryParams,
optionalFilesContent?: {
[fileName: string]: string;
},
Expand Down Expand Up @@ -215,7 +215,7 @@ export const actionCreators: ActionCreators = {
createWorkspaceFromDevfile:
(
devfile: devfileApi.Devfile,
attributes: Partial<FactoryParams>,
attributes: FactoryParams,
optionalFilesContent?: {
[fileName: string]: string;
},
Expand Down

0 comments on commit b64ea5c

Please sign in to comment.