Cloudtopiaa_Reseller_Backend/src/controllers/provisioningController.js
2025-07-31 08:15:46 +05:30

357 lines
8.2 KiB
JavaScript

const { Instance, InstanceSnapshot, InstanceEvent, Customer, Product, AuditLog } = require('../models');
const { Op } = require('sequelize');
// Get all instances for reseller
const getInstances = async (req, res) => {
try {
const { page = 1, limit = 20, status, type, customerId, region } = req.query;
const resellerId = req.user.resellerId;
const offset = (page - 1) * limit;
const where = { resellerId };
if (status) where.status = status;
if (type) where.type = type;
if (customerId) where.customerId = customerId;
if (region) where.region = region;
const { count, rows: instances } = await Instance.findAndCountAll({
where,
include: [
{
model: Customer,
as: 'customer',
attributes: ['id', 'companyName', 'contactPerson']
}
],
limit: parseInt(limit),
offset: parseInt(offset),
order: [['createdAt', 'DESC']]
});
res.json({
success: true,
data: {
instances,
pagination: {
total: count,
page: parseInt(page),
pages: Math.ceil(count / limit),
limit: parseInt(limit)
}
}
});
} catch (error) {
console.error('Get instances error:', error);
res.status(500).json({
success: false,
message: 'Failed to fetch instances'
});
}
};
// Create new instance
const createInstance = async (req, res) => {
try {
const {
customerId,
name,
template,
size,
region,
zone,
specifications,
configuration = {},
tags = []
} = req.body;
const resellerId = req.user.resellerId;
// Verify customer belongs to reseller
const customer = await Customer.findOne({
where: { id: customerId, resellerId }
});
if (!customer) {
return res.status(404).json({
success: false,
message: 'Customer not found'
});
}
// Create instance record
const instance = await Instance.create({
customerId,
resellerId,
name,
template,
size,
region,
zone,
specifications,
configuration,
tags,
status: 'pending'
});
// Log creation event
await InstanceEvent.create({
instanceId: instance.id,
eventType: 'created',
status: 'completed',
message: 'Instance created successfully',
triggeredBy: req.user.id,
source: 'user',
startedAt: new Date(),
completedAt: new Date()
});
// Log audit
await AuditLog.create({
userId: req.user.id,
action: 'INSTANCE_CREATED',
resource: 'instance',
resourceId: instance.id,
newValues: instance.toJSON(),
ipAddress: req.ip,
userAgent: req.get('User-Agent')
});
// TODO: Integrate with Cloudtopiaa IaaS API to actually provision the instance
// This would be an async operation that updates the instance status
res.status(201).json({
success: true,
message: 'Instance creation initiated',
data: { instance }
});
} catch (error) {
console.error('Create instance error:', error);
res.status(500).json({
success: false,
message: 'Failed to create instance'
});
}
};
// Start instance
const startInstance = async (req, res) => {
try {
const { instanceId } = req.params;
const resellerId = req.user.resellerId;
const instance = await Instance.findOne({
where: { id: instanceId, resellerId }
});
if (!instance) {
return res.status(404).json({
success: false,
message: 'Instance not found'
});
}
if (!instance.canStart()) {
return res.status(400).json({
success: false,
message: 'Instance cannot be started in current state'
});
}
// Update instance status
await instance.update({ status: 'starting' });
// Log event
await InstanceEvent.create({
instanceId: instance.id,
eventType: 'started',
status: 'in_progress',
message: 'Starting instance',
triggeredBy: req.user.id,
source: 'user',
startedAt: new Date()
});
// TODO: Call Cloudtopiaa IaaS API to start the instance
// This would be an async operation
res.json({
success: true,
message: 'Instance start initiated',
data: { instance }
});
} catch (error) {
console.error('Start instance error:', error);
res.status(500).json({
success: false,
message: 'Failed to start instance'
});
}
};
// Stop instance
const stopInstance = async (req, res) => {
try {
const { instanceId } = req.params;
const resellerId = req.user.resellerId;
const instance = await Instance.findOne({
where: { id: instanceId, resellerId }
});
if (!instance) {
return res.status(404).json({
success: false,
message: 'Instance not found'
});
}
if (!instance.canStop()) {
return res.status(400).json({
success: false,
message: 'Instance cannot be stopped in current state'
});
}
// Update instance status
await instance.update({ status: 'stopping' });
// Log event
await InstanceEvent.create({
instanceId: instance.id,
eventType: 'stopped',
status: 'in_progress',
message: 'Stopping instance',
triggeredBy: req.user.id,
source: 'user',
startedAt: new Date()
});
res.json({
success: true,
message: 'Instance stop initiated',
data: { instance }
});
} catch (error) {
console.error('Stop instance error:', error);
res.status(500).json({
success: false,
message: 'Failed to stop instance'
});
}
};
// Create snapshot
const createSnapshot = async (req, res) => {
try {
const { instanceId } = req.params;
const { name, description, type = 'manual' } = req.body;
const resellerId = req.user.resellerId;
const instance = await Instance.findOne({
where: { id: instanceId, resellerId }
});
if (!instance) {
return res.status(404).json({
success: false,
message: 'Instance not found'
});
}
// Create snapshot record
const snapshot = await InstanceSnapshot.create({
instanceId,
name,
description,
type,
status: 'creating'
});
// Log event
await InstanceEvent.create({
instanceId: instance.id,
eventType: 'snapshot_created',
status: 'in_progress',
message: `Creating snapshot: ${name}`,
triggeredBy: req.user.id,
source: 'user',
startedAt: new Date()
});
res.status(201).json({
success: true,
message: 'Snapshot creation initiated',
data: { snapshot }
});
} catch (error) {
console.error('Create snapshot error:', error);
res.status(500).json({
success: false,
message: 'Failed to create snapshot'
});
}
};
// Get instance events
const getInstanceEvents = async (req, res) => {
try {
const { instanceId } = req.params;
const { page = 1, limit = 20 } = req.query;
const resellerId = req.user.resellerId;
const offset = (page - 1) * limit;
// Verify instance belongs to reseller
const instance = await Instance.findOne({
where: { id: instanceId, resellerId }
});
if (!instance) {
return res.status(404).json({
success: false,
message: 'Instance not found'
});
}
const { count, rows: events } = await InstanceEvent.findAndCountAll({
where: { instanceId },
include: [
{
model: require('../models').User,
as: 'user',
attributes: ['id', 'firstName', 'lastName']
}
],
limit: parseInt(limit),
offset: parseInt(offset),
order: [['createdAt', 'DESC']]
});
res.json({
success: true,
data: {
events,
pagination: {
total: count,
page: parseInt(page),
pages: Math.ceil(count / limit),
limit: parseInt(limit)
}
}
});
} catch (error) {
console.error('Get instance events error:', error);
res.status(500).json({
success: false,
message: 'Failed to fetch instance events'
});
}
};
module.exports = {
getInstances,
createInstance,
startInstance,
stopInstance,
createSnapshot,
getInstanceEvents
};