Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom web component based extension #3471

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions backend/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,12 @@ function extractHeadersData(req) {
const clientCAHeader = 'x-client-certificate-data';
const clientKeyDataHeader = 'x-client-key-data';
const authorizationHeader = 'x-k8s-authorization';

const targetApiServer = handleDockerDesktopSubsitution(
new URL(req.headers[urlHeader]),
);
let targetApiServer;
if (req.headers[urlHeader]) {
targetApiServer = handleDockerDesktopSubsitution(
new URL(req.headers[urlHeader]),
);
}
const ca = decodeHeaderToBuffer(req.headers[caHeader]) || certs;
const cert = decodeHeaderToBuffer(req.headers[clientCAHeader]);
const key = decodeHeaderToBuffer(req.headers[clientKeyDataHeader]);
Expand Down
6 changes: 5 additions & 1 deletion backend/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { makeHandleRequest, serveStaticApp, serveMonaco } from './common';
import { proxyHandler } from './proxy.js';
import { handleTracking } from './tracking.js';
import jsyaml from 'js-yaml';
//import { requestLogger } from './utils/other'; //uncomment this to log the outgoing traffic
Expand Down Expand Up @@ -52,6 +53,7 @@ if (gzipEnabled)
if (process.env.NODE_ENV === 'development') {
app.use(cors({ origin: '*' }));
}
app.use('/proxy', proxyHandler);

let server = null;

Expand Down Expand Up @@ -81,13 +83,15 @@ const isDocker = process.env.IS_DOCKER === 'true';
const handleRequest = makeHandleRequest();

if (isDocker) {
// Running in dev mode
// yup, order matters here
serveMonaco(app);
app.use('/backend', handleRequest);
serveStaticApp(app, '/', '/core-ui');
} else {
// Running in prod mode
handleTracking(app);
app.use(handleRequest);
app.use('/backend', handleRequest);
}

process.on('SIGINT', function() {
Expand Down
45 changes: 45 additions & 0 deletions backend/proxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { request as httpsRequest } from 'https';
import { request as httpRequest } from 'http';
import { URL } from 'url';

async function proxyHandler(req, res) {
const targetUrl = req.query.url;
if (!targetUrl) {
return res.status(400).send('Target URL is required as a query parameter');
}

try {
const parsedUrl = new URL(targetUrl);
const isHttps = parsedUrl.protocol === 'https:';
const libRequest = isHttps ? httpsRequest : httpRequest;

const options = {
hostname: parsedUrl.hostname,
port: parsedUrl.port || (isHttps ? 443 : 80),
path: parsedUrl.pathname + parsedUrl.search,
method: req.method,
headers: { ...req.headers, host: parsedUrl.host },
};

const proxyReq = libRequest(options, proxyRes => {
// Forward status and headers from the target response
res.writeHead(proxyRes.statusCode, proxyRes.headers);
// Pipe the response data from the target back to the client
proxyRes.pipe(res);
});

proxyReq.on('error', () => {
res.status(500).send('An error occurred while making the proxy request.');
});

if (Buffer.isBuffer(req.body)) {
proxyReq.end(req.body); // If the body is already buffered, use it directly.
} else {
req.pipe(proxyReq); // Otherwise, pipe the request for streamed or chunked data.
}
} catch (error) {
res.status(500).send('An error occurred while processing the request.');
}
}

export { proxyHandler };
6 changes: 6 additions & 0 deletions examples/web-component-ext/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# How to set up your custom busola extension\

1. Modify general.yaml section (change scope to 'namespace' or 'cluster', etc. )
2. Adjust ui.html and script.js files. Remember to keep general.customElement property in sync with the name of the custom element defined in script.js. The script is loaded only only once and general.customElement property is used to determine if the customElement with that name is already defined.
3. Run ./deploy.sh script to deploy the extension to the cluster. It creates a config map with the extension and deploys it to the cluster. You can directly apply the config map with the command: kubectl kustomize . | kubectl apply -n kyma-system -f -
4. run npm start to start the development server.
4 changes: 4 additions & 0 deletions examples/web-component-ext/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

kubectl kustomize . > ./sm-ui.yaml
kubectl apply -f ./sm-ui.yaml -n kyma-system
10 changes: 10 additions & 0 deletions examples/web-component-ext/general.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resource:
kind: Secret
version: v1
urlPath: service-management-ui
category: Kyma
name: Service Management UI
scope: cluster
customElement: sm-catalog
description: >-
Service Management UI
11 changes: 11 additions & 0 deletions examples/web-component-ext/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
configMapGenerator:
- name: sm-ui
files:
- customHtml=ui.html
- customScript=script.js
- general=general.yaml
options:
disableNameSuffixHash: true
labels:
busola.io/extension: 'resource'
busola.io/extension-version: '0.5'
Loading
Loading