Skip to content

Commit

Permalink
🌱 Enhance ENV handling (#1494)
Browse files Browse the repository at this point in the history
  - Move from using `process.env` to `KONVEYOR_ENV` so all environment
    variables can be documented in Typescript/jsdoc

  - Add jsdoc to `KonveyorEnvType`

  - Setup the server to exclude any `KonveyorEnvType` keys that are for
    the server's use (keys in `SERVER_ENV_KEYS`) when encoding the
    environment variables for the client

  - With documenting `KonveyorEnvType.UI_INGRESS_PROXY_BODY_SIZE`, update
    `upload-binary.tsx` to consider the value as decimal megabytes when
    parsing and displaying the value

Signed-off-by: Scott J Dickerson <[email protected]>
  • Loading branch information
sjd78 authored Oct 31, 2023
1 parent eb632fe commit d3eb379
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 21 deletions.
11 changes: 8 additions & 3 deletions client/config/webpack.dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ import ReactRefreshTypeScript from "react-refresh-typescript";
import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";

import { encodeEnv, KONVEYOR_ENV, proxyMap } from "@konveyor-ui/common";
import {
encodeEnv,
KONVEYOR_ENV,
SERVER_ENV_KEYS,
proxyMap,
} from "@konveyor-ui/common";
import { stylePaths } from "./stylePaths";
import commonWebpackConfiguration from "./webpack.common";

const brandType = process.env["PROFILE"] || "konveyor";
const brandType = KONVEYOR_ENV.PROFILE;
const pathTo = (relativePath: string) => path.resolve(__dirname, relativePath);

interface Configuration extends WebpackConfiguration {
Expand Down Expand Up @@ -96,7 +101,7 @@ const config: Configuration = mergeWithRules({
filename: "index.html",
template: pathTo("../public/index.html.ejs"),
templateParameters: {
_env: encodeEnv(KONVEYOR_ENV),
_env: encodeEnv(KONVEYOR_ENV, SERVER_ENV_KEYS),
brandType,
},
favicon: pathTo(`../public/${brandType}-favicon.ico`),
Expand Down
3 changes: 2 additions & 1 deletion client/config/webpack.prod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import MiniCssExtractPlugin from "mini-css-extract-plugin";
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
import HtmlWebpackPlugin from "html-webpack-plugin";

import { KONVEYOR_ENV } from "@konveyor-ui/common";
import { stylePaths } from "./stylePaths";
import commonWebpackConfiguration from "./webpack.common";

const brandType = process.env["PROFILE"] || "konveyor";
const brandType = KONVEYOR_ENV.PROFILE;
const pathTo = (relativePath: string) => path.resolve(__dirname, relativePath);

const config = merge<Configuration>(commonWebpackConfiguration, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,7 @@ export const UploadBinary: React.FC = () => {
}
};

const uploadLimitInBytes =
parseInt(uploadLimit.slice(0, -1)) * Math.pow(1024, 2);
const uploadLimitInBytes = parseInt(uploadLimit.slice(0, -1)) * 1_000_000;

const readFile = (file: File) => {
return new Promise<string | null>((resolve, reject) => {
Expand Down Expand Up @@ -199,8 +198,8 @@ export const UploadBinary: React.FC = () => {
<>
<div>Accepted file types: war, ear, jar or zip</div>
<div>
Upload size limit: {Math.round(uploadLimitInBytes / 1000000)}{" "}
MB
Upload size limit:
{Math.round(uploadLimitInBytes / 1_000_000)} MB
</div>
</>
}
Expand Down
30 changes: 25 additions & 5 deletions common/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,44 @@ export type KonveyorEnvType = {
NODE_ENV: "development" | "production" | "test";
VERSION: string;

/** Require keycloak authentication? */
/** Enable RBAC authentication/authorization */
AUTH_REQUIRED: "true" | "false";

/** SSO / Keycloak realm */
KEYCLOAK_REALM: string;

/** SSO / Keycloak client id */
KEYCLOAK_CLIENT_ID: string;
KEYCLOAK_SERVER_URL: string;

/** Branding to apply to the UI */
PROFILE: "konveyor" | "mta";

/** Upload file size limit */
/** UI upload file size limit in megabytes (MB), suffixed with "m" */
UI_INGRESS_PROXY_BODY_SIZE: string;

/** Allow clearing local maven artifact repository? Requires availability of RWX volumes for hub. */
RWX_SUPPORTED: "true" | "false";

/** The listen port for the UI's server */
PORT?: string;

/** Target URL for the UI server's `/auth` proxy */
KEYCLOAK_SERVER_URL?: string;

/** Target URL for the UI server's `/hub` proxy */
TACKLE_HUB_URL?: string;
};

/**
* Keys in `KonveyorEnvType` that are only used on the server and therefore do not
* need to be sent to the client.
*/
export const SERVER_ENV_KEYS = [
"PORT",
"KEYCLOAK_SERVER_URL",
"TACKLE_HUB_URL",
];

/**
* Create a `KonveyorEnv` from a partial `KonveyorEnv` with a set of default values.
*/
Expand All @@ -39,7 +61,6 @@ export const buildKonveyorEnv = ({
AUTH_REQUIRED = "false",
KEYCLOAK_REALM = "tackle",
KEYCLOAK_CLIENT_ID = "tackle-ui",
KEYCLOAK_SERVER_URL = "",

PROFILE = "konveyor",
UI_INGRESS_PROXY_BODY_SIZE = "500m",
Expand All @@ -51,7 +72,6 @@ export const buildKonveyorEnv = ({
AUTH_REQUIRED,
KEYCLOAK_REALM,
KEYCLOAK_CLIENT_ID,
KEYCLOAK_SERVER_URL,

PROFILE,
UI_INGRESS_PROXY_BODY_SIZE,
Expand Down
10 changes: 9 additions & 1 deletion common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ export * from "./proxies.js";
/**
* Return a base64 encoded JSON string containing the given `env` object.
*/
export const encodeEnv = (env: object): string => btoa(JSON.stringify(env));
export const encodeEnv = (env: object, exclude?: string[]): string => {
const filtered = exclude
? Object.fromEntries(
Object.entries(env).filter(([key]) => !exclude.includes(key))
)
: env;

return btoa(JSON.stringify(filtered));
};

/**
* Return an objects from a base64 encoded JSON string.
Expand Down
7 changes: 5 additions & 2 deletions common/src/proxies.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Options } from "http-proxy-middleware";
import { KONVEYOR_ENV } from "./environment.js";

export const proxyMap: Record<string, Options> = {
"/auth": {
target: process.env.KEYCLOAK_SERVER_URL || "http://localhost:9001",
target: KONVEYOR_ENV.KEYCLOAK_SERVER_URL || "http://localhost:9001",
logLevel: process.env.DEBUG ? "debug" : "info",

changeOrigin: true,
Expand Down Expand Up @@ -30,7 +31,7 @@ export const proxyMap: Record<string, Options> = {
},

"/hub": {
target: process.env.TACKLE_HUB_URL || "http://localhost:9002",
target: KONVEYOR_ENV.TACKLE_HUB_URL || "http://localhost:9002",
logLevel: process.env.DEBUG ? "debug" : "info",

changeOrigin: true,
Expand All @@ -39,6 +40,8 @@ export const proxyMap: Record<string, Options> = {
},

onProxyReq: (proxyReq, req, _res) => {
// Add the Bearer token to the request if it is not already present, AND if
// the token is part of the request as a cookie
if (req.cookies?.keycloak_cookie && !req.headers["authorization"]) {
proxyReq.setHeader(
"Authorization",
Expand Down
15 changes: 10 additions & 5 deletions server/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@ import cookieParser from "cookie-parser";
import { createHttpTerminator } from "http-terminator";
import { createProxyMiddleware } from "http-proxy-middleware";

import { encodeEnv, KONVEYOR_ENV, proxyMap } from "@konveyor-ui/common";
import {
encodeEnv,
KONVEYOR_ENV,
SERVER_ENV_KEYS,
proxyMap,
} from "@konveyor-ui/common";

const __dirname = fileURLToPath(new URL(".", import.meta.url));
const pathToClientDist = path.join(__dirname, "../../client/dist");

const brandType = process.env["PROFILE"] || "konveyor";
const port = 8080;
const brandType = KONVEYOR_ENV.PROFILE;
const port = parseInt(KONVEYOR_ENV.PORT, 10) || 8080;

const app = express();
app.use(cookieParser());
Expand All @@ -32,7 +37,7 @@ app.use(express.static(pathToClientDist));

// Handle any request that hasn't already been handled by express.static or proxy
app.get("*", (_, res) => {
if (process.env.NODE_ENV === "development") {
if (KONVEYOR_ENV.NODE_ENV === "development") {
res.send(`
<style>pre { margin-left: 20px; }</style>
You're running in development mode! The UI is served by webpack-dev-server on port 9000: <a href="http://localhost:9000">http://localhost:9000</a><br /><br />
Expand All @@ -41,7 +46,7 @@ app.get("*", (_, res) => {
`);
} else {
res.render("index.html.ejs", {
_env: encodeEnv(KONVEYOR_ENV),
_env: encodeEnv(KONVEYOR_ENV, SERVER_ENV_KEYS),
brandType,
});
}
Expand Down

0 comments on commit d3eb379

Please sign in to comment.