This commit is contained in:
2026-06-25 16:51:56 -05:00
parent 94f4d8959d
commit 402bf6782a
25 changed files with 1323 additions and 103 deletions

View File

@@ -82,7 +82,7 @@ export async function previewVCenterImport(req, res) {
if (!parsed.success) return res.status(400).json({ error: 'Invalid vCenter preview payload' });
try {
const connection = parsed.data.connectionId ? getVCenterConnection(parsed.data.connectionId, req.user.id, true) : null;
if (parsed.data.connectionId && !connection) return res.status(404).json({ error: 'vCenter connection not found' });
if (parsed.data.connectionId && !connection) return res.status(404).json({ error: 'VMware connection not found' });
res.json(await previewVCenterHosts({ ...parsed.data, connection }));
} catch (err) {
res.status(err.statusCode || 502).json({ error: err.message, trace: err.trace || [] });
@@ -94,7 +94,7 @@ export async function importVCenterHosts(req, res) {
if (!parsed.success) return res.status(400).json({ error: 'Invalid vCenter import payload' });
try {
const connection = parsed.data.connectionId ? getVCenterConnection(parsed.data.connectionId, req.user.id, true) : null;
if (parsed.data.connectionId && !connection) return res.status(404).json({ error: 'vCenter connection not found' });
if (parsed.data.connectionId && !connection) return res.status(404).json({ error: 'VMware connection not found' });
const preview = await previewVCenterHosts({ ...parsed.data, connection });
const selected = new Set(parsed.data.vmIds || []);
const candidates = selected.size
@@ -125,16 +125,16 @@ export function listVCenterConnectionRecords(req, res) {
export function createVCenterConnectionRecord(req, res) {
const parsed = vcenterConnectionSchema.safeParse(req.body);
if (!parsed.success) return res.status(400).json({ error: 'Invalid vCenter connection payload' });
if (!parsed.data.password) return res.status(400).json({ error: 'A vCenter password is required when creating a connection' });
if (!parsed.success) return res.status(400).json({ error: 'Invalid VMware connection payload' });
if (!parsed.data.password) return res.status(400).json({ error: 'A VMware password is required when creating a connection' });
res.status(201).json(createVCenterConnection(parsed.data, req.user.id));
}
export function updateVCenterConnectionRecord(req, res) {
const parsed = vcenterConnectionSchema.safeParse(req.body);
if (!parsed.success) return res.status(400).json({ error: 'Invalid vCenter connection payload' });
if (!parsed.success) return res.status(400).json({ error: 'Invalid VMware connection payload' });
const connection = updateVCenterConnection(req.params.connectionId, parsed.data, req.user.id);
if (!connection) return res.status(404).json({ error: 'vCenter connection not found' });
if (!connection) return res.status(404).json({ error: 'VMware connection not found' });
res.json(connection);
}
@@ -145,7 +145,7 @@ export function deleteVCenterConnectionRecord(req, res) {
export async function testVCenterConnectionRecord(req, res) {
const connection = getVCenterConnection(req.params.connectionId, req.user.id, true);
if (!connection) return res.status(404).json({ error: 'vCenter connection not found' });
if (!connection) return res.status(404).json({ error: 'VMware connection not found' });
try {
const result = await testVCenterConnection(connection);
recordVCenterConnectionTest(req.params.connectionId, 'success', result.message);

View File

@@ -1,4 +1,4 @@
import { folderSchema, scriptTestRunSchema } from '../forms/schemas.js';
import { folderSchema, scriptCompatibilitySchema, scriptTestRunSchema } from '../forms/schemas.js';
import {
cloneScript,
createFolder,
@@ -15,6 +15,7 @@ import {
} from '../models/libraryModel.js';
import { camelJob } from '../models/mappers.js';
import { executeScriptTest } from '../services/powershellRunner.js';
import { analyzeScriptTargetCompatibility } from '../services/powershellCompatibilityService.js';
export function folders(req, res) {
res.json(listFolders(req.user.id));
@@ -84,6 +85,14 @@ export function scriptUsageAction(req, res) {
res.json(usage);
}
export function scriptCompatibilityAction(req, res) {
const parsed = scriptCompatibilitySchema.safeParse(req.body);
if (!parsed.success) return res.status(400).json({ error: 'Invalid compatibility payload' });
const result = analyzeScriptTargetCompatibility(req.params.id, parsed.data, req.user.id);
if (!result) return res.status(404).json({ error: 'Script not found' });
res.json(result);
}
export function testRunScriptAction(req, res) {
const parsed = scriptTestRunSchema.safeParse(req.body);
if (!parsed.success) return res.status(400).json({ error: 'Invalid test run payload' });

View File

@@ -1,6 +1,7 @@
import { camelJob } from '../models/mappers.js';
import { createRunPlan, deleteRunPlan, listRunPlans, loadVisibleRunPlan, updateRunPlan } from '../models/runPlanModel.js';
import { executeRunPlan } from '../services/powershellRunner.js';
import { analyzeRunPlanCompatibility } from '../services/powershellCompatibilityService.js';
export function index(req, res) {
res.json(listRunPlans(req.user.id));
@@ -37,3 +38,9 @@ export function execute(req, res) {
res.status(400).json({ error: error.message });
}
}
export function compatibility(req, res) {
const result = analyzeRunPlanCompatibility(req.params.id, req.user.id);
if (!result) return res.status(404).json({ error: 'RunPlan not found' });
res.json(result);
}