Skip to content

Commit

Permalink
chore: Upgrade to @kubernetes/[email protected]
Browse files Browse the repository at this point in the history
- Finally removes dependency on 'request'

Signed-off-by: Sebastian Malton <[email protected]>
  • Loading branch information
Nokel81 committed May 25, 2023
1 parent 90c449c commit f36a966
Show file tree
Hide file tree
Showing 12 changed files with 388 additions and 150 deletions.
1 change: 0 additions & 1 deletion open-lens/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@
"@types/react-router-dom": "^5.3.3",
"@types/react-virtualized-auto-sizer": "^1.0.1",
"@types/react-window": "^1.8.5",
"@types/request-promise-native": "^1.0.18",
"@types/tar": "^6.1.4",
"@types/tcp-port-used": "^1.0.1",
"@types/url-parse": "^1.4.8",
Expand Down
312 changes: 275 additions & 37 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@
"@k8slens/startable-stoppable": "^1.0.0-alpha.1",
"@k8slens/tooltip": "^1.0.0-alpha.5",
"@k8slens/utilities": "^1.0.0-alpha.1",
"@kubernetes/client-node": "^0.18.1",
"@kubernetes/client-node": "^1.0.0-rc2",
"@material-ui/core": "^4.12.3",
"@material-ui/lab": "^4.0.0-alpha.60",
"@ogre-tools/fp": "^16.1.0",
Expand Down
12 changes: 7 additions & 5 deletions packages/core/src/common/cluster/create-can-i.injectable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ const createCanIInjectable = getInjectable({

return (api) => async (resourceAttributes: V1ResourceAttributes): Promise<boolean> => {
try {
const { body } = await api.createSelfSubjectAccessReview({
apiVersion: "authorization.k8s.io/v1",
kind: "SelfSubjectAccessReview",
spec: { resourceAttributes },
const review = await api.createSelfSubjectAccessReview({
body: {
apiVersion: "authorization.k8s.io/v1",
kind: "SelfSubjectAccessReview",
spec: { resourceAttributes },
},
});

return body.status?.allowed ?? false;
return review.status?.allowed ?? false;
} catch (error) {
logger.error(`[AUTHORIZATION-REVIEW]: failed to create access review: ${error}`, { resourceAttributes });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ const createRequestNamespaceListPermissionsInjectable = getInjectable({

return (api) => async (namespace) => {
try {
const { body: { status }} = await api.createSelfSubjectRulesReview({
apiVersion: "authorization.k8s.io/v1",
kind: "SelfSubjectRulesReview",
spec: { namespace },
const { status } = await api.createSelfSubjectRulesReview({
body: {
apiVersion: "authorization.k8s.io/v1",
kind: "SelfSubjectRulesReview",
spec: { namespace },
},
});

if (!status || status.incomplete) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type CreateListNamespaces = (api: CoreV1Api) => ListNamespaces;
const createListNamespacesInjectable = getInjectable({
id: "create-list-namespaces",
instantiate: (): CreateListNamespaces => (api) => async () => {
const { body: { items }} = await api.listNamespace();
const { items } = await api.listNamespace();

return items
.map(ns => ns.metadata?.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import type { AuthorizationV1Api, V1SubjectRulesReviewStatus } from "@kubernetes/client-node";
import type { DiContainer } from "@ogre-tools/injectable";
import type { IncomingMessage } from "http";
import { anyObject } from "jest-mock-extended";
import { getDiForUnitTesting } from "../../main/getDiForUnitTesting";
import { cast } from "../../test-utils/cast";
Expand Down Expand Up @@ -46,11 +45,13 @@ describe("requestNamespaceListPermissions", () => {
});

it("should request the creation of a SelfSubjectRulesReview", () => {
expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({
spec: {
namespace: "irrelevant-namespace",
},
}));
expect(createSelfSubjectRulesReviewMock).toBeCalledWith({
body: anyObject({
spec: {
namespace: "irrelevant-namespace",
},
}),
});
});

([
Expand Down Expand Up @@ -189,11 +190,8 @@ describe("requestNamespaceListPermissions", () => {
describe(`when api returns ${description}`, () => {
beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve({
body: {
status,
spec: {},
},
response: null as unknown as IncomingMessage,
status,
spec: {},
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import type { AuthorizationV1Api, CoreV1Api, V1APIGroupList, V1APIVersions, V1NamespaceList, V1SelfSubjectAccessReview, V1SelfSubjectRulesReview } from "@kubernetes/client-node";
import type { AuthorizationV1Api, CoreV1Api, V1APIGroupList, V1APIVersions, V1SelfSubjectAccessReview, V1SelfSubjectRulesReview } from "@kubernetes/client-node";
import type { Cluster } from "../../common/cluster/cluster";
import createAuthorizationApiInjectable from "../../common/cluster/create-authorization-api.injectable";
import writeJsonFileInjectable from "../../common/fs/write-json-file.injectable";
Expand Down Expand Up @@ -477,20 +477,18 @@ const nonCoreApiResponse = {
} as V1APIGroupList;

const listNamespaceResponse = {
body: {
items: [
{
metadata: {
name: "default",
},
items: [
{
metadata: {
name: "default",
},
{
metadata: {
name: "my-namespace",
},
},
{
metadata: {
name: "my-namespace",
},
],
} as PartialDeep<V1NamespaceList>,
},
],
} as Awaited<ReturnType<CoreV1Api["listNamespace"]>>;

const coreApiKindsResponse = {
Expand Down Expand Up @@ -585,51 +583,44 @@ const discoveryK8sIoKindsResponse = {
],
};

type CreateSelfSubjectRulesReviewRes = Awaited<ReturnType<AuthorizationV1Api["createSelfSubjectRulesReview"]>>;

const defaultIncompletePermissions = {
body: {
status: {
incomplete: true,
},
} as PartialDeep<V1SelfSubjectRulesReview>,
} as CreateSelfSubjectRulesReviewRes;
status: {
incomplete: true,
},
} as V1SelfSubjectRulesReview;

const emptyPermissions = {
body: {
status: {
resourceRules: [],
},
} as PartialDeep<V1SelfSubjectRulesReview>,
} as CreateSelfSubjectRulesReviewRes;
status: {
resourceRules: [],
incomplete: false,
nonResourceRules: [],
},
spec: {},
} as V1SelfSubjectRulesReview;

const defaultSingleListPermissions = {
body: {
status: {
resourceRules: [{
status: {
resourceRules: [{
apiGroups: [""],
resources: ["pods"],
verbs: ["list"],
}],
},
} as V1SelfSubjectRulesReview;

const defaultMultipleListPermissions = {
status: {
resourceRules: [
{
apiGroups: [""],
resources: ["pods"],
verbs: ["get"],
},
{
apiGroups: [""],
resources: ["pods"],
verbs: ["list"],
}],
},
} as PartialDeep<V1SelfSubjectRulesReview>,
} as CreateSelfSubjectRulesReviewRes;

const defaultMultipleListPermissions = {
body: {
status: {
resourceRules: [
{
apiGroups: [""],
resources: ["pods"],
verbs: ["get"],
},
{
apiGroups: [""],
resources: ["pods"],
verbs: ["list"],
},
],
},
} as PartialDeep<V1SelfSubjectRulesReview>,
} as CreateSelfSubjectRulesReviewRes;
},
],
},
} as V1SelfSubjectRulesReview;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/

import { type KubeConfig, HttpError } from "@kubernetes/client-node";
import type { KubeConfig } from "@kubernetes/client-node";
import { ApiException } from "@kubernetes/client-node";
import { reaction, comparer, runInAction } from "mobx";
import { ClusterStatus } from "../../common/cluster-types";
import type { CreateListNamespaces } from "../../common/cluster/list-namespaces.injectable";
Expand Down Expand Up @@ -375,10 +376,8 @@ class ClusterConnection {
const ctx = proxyConfig.getContextObject(this.cluster.contextName.get());
const namespaceList = [ctx?.namespace].filter(isDefined);

if (namespaceList.length === 0 && error instanceof HttpError && error.statusCode === 403) {
const { response } = error as HttpError & { response: Response };

this.dependencies.logger.info("[CLUSTER]: listing namespaces is forbidden, broadcasting", { clusterId: this.cluster.id, error: response.body });
if (namespaceList.length === 0 && error instanceof ApiException && error.code === 403) {
this.dependencies.logger.info("[CLUSTER]: listing namespaces is forbidden, broadcasting", { clusterId: this.cluster.id, error: error.body || error.message });
this.dependencies.broadcastMessage(clusterListNamespaceForbiddenChannel, this.cluster.id);
}

Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/main/prometheus/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ export const createPrometheusProvider = ({ getService, ...opts }: CreatePromethe
export async function findFirstNamespacedService(client: CoreV1Api, ...selectors: string[]): Promise<PrometheusServiceInfo> {
try {
for (const selector of selectors) {
const { body: { items: [service] }} = await client.listServiceForAllNamespaces(undefined, undefined, undefined, selector);
const { items: [service] } = await client.listServiceForAllNamespaces({
labelSelector: selector,
});

if (service?.metadata?.namespace && service.metadata.name && service.spec?.ports) {
return {
Expand All @@ -71,7 +73,7 @@ export async function findFirstNamespacedService(client: CoreV1Api, ...selectors

export async function findNamespacedService(client: CoreV1Api, name: string, namespace: string): Promise<PrometheusServiceInfo> {
try {
const { body: service } = await client.readNamespacedService(name, namespace);
const service = await client.readNamespacedService({ name, namespace });

if (!service.metadata?.namespace || !service.metadata.name || !service.spec?.ports) {
throw new Error(`Service found in namespace="${namespace}" did not have required information`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ const getServiceAccountRouteInjectable = getRouteInjectable({
method: "get",
path: `${apiPrefix}/kubeconfig/service-account/{namespace}/{account}`,
})(async ({ params, cluster }) => {
const { namespace, account } = params;
const loadProxyKubeconfig = di.inject(loadProxyKubeconfigInjectable, cluster);
const proxyKubeconfig = await loadProxyKubeconfig();
const client = proxyKubeconfig.makeApiClient(CoreV1Api);
const secretList = await client.listNamespacedSecret(params.namespace);
const { items } = await client.listNamespacedSecret({ namespace });

const secret = secretList.body.items.find(secret => {
const secret = items.find(secret => {
const { annotations = {}} = secret.metadata ?? {};

return annotations["kubernetes.io/service-account.name"] === params.account;
Expand Down Expand Up @@ -63,7 +64,7 @@ const getServiceAccountRouteInjectable = getRouteInjectable({
],
contexts: [
{
name: `${contextName}-${params.account}`,
name: `${contextName}-${account}`,
context: {
user: params.account,
cluster: contextName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ export class NodeShellSession extends ShellSession {

const cleanup = once(() => {
coreApi
.deleteNamespacedPod(this.podName, "kube-system")
.deleteNamespacedPod({
name: this.podName,
namespace: "kube-system",
})
.catch(error => this.dependencies.logger.warn(`[NODE-SHELL]: failed to remove pod shell`, error));
});

Expand Down Expand Up @@ -111,32 +114,35 @@ export class NodeShellSession extends ShellSession {
: undefined;

return coreApi
.createNamespacedPod("kube-system", {
metadata: {
name: this.podName,
namespace: "kube-system",
},
spec: {
nodeName: this.nodeName,
restartPolicy: "Never",
terminationGracePeriodSeconds: 0,
hostPID: true,
hostIPC: true,
hostNetwork: true,
tolerations: [{
operator: "Exists",
}],
priorityClassName: "system-node-critical",
containers: [{
name: "shell",
image: nodeShellImage || initialNodeShellImage,
securityContext: {
privileged: true,
},
command: ["nsenter"],
args: ["-t", "1", "-m", "-u", "-i", "-n", "sleep", "14000"],
}],
imagePullSecrets,
.createNamespacedPod({
namespace: "kube-system",
body: {
metadata: {
name: this.podName,
namespace: "kube-system",
},
spec: {
nodeName: this.nodeName,
restartPolicy: "Never",
terminationGracePeriodSeconds: 0,
hostPID: true,
hostIPC: true,
hostNetwork: true,
tolerations: [{
operator: "Exists",
}],
priorityClassName: "system-node-critical",
containers: [{
name: "shell",
image: nodeShellImage || initialNodeShellImage,
securityContext: {
privileged: true,
},
command: ["nsenter"],
args: ["-t", "1", "-m", "-u", "-i", "-n", "sleep", "14000"],
}],
imagePullSecrets,
},
},
});
}
Expand Down

0 comments on commit f36a966

Please sign in to comment.