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 c3bcc06
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 40 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 @@ -18,7 +18,7 @@
white-space: nowrap;
}

.navItem [class*="nav__link"] {
.navItem [class*='nav__link'] {
padding-left: 45px;
}

Expand All @@ -39,7 +39,7 @@
color: inherit !important;
}

.navItem > div:not([class*="expanded"]) {
.navItem > div:not([class*='expanded']) {
display: none;
}

Expand Down
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
2 changes: 1 addition & 1 deletion packages/dashboard-frontend/src/overrides.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@
padding: 0 !important;
}

span[class*="label-required"] {
span[class*='label-required'] {
color: var(--pf-global--palette--red-100);
}
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 c3bcc06

Please sign in to comment.