1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Move requesting isGlobalWatchAllowed to renderer

- Check accessibleNamespaces in globalWatch handler

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2021-06-01 10:37:18 -04:00
parent a72ac1cb3c
commit 7b34d63703
5 changed files with 43 additions and 15 deletions

View File

@ -26,6 +26,7 @@
export const ClusterListNamespaceForbiddenChannel = "cluster:list-namespace-forbidden";
export const ClusterGetResourcesChannel = "cluster:resources";
export const ClusterResourceIsAllowedChannel = "cluster:resource:is-allowed";
export const ClusterGlobalWatchChannel = "cluster:resource:global-watch-allowed";
export type ListNamespaceForbiddenArgs = [clusterId: string];

View File

@ -77,7 +77,6 @@ export interface ClusterState {
ready: boolean;
failureReason: string;
allowedNamespaces: string[]
isGlobalWatchEnabled: boolean;
}
/**
@ -167,12 +166,6 @@ export class Cluster implements ClusterModel, ClusterState {
*/
@observable failureReason: string;
/**
* Global watch-api accessibility , e.g. "/api/v1/services?watch=1"
*
* @observable
*/
@observable isGlobalWatchEnabled = false;
/**
* Preferences
*
@ -427,8 +420,6 @@ export class Cluster implements ClusterModel, ClusterState {
* @internal
*/
private async refreshAccessibility(): Promise<void> {
this.isGlobalWatchEnabled = await this.canUseWatchApi({ resource: "*" });
this.allowedNamespaces = await this.getAllowedNamespaces();
this.ready = true;
@ -635,7 +626,6 @@ export class Cluster implements ClusterModel, ClusterState {
accessible: this.accessible,
failureReason: this.failureReason,
allowedNamespaces: this.allowedNamespaces,
isGlobalWatchEnabled: this.isGlobalWatchEnabled,
};
return toJS(state);

View File

@ -25,7 +25,7 @@ import { clusterFrameMap } from "../../common/cluster-frames";
import { clusterActivateHandler, clusterSetFrameIdHandler, clusterVisibilityHandler, clusterRefreshHandler, clusterDisconnectHandler, clusterKubectlApplyAllHandler, clusterKubectlDeleteAllHandler } from "../../common/cluster-ipc";
import { ClusterId, ClusterStore } from "../../common/cluster-store";
import { appEventBus } from "../../common/event-bus";
import { ClusterGetResourcesChannel, ClusterResourceIsAllowedChannel, ipcMainHandle } from "../../common/ipc";
import { ClusterGetResourcesChannel, ClusterGlobalWatchChannel, ClusterResourceIsAllowedChannel, ipcMainHandle } from "../../common/ipc";
import { catalogEntityRegistry } from "../catalog";
import { ResourceApplier } from "../resource-applier";
@ -138,4 +138,22 @@ export function initIpcMainHandlers() {
return Array.from(isAllowed);
});
ipcMainHandle(ClusterGlobalWatchChannel, async (event, clusterId: ClusterId): Promise<boolean> => {
const cluster = ClusterStore.getInstance().getById(clusterId);
if (!cluster) {
throw `${clusterId} is not a valid cluster id`;
}
if (cluster.accessibleNamespaces.length > 0) {
/**
* Don't allow global watching when the user has specified namespaces.
* Assume that the cluster can't even list namespaces
*/
return false;
}
return cluster.canUseWatchApi({ resource: "*" });
});
}

View File

@ -21,7 +21,7 @@
import { action, makeObservable, observable, reaction } from "mobx";
import type { ClusterId } from "../../common/cluster-store";
import { ClusterResourceIsAllowedChannel, ClusterGetResourcesChannel, requestMain } from "../../common/ipc";
import { ClusterResourceIsAllowedChannel, ClusterGetResourcesChannel, ClusterGlobalWatchChannel, requestMain } from "../../common/ipc";
import { Disposer, Singleton } from "../utils";
import type { ApiResourceMap } from "../../main/utils/api-resources";
import { ObservableTimer } from "../../common/utils/observable-timer";
@ -44,6 +44,13 @@ export class AllowedResources extends Singleton {
protected timer = new ObservableTimer(60 * 1000);
disposer: Disposer;
/**
* Global watch-api accessibility , e.g. "/api/v1/services?watch=1"
*
* @observable
*/
@observable private globalWatchAllowed = false;
constructor(protected clusterId: ClusterId, protected getNamespaces: () => NamespaceName[]) {
super();
@ -71,13 +78,18 @@ export class AllowedResources extends Singleton {
@action
private async refresh(namespaces: NamespaceName[]) {
try {
this.allowedResources.replace(await requestMain(ClusterResourceIsAllowedChannel, this.clusterId, namespaces));
const allowedResourcesP = requestMain(ClusterResourceIsAllowedChannel, this.clusterId, namespaces);
const globalWatchAllowedP = requestMain(ClusterGlobalWatchChannel, this.clusterId);
this.allowedResources.replace(await allowedResourcesP);
this.globalWatchAllowed = await globalWatchAllowedP;
} catch (error) {
console.error("[ALLOWED-RESOURCES]: failed to refresh", error, { namespaces });
Notifications.error("Failed to refresh allowed resources");
}
}
/**
* Get the permissive list permissions of `name` over `namespaces`
* @param obj The name of the resource
@ -87,6 +99,10 @@ export class AllowedResources extends Singleton {
isAllowed(obj: KubeObject): boolean {
return this.allowedResources.has(obj.apiBase);
}
isGlobalWatchAllowed(): boolean {
return this.globalWatchAllowed;
}
}
/**

View File

@ -31,7 +31,7 @@ import { ensureObjectSelfLink, IKubeApiQueryParams, KubeApi } from "./api/kube-a
import { parseKubeApi } from "./api/kube-api-parse";
import type { KubeJsonApiData } from "./api/kube-json-api";
import { Notifications } from "./components/notifications";
import { isAllowedResource } from "./api/allowed-resources";
import { AllowedResources, isAllowedResource } from "./api/allowed-resources";
export interface KubeObjectStoreLoadingParams {
namespaces: string[];
@ -317,7 +317,10 @@ export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemSt
if (this.api.isNamespaced) {
Promise.race([rejectPromiseBy(abortController.signal), Promise.all([this.contextReady, this.namespacesReady])])
.then(() => {
if (this.context.cluster.isGlobalWatchEnabled && this.loadedNamespaces.length === 0) {
if (
AllowedResources.getInstance().isGlobalWatchAllowed()
&& this.loadedNamespaces.length === 0
) {
return this.watchNamespace("", abortController);
}