Skip to content

Commit 289ad24

Browse files
authored
[Branding] assets folder and SSL support (opensearch-project#1329)
Adding `assets` folder that gets served up under UI for ease of us. SSL support when OpenSearch Dashboards SSL is enabled. Issue Resolved: opensearch-project#1164 Signed-off-by: Kawika Avilla <[email protected]>
1 parent 9c82c52 commit 289ad24

File tree

7 files changed

+64
-9
lines changed

7 files changed

+64
-9
lines changed

assets/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Ignore everything in this directory
2+
*
3+
# Except this file
4+
!.gitignore

src/core/server/core_app/core_app.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export class CoreApp {
8989
}
9090
private registerStaticDirs(coreSetup: InternalCoreSetup) {
9191
coreSetup.http.registerStaticDir('/ui/{path*}', Path.resolve(__dirname, './assets'));
92+
coreSetup.http.registerStaticDir('/ui/assets/{path*}', fromRoot('assets'));
9293

9394
coreSetup.http.registerStaticDir(
9495
'/node_modules/@osd/ui-framework/dist/{path*}',

src/core/server/rendering/rendering_service.tsx

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import React from 'react';
3434
import { renderToStaticMarkup } from 'react-dom/server';
3535
import { first, take } from 'rxjs/operators';
3636
import { i18n } from '@osd/i18n';
37+
import { Agent as HttpsAgent } from 'https';
3738

3839
import Axios from 'axios';
3940
// @ts-expect-error untyped internal module used to prevent axios from using xhr adapter in tests
@@ -50,22 +51,29 @@ import {
5051
BrandingAssignment,
5152
} from './types';
5253
import { OpenSearchDashboardsConfigType } from '../opensearch_dashboards_config';
54+
import { HttpConfigType } from '../http/http_config';
55+
import { SslConfig } from '../http/ssl_config';
5356

5457
const DEFAULT_TITLE = 'OpenSearch Dashboards';
5558

5659
/** @internal */
5760
export class RenderingService {
5861
constructor(private readonly coreContext: CoreContext) {}
5962
private logger = this.coreContext.logger;
63+
private httpsAgent?: HttpsAgent;
64+
6065
public async setup({
6166
http,
6267
status,
6368
uiPlugins,
6469
}: RenderingSetupDeps): Promise<InternalRenderingServiceSetup> {
65-
const opensearchDashboardsConfig = await this.coreContext.configService
66-
.atPath<OpenSearchDashboardsConfigType>('opensearchDashboards')
67-
.pipe(first())
68-
.toPromise();
70+
const [opensearchDashboardsConfig, serverConfig] = await Promise.all([
71+
this.coreContext.configService
72+
.atPath<OpenSearchDashboardsConfigType>('opensearchDashboards')
73+
.pipe(first())
74+
.toPromise(),
75+
this.coreContext.configService.atPath<HttpConfigType>('server').pipe(first()).toPromise(),
76+
]);
6977

7078
return {
7179
render: async (
@@ -87,9 +95,12 @@ export class RenderingService {
8795
const darkMode = settings.user?.['theme:darkMode']?.userValue
8896
? Boolean(settings.user['theme:darkMode'].userValue)
8997
: false;
98+
99+
this.setupHttpAgent(serverConfig as HttpConfigType);
100+
90101
const brandingAssignment = await this.assignBrandingConfig(
91102
darkMode,
92-
opensearchDashboardsConfig
103+
opensearchDashboardsConfig as OpenSearchDashboardsConfigType
93104
);
94105

95106
const metadata: RenderingMetadata = {
@@ -150,6 +161,26 @@ export class RenderingService {
150161

151162
public async stop() {}
152163

164+
/**
165+
* Setups HTTP Agent if SSL is enabled to pass SSL config
166+
* values to Axios to make requests in while validating
167+
* resources.
168+
*
169+
* @param {Readonly<HttpConfigType>} httpConfig
170+
*/
171+
private setupHttpAgent(httpConfig: Readonly<HttpConfigType>) {
172+
if (httpConfig.ssl?.enabled) {
173+
const sslConfig = new SslConfig(httpConfig.ssl);
174+
this.httpsAgent = new HttpsAgent({
175+
ca: sslConfig.certificateAuthorities,
176+
cert: sslConfig.certificate,
177+
key: sslConfig.key,
178+
passphrase: sslConfig.keyPassphrase,
179+
rejectUnauthorized: false,
180+
});
181+
}
182+
}
183+
153184
/**
154185
* Assign values for branding related configurations based on branding validation
155186
* by calling checkBrandingValid(). For dark mode URLs, add additonal validation
@@ -322,7 +353,11 @@ export class RenderingService {
322353
this.logger.get('branding').error(`${configName} config is invalid. Using default branding.`);
323354
return false;
324355
}
325-
return await Axios.get(url, { adapter: AxiosHttpAdapter, maxRedirects: 0 })
356+
return await Axios.get(url, {
357+
httpsAgent: this.httpsAgent,
358+
adapter: AxiosHttpAdapter,
359+
maxRedirects: 0,
360+
})
326361
.then(() => {
327362
return true;
328363
})

src/dev/build/tasks/clean_tasks.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,12 @@ export const CleanEmptyFolders: Task = {
204204

205205
async run(config, log, build) {
206206
// Delete every single empty folder from
207-
// the distributable except the plugins
208-
// and data folder.
207+
// the distributable except the plugins,
208+
// data, and assets folder.
209209
await deleteEmptyFolders(log, build.resolvePath('.'), [
210210
build.resolvePath('plugins'),
211211
build.resolvePath('data'),
212+
build.resolvePath('assets'),
212213
]);
213214
},
214215
};

src/dev/build/tasks/create_empty_dirs_and_files_task.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ export const CreateEmptyDirsAndFiles: Task = {
3131
description: 'Creating some empty directories and files to prevent file-permission issues',
3232

3333
async run(config, log, build) {
34-
await Promise.all([mkdirp(build.resolvePath('plugins')), mkdirp(build.resolvePath('data'))]);
34+
await Promise.all([
35+
mkdirp(build.resolvePath('plugins')),
36+
mkdirp(build.resolvePath('data')),
37+
mkdirp(build.resolvePath('assets')),
38+
]);
3539
},
3640
};

src/dev/build/tasks/os_packages/run_fpm.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ export async function runFpm(
126126
`usr/share/opensearch-dashboards/config`,
127127
'--exclude',
128128
`usr/share/opensearch-dashboards/data`,
129+
'--exclude',
130+
`usr/share/opensearch-dashboards/assets`,
129131

130132
// flags specific to the package we are building, supplied by tasks below
131133
...pkgSpecificFlags,

test/server_integration/http/ssl/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,13 @@ export default function ({ getService }) {
3737
it('handles requests using ssl', async () => {
3838
await supertest.get('/').expect(302);
3939
});
40+
41+
it('handles UI requests using ssl', async () => {
42+
await supertest.get('ui/').expect(302);
43+
});
44+
45+
it('handles UI assests requests using ssl', async () => {
46+
await supertest.get('ui/assets').expect(302);
47+
});
4048
});
4149
}

0 commit comments

Comments
 (0)