Skip to content

Commit d395523

Browse files
authoredJul 25, 2023
feat(proxy): Add local app route feature (#1776)
1 parent 4448a47 commit d395523

File tree

2 files changed

+88
-18
lines changed

2 files changed

+88
-18
lines changed
 

‎packages/config-utils/proxy.js

+70-18
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,68 @@ const { registerChrome } = require('./standalone/services/default/chrome');
1616

1717
const defaultReposDir = path.join(__dirname, 'repos');
1818

19+
const checkLocalAppHost = (appName, hostUrl, port) => {
20+
const check = execSync(`curl --max-time 5 --silent --head ${hostUrl} | awk '/^HTTP/{print $2}'`).toString().trim();
21+
22+
if (check !== '200') {
23+
console.error('\n' + appName[0].toUpperCase() + appName.substring(1) + ' is not running or available via ' + hostUrl);
24+
console.log(
25+
'\nMake sure to run `npm run start -- --port=' +
26+
port +
27+
'` in the ' +
28+
appName +
29+
" application directory to start it's webpack dev server and the bundle is built.\n"
30+
);
31+
32+
return false;
33+
} else {
34+
return true;
35+
}
36+
};
37+
38+
const buildRoutes = (routes, target) =>
39+
Object.entries(routes || {}).map(([route, redirect]) => {
40+
const currTarget = redirect.host || redirect;
41+
delete redirect.host;
42+
return {
43+
context: (path) => path.includes(route),
44+
target: currTarget === 'PORTAL_BACKEND_MARKER' ? target : currTarget,
45+
secure: false,
46+
changeOrigin: true,
47+
autoRewrite: true,
48+
ws: true,
49+
onProxyReq: cookieTransform,
50+
...(currTarget === 'PORTAL_BACKEND_MARKER' && { router }),
51+
...(typeof redirect === 'object' ? redirect : {}),
52+
};
53+
});
54+
55+
const buildLocalAppRoutes = (localApps, defaultLocalAppHost, target) =>
56+
buildRoutes(
57+
(!Array.isArray(localApps) ? localApps.split(',') : localApps).reduce((acc, curr) => {
58+
const [appName, appConfig] = (curr || '').split(':');
59+
const [appPort = 8003, protocol = 'http'] = appConfig.split('~');
60+
const appUrl = `${protocol}://${defaultLocalAppHost}:${appPort}`;
61+
62+
if (checkLocalAppHost(appName, appUrl, appPort)) {
63+
console.log('Creating app proxy routes for: ' + appName + ' to ' + appUrl);
64+
65+
return {
66+
...acc,
67+
[`/apps/${appName}`]: {
68+
host: appUrl,
69+
},
70+
[`/preview/apps/${appName}`]: {
71+
host: appUrl,
72+
},
73+
};
74+
} else {
75+
process.exit();
76+
}
77+
}, {}),
78+
target
79+
);
80+
1981
module.exports = ({
2082
env = 'ci-beta',
2183
customProxy = [],
@@ -39,9 +101,12 @@ module.exports = ({
39101
bounceProd = false,
40102
useAgent = true,
41103
useDevBuild = true,
104+
localApps = process.env.LOCAL_APPS,
42105
}) => {
43106
const proxy = [];
44107
const majorEnv = env.split('-')[0];
108+
const defaultLocalAppHost = process.env.LOCAL_APP_HOST || majorEnv + '.foo.redhat.com';
109+
45110
if (target === '') {
46111
target += 'https://';
47112
if (!['prod', 'stage'].includes(majorEnv)) {
@@ -86,24 +151,11 @@ module.exports = ({
86151

87152
if (routes) {
88153
routes = routes.routes || routes;
89-
console.log('Making proxy from SPANDX routes');
90-
proxy.push(
91-
...Object.entries(routes || {}).map(([route, redirect]) => {
92-
const currTarget = redirect.host || redirect;
93-
delete redirect.host;
94-
return {
95-
context: (path) => path.includes(route),
96-
target: currTarget === 'PORTAL_BACKEND_MARKER' ? target : currTarget,
97-
secure: false,
98-
changeOrigin: true,
99-
autoRewrite: true,
100-
ws: true,
101-
onProxyReq: cookieTransform,
102-
...(currTarget === 'PORTAL_BACKEND_MARKER' && { router }),
103-
...(typeof redirect === 'object' ? redirect : {}),
104-
};
105-
})
106-
);
154+
proxy.push(...buildRoutes(routes, target));
155+
}
156+
157+
if (localApps?.length > 0) {
158+
proxy.push(...buildLocalAppRoutes(localApps, defaultLocalAppHost, target));
107159
}
108160

109161
if (customProxy) {

‎packages/config/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,24 @@ const { config: webpackConfig, plugins } = config({
197197

198198
This configuration will redirect all API requests to QA environment, so you can check CI UI with QA data.
199199

200+
#### Running multiple local (frontend) applications
201+
202+
With the proxy enabled it is possible to run multiple frontend applications together using one proxy and webpack dev servers for each other application via passing a `LOCAL_APPS` variable.
203+
204+
```
205+
$ LOCAL_APPS=APP_NAME:APP_PORT[~APP_PROTOCOL] npm run start:proxy
206+
```
207+
208+
##### Steps to run multiple applications
209+
210+
1) Choose a "main application", which will run the proxy and proxy all other applications, for example Inventory and open a terminal in it's directory
211+
2) Open another terminal in any other application that you want to run with the Inventory, for example Advisor and start it's webpack dev server with `npm run start`
212+
3) Ensure the dev server is started and make not of it's addresses and port it is listening to. (This example assumes it runs on port `8002`)
213+
3.1) You can repeat this process for any application you want to run the Inventory with.
214+
4) With this information now, in the terminal for Inventory you can start the proxy and pass applications via the `LOCAL_APPS` variable, like `LOCAL_APPS=advisor:2002 npm run start:proxy`
215+
4.1) You can pass multiple applications as a comma separated list, like `LOCAL_APPS=advisor:8002,compliance:8003 npm run start:proxy`
216+
5) With this you should be able to see any changes in both Inventroy and Advisor via the usual `https://stage.foo.redhat.com:1337`.
217+
200218
#### Env
201219
A hyphenated string in the form of (qa|ci|stage|prod)-(stable|beta). Used to determine the proxy target (such as ci.console.redhat.com or console.stage.redhat.com) and branch to checkout of build repos. If "stage" is specific qa is used as the branch.
202220

0 commit comments

Comments
 (0)
Please sign in to comment.