mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
move config route to main
Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
f0716e7a28
commit
47d82e4d62
@ -8,7 +8,7 @@ import compression from "compression"
|
|||||||
import helmet from "helmet"
|
import helmet from "helmet"
|
||||||
import morgan from "morgan"
|
import morgan from "morgan"
|
||||||
import { logger } from "../server/utils/logger"
|
import { logger } from "../server/utils/logger"
|
||||||
import { configRoute, kubewatchRoute, metricsRoute, readyStateRoute } from "../server/routes";
|
import { kubewatchRoute, metricsRoute, readyStateRoute } from "../server/routes";
|
||||||
import { useRequestHeaderToken } from "../server/middlewares";
|
import { useRequestHeaderToken } from "../server/middlewares";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -23,7 +23,6 @@ const outputDir = path.resolve(process.cwd(), BUILD_DIR, CLIENT_DIR);
|
|||||||
app.set('trust proxy', 1); // trust first proxy
|
app.set('trust proxy', 1); // trust first proxy
|
||||||
|
|
||||||
localApis.use(
|
localApis.use(
|
||||||
configRoute(),
|
|
||||||
readyStateRoute(),
|
readyStateRoute(),
|
||||||
kubewatchRoute(),
|
kubewatchRoute(),
|
||||||
metricsRoute()
|
metricsRoute()
|
||||||
|
|||||||
@ -1,9 +1,4 @@
|
|||||||
export interface IClusterConfigMap {
|
export interface IClusterInfo {
|
||||||
clusterName: string;
|
|
||||||
clusterUrl: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IClusterInfo extends IClusterConfigMap {
|
|
||||||
kubeVersion?: string;
|
kubeVersion?: string;
|
||||||
pharosVersion?: string;
|
clusterName?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,48 +0,0 @@
|
|||||||
//-- Config route
|
|
||||||
|
|
||||||
import config from "../config";
|
|
||||||
import { IConfig } from "../common/config"
|
|
||||||
import { Router } from "express";
|
|
||||||
import { userSession } from "../user-session";
|
|
||||||
import { getClusterInfo } from "../api/get-cluster-info";
|
|
||||||
import { isClusterAdmin } from "../api/is-cluster-admin";
|
|
||||||
import { getAllowedNamespaces } from "../api/get-namespaces";
|
|
||||||
import { parseJwt } from "../utils/parse-jwt";
|
|
||||||
|
|
||||||
export function configRoute() {
|
|
||||||
const router = Router();
|
|
||||||
|
|
||||||
router.route('/config')
|
|
||||||
.get(async (req, res) => {
|
|
||||||
const { username, authHeader } = userSession.get(req);
|
|
||||||
const authToken = userSession.getToken(req);
|
|
||||||
|
|
||||||
const data: IConfig = {
|
|
||||||
clusterName: config.KUBE_CLUSTER_NAME,
|
|
||||||
lensVersion: config.LENS_VERSION,
|
|
||||||
lensTheme: config.LENS_THEME,
|
|
||||||
chartsEnabled: !!config.CHARTS_ENABLED,
|
|
||||||
kubectlAccess: !!req.headers["x-lens-kubectl-token"]
|
|
||||||
};
|
|
||||||
|
|
||||||
// load config data from other places
|
|
||||||
const loading: Promise<any>[] = [
|
|
||||||
getClusterInfo().then(info => Object.assign(data, info)),
|
|
||||||
];
|
|
||||||
|
|
||||||
// validate user token from session and fetch more config data
|
|
||||||
if (authToken) {
|
|
||||||
const { sub, email } = parseJwt(authToken);
|
|
||||||
data.username = email || sub || username;
|
|
||||||
data.token = authToken;
|
|
||||||
loading.push(
|
|
||||||
isClusterAdmin({ authHeader }).then(isAdmin => data.isClusterAdmin = isAdmin),
|
|
||||||
getAllowedNamespaces({ authHeader }).then(list => data.allowedNamespaces = list),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
await Promise.all(loading);
|
|
||||||
res.json(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
return router;
|
|
||||||
}
|
|
||||||
@ -1,4 +1,3 @@
|
|||||||
export * from "./config-route"
|
|
||||||
export * from "./kubewatch-route"
|
export * from "./kubewatch-route"
|
||||||
export * from "./metrics-route"
|
export * from "./metrics-route"
|
||||||
export * from "./ready-state-route"
|
export * from "./ready-state-route"
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import * as http from "http";
|
import * as http from "http";
|
||||||
import { Cluster } from "./cluster";
|
import { Cluster } from "./cluster";
|
||||||
|
import { configRoute } from "./routes/config"
|
||||||
import { helmApi } from "./helm-api"
|
import { helmApi } from "./helm-api"
|
||||||
import { resourceApplierApi } from "./resource-applier-api"
|
import { resourceApplierApi } from "./resource-applier-api"
|
||||||
import { kubeconfigRoute } from "./routes/kubeconfig"
|
import { kubeconfigRoute } from "./routes/kubeconfig"
|
||||||
@ -66,6 +67,7 @@ export class Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected addRoutes() {
|
protected addRoutes() {
|
||||||
|
this.router.add({ method: 'get', path: '/api/config' }, configRoute.routeConfig.bind(configRoute))
|
||||||
this.router.add({ method: 'get', path: '/api/kubeconfig/service-account/{namespace}/{account}' }, kubeconfigRoute.routeServiceAccountRoute.bind(kubeconfigRoute))
|
this.router.add({ method: 'get', path: '/api/kubeconfig/service-account/{namespace}/{account}' }, kubeconfigRoute.routeServiceAccountRoute.bind(kubeconfigRoute))
|
||||||
|
|
||||||
// Helm API
|
// Helm API
|
||||||
|
|||||||
66
src/main/routes/config.ts
Normal file
66
src/main/routes/config.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import { LensApiRequest } from "../router"
|
||||||
|
import { LensApi } from "../lens-api"
|
||||||
|
import { userStore } from "../../common/user-store"
|
||||||
|
import { getAppVersion } from "../../common/app-utils"
|
||||||
|
import { CoreV1Api, AuthorizationV1Api } from "@kubernetes/client-node"
|
||||||
|
import { Cluster } from "../cluster"
|
||||||
|
|
||||||
|
|
||||||
|
function selfSubjectAccessReview(authApi: AuthorizationV1Api, namespace: string) {
|
||||||
|
return authApi.createSelfSubjectAccessReview({
|
||||||
|
apiVersion: "authorization.k8s.io/v1",
|
||||||
|
kind: "SelfSubjectAccessReview",
|
||||||
|
spec: {
|
||||||
|
resourceAttributes: {
|
||||||
|
namespace: namespace,
|
||||||
|
resource: "pod",
|
||||||
|
verb: "list",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAllowedNamespaces(cluster: Cluster) {
|
||||||
|
const api = cluster.contextHandler.kc.makeApiClient(CoreV1Api)
|
||||||
|
const authApi = cluster.contextHandler.kc.makeApiClient(AuthorizationV1Api)
|
||||||
|
try {
|
||||||
|
const namespaceList = await api.listNamespace()
|
||||||
|
const nsAccessStatuses = await Promise.all(
|
||||||
|
namespaceList.body.items.map(ns => {
|
||||||
|
return selfSubjectAccessReview(authApi, ns.metadata.name)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return namespaceList.body.items
|
||||||
|
.filter((ns, i) => nsAccessStatuses[i].body.status.allowed)
|
||||||
|
.map(ns => ns.metadata.name)
|
||||||
|
} catch(error) {
|
||||||
|
const kc = cluster.contextHandler.kc
|
||||||
|
const ctx = kc.getContextObject(kc.currentContext)
|
||||||
|
if (ctx.namespace) {
|
||||||
|
return [ctx.namespace]
|
||||||
|
} else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigRoute extends LensApi {
|
||||||
|
|
||||||
|
public async routeConfig(request: LensApiRequest) {
|
||||||
|
const { params, response, cluster} = request
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
clusterName: cluster.contextName,
|
||||||
|
lensVersion: getAppVersion(),
|
||||||
|
lensTheme: `kontena-${userStore.getPreferences().colorTheme}`,
|
||||||
|
kubeVersion: cluster.version,
|
||||||
|
chartsEnabled: true,
|
||||||
|
isClusterAdmin: cluster.isAdmin,
|
||||||
|
allowedNamespaces: await getAllowedNamespaces(cluster)
|
||||||
|
};
|
||||||
|
|
||||||
|
this.respondJson(response, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const configRoute = new ConfigRoute()
|
||||||
Loading…
Reference in New Issue
Block a user