Skip to content

Commit 61651e5

Browse files
Refactor Kubernetes client and volume handling
- Removed the hashUtil module and its usage in volume name generation. - Simplified volume mount and volume generation logic in deployment and PVC manifests. - Updated generatePV and generatePVC functions to eliminate unnecessary parameters and hash calculations. - Adjusted k8sManifests to streamline volume handling without deploymentName and uniqueId. - Cleaned up code for better readability and maintainability.
1 parent d3d3316 commit 61651e5

20 files changed

Lines changed: 1276 additions & 2269 deletions

api/package-lock.json

Lines changed: 715 additions & 500 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
"license": "ISC",
1414
"type": "commonjs",
1515
"dependencies": {
16-
"@kubernetes/client-node": "^1.3.0",
1716
"axios": "^1.9.0",
1817
"bcryptjs": "^3.0.2",
1918
"cookie-parser": "^1.4.7",

api/src/controllers/application/applyApplication.controller.ts

Lines changed: 19 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,17 @@
11
import { Request, Response } from "express";
22
import fs from "fs";
33
import path from "path";
4-
import yaml from "js-yaml";
4+
import { exec as execCb } from "child_process";
5+
import { promisify } from "util";
56
import Application from "../../models/application.model";
67
import asyncHandler from "../../utils/handlers/asyncHandler";
78
import generateK8sManifests from "../../utils/k8s/k8sManifests";
89
import log, { formatNotification } from "../../utils/logging/logger";
910
import type IApplication from "../../types/application.types";
1011
import type { Document } from "mongoose";
1112
import env from "../../config/env";
12-
import k8sClient from "../../utils/k8s/client";
13-
14-
/**
15-
* Safely parse and apply YAML content to Kubernetes
16-
*/
17-
async function applyYamlContent(
18-
yamlContent: string,
19-
description?: string
20-
): Promise<void> {
21-
// Skip empty or whitespace-only content
22-
if (!yamlContent || yamlContent.trim() === "") {
23-
if (description) {
24-
log({
25-
type: "info",
26-
message: `Skipping empty ${description} - no content to apply`,
27-
});
28-
}
29-
return;
30-
}
3113

32-
try {
33-
// Parse YAML to JavaScript object
34-
const resource = yaml.load(yamlContent) as any;
35-
36-
// Skip if parsing resulted in null or empty object
37-
if (!resource || typeof resource !== "object") {
38-
if (description) {
39-
log({
40-
type: "info",
41-
message: `Skipping ${description} - no valid resource found`,
42-
});
43-
}
44-
return;
45-
}
46-
47-
// Apply the parsed resource
48-
await k8sClient.applyResource(resource);
49-
} catch (error) {
50-
const errorMsg = `Failed to apply ${description || "YAML content"}`;
51-
log({
52-
type: "error",
53-
message: errorMsg,
54-
meta: { error, content: yamlContent },
55-
});
56-
throw new Error(
57-
`${errorMsg}: ${error instanceof Error ? error.message : "Unknown error"}`
58-
);
59-
}
60-
}
14+
const exec = promisify(execCb);
6115

6216
function writeManifestFiles(
6317
appDir: string,
@@ -77,68 +31,31 @@ async function applyManifestSequence(
7731
res: Response
7832
) {
7933
try {
80-
// Apply namespace first using secure Kubernetes client
81-
const namespaceContent = fs.readFileSync(
82-
path.join(appDir, "namespace.yaml"),
83-
"utf8"
84-
);
85-
await applyYamlContent(namespaceContent, "namespace");
34+
// Apply namespace first
35+
await exec(`kubectl apply -f namespace.yaml`, { cwd: appDir });
8636

8737
// Apply PVs first if present
8838
if (fs.existsSync(path.join(appDir, "pvs.yaml"))) {
89-
const pvsContent = fs.readFileSync(path.join(appDir, "pvs.yaml"), "utf8");
90-
await applyYamlContent(pvsContent, "persistent volumes");
39+
await exec(`kubectl apply -f pvs.yaml`, { cwd: appDir });
9140
}
9241

9342
// Apply PVCs next if present
9443
if (fs.existsSync(path.join(appDir, "pvcs.yaml"))) {
95-
const pvcsContent = fs.readFileSync(
96-
path.join(appDir, "pvcs.yaml"),
97-
"utf8"
98-
);
99-
await applyYamlContent(pvcsContent, "persistent volume claims");
44+
await exec(`kubectl apply -f pvcs.yaml`, { cwd: appDir });
10045
}
10146

102-
// Apply secret using secure client
103-
const secretContent = fs.readFileSync(
104-
path.join(appDir, "secret.yaml"),
105-
"utf8"
106-
);
107-
await applyYamlContent(secretContent, "secret");
108-
109-
// Apply image pull secret if present
47+
await exec(`kubectl apply -f secret.yaml`, { cwd: appDir });
11048
if (fs.existsSync(path.join(appDir, "imagepullsecret.yaml"))) {
111-
const imagePullSecretContent = fs.readFileSync(
112-
path.join(appDir, "imagepullsecret.yaml"),
113-
"utf8"
114-
);
115-
await applyYamlContent(imagePullSecretContent, "image pull secret");
49+
await exec(`kubectl apply -f imagepullsecret.yaml`, { cwd: appDir });
11650
}
117-
118-
// Apply remaining manifests
119-
const results = [];
120-
for (const filename of manifestFiles) {
121-
if (
122-
filename !== "namespace.yaml" &&
123-
filename !== "pvs.yaml" &&
124-
filename !== "pvcs.yaml" &&
125-
filename !== "secret.yaml" &&
126-
filename !== "imagepullsecret.yaml"
127-
) {
128-
const filePath = path.join(appDir, filename);
129-
if (fs.existsSync(filePath)) {
130-
const content = fs.readFileSync(filePath, "utf8");
131-
await applyYamlContent(content, filename);
132-
results.push({ file: filename, status: "applied" });
133-
}
134-
}
135-
}
136-
51+
const { stdout } = await exec(
52+
`kubectl apply -f . --prune -l app=${appName} --field-manager=application-controller`,
53+
{ cwd: appDir }
54+
);
13755
log({ type: "success", message: `Application applied: ${appName}` });
13856
res.json({
13957
...formatNotification("Application applied", "success"),
140-
output: `Successfully applied ${results.length} resources`,
141-
results,
58+
output: stdout,
14259
});
14360
} catch (err: any) {
14461
log({ type: "error", message: "Failed to apply manifests", meta: err });
@@ -152,7 +69,7 @@ async function applyManifestSequence(
15269
}
15370
res.status(500).json({
15471
...formatNotification("Failed to apply manifests", "error"),
155-
error: err.message,
72+
error: err.stderr || err.message,
15673
manifests,
15774
});
15875
}
@@ -229,22 +146,18 @@ const applyApplication = asyncHandler(async (req: Request, res: Response) => {
229146
}
230147
}
231148

232-
// Apply namespace first using secure client
233-
const namespaceContent = fs.readFileSync(
234-
path.join(appDir, "namespace.yaml"),
235-
"utf8"
236-
);
237-
await applyYamlContent(namespaceContent, "namespace");
149+
// Apply namespace first
150+
await exec(`kubectl apply -f namespace.yaml`, { cwd: appDir });
238151

239152
// Apply PVs first if present
240153
if (manifestsResult.pvs) {
241154
fs.writeFileSync(path.join(appDir, "pvs.yaml"), manifestsResult.pvs);
242-
await applyYamlContent(manifestsResult.pvs, "persistent volumes");
155+
await exec(`kubectl apply -f pvs.yaml`, { cwd: appDir });
243156
}
244157

245158
// Apply PVCs next if present
246159
if (pvcsYaml) {
247-
await applyYamlContent(pvcsYaml, "persistent volume claims");
160+
await exec(`kubectl apply -f pvcs.yaml`, { cwd: appDir });
248161
}
249162

250163
// Now apply the rest (deployment, service, ingress, secrets, etc.)

0 commit comments

Comments
 (0)