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

Fix core resources not showing up

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-11-28 11:13:25 -05:00
parent 00a8b81df4
commit 5f58196529
25 changed files with 58 additions and 39 deletions

View File

@ -175,15 +175,6 @@ export class Cluster implements ClusterModel {
private readonly knownResources = observable.array<KubeApiResource>();
private readonly knownNamespacedResources = computed(() => (
this.knownResources
.filter(r => r.namespaced === true)
));
private readonly knownClusterscopedResources = computed(() => (
this.knownResources
.filter(r => r.namespaced === false)
));
// The formatting of this is `group.name` or `name` (if in core)
private readonly allowedResources = observable.set<string>();
@ -677,21 +668,14 @@ export class Cluster implements ClusterModel {
}
try {
const canListClusterScopedResource = await requestNamespaceListPermissions("");
const apiLimit = plimit(5); // 5 concurrent api requests
const canListNamespacedResourceCheckers = await Promise.all((
const canListResourceCheckers = await Promise.all((
this.allowedNamespaces.map(namespace => apiLimit(() => requestNamespaceListPermissions(namespace)))
));
const canListNamespacedResource: CanListResource = (resource) => canListNamespacedResourceCheckers.some(fn => fn(resource));
const canListNamespacedResource: CanListResource = (resource) => canListResourceCheckers.some(fn => fn(resource));
const allowedClusterScopedResources = this.knownClusterscopedResources
.get()
.filter(canListClusterScopedResource);
const allowedNamespaceScopedResources = this.knownNamespacedResources
.get()
.filter(canListNamespacedResource);
return [...allowedClusterScopedResources, ...allowedNamespaceScopedResources]
return this.knownResources
.filter(canListNamespacedResource)
.map(formatKubeApiResource);
} catch (error) {
return [];

View File

@ -47,11 +47,14 @@ const requestNamespaceListPermissionsForInjectable = getInjectable({
const { resourceRules } = status;
return (resource) => {
const resourceRule = resourceRules.find(rule => {
console.log(rule);
void resource;
const resourceRule = resourceRules.find(({
apiGroups = [],
resources = [],
}) => {
const isAboutRelevantApiGroup = apiGroups.includes("*") || apiGroups.includes(resource.group);
const isAboutResource = resources.includes("*") || resources.includes(resource.apiName);
return true;
return isAboutRelevantApiGroup && isAboutResource;
});
if (!resourceRule) {
@ -63,7 +66,7 @@ const requestNamespaceListPermissionsForInjectable = getInjectable({
return verbs.includes("*") || verbs.includes("list");
};
} catch (error) {
logger.error(`[AUTHORIZATION-NAMESPACE-REVIEW]: failed to create subject rules review: ${error}`, { namespace });
logger.error(`[AUTHORIZATION-NAMESPACE-REVIEW]: failed to create subject rules review`, { namespace, error });
return () => true;
}

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import shouldShowResourceInjectable from "../../../../../../renderer/cluster-frame-context/should-show-resource.injectable";
import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const configMapsRouteInjectable = getInjectable({
@ -11,8 +11,9 @@ const configMapsRouteInjectable = getInjectable({
instantiate: (di) => ({
path: "/configmaps",
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectable, {
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "configmaps",
group: "v1",
}),
}),
injectionToken: frontEndRouteInjectionToken,

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import shouldShowResourceInjectable from "../../../../../../renderer/cluster-frame-context/should-show-resource.injectable";
import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const horizontalPodAutoscalersRouteInjectable = getInjectable({
@ -12,7 +12,7 @@ const horizontalPodAutoscalersRouteInjectable = getInjectable({
instantiate: (di) => ({
path: "/hpa",
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectable, {
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "horizontalpodautoscalers",
group: "autoscaling",
}),

View File

@ -14,6 +14,7 @@ const leasesRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "leases",
group: "coordination.k8s.io",
}),
}),

View File

@ -14,6 +14,7 @@ const limitRangesRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "limitranges",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const resourceQuotasRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "resourcequotas",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const secretsRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "secrets",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const eventsRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "events",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const namespacesRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "namespaces",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const endpointsRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "endpoints",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const servicesRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "services",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const nodesRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "nodes",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const clusterOverviewRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "nodes",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const persistentVolumeClaimsRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "persistentvolumeclaims",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const persistentVolumesRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "persistentvolumes",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const serviceAccountsRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "serviceaccounts",
group: "v1",
}),
}),

View File

@ -14,6 +14,7 @@ const podsRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "pods",
group: "v1",
}),
}),

View File

@ -13,25 +13,21 @@ export type KubeResource =
export interface KubeApiResource {
kind: string;
group?: string;
group: string;
apiName: string;
namespaced: boolean;
}
export interface KubeApiResourceDescriptor {
apiName: string;
group?: string;
group: string;
}
export const formatKubeApiResource = (res: KubeApiResourceDescriptor) => (
res.group
? `${res.group}/${res.apiName}`
: res.apiName
);
export const formatKubeApiResource = (res: KubeApiResourceDescriptor) => `${res.group}/${res.apiName}`;
export interface KubeApiResourceData {
kind: string; // resource type (e.g. "Namespace")
group?: string; // api-group, if empty then "core"
group: string; // api-group, if empty then "core"
namespaced: boolean;
}
@ -48,6 +44,7 @@ export const apiResourceRecord: Record<KubeResource, KubeApiResourceData> = {
},
configmaps: {
kind: "ConfigMap",
group: "v1",
namespaced: true,
},
cronjobs: {
@ -72,10 +69,12 @@ export const apiResourceRecord: Record<KubeResource, KubeApiResourceData> = {
},
endpoints: {
kind: "Endpoint",
group: "v1",
namespaced: true,
},
events: {
kind: "Event",
group: "v1",
namespaced: true,
},
horizontalpodautoscalers: {
@ -95,14 +94,17 @@ export const apiResourceRecord: Record<KubeResource, KubeApiResourceData> = {
},
namespaces: {
kind: "Namespace",
group: "v1",
namespaced: false,
},
limitranges: {
kind: "LimitRange",
group: "v1",
namespaced: true,
},
leases: {
kind: "Lease",
group: "v1",
namespaced: true,
},
networkpolicies: {
@ -112,18 +114,22 @@ export const apiResourceRecord: Record<KubeResource, KubeApiResourceData> = {
},
nodes: {
kind: "Node",
group: "v1",
namespaced: false,
},
persistentvolumes: {
kind: "PersistentVolume",
group: "v1",
namespaced: false,
},
persistentvolumeclaims: {
kind: "PersistentVolumeClaim",
group: "v1",
namespaced: true,
},
pods: {
kind: "Pod",
group: "v1",
namespaced: true,
},
poddisruptionbudgets: {
@ -148,6 +154,7 @@ export const apiResourceRecord: Record<KubeResource, KubeApiResourceData> = {
},
resourcequotas: {
kind: "ResourceQuota",
group: "v1",
namespaced: true,
},
replicasets: {
@ -167,14 +174,17 @@ export const apiResourceRecord: Record<KubeResource, KubeApiResourceData> = {
},
secrets: {
kind: "Secret",
group: "v1",
namespaced: true,
},
serviceaccounts: {
kind: "ServiceAccount",
group: "v1",
namespaced: true,
},
services: {
kind: "Service",
group: "v1",
namespaced: true,
},
statefulsets: {

View File

@ -100,6 +100,7 @@ describe("cluster/namespaces - edit namespace from new tab", () => {
builder.allowKubeResource({
apiName: "namespaces",
group: "v1",
});
});

View File

@ -44,6 +44,7 @@ describe("cluster/namespaces - edit namespaces from previously opened tab", () =
builder.allowKubeResource({
apiName: "namespaces",
group: "v1",
});
});

View File

@ -52,6 +52,7 @@ describe("cluster - visibility of sidebar items", () => {
beforeEach(() => {
builder.allowKubeResource({
apiName: "namespaces",
group: "v1",
});
});
@ -76,6 +77,7 @@ const testRouteInjectable = getInjectable({
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "namespaces",
group: "v1",
}),
}),

View File

@ -15,6 +15,7 @@ describe("workload overview", () => {
applicationBuilder = getApplicationBuilder().setEnvironmentToClusterFrame();
applicationBuilder.allowKubeResource({
apiName: "pods",
group: "v1",
});
rendered = await applicationBuilder.render();
});

View File

@ -21,6 +21,7 @@ const podsWorkloadInjectable = getInjectable({
return {
resource: {
apiName: "pods",
group: "v1",
},
open: navigate,

View File

@ -7,7 +7,7 @@ import { withInjectables } from "@ogre-tools/injectable-react";
import type { IComputedValue } from "mobx";
import { observer } from "mobx-react";
import React from "react";
import shouldShowResourceInjectable from "../cluster-frame-context/should-show-resource.injectable";
import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
import { Events } from "../components/+events/events";
export interface WorkloadEventsProps {}
@ -32,8 +32,9 @@ const NonInjectedWorkloadEvents = observer(({ workloadEventsAreAllowed }: Depend
export const WorkloadEvents = withInjectables<Dependencies, WorkloadEventsProps>(NonInjectedWorkloadEvents, {
getProps: (di, props) => ({
workloadEventsAreAllowed: di.inject(shouldShowResourceInjectable, {
workloadEventsAreAllowed: di.inject(shouldShowResourceInjectionToken, {
apiName: "events",
group: "v1",
}),
...props,
}),