mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-14 02:47:00 +00:00
276 lines
6.1 KiB
JavaScript
276 lines
6.1 KiB
JavaScript
const express = require("express");
|
|
const { body, validationResult } = require("express-validator");
|
|
const { getPrismaClient } = require("../config/prisma");
|
|
const { randomUUID } = require("node:crypto");
|
|
const { authenticateToken } = require("../middleware/auth");
|
|
const { requireManageHosts } = require("../middleware/permissions");
|
|
|
|
const router = express.Router();
|
|
const prisma = getPrismaClient();
|
|
|
|
// Get all host groups
|
|
router.get("/", authenticateToken, async (_req, res) => {
|
|
try {
|
|
const hostGroups = await prisma.host_groups.findMany({
|
|
include: {
|
|
_count: {
|
|
select: {
|
|
host_group_memberships: true,
|
|
},
|
|
},
|
|
},
|
|
orderBy: {
|
|
name: "asc",
|
|
},
|
|
});
|
|
|
|
// Transform the count field to match frontend expectations
|
|
const transformedGroups = hostGroups.map((group) => ({
|
|
...group,
|
|
_count: {
|
|
hosts: group._count.host_group_memberships,
|
|
},
|
|
}));
|
|
|
|
res.json(transformedGroups);
|
|
} catch (error) {
|
|
console.error("Error fetching host groups:", error);
|
|
res.status(500).json({ error: "Failed to fetch host groups" });
|
|
}
|
|
});
|
|
|
|
// Get a specific host group by ID
|
|
router.get("/:id", authenticateToken, async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
const hostGroup = await prisma.host_groups.findUnique({
|
|
where: { id },
|
|
include: {
|
|
host_group_memberships: {
|
|
include: {
|
|
hosts: {
|
|
select: {
|
|
id: true,
|
|
friendly_name: true,
|
|
hostname: true,
|
|
ip: true,
|
|
os_type: true,
|
|
os_version: true,
|
|
status: true,
|
|
last_update: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!hostGroup) {
|
|
return res.status(404).json({ error: "Host group not found" });
|
|
}
|
|
|
|
res.json(hostGroup);
|
|
} catch (error) {
|
|
console.error("Error fetching host group:", error);
|
|
res.status(500).json({ error: "Failed to fetch host group" });
|
|
}
|
|
});
|
|
|
|
// Create a new host group
|
|
router.post(
|
|
"/",
|
|
authenticateToken,
|
|
requireManageHosts,
|
|
[
|
|
body("name").trim().isLength({ min: 1 }).withMessage("Name is required"),
|
|
body("description").optional().trim(),
|
|
body("color")
|
|
.optional()
|
|
.isHexColor()
|
|
.withMessage("Color must be a valid hex color"),
|
|
],
|
|
async (req, res) => {
|
|
try {
|
|
const errors = validationResult(req);
|
|
if (!errors.isEmpty()) {
|
|
return res.status(400).json({ errors: errors.array() });
|
|
}
|
|
|
|
const { name, description, color } = req.body;
|
|
|
|
// Check if host group with this name already exists
|
|
const existingGroup = await prisma.host_groups.findUnique({
|
|
where: { name },
|
|
});
|
|
|
|
if (existingGroup) {
|
|
return res
|
|
.status(400)
|
|
.json({ error: "A host group with this name already exists" });
|
|
}
|
|
|
|
const hostGroup = await prisma.host_groups.create({
|
|
data: {
|
|
id: randomUUID(),
|
|
name,
|
|
description: description || null,
|
|
color: color || "#3B82F6",
|
|
updated_at: new Date(),
|
|
},
|
|
});
|
|
|
|
res.status(201).json(hostGroup);
|
|
} catch (error) {
|
|
console.error("Error creating host group:", error);
|
|
res.status(500).json({ error: "Failed to create host group" });
|
|
}
|
|
},
|
|
);
|
|
|
|
// Update a host group
|
|
router.put(
|
|
"/:id",
|
|
authenticateToken,
|
|
requireManageHosts,
|
|
[
|
|
body("name").trim().isLength({ min: 1 }).withMessage("Name is required"),
|
|
body("description").optional().trim(),
|
|
body("color")
|
|
.optional()
|
|
.isHexColor()
|
|
.withMessage("Color must be a valid hex color"),
|
|
],
|
|
async (req, res) => {
|
|
try {
|
|
const errors = validationResult(req);
|
|
if (!errors.isEmpty()) {
|
|
return res.status(400).json({ errors: errors.array() });
|
|
}
|
|
|
|
const { id } = req.params;
|
|
const { name, description, color } = req.body;
|
|
|
|
// Check if host group exists
|
|
const existingGroup = await prisma.host_groups.findUnique({
|
|
where: { id },
|
|
});
|
|
|
|
if (!existingGroup) {
|
|
return res.status(404).json({ error: "Host group not found" });
|
|
}
|
|
|
|
// Check if another host group with this name already exists
|
|
const duplicateGroup = await prisma.host_groups.findFirst({
|
|
where: {
|
|
name,
|
|
id: { not: id },
|
|
},
|
|
});
|
|
|
|
if (duplicateGroup) {
|
|
return res
|
|
.status(400)
|
|
.json({ error: "A host group with this name already exists" });
|
|
}
|
|
|
|
const hostGroup = await prisma.host_groups.update({
|
|
where: { id },
|
|
data: {
|
|
name,
|
|
description: description || null,
|
|
color: color || "#3B82F6",
|
|
updated_at: new Date(),
|
|
},
|
|
});
|
|
|
|
res.json(hostGroup);
|
|
} catch (error) {
|
|
console.error("Error updating host group:", error);
|
|
res.status(500).json({ error: "Failed to update host group" });
|
|
}
|
|
},
|
|
);
|
|
|
|
// Delete a host group
|
|
router.delete(
|
|
"/:id",
|
|
authenticateToken,
|
|
requireManageHosts,
|
|
async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
// Check if host group exists
|
|
const existingGroup = await prisma.host_groups.findUnique({
|
|
where: { id },
|
|
include: {
|
|
_count: {
|
|
select: {
|
|
host_group_memberships: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!existingGroup) {
|
|
return res.status(404).json({ error: "Host group not found" });
|
|
}
|
|
|
|
// If host group has memberships, remove them first
|
|
if (existingGroup._count.host_group_memberships > 0) {
|
|
await prisma.host_group_memberships.deleteMany({
|
|
where: { host_group_id: id },
|
|
});
|
|
}
|
|
|
|
await prisma.host_groups.delete({
|
|
where: { id },
|
|
});
|
|
|
|
res.json({ message: "Host group deleted successfully" });
|
|
} catch (error) {
|
|
console.error("Error deleting host group:", error);
|
|
res.status(500).json({ error: "Failed to delete host group" });
|
|
}
|
|
},
|
|
);
|
|
|
|
// Get hosts in a specific group
|
|
router.get("/:id/hosts", authenticateToken, async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
const hosts = await prisma.hosts.findMany({
|
|
where: {
|
|
host_group_memberships: {
|
|
some: {
|
|
host_group_id: id,
|
|
},
|
|
},
|
|
},
|
|
select: {
|
|
id: true,
|
|
friendly_name: true,
|
|
ip: true,
|
|
os_type: true,
|
|
os_version: true,
|
|
architecture: true,
|
|
status: true,
|
|
last_update: true,
|
|
created_at: true,
|
|
},
|
|
orderBy: {
|
|
friendly_name: "asc",
|
|
},
|
|
});
|
|
|
|
res.json(hosts);
|
|
} catch (error) {
|
|
console.error("Error fetching hosts in group:", error);
|
|
res.status(500).json({ error: "Failed to fetch hosts in group" });
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|