Files
patchmon.net/backend/src/routes/hostGroupRoutes.js
2025-09-20 10:56:59 +01:00

227 lines
5.8 KiB
JavaScript

const express = require('express');
const { body, validationResult } = require('express-validator');
const { PrismaClient } = require('@prisma/client');
const { authenticateToken } = require('../middleware/auth');
const { requireManageHosts } = require('../middleware/permissions');
const router = express.Router();
const prisma = new PrismaClient();
// Get all host groups
router.get('/', authenticateToken, async (req, res) => {
try {
const hostGroups = await prisma.hostGroup.findMany({
include: {
_count: {
select: {
hosts: true
}
}
},
orderBy: {
name: 'asc'
}
});
res.json(hostGroups);
} 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.hostGroup.findUnique({
where: { id },
include: {
hosts: {
select: {
id: true,
friendlyName: true,
hostname: true,
ip: true,
osType: true,
osVersion: true,
status: true,
lastUpdate: 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.hostGroup.findUnique({
where: { name }
});
if (existingGroup) {
return res.status(400).json({ error: 'A host group with this name already exists' });
}
const hostGroup = await prisma.hostGroup.create({
data: {
name,
description: description || null,
color: color || '#3B82F6'
}
});
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.hostGroup.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.hostGroup.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.hostGroup.update({
where: { id },
data: {
name,
description: description || null,
color: color || '#3B82F6'
}
});
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.hostGroup.findUnique({
where: { id },
include: {
_count: {
select: {
hosts: true
}
}
}
});
if (!existingGroup) {
return res.status(404).json({ error: 'Host group not found' });
}
// Check if host group has hosts
if (existingGroup._count.hosts > 0) {
return res.status(400).json({
error: 'Cannot delete host group that contains hosts. Please move or remove hosts first.'
});
}
await prisma.hostGroup.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.host.findMany({
where: { hostGroupId: id },
select: {
id: true,
friendlyName: true,
ip: true,
osType: true,
osVersion: true,
architecture: true,
status: true,
lastUpdate: true,
createdAt: true
},
orderBy: {
friendlyName: '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;