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

Refactoring of AuthorizationNamespaceReview

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-11-25 12:24:29 -05:00
parent 420bbfd23f
commit 78a4177621

View File

@ -6,7 +6,6 @@
import type { KubeConfig } from "@kubernetes/client-node"; import type { KubeConfig } from "@kubernetes/client-node";
import { AuthorizationV1Api } from "@kubernetes/client-node"; import { AuthorizationV1Api } from "@kubernetes/client-node";
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import type { Logger } from "../logger";
import loggerInjectable from "../logger.injectable"; import loggerInjectable from "../logger.injectable";
import type { KubeApiResource } from "../rbac"; import type { KubeApiResource } from "../rbac";
@ -23,69 +22,67 @@ export type RequestNamespaceResources = (namespace: string, availableResources:
*/ */
export type AuthorizationNamespaceReview = (proxyConfig: KubeConfig) => RequestNamespaceResources; export type AuthorizationNamespaceReview = (proxyConfig: KubeConfig) => RequestNamespaceResources;
interface Dependencies {
logger: Logger;
}
const authorizationNamespaceReview = ({ logger }: Dependencies): AuthorizationNamespaceReview => {
return (proxyConfig) => {
const api = proxyConfig.makeApiClient(AuthorizationV1Api);
return async (namespace, availableResources) => {
try {
const { body } = await api.createSelfSubjectRulesReview({
apiVersion: "authorization.k8s.io/v1",
kind: "SelfSubjectRulesReview",
spec: { namespace },
});
const resources = new Set<string>();
if (!body.status || body.status.incomplete) {
logger.warn(`[AUTHORIZATION-NAMESPACE-REVIEW]: allowing all resources in namespace="${namespace}" due to incomplete SelfSubjectRulesReview: ${body.status?.evaluationError}`);
return availableResources.map(r => r.apiName);
}
body.status.resourceRules.forEach(resourceRule => {
if (!resourceRule.verbs.some(verb => ["*", "list"].includes(verb)) || !resourceRule.resources) {
return;
}
const apiGroups = resourceRule.apiGroups;
if (resourceRule.resources.length === 1 && resourceRule.resources[0] === "*" && apiGroups) {
if (apiGroups[0] === "*") {
availableResources.forEach(resource => resources.add(resource.apiName));
} else {
availableResources.forEach((apiResource)=> {
if (apiGroups.includes(apiResource.group || "")) {
resources.add(apiResource.apiName);
}
});
}
} else {
resourceRule.resources.forEach(resource => resources.add(resource));
}
});
return [...resources];
} catch (error) {
logger.error(`[AUTHORIZATION-NAMESPACE-REVIEW]: failed to create subject rules review: ${error}`, { namespace });
return [];
}
};
};
};
const authorizationNamespaceReviewInjectable = getInjectable({ const authorizationNamespaceReviewInjectable = getInjectable({
id: "authorization-namespace-review", id: "authorization-namespace-review",
instantiate: (di) => { instantiate: (di): AuthorizationNamespaceReview => {
const logger = di.inject(loggerInjectable); const logger = di.inject(loggerInjectable);
return authorizationNamespaceReview({ logger }); return (proxyConfig) => {
const api = proxyConfig.makeApiClient(AuthorizationV1Api);
return async (namespace, availableResources) => {
try {
const { body: { status }} = await api.createSelfSubjectRulesReview({
apiVersion: "authorization.k8s.io/v1",
kind: "SelfSubjectRulesReview",
spec: { namespace },
});
const allowedResources = new Set<string>();
if (!status || status.incomplete) {
logger.warn(`[AUTHORIZATION-NAMESPACE-REVIEW]: allowing all resources in namespace="${namespace}" due to incomplete SelfSubjectRulesReview: ${status?.evaluationError}`);
return availableResources.map(r => r.apiName);
}
for (const { verbs, resources, apiGroups } of status.resourceRules) {
if (
!resources
|| (!verbs.includes("*") && !verbs.includes("list"))
) {
continue;
}
if (resources[0] !== "*" || !apiGroups) {
for (const resource of resources) {
allowedResources.add(resource);
}
continue;
}
if (apiGroups[0] === "*") {
for (const resource of availableResources) {
allowedResources.add(resource.apiName);
}
continue;
}
for (const resource of availableResources) {
if (apiGroups.includes(resource.group || "")) {
allowedResources.add(resource.apiName);
}
}
}
return [...allowedResources];
} catch (error) {
logger.error(`[AUTHORIZATION-NAMESPACE-REVIEW]: failed to create subject rules review: ${error}`, { namespace });
return [];
}
};
};
}, },
}); });