mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Updated decc manager
This commit is contained in:
parent
526a38422c
commit
bbcf89bb1e
@ -19,6 +19,7 @@ export interface UserStoreModel {
|
||||
seenContexts: string[];
|
||||
preferences: UserPreferences;
|
||||
token: Token;
|
||||
lastLoggedInUser: string;
|
||||
}
|
||||
|
||||
export interface UserPreferences {
|
||||
@ -113,6 +114,8 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
||||
refreshToken: ""
|
||||
}
|
||||
|
||||
@observable lastLoggedInUser = "";
|
||||
|
||||
get isNewVersion() {
|
||||
return semver.gt(getAppVersion(), this.lastSeenAppVersion);
|
||||
}
|
||||
@ -188,8 +191,11 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
||||
|
||||
isTokenExpired(validTill: number): boolean {
|
||||
// Create a current UnixTime style date in ms
|
||||
const timeNow = Date.now();
|
||||
if ((new Date(validTill * 1000).getMinutes() - new Date().getMinutes()) / 1000 / 60 < 0) {
|
||||
const timeNow = Math.round(Date.now());
|
||||
console.log(`isTokenExpired: timeNow: ${new Date(timeNow).toString()}`);
|
||||
console.log(`isTokenExpired: validTill: ${new Date(validTill).toString()}`);
|
||||
//if ((new Date(validTill).getMinutes() - new Date().getMinutes()) / 1000 / 60 < 0) {
|
||||
if (timeNow > validTill) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -197,6 +203,7 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
||||
|
||||
@action
|
||||
setTokenDetails(token: string, refreshToken: string) {
|
||||
|
||||
let tokenDecoded = this.decodeToken(token);
|
||||
let refreshTokenDecoded = this.decodeToken(refreshToken);
|
||||
|
||||
@ -205,15 +212,21 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
||||
this.token.preferredUserName = tokenDecoded.preferred_username;
|
||||
|
||||
// Create a current UnixTime style date in secs
|
||||
const timeNow = Math.round(Date.now() / 1000);
|
||||
this.token.tokenValidTill = timeNow + tokenDecoded.exp;
|
||||
this.token.refreshTokenValidTill = timeNow + refreshTokenDecoded.exp;
|
||||
this.token.tokenValidTill = tokenDecoded.exp * 1000;
|
||||
this.token.refreshTokenValidTill = refreshTokenDecoded.exp * 1000;
|
||||
|
||||
console.info('The saved token object is: ' + JSON.stringify(this.token));
|
||||
const tokenSavedAt = new Date();
|
||||
console.log(`keycloak token retrieved at: ${tokenSavedAt.toLocaleTimeString()}`);
|
||||
|
||||
console.info('Check if token date is expired: ' + this.isTokenExpired(this.token.tokenValidTill));
|
||||
}
|
||||
|
||||
@action
|
||||
saveLastLoggedInUser(user: string) {
|
||||
this.lastLoggedInUser = user;
|
||||
}
|
||||
|
||||
@action
|
||||
protected async fromStore(data: Partial<UserStoreModel> = {}) {
|
||||
const { lastSeenAppVersion, seenContexts = [], preferences, kubeConfigPath, token } = data
|
||||
@ -235,6 +248,7 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
||||
seenContexts: Array.from(this.seenContexts),
|
||||
preferences: this.preferences,
|
||||
token: this.token,
|
||||
lastLoggedInUser: this.lastLoggedInUser,
|
||||
}
|
||||
return toJS(model, {
|
||||
recurseEverything: true,
|
||||
|
||||
@ -125,8 +125,12 @@ export class Cluster implements ClusterModel {
|
||||
}
|
||||
|
||||
async activate(init = false) {
|
||||
logger.info(`[CLUSTER]: activate`, this.getMeta());
|
||||
const clusterActivatedAt = new Date();
|
||||
logger.info(`[CLUSTER]: activate@${clusterActivatedAt.toString()}`, this.getMeta());
|
||||
await this.whenInitialized;
|
||||
logger.info("[CLUSTER]: activate now initialized")
|
||||
logger.info(`[CLUSTER]: activate eventDisposers length: ${this.eventDisposers.length}`);
|
||||
logger.info(`[CLUSTER]: activate eventDisposers: ${this.eventDisposers}`);
|
||||
if (!this.eventDisposers.length) {
|
||||
this.bindEvents();
|
||||
}
|
||||
@ -158,7 +162,8 @@ export class Cluster implements ClusterModel {
|
||||
|
||||
@action
|
||||
async refresh() {
|
||||
logger.info(`[CLUSTER]: refresh`, this.getMeta());
|
||||
const clusterRefreshAt = new Date();
|
||||
logger.info(`[CLUSTER]: refresh@${clusterRefreshAt.toString()}`, this.getMeta());
|
||||
await this.refreshConnectionStatus(); // refresh "version", "online", etc.
|
||||
if (this.accessible) {
|
||||
this.kubeCtl = new Kubectl(this.version)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import "../common/cluster-ipc";
|
||||
import type http from "http"
|
||||
import { autorun } from "mobx";
|
||||
import { ClusterStore, clusterStore, getClusterIdFromHost } from "../common/cluster-store"
|
||||
import { ClusterModel, ClusterStore, clusterStore, getClusterIdFromHost } from "../common/cluster-store"
|
||||
import { Cluster } from "./cluster"
|
||||
import logger from "./logger";
|
||||
import { apiKubePrefix } from "../common/vars";
|
||||
@ -11,6 +11,10 @@ import * as request from "request-promise-native";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import {kubeconfig} from '../common/utils/k8sTemplates';
|
||||
import YAML from 'yaml';
|
||||
import { readFile } from "fs-extra"
|
||||
import { getNodeWarningConditions, loadConfig, podHasIssues } from "../common/kube-helpers"
|
||||
import { customRequestPromise } from "../common/request";
|
||||
import orderBy from "lodash/orderBy";
|
||||
|
||||
const ignoredDECCNamespaces = [
|
||||
'kube-system', 'kube-public', 'openstack-provider-system', 'system',
|
||||
@ -18,145 +22,245 @@ const ignoredDECCNamespaces = [
|
||||
];
|
||||
|
||||
export class DECCManager {
|
||||
constructor(protected keycloakServer: http.Server, protected deccURL: string) {
|
||||
constructor(protected deccURL: string) {
|
||||
}
|
||||
// auto-init clusters
|
||||
// autorun(() => {
|
||||
// clusterStore.clusters.forEach(cluster => {
|
||||
// if (!cluster.initialized) {
|
||||
// logger.info(`[CLUSTER-MANAGER]: init cluster`, cluster.getMeta());
|
||||
// cluster.init(port);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
// // auto-stop removed clusters
|
||||
// autorun(() => {
|
||||
// const removedClusters = Array.from(clusterStore.removedClusters.values());
|
||||
// if (removedClusters.length > 0) {
|
||||
// const meta = removedClusters.map(cluster => cluster.getMeta());
|
||||
// logger.info(`[CLUSTER-MANAGER]: removing clusters`, meta);
|
||||
// removedClusters.forEach(cluster => cluster.disconnect());
|
||||
// clusterStore.removedClusters.clear();
|
||||
// }
|
||||
// }, {
|
||||
// delay: 250
|
||||
// });
|
||||
// }
|
||||
|
||||
getNamespacesForUser() {
|
||||
var namespacesUserCanAccess: Array<Workspace> = workspaceStore.workspacesList;
|
||||
var parsedToken = userStore.decodeToken (userStore.getTokenDetails().token);
|
||||
|
||||
// get all namespaces this id has access to
|
||||
const namespaces = {
|
||||
method: 'GET',
|
||||
url: `http://${this.deccURL}/api/v1/namespaces`,
|
||||
async getNamespaces(): Promise<[]> {
|
||||
const res = await customRequestPromise({
|
||||
uri: `http://${this.deccURL}/api/v1/namespaces`,
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + userStore.getTokenDetails().token
|
||||
},
|
||||
json: true
|
||||
};
|
||||
json: true,
|
||||
resolveWithFullResponse: true,
|
||||
timeout: 10000,
|
||||
});
|
||||
// logger.info(`getNamespaces: res - ${JSON.stringify(res)}`);
|
||||
return res.body;
|
||||
}
|
||||
|
||||
request(namespaces)
|
||||
.then(function(response) {
|
||||
//API call ok....
|
||||
const deccNamespaces = response["items"];
|
||||
// logger.info(JSON.stringify(deccNamespaces));
|
||||
|
||||
deccNamespaces.forEach(function(namespace) {
|
||||
async getClustersByNamespace(ns: string): Promise<[]> {
|
||||
const res = await customRequestPromise({
|
||||
uri: `http://${this.deccURL}/apis/cluster.k8s.io/v1alpha1/namespaces/${ns}/clusters`,
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + userStore.getTokenDetails().token
|
||||
},
|
||||
json: true,
|
||||
resolveWithFullResponse: true,
|
||||
timeout: 10000,
|
||||
});
|
||||
// logger.info(`getClustersByNamespace: res - ${JSON.stringify(res)}`);
|
||||
return res.body;
|
||||
}
|
||||
|
||||
async getDECCNamespaces() {
|
||||
try {
|
||||
const res = await this.getNamespaces();
|
||||
// logger.info(`getDECCNamespaces: res - ${JSON.stringify(res)}`);
|
||||
var deccNamespaces = [];
|
||||
res["items"].forEach(function(namespace) {
|
||||
if (!ignoredDECCNamespaces.includes(namespace.metadata.name)) {
|
||||
// console.log("Namespace Name: " + namespace.metadata.name);
|
||||
let ns = namespace.metadata.name;
|
||||
//console.log("parsedToken.iam_roles: ", parsedToken.iam_roles);
|
||||
if (parsedToken.iam_roles.includes(`m:kaas:${ns}@reader`) || parsedToken.iam_roles.includes(`m:kaas:${ns}@writer`)) {
|
||||
// add namespace to workspaceStore if not present
|
||||
console.log(`User: ${parsedToken.preferred_username} has access to namespace: ${ns}`);
|
||||
if (!workspaceStore.getByName(ns)) {
|
||||
workspaceStore.saveWorkspace({id: uuid(), name: ns, description: `DECC Namespace: ${ns}`});
|
||||
console.log(`Added new workspace: ${ns}`);
|
||||
namespacesUserCanAccess.push(ns);
|
||||
}
|
||||
};
|
||||
// logger.info(`getDECCNamespaces: Found namespace: ${namespace.metadata.name}`);
|
||||
deccNamespaces.push(namespace.metadata.name);
|
||||
};
|
||||
});
|
||||
return deccNamespaces;
|
||||
|
||||
return namespacesUserCanAccess;
|
||||
})
|
||||
.catch(function (err) {
|
||||
// API call failed...
|
||||
console.log(err);
|
||||
} catch (err) {
|
||||
logger.error(`getDECCNamespaces: ${String(err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
getDECCNamespacesForUser(deccNamespaces, userIAMRoles: string[], username: string) {
|
||||
var deccNamespacesForUser = [];
|
||||
deccNamespaces.forEach(function(ns) {
|
||||
if (userIAMRoles.includes(`m:kaas:${ns}@reader`) || userIAMRoles.includes(`m:kaas:${ns}@writer`)) {
|
||||
// add namespace to workspaceStore if not present
|
||||
//logger.info(`getDECCNamespacesForUser: User ${username} has access to namespace ${ns}`);
|
||||
deccNamespacesForUser.push(ns);
|
||||
}
|
||||
});
|
||||
return deccNamespacesForUser;
|
||||
}
|
||||
|
||||
async getDECCClustersForNamespace(ns: string) {
|
||||
try {
|
||||
const res = await this.getClustersByNamespace(ns);
|
||||
//logger.info(`getDECCClustersForNamespace: res - ${JSON.stringify(res)}`);
|
||||
|
||||
var deccClustersForNamespace = [];
|
||||
//API call ok....
|
||||
res["items"].forEach(function(deccCluster) {
|
||||
deccClustersForNamespace.push(deccCluster);
|
||||
});
|
||||
return deccClustersForNamespace;
|
||||
} catch(err) {
|
||||
logger.error(`getDECCClustersForNamespace: ${String(err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
addLensDECCWorkspace(ws: string) {
|
||||
const wsPrefix = `decc`;
|
||||
|
||||
if (!workspaceStore.getByName(`${wsPrefix}-${ws}`)) {
|
||||
workspaceStore.saveWorkspace({id: uuid(), name: `${wsPrefix}-${ws}`, description: `DECC Namespace: ${ws}`});
|
||||
logger.info(`Added new workspace: ${wsPrefix}-${ws}`);
|
||||
}
|
||||
}
|
||||
|
||||
addLensClusterToDECCWorkspace(deccCluster, idToken: string, refreshToken: string, username: string, workspace: Workspace) {
|
||||
// check if cluster is already in the cluster store
|
||||
var clusterPresent = false;
|
||||
const clusterPrefix = `decc`
|
||||
|
||||
clusterStore.getByWorkspaceId(workspace.id).forEach(cluster => {
|
||||
if (cluster.preferences.clusterName === `${username}@${clusterPrefix}-${deccCluster.metadata.name}`) {
|
||||
clusterPresent = true;
|
||||
}
|
||||
});
|
||||
|
||||
if ("status" in deccCluster && !clusterPresent) {
|
||||
let ucpDashboard = `https://${deccCluster.status.providerStatus.ucpDashboard.split(":", 2).reverse()[0].substring(2)}:443`;
|
||||
//logger.info(`addLensClusterToDECCWorkspace: ucpDashboard - ${ucpDashboard}`);
|
||||
|
||||
const jsConfig = kubeconfig({
|
||||
username: username,
|
||||
clusterName: `${clusterPrefix}-${deccCluster.metadata.name}`,
|
||||
clientId: deccCluster.status.providerStatus.oidc.clientId,
|
||||
idpCertificateAuthorityData: deccCluster.status.providerStatus.oidc.certificate,
|
||||
idpIssuerUrl: deccCluster.status.providerStatus.oidc.issuerUrl,
|
||||
server: ucpDashboard,
|
||||
apiCertificate: deccCluster.status.providerStatus.apiServerCertificate,
|
||||
idToken: idToken,
|
||||
refreshToken: refreshToken
|
||||
});
|
||||
|
||||
//console.log(`Generated kubeconfig: ${YAML.stringify(jsConfig)}`)
|
||||
|
||||
let newClusters: ClusterModel[] = [];
|
||||
let newCluster = new Cluster({
|
||||
id: deccCluster.metadata.uid,
|
||||
contextName: `${username}@${clusterPrefix}-${deccCluster.metadata.name}`,
|
||||
preferences: {
|
||||
clusterName: `${username}@${clusterPrefix}-${deccCluster.metadata.name}`,
|
||||
httpsProxy: undefined,
|
||||
},
|
||||
kubeConfigPath: ClusterStore.embedCustomKubeConfig(deccCluster.metadata.uid, YAML.stringify(jsConfig)),
|
||||
workspace: workspace.id,
|
||||
});
|
||||
|
||||
newClusters.push(newCluster);
|
||||
clusterStore.addCluster(...newClusters);
|
||||
logger.info(`addLensClusterToDECCWorkspace: Created Cluster Name: ${username}@${clusterPrefix}-${deccCluster.metadata.name}, Cluster UCP Dashboard URL: ${ucpDashboard}`)
|
||||
};
|
||||
}
|
||||
|
||||
addLensClustersToDECCWorkspace(deccClusters, idToken: string, refreshToken: string, username: string, wsName: string) {
|
||||
const wsPrefix = `decc`;
|
||||
const workspace = workspaceStore.getByName(`${wsPrefix}-${wsName}`);
|
||||
|
||||
//logger.info(`addLensClustersToDECCWorkspace: Processing clusters in Workspace ${workspace.name} for User ${username}`);
|
||||
|
||||
deccClusters.forEach(cluster => {
|
||||
this.addLensClusterToDECCWorkspace(cluster, idToken, refreshToken, username, workspace)
|
||||
});
|
||||
}
|
||||
|
||||
addClustersToWorkspace() {
|
||||
var parsedToken = userStore.decodeToken (userStore.getTokenDetails().token);
|
||||
console.log(`deccURL: ${this.deccURL}`);
|
||||
deleteLensDECCClustersByWorkspace(ws) {
|
||||
logger.info(`deleteLensDECCClustersByWorkspace: Removing all Lens DECC clusters for Workspace ${ws.name}`)
|
||||
clusterStore.removeByWorkspaceId(ws.id);
|
||||
}
|
||||
|
||||
workspaceStore.workspacesList.forEach(function(ws) {
|
||||
console.log(`Adding clusters for ws: ${ws.name}`);
|
||||
let clusters = {
|
||||
method: 'GET',
|
||||
url: `http://a09bfce9ea3074e25b8e5e7b1df576fd-1162277427.eu-west-2.elb.amazonaws.com/apis/cluster.k8s.io/v1alpha1/namespaces/${ws.name}/clusters`,
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + userStore.getTokenDetails().token
|
||||
},
|
||||
json: true
|
||||
};
|
||||
|
||||
request(clusters)
|
||||
.then(function(response) {
|
||||
//API call ok....
|
||||
const deccClusters = response["items"];
|
||||
deccClusters.forEach(function(deccCluster: object) {
|
||||
// check if cluster is already in the cluster store
|
||||
let clusterPresent = false;
|
||||
clusterStore.getByWorkspaceId(ws.id).forEach(wsCluster => {
|
||||
if (wsCluster.contextName === `${parsedToken.preferred_username}@${deccCluster.metadata.name}`) {
|
||||
clusterPresent = true;
|
||||
}
|
||||
});
|
||||
|
||||
if ("status" in deccCluster && !clusterPresent) {
|
||||
// clusterUCPURL = cluster.status.
|
||||
|
||||
let ucpDashboard = `https://${deccCluster.status.providerStatus.ucpDashboard.split(":", 2).reverse()[0].substring(2)}:443`;
|
||||
console.log (`ucpDashboard: ${ucpDashboard}`);
|
||||
|
||||
const jsConfig = kubeconfig({
|
||||
username: parsedToken.preferred_username,
|
||||
clusterName: deccCluster.metadata.name,
|
||||
clientId: deccCluster.status.providerStatus.oidc.clientId,
|
||||
idpCertificateAuthorityData: deccCluster.status.providerStatus.oidc.certificate,
|
||||
idpIssuerUrl: deccCluster.status.providerStatus.oidc.issuerUrl,
|
||||
server: ucpDashboard,
|
||||
apiCertificate: deccCluster.status.providerStatus.apiServerCertificate,
|
||||
idToken: userStore.getTokenDetails().token,
|
||||
refreshToken: userStore.getTokenDetails().refreshToken
|
||||
});
|
||||
|
||||
console.log(`Generated kubeconfig: ${YAML.stringify(jsConfig)}`)
|
||||
|
||||
console.log(`Cluster Name: ${deccCluster.metadata.name}, Cluster UCP Dashboard URL: ${deccCluster.status.providerStatus.ucpDashboard}`)
|
||||
let newCluster = new Cluster({
|
||||
id: uuid(),
|
||||
contextName: `${parsedToken.preferred_username}@${deccCluster.metadata.name}`,
|
||||
preferences: {
|
||||
clusterName: deccCluster.metadata.name,
|
||||
httpsProxy: undefined,
|
||||
},
|
||||
kubeConfigPath: ClusterStore.embedCustomKubeConfig(deccCluster.metadata.uid, YAML.stringify(jsConfig)),
|
||||
workspace: ws.name,
|
||||
});
|
||||
|
||||
clusterStore.addCluster(newCluster);
|
||||
};
|
||||
});
|
||||
})
|
||||
.catch(function (err: string) {
|
||||
// API call failed...
|
||||
console.log(err);
|
||||
deleteLensDECCWorkspace(workspaceId) {
|
||||
workspaceStore.removeWorkspace(workspaceId);
|
||||
}
|
||||
|
||||
deleteLensDECCWorkspaces(userDECCNamespaces) {
|
||||
const wsPrefix = `decc`;
|
||||
workspaceStore.workspacesList.forEach(ws => {
|
||||
let strippedPrefixWorkspaceName = ws.name.slice(5);
|
||||
//logger.info(`deleteLensDECCWorkspaces: Existing Workspace ${ws.name} being checked against ${userDECCNamespaces.toString()}`)
|
||||
if (ws.name != "default") {
|
||||
//logger.info(`deleteLensDECCWorkspaces: Stripped Workspace ${strippedPrefixWorkspaceName} being checked against ${userDECCNamespaces.toString()}`)
|
||||
if (!userDECCNamespaces.includes(`${strippedPrefixWorkspaceName}`)) {
|
||||
logger.info(`deleteLensDECCWorkspaces: User does not have access to existing Workspace ${ws.name} - Deleting`)
|
||||
this.deleteLensDECCClustersByWorkspace(ws);
|
||||
this.deleteLensDECCWorkspace(ws.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
refreshLensDECCClusterKubeconfigs(idToken:string , refreshToken: string, username: string, workspace: string) {
|
||||
//logger.info(`refreshLensDECCClusterKubeconfigs: Processing Workspace Name ${workspace}`);
|
||||
const wsPrefix = `decc`;
|
||||
const ws = workspaceStore.getByName(`${wsPrefix}-${workspace}`);
|
||||
|
||||
if (ws === undefined) { return }
|
||||
|
||||
//logger.info(`refreshLensDECCClusterKubeconfigs: Processing Workspace ${JSON.stringify(ws)}`)
|
||||
clusterStore.getByWorkspaceId(ws.id).forEach(cluster => {
|
||||
const currentKubeConfig = loadConfig(cluster.kubeConfigPath); //readFile(cluster.kubeConfigPath, "utf8");
|
||||
// console.log(`refreshClusterKubeConfigs: Read kubeconfig from file: ${cluster.kubeConfigPath}. Contents: ${YAML.stringify(kubeConfig)}`);
|
||||
// console.log(`refreshClusterKubeConfigs: kubeconfig users[0]: ${YAML.stringify(kubeConfig.users[0])}`);
|
||||
// console.log(`refreshClusterKubeConfigs: kubeconfig users[0] id-token: ${YAML.stringify(kubeConfig.users[0].authProvider.config["id-token"])}`);
|
||||
// console.log(`refreshClusterKubeConfigs: kubeconfig users[0] refresh-token: ${YAML.stringify(kubeConfig.users[0].authProvider.config["refresh-token"])}`);
|
||||
const jsConfig = kubeconfig({
|
||||
username: username,
|
||||
clusterName: currentKubeConfig.clusters[0].name,
|
||||
clientId: currentKubeConfig.users[0].authProvider.config["client-id"],
|
||||
idpCertificateAuthorityData: currentKubeConfig.users[0].authProvider.config["idp-certificate-authority-data"],
|
||||
idpIssuerUrl: currentKubeConfig.users[0].authProvider.config["idp-issuer-url"],
|
||||
server: currentKubeConfig.clusters[0].server,
|
||||
apiCertificate: currentKubeConfig.clusters[0].caData,
|
||||
idToken: idToken,
|
||||
refreshToken: refreshToken
|
||||
});
|
||||
|
||||
ClusterStore.embedCustomKubeConfig(cluster.id, YAML.stringify(jsConfig));
|
||||
logger.info(`refreshLensDECCClusterKubeconfigs: Updated Cluster ${cluster.preferences.clusterName} kubeconfig with new token values`);
|
||||
cluster.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
async createDECCLensEnv() {
|
||||
const idToken = userStore.token.token;
|
||||
const parsedIdToken = userStore.decodeToken (userStore.token.token);
|
||||
const refreshToken = userStore.token.refreshToken;
|
||||
const username = parsedIdToken.preferred_username;
|
||||
const userIAMRoles = parsedIdToken.iam_roles;
|
||||
|
||||
// get all available DECC Namespaces
|
||||
const deccNamespaces = await this.getDECCNamespaces();
|
||||
// logger.info(`createDECCLensEnv: The following namespaces exist in DECC - ${deccNamespaces.toString()}`);
|
||||
|
||||
// get all DECC Namespaces the user has access to
|
||||
const userDECCNamespaces: string[] = await this.getDECCNamespacesForUser(deccNamespaces, userIAMRoles, username);
|
||||
if (userDECCNamespaces.length > 0) {
|
||||
userDECCNamespaces.sort();
|
||||
logger.info(`createDECCLensEnv: The following namespaces exist in DECC for User ${username} - ${userDECCNamespaces.toString()}`);
|
||||
|
||||
// lets remove workspaces this user does not have access to
|
||||
this.deleteLensDECCWorkspaces(userDECCNamespaces);
|
||||
|
||||
userDECCNamespaces.forEach(async (ns) => {
|
||||
try {
|
||||
let deccClustersByNamespace = await this.getDECCClustersForNamespace(ns);
|
||||
//logger.info(`createDECCLensEnv: The following clusters exist in Namespace ${ns} - ${JSON.stringify(deccClustersByNamespace)}`);
|
||||
|
||||
// refresh tokens for any existing clusters
|
||||
this.refreshLensDECCClusterKubeconfigs(idToken, refreshToken, username, ns);
|
||||
|
||||
// now lets add the workspace in Lens
|
||||
this.addLensDECCWorkspace(ns);
|
||||
|
||||
// now lets add the clusters to the workspace
|
||||
this.addLensClustersToDECCWorkspace(deccClustersByNamespace, idToken, refreshToken, username, ns);
|
||||
|
||||
} catch (err) {
|
||||
logger.error(`createDECCLensEnv: ${String(err)}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,11 +50,6 @@ const keycloakWinURL = process.env.NODE_ENV === 'development'
|
||||
: `file://${__static}/keycloak_index.html`
|
||||
const { ipcMain } = require('electron')
|
||||
|
||||
const ignoredDECCNamespaces = [
|
||||
'kube-system', 'kube-public', 'openstack-provider-system', 'system',
|
||||
'kaas', 'lcm-system', 'istio-system', 'kube-node-lease', 'stacklight'
|
||||
];
|
||||
|
||||
async function main() {
|
||||
await shellSync();
|
||||
logger.info(`🚀 Starting Lens from "${workingDir}"`)
|
||||
@ -103,7 +98,7 @@ async function main() {
|
||||
}).listen(3000);
|
||||
|
||||
// create cluster manager
|
||||
deccManager = new DECCManager(keycloakServer, 'a09bfce9ea3074e25b8e5e7b1df576fd-1162277427.eu-west-2.elb.amazonaws.com');
|
||||
//deccManager = new DECCManager(keycloakServer, 'a09bfce9ea3074e25b8e5e7b1df576fd-1162277427.eu-west-2.elb.amazonaws.com');
|
||||
|
||||
|
||||
// create window manager and open app
|
||||
@ -141,22 +136,31 @@ app.on("will-quit", async (event) => {
|
||||
ipcMain.on('keycloak-token', (event, idToken, refreshToken) => {
|
||||
logger.info('test keycloak close main win');
|
||||
userStore.setTokenDetails(idToken, refreshToken);
|
||||
logger.info('saved id token and refreshToken to userStore');
|
||||
//logger.info('saved id token and refreshToken to userStore');
|
||||
|
||||
logger.info('the idToken is: ' + userStore.getTokenDetails().token);
|
||||
//logger.info('the idToken is: ' + userStore.getTokenDetails().token);
|
||||
|
||||
var parsedToken = userStore.decodeToken (idToken);
|
||||
// create cluster manager
|
||||
deccManager = new DECCManager('a09bfce9ea3074e25b8e5e7b1df576fd-1162277427.eu-west-2.elb.amazonaws.com');
|
||||
deccManager.createDECCLensEnv();
|
||||
|
||||
deccManager.getNamespacesForUser();
|
||||
deccManager.addClustersToWorkspace();
|
||||
|
||||
// deccManager.refreshClusterKubeConfigs();
|
||||
// deccManager.getNamespacesForUser();
|
||||
// deccManager.addClustersToWorkspace();
|
||||
|
||||
//TODO: refresh token!
|
||||
windowManager.showMain();
|
||||
});
|
||||
|
||||
ipcMain.on('keycloak-token-update', (event, token) => {
|
||||
logger.error('token refresh receivied:' + token);
|
||||
//TODO: handle refresh token!
|
||||
ipcMain.on('keycloak-token-update', (event, idToken, refreshToken) => {
|
||||
logger.info('token refresh receivied:' + idToken);
|
||||
if(userStore.isTokenExpired(userStore.token.tokenValidTill)) {
|
||||
userStore.setTokenDetails(idToken, refreshToken);
|
||||
logger.info('saved new id token and refreshToken to userStore');
|
||||
logger.info('the idToken is: ' + userStore.getTokenDetails().token);
|
||||
//deccManager.refreshClusterKubeConfigs();
|
||||
};
|
||||
});
|
||||
|
||||
ipcMain.on('keycloak-logout', (event, data) => {
|
||||
|
||||
@ -7,6 +7,11 @@ import { preferencesURL } from "../renderer/components/+preferences/preferences.
|
||||
import { whatsNewURL } from "../renderer/components/+whats-new/whats-new.route";
|
||||
import { clusterSettingsURL } from "../renderer/components/+cluster-settings/cluster-settings.route";
|
||||
import logger from "./logger";
|
||||
import { landingURL } from "../renderer/components/+landing-page/landing-page.route";
|
||||
|
||||
const keycloakWinURL = process.env.NODE_ENV === 'development'
|
||||
? `http://localhost:3000/keycloak_index.html`
|
||||
: `file://${__static}/keycloak_index.html`
|
||||
|
||||
export function initMenu(windowManager: WindowManager) {
|
||||
autorun(() => buildMenu(windowManager), {
|
||||
@ -37,6 +42,10 @@ export function buildMenu(windowManager: WindowManager) {
|
||||
})
|
||||
}
|
||||
|
||||
function showKeycloak() {
|
||||
windowManager.showKeycloak()
|
||||
}
|
||||
|
||||
function showAbout(browserWindow: BrowserWindow) {
|
||||
const appInfo = [
|
||||
`${appName}: ${app.getVersion()}`,
|
||||
@ -121,7 +130,15 @@ export function buildMenu(windowManager: WindowManager) {
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ role: 'quit' }
|
||||
])
|
||||
]),
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Logout',
|
||||
click() {
|
||||
//navigate(keycloakWinURL)
|
||||
windowManager.showLogout()
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
mt.push(fileMenu)
|
||||
|
||||
@ -4,6 +4,7 @@ import { BrowserWindow, dialog, ipcMain, shell, webContents } from "electron"
|
||||
import windowStateKeeper from "electron-window-state"
|
||||
import { observable } from "mobx";
|
||||
import { initMenu } from "./menu";
|
||||
import { userStore } from "../common/user-store";
|
||||
|
||||
export class WindowManager {
|
||||
protected mainView: BrowserWindow;
|
||||
@ -95,6 +96,16 @@ export class WindowManager {
|
||||
}
|
||||
}
|
||||
|
||||
public async showLogout() {
|
||||
try {
|
||||
userStore.saveLastLoggedInUser(userStore.token.preferredUserName);
|
||||
await this.mainView.loadURL(`http://localhost:${this.keycloakPort}?logout=true`)
|
||||
this.mainView.show();
|
||||
} catch (err) {
|
||||
dialog.showErrorBox("ERROR!", err.toString())
|
||||
}
|
||||
}
|
||||
|
||||
public async showMain() {
|
||||
try {
|
||||
//await this.showSplash();
|
||||
|
||||
@ -27,15 +27,14 @@ if(logoutUser){
|
||||
console.log("keycloak object: "+ JSON.stringify(keycloak));
|
||||
ipcRenderer.send('keycloak-token', keycloak.idToken, keycloak.refreshToken);
|
||||
|
||||
//TODO: check if token refresh is possible here
|
||||
/*
|
||||
setInterval(() => {
|
||||
console.log("interval");
|
||||
keycloak.updateToken(10).error(() => keycloak.logout());
|
||||
console.log(keycloak.token);
|
||||
ipcRenderer.send('keycloak-token-update', keycloak.token);
|
||||
}, 10000);
|
||||
*/
|
||||
//TODO: check if token refresh is possible here
|
||||
setInterval(() => {
|
||||
let tokenRefreshAt = new Date();
|
||||
console.log(`keycloak interval: ${tokenRefreshAt.toString()}`);
|
||||
keycloak.updateToken(10).error(() => keycloak.logout());
|
||||
console.log(keycloak.token);
|
||||
ipcRenderer.send('keycloak-token-update', keycloak.idToken, keycloak.refreshToken);
|
||||
}, 10000);
|
||||
}
|
||||
}).error(function(error) {
|
||||
console.log('error: ' + JSON.stringify(error));
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
"moduleResolution": "Node",
|
||||
"sourceMap": true,
|
||||
"strict": false,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitAny": false,
|
||||
"noUnusedLocals": false,
|
||||
"noImplicitReturns": false,
|
||||
"experimentalDecorators": true,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user