Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: resolve eslint warnings (max-statements, complexity) #1486

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 23 additions & 60 deletions src/lib/controller/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
import { mutateProcessor } from "../mutate-processor";
import { validateProcessor } from "../validate-processor";
import { StoreController } from "./store";
import { ResponseItem, AdmissionRequest } from "../types";
import { AdmissionRequest } from "../types";
import { karForMutate, karForValidate, KubeAdmissionReview } from "./index.util";

if (!process.env.PEPR_NODE_WARNINGS) {
process.removeAllListeners("warning");
}

export class Controller {
// Track whether the server is running
#running = false;
Expand Down Expand Up @@ -206,77 +208,38 @@
// Get the request from the body or create an empty request
const request: AdmissionRequest = req.body?.request || ({} as AdmissionRequest);

// Run the before hook if it exists
this.#beforeHook && this.#beforeHook(request || {});

// Setup identifiers for logging
const name = request?.name ? `/${request.name}` : "";
const namespace = request?.namespace || "";
const gvk = request?.kind || { group: "", version: "", kind: "" };

const reqMetadata = {
uid: request.uid,
namespace,
name,
const { name, namespace, gvk } = {

Check warning on line 211 in src/lib/controller/index.ts

View check run for this annotation

Codecov / codecov/patch

src/lib/controller/index.ts#L211

Added line #L211 was not covered by tests
name: request?.name ? `/${request.name}` : "",
namespace: request?.namespace || "",
gvk: request?.kind || { group: "", version: "", kind: "" },
};

const reqMetadata = { uid: request.uid, namespace, name };

Check warning on line 217 in src/lib/controller/index.ts

View check run for this annotation

Codecov / codecov/patch

src/lib/controller/index.ts#L217

Added line #L217 was not covered by tests
Log.info({ ...reqMetadata, gvk, operation: request.operation, admissionKind }, "Incoming request");
Log.debug({ ...reqMetadata, request }, "Incoming request body");

// Process the request
let response: MutateResponse | ValidateResponse[];
// Run the before hook if it exists
this.#beforeHook && this.#beforeHook(request || {});

// Call mutate or validate based on the admission kind
if (admissionKind === "Mutate") {
response = await mutateProcessor(this.#config, this.#capabilities, request, reqMetadata);
} else {
response = await validateProcessor(this.#config, this.#capabilities, request, reqMetadata);
}
// Process the request
const response: MutateResponse | ValidateResponse[] =
admissionKind === "Mutate"
? await mutateProcessor(this.#config, this.#capabilities, request, reqMetadata)
: await validateProcessor(this.#config, this.#capabilities, request, reqMetadata);

Check warning on line 228 in src/lib/controller/index.ts

View check run for this annotation

Codecov / codecov/patch

src/lib/controller/index.ts#L227-L228

Added lines #L227 - L228 were not covered by tests

// Run the after hook if it exists
const responseList: ValidateResponse[] | MutateResponse[] = Array.isArray(response) ? response : [response];
responseList.map(res => {
[response].flat().map(res => {

Check warning on line 231 in src/lib/controller/index.ts

View check run for this annotation

Codecov / codecov/patch

src/lib/controller/index.ts#L231

Added line #L231 was not covered by tests
this.#afterHook && this.#afterHook(res);
// Log the response
Log.info({ ...reqMetadata, res }, "Check response");
});

let kubeAdmissionResponse: ValidateResponse[] | MutateResponse | ResponseItem;

if (admissionKind === "Mutate") {
kubeAdmissionResponse = response;
Log.debug({ ...reqMetadata, response }, "Outgoing response");
res.send({
apiVersion: "admission.k8s.io/v1",
kind: "AdmissionReview",
response: kubeAdmissionResponse,
});
} else {
kubeAdmissionResponse =
responseList.length === 0
? {
uid: request.uid,
allowed: true,
status: { message: "no in-scope validations -- allowed!" },
}
: {
uid: responseList[0].uid,
allowed: responseList.filter(r => !r.allowed).length === 0,
status: {
message: (responseList as ValidateResponse[])
.filter(rl => !rl.allowed)
.map(curr => curr.status?.message)
.join("; "),
},
};
res.send({
apiVersion: "admission.k8s.io/v1",
kind: "AdmissionReview",
response: kubeAdmissionResponse,
});
}

Log.debug({ ...reqMetadata, kubeAdmissionResponse }, "Outgoing response");
const kar: KubeAdmissionReview =
admissionKind === "Mutate"
? karForMutate(response as MutateResponse)
: karForValidate(request, response as ValidateResponse[]);

Check warning on line 239 in src/lib/controller/index.ts

View check run for this annotation

Codecov / codecov/patch

src/lib/controller/index.ts#L238-L239

Added lines #L238 - L239 were not covered by tests

Log.debug({ ...reqMetadata, kubeAdmissionResponse: kar.response }, "Outgoing response");
res.send(kar);

Check warning on line 242 in src/lib/controller/index.ts

View check run for this annotation

Codecov / codecov/patch

src/lib/controller/index.ts#L241-L242

Added lines #L241 - L242 were not covered by tests

this.#metricsCollector.observeEnd(startTime, admissionKind);
} catch (err) {
Expand Down
103 changes: 103 additions & 0 deletions src/lib/controller/index.util.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors

import { describe, it, expect } from "@jest/globals";
import { MutateResponse, ValidateResponse } from "../k8s";
import * as sut from "./index.util";
import { AdmissionRequest } from "../types";

describe("karForMutate()", () => {
it("returns given MutateResponse wrapped in an KubeAdmissionReview", () => {
const mr: MutateResponse = { uid: "uid", allowed: true };
const kar: sut.KubeAdmissionReview = {
apiVersion: "admission.k8s.io/v1",
kind: "AdmissionReview",
response: mr,
};
const result = sut.karForMutate(mr);
expect(result).toEqual(kar);
});
});

describe("karForValidate()", () => {
describe("given 0 ValidationResponse[]'s", () => {
it("returns KubeAdmissionReview with abbreviated success message", () => {
const ar = { uid: "uid" } as unknown as AdmissionRequest;
const vrs: ValidateResponse[] = [];
const resp = {
uid: ar.uid,
allowed: true,
status: { code: 200, message: "no in-scope validations -- allowed!" },
};
const kar: sut.KubeAdmissionReview = {
apiVersion: "admission.k8s.io/v1",
kind: "AdmissionReview",
response: resp,
};
const result = sut.karForValidate(ar, vrs);
expect(result).toEqual(kar);
});
});

describe("given 1-or-more ValidationResponse[]'s", () => {
it("returns KubeAdmissionReview with detailed success message", () => {
const ar = { uid: "uid" } as unknown as AdmissionRequest;
const vrs: ValidateResponse[] = [
{
uid: "uid",
allowed: true,
status: {
code: 200,
message: "msg",
},
},
];
const resp = {
uid: ar.uid,
allowed: true,
status: { code: 200, message: "" },
};
const kar: sut.KubeAdmissionReview = {
apiVersion: "admission.k8s.io/v1",
kind: "AdmissionReview",
response: resp,
};
const result = sut.karForValidate(ar, vrs);
expect(result).toEqual(kar);
});

it("returns KubeAdmissionReview with detailed failure message", () => {
const ar = { uid: "uid" } as unknown as AdmissionRequest;
const vrs: ValidateResponse[] = [
{
uid: "uid",
allowed: false,
status: {
code: 422,
message: "mess",
},
},
{
uid: "uid",
allowed: false,
status: {
code: 422,
message: "age",
},
},
];
const resp = {
uid: ar.uid,
allowed: false,
status: { code: 422, message: "mess; age" },
};
const kar: sut.KubeAdmissionReview = {
apiVersion: "admission.k8s.io/v1",
kind: "AdmissionReview",
response: resp,
};
const result = sut.karForValidate(ar, vrs);
expect(result).toEqual(kar);
});
});
});
47 changes: 47 additions & 0 deletions src/lib/controller/index.util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors

import { MutateResponse, ValidateResponse } from "../k8s";
import { ResponseItem, AdmissionRequest } from "../types";

export interface KubeAdmissionReview {
apiVersion: string;
kind: string;
response: ValidateResponse[] | MutateResponse | ResponseItem;
}

export function karForMutate(mr: MutateResponse): KubeAdmissionReview {
return {
apiVersion: "admission.k8s.io/v1",
kind: "AdmissionReview",
response: mr,
};
}

export function karForValidate(ar: AdmissionRequest, vr: ValidateResponse[]): KubeAdmissionReview {
const isAllowed = vr.filter(r => !r.allowed).length === 0;

const resp: ValidateResponse =
vr.length === 0
? {
uid: ar.uid,
allowed: true,
status: { code: 200, message: "no in-scope validations -- allowed!" },
}
: {
uid: vr[0].uid,
allowed: isAllowed,
status: {
code: isAllowed ? 200 : 422,
message: vr
.filter(rl => !rl.allowed)
.map(curr => curr.status?.message)
.join("; "),
},
};
return {
apiVersion: "admission.k8s.io/v1",
kind: "AdmissionReview",
response: resp,
};
}
Loading