mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix getting allowed resources, don't display workloads overview if no resources are allowed
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
55d3e996cb
commit
439c469ce6
@ -519,20 +519,25 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
return getClusterResources(await this.getProxyKubeconfig());
|
||||
}, 60 * 1000); // 1min
|
||||
|
||||
private isAllowedCheckers = new ExtendedObservableMap<string, () => Promise<Map<string, boolean>>>();
|
||||
private isAllowedCheckers = new ExtendedObservableMap<string, () => Promise<Set<string>>>();
|
||||
|
||||
private async getIsAllowedResourcesInNamespace(namespace: string): Promise<Map<string, boolean>> {
|
||||
private async getIsAllowedResourcesInNamespace(namespace: string): Promise<Set<string>> {
|
||||
console.log("getIsAllowedResourcesInNamespace", Date.now());
|
||||
const groups = await this.getApiResourceMap();
|
||||
const isAllowed = new Map<string, boolean>();
|
||||
const isAllowed = new Set<string>();
|
||||
|
||||
for (const group of groups.values()) {
|
||||
for (const versions of group.values()) {
|
||||
for (const resource of versions.keys()) {
|
||||
isAllowed.set(resource, await this.canI({
|
||||
name: resource,
|
||||
const canList = await this.canI({
|
||||
resource,
|
||||
namespace,
|
||||
verb: "list",
|
||||
}));
|
||||
});
|
||||
|
||||
if (canList) {
|
||||
isAllowed.add(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -540,7 +545,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
return isAllowed;
|
||||
}
|
||||
|
||||
async getIsAllowedResources(namespace: string): Promise<Map<string, boolean>> {
|
||||
async getIsAllowedResources(namespace: string): Promise<Set<string>> {
|
||||
return this.isAllowedCheckers.getOrInsert(
|
||||
namespace,
|
||||
() => asyncThrottle(
|
||||
@ -566,7 +571,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
const accessReview = await this.canIApiLimit(() => authApi.createSelfSubjectAccessReview({
|
||||
apiVersion: "authorization.k8s.io/v1",
|
||||
kind: "SelfSubjectAccessReview",
|
||||
spec: { resourceAttributes }
|
||||
spec: { resourceAttributes },
|
||||
}));
|
||||
|
||||
return accessReview.body.status.allowed;
|
||||
|
||||
@ -119,19 +119,19 @@ export function initIpcMainHandlers() {
|
||||
?.getApiResourceMap();
|
||||
});
|
||||
|
||||
ipcMainHandle(ClusterResourceIsAllowedChannel, async (event, clusterId: ClusterId, namespaces: string[]): Promise<[string, boolean][]> => {
|
||||
ipcMainHandle(ClusterResourceIsAllowedChannel, async (event, clusterId: ClusterId, namespaces: string[]): Promise<string[]> => {
|
||||
const cluster = ClusterStore.getInstance().getById(clusterId);
|
||||
|
||||
if (!cluster) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const isAllowed = new Map<string, boolean>();
|
||||
const isAllowed = new Set<string>();
|
||||
|
||||
await Promise.all(
|
||||
namespaces.map(async namespace => {
|
||||
for (const [resource, canList] of await cluster.getIsAllowedResources(namespace)) {
|
||||
isAllowed.set(resource, Boolean(isAllowed.get(resource)) || canList);
|
||||
for (const resource of await cluster.getIsAllowedResources(namespace)) {
|
||||
isAllowed.add(resource);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { action, makeObservable, observable, ObservableMap, reaction } from "mobx";
|
||||
import { action, makeObservable, observable, reaction } from "mobx";
|
||||
import type { ClusterId } from "../../common/cluster-store";
|
||||
import { ClusterResourceIsAllowedChannel, ClusterGetResourcesChannel, requestMain } from "../../common/ipc";
|
||||
import { Disposer, Singleton } from "../utils";
|
||||
@ -31,7 +31,7 @@ type NamespaceName = string;
|
||||
type ResourceName = string;
|
||||
|
||||
export class AllowedResources extends Singleton {
|
||||
protected allowedResourceMap = new ObservableMap<ResourceName, boolean>();
|
||||
protected allowedResources = observable.set<ResourceName>();
|
||||
@observable public resources: ApiResourceMap;
|
||||
|
||||
/**
|
||||
@ -65,9 +65,10 @@ export class AllowedResources extends Singleton {
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
private async refresh(namespaces: NamespaceName[]) {
|
||||
try {
|
||||
this.allowedResourceMap.replace(await requestMain(ClusterResourceIsAllowedChannel, this.clusterId, namespaces));
|
||||
this.allowedResources.replace(await requestMain(ClusterResourceIsAllowedChannel, this.clusterId, namespaces));
|
||||
} catch (error) {
|
||||
console.error("[ALLOWED-RESOURCES]: failed to refresh", error, { namespaces });
|
||||
Notifications.error("Failed to refresh allowed resources");
|
||||
@ -81,7 +82,7 @@ export class AllowedResources extends Singleton {
|
||||
* @returns `true` if the resource exists; is cluster scoped and can be listed, or is namespaced and can be listed in at least one of the namespaces
|
||||
*/
|
||||
isAllowed(name: ResourceName): boolean {
|
||||
return this.allowedResourceMap.get(name) ?? false;
|
||||
return this.allowedResources.has(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -39,14 +39,7 @@ import * as routes from "../../../common/routes";
|
||||
@observer
|
||||
export class Workloads extends React.Component {
|
||||
@computed static get tabRoutes(): TabLayoutRoute[] {
|
||||
const tabs: TabLayoutRoute[] = [
|
||||
{
|
||||
title: "Overview",
|
||||
component: WorkloadsOverview,
|
||||
url: routes.overviewURL(),
|
||||
routePath: routes.overviewRoute.path.toString()
|
||||
}
|
||||
];
|
||||
const tabs: TabLayoutRoute[] = [];
|
||||
|
||||
if (isAllowedResource("pods")) {
|
||||
tabs.push({
|
||||
@ -111,6 +104,15 @@ export class Workloads extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
if (tabs.length > 0) {
|
||||
tabs.unshift({
|
||||
title: "Overview",
|
||||
component: WorkloadsOverview,
|
||||
url: routes.overviewURL(),
|
||||
routePath: routes.overviewRoute.path.toString()
|
||||
});
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user