Files
qmi-cloud/qmi-cloud-common/mongo.js
Manuel Romero f62f0b8253 snapshots stuff
2025-02-11 11:44:20 +01:00

494 lines
14 KiB
JavaScript

const mongoose = require('mongoose');
const boom = require('@hapi/boom');
console.log("--- MongoDB connecting... ", process.env.MONGO_URI);
// Connect to DB
mongoose.connect(process.env.MONGO_URI);
// When successfully connected
mongoose.connection.on('connected', () => {
console.log('--- MongoDB connected');
});
// When successfully reconnected
mongoose.connection.on('reconnected', () => {
console.log('--- MongoDB dbevent: reconnected');
});
// If the connection throws an error
mongoose.connection.on('error', (err) => {
console.log(`--- MongoDB dbevent: error: ${err}`);
//console.log(`Retry mongo connect`);
//mongoose.connect(process.env.MONGO_URI, options);
});
// Get Data Models
const Scenario = require('./models/Scenario');
const Schedule = require('./models/Schedule');
const Provision = require('./models/Provision');
const Destroy = require('./models/Destroy');
const User = require('./models/User');
const VmType = require('./models/VmType');
const ApiKey = require('./models/ApiKey');
const Notification = require('./models/Notification');
const Subscription = require('./models/Subscription');
const Event = require('./models/Event');
const SharedProvision = require('./models/SharedProvision');
const TrainingTemplate = require('./models/TrainingTemplate');
const TrainingSession = require('./models/TrainingSession');
const TrainingStudent = require('./models/TrainingStudent');
const Webhook = require('./models/Webhook');
const Snapshot = require('./models/Snapshot');
const getNewCountExtend = function(provision) {
return provision.countExtend !== undefined? (provision.countExtend + 1) : 1;
};
const getNewTimeRunning = function (provision) {
let timeRunning = provision.timeRunning !== undefined? provision.timeRunning : 0; //minutes
if ( provision.statusVms === 'Stopped' ) {
return timeRunning;
} else {
let runningFrom = provision.runningFrom? new Date(provision.runningFrom).getTime() : new Date(provision.created).getTime();
let diffMinutes = Math.abs(new Date().getTime() - runningFrom)/1000/60;
let minutesFromLastRunning = Math.floor(diffMinutes);
return Math.floor(minutesFromLastRunning + timeRunning);
}
};
const getPage = async ( model, filter, page, populates, select ) => {
var sort = {};
var modelAttributes = Object.keys(model.schema.tree);
if ( modelAttributes.indexOf("created") !== -1) {
sort = {created: -1};
}
try {
var exec = model.find(filter, select).sort(sort);
var totalDocs = await model.countDocuments(filter);
var isPage = false;
if ( page && page.page > 0 && page.size !== undefined ) {
var skip = 0;
skip = (page.page - 1) * page.size;
exec = exec.skip(skip);
exec = exec.limit(page.size);
isPage = true;
}
if ( populates ) {
populates = JSON.parse(populates);
populates.forEach(p=> {
exec = exec.populate(p);
});
} else {
if ( model === Provision ) {
exec = exec.populate({ path: 'user', select: 'displayName upn'}).populate({path:'destroy', select: "-user -jobId"}).populate({path:'_scenarioDoc', select: "-availableProductVersions -updated -created"}).populate({path: "schedule"}).populate('deployOpts');
}
if ( model === SharedProvision ) {
exec = exec.populate('provision').populate({path: 'sharedWithUser', select: 'displayName upn oid active'}).populate({path: 'user', select: 'displayName upn'});
}
if ( model === ApiKey ) {
exec = exec.populate('user');
}
if ( model === Webhook ) {
exec = exec.populate('owner');
}
if ( model === Scenario ) {
exec = exec.populate('subscription').populate('deployOpts');
}
if ( model === Event ) {
exec = exec.populate({path: 'user', select: 'displayName'});
}
if ( model === TrainingSession ) {
exec = exec.populate('user').populate('template');
}
}
const entity = await exec;
var out = {
total: totalDocs,
count: entity.length,
results: entity
}
if ( isPage && (page.page * page.size < totalDocs)) {
out.next = {
page: page.page + 1,
size: page.size
};
}
return out;
} catch (err) {
throw boom.boomify(err)
}
};
const get = async (model, filter, select, skip, limit, populates, reply) => {
var sort = {};
var modelAttributes = Object.keys(model.schema.tree);
if ( model === Scenario ) {
if ( modelAttributes.indexOf("updated") !== -1) {
sort.updated = -1;
}
}
if ( modelAttributes.indexOf("created") !== -1) {
sort.created = -1;
}
try {
var exec = model.find(filter, select).sort(sort);
var totalDocs = await model.countDocuments(filter);
skip = skip? parseInt(skip) : 0;
exec = exec.skip(skip);
if ( limit ) {
limit = parseInt(limit);
exec = exec.limit(limit);
}
if ( populates ) {
populates = JSON.parse(populates);
populates.forEach(p=> {
exec = exec.populate(p);
});
} else {
if ( model === Provision ) {
exec = exec.populate({ path: 'user', select: 'displayName upn'}).populate({path:'destroy', select: "-user -jobId"}).populate({path:'_scenarioDoc', select: "-availableProductVersions -updated -created"}).populate({path: "schedule"}).populate('deployOpts');
}
if ( model === SharedProvision ) {
exec = exec.populate({path:'provision', populate: [{
path: 'schedule',
},{
path: '_scenarioDoc',
select: "-availableProductVersions -updated -created"
},{
path: 'destroy',
select: "-user -jobId"
}]}).populate({path: 'sharedWithUser', select: 'displayName upn oid active'}).populate({path: 'user', select: 'displayName upn'});
}
if ( model === ApiKey ) {
exec = exec.populate('user');
}
if ( model === Webhook ) {
exec = exec.populate('owner');
}
if ( model === Scenario ) {
exec = exec.populate('subscription').populate('deployOpts').populate('allowedUsers');
}
if ( model === Event ) {
exec = exec.populate({path: 'user', select: 'displayName'});
}
if ( model === TrainingSession ) {
exec = exec.populate('user').populate('template');
}
}
const entity = await exec;
var out = {
total: totalDocs,
count: entity.length,
results: entity
}
if ( limit && (skip + limit) < totalDocs) {
out.nextSkip = skip+limit;
out.nextLimit = limit;
}
return out;
} catch (err) {
throw boom.boomify(err)
}
}
const getById = async (model, id, populates, reply) => {
try {
var exec = model.findById(id);
if (populates){
populates.forEach(p=> {
exec = exec.populate(p);
});
} else {
if ( model === Provision ) {
exec = exec.populate('user').populate('destroy').populate('_scenarioDoc').populate("schedule").populate('deployOpts');
}
if ( model === SharedProvision ) {
exec = exec.populate('provision').populate({path: 'sharedWithUser', select: 'displayName upn oid active'}).populate({path: 'user', select: 'displayName upn'});
}
if ( model === ApiKey ) {
exec = exec.populate('user');
}
if ( model === Webhook ) {
exec = exec.populate('owner');
}
if ( model === Scenario ) {
exec = exec.populate('subscription').populate('deployOpts').populate('allowedUsers');
}
if ( model === Event ) {
exec = exec.populate({path: 'user', select: 'displayName'});
}
if ( model === TrainingSession ) {
exec = exec.populate('user').populate('template');
}
if ( model === Snapshot ) {
exec = exec.populate('owner').populate('provision');
}
}
const entity = await exec;
return entity;
} catch (err) {
throw boom.boomify(err);
}
};
const getOne = async (model, filter, populates, reply) => {
try {
var exec = model.findOne(filter);
if (populates){
populates.forEach(p=> {
exec = exec.populate(p);
});
} else {
if ( model === Provision ) {
exec = exec.populate('user').populate('destroy').populate('_scenarioDoc').populate("schedule").populate('deployOpts');
}
if ( model === SharedProvision ) {
exec = exec.populate('provision').populate({path: 'sharedWithUser', select: 'displayName upn oid active'}).populate({path: 'user', select: 'displayName upn'});
}
if ( model === ApiKey ) {
exec = exec.populate('user');
}
if ( model === Webhook ) {
exec = exec.populate('owner');
}
if ( model === Scenario ) {
exec = exec.populate('subscription').populate('deployOpts').populate('allowedUsers');
}
if ( model === Event ) {
exec = exec.populate({path: 'user', select: 'displayName'});
}
if ( model === TrainingSession ) {
exec = exec.populate('user').populate('template');
}
if ( model === Snapshot ) {
exec = exec.populate('owner').populate('provision');
}
}
const entity = await exec;
return entity;
} catch (err) {
throw boom.boomify(err);
}
};
const add = async (model, data, reply) => {
try {
const entity = new model(data)
return entity.save();
} catch (err) {
throw boom.boomify(err);
}
};
const update = async (model, id, body, reply) => {
try {
const { ...updateData } = body;
updateData.updated = new Date();
//console.log("UPDATE", id, updateData);
var exec = model.findByIdAndUpdate(id, updateData, { new: true });
if ( model === Provision ) {
exec = exec.populate('user').populate('destroy').populate('_scenarioDoc').populate("schedule").populate('deployOpts');
}
if ( model === SharedProvision ) {
exec = exec.populate('provision').populate({path: 'sharedWithUser', select: 'displayName upn oid active'}).populate({path: 'user', select: 'displayName upn'});
}
if ( model === ApiKey ) {
exec = exec.populate('user');
}
if ( model === Webhook ) {
exec = exec.populate('owner');
}
if ( model === Scenario ) {
exec = exec.populate('subscription').populate('deployOpts');
}
if ( model === TrainingSession ) {
exec = exec.populate('user').populate('template');
}
if ( model === Snapshot ) {
exec = exec.populate('owner').populate('provision');
}
const update = await exec;
return update;
} catch (err) {
throw boom.boomify(err)
}
};
const updateMany = async (model, filter, body, reply) => {
try {
const { ...updateData } = body;
updateData.updated = new Date();
var exec = model.updateMany(filter, updateData);
if ( model === Provision ) {
exec = exec.populate('user').populate('destroy').populate('_scenarioDoc').populate("schedule").populate('deployOpts');
}
if ( model === SharedProvision ) {
exec = exec.populate('provision').populate({path: 'sharedWithUser', select: 'displayName upn oid active'}).populate({path: 'user', select: 'displayName upn'});
}
if ( model === ApiKey ) {
exec = exec.populate('user');
}
if ( model === Webhook ) {
exec = exec.populate('owner');
}
if ( model === Scenario ) {
exec = exec.populate('subscription').populate('deployOpts');
}
if ( model === TrainingSession ) {
exec = exec.populate('user').populate('template');
}
if ( model === Snapshot ) {
exec = exec.populate('owner').populate('provision');
}
return await exec;
} catch (err) {
throw boom.boomify(err)
}
};
const del = async (model, id, reply) => {
try {
return await model.findByIdAndDelete(id);
} catch (err) {
throw boom.boomify(err)
}
}
const delMany = async(model, filter, reply) => {
try {
return await model.deleteMany(filter);
} catch (err) {
throw boom.boomify(err)
}
}
const count = async (model, filter, reply) => {
try {
var totalDocs = await model.countDocuments(filter);
return totalDocs;
} catch (err) {
throw boom.boomify(err)
}
}
function _m(model) {
return {
get: async (filter, select, skip, limit, populates, reply) => {
return get(model, filter, select, skip, limit, populates, reply);
},
getPage: async (filter, page, populates, select, reply) => {
return getPage(model, filter, page, populates, select, reply);
},
getById: async (id, populates, reply) => {
return getById(model, id, populates, reply);
},
getOne: async (filter, populates, reply)=> {
return getOne(model, filter, populates, reply);
},
add: async (data, reply) => {
return add(model, data, reply);
},
update: async (id, data, reply) => {
return update(model, id, data, reply);
},
updateMany: async(filter, data, reply) => {
return updateMany(model, filter, data, reply);
},
del: async (id, reply) => {
return del(model, id, reply);
},
count: async (filter, reply) => {
return count(model, filter, reply);
},
delMany: async(filter, reply) => {
return delMany(model, filter, reply);
}
}
}
module.exports = {
schedule: _m(Schedule),
provision: _m(Provision),
destroy: _m(Destroy),
scenario: _m(Scenario),
vmtype: _m(VmType),
apiKey: _m(ApiKey),
notification: _m(Notification),
subscription: _m(Subscription),
event: _m(Event),
user: _m(User),
sharedProvision: _m(SharedProvision),
trainingSession: _m(TrainingSession),
trainingTemplate: _m(TrainingTemplate),
trainingStudent: _m(TrainingStudent),
webhook: _m(Webhook),
snapshot: _m(Snapshot),
utils: {
getNewTimeRunning: getNewTimeRunning,
getNewCountExtend: getNewCountExtend
},
mongoose: mongoose,
models: {
Provision: Provision,
Destroy: Destroy,
Scenario: Scenario,
User: User,
Schedule: Schedule,
VmType: VmType,
Notification: Notification,
ApiKey: ApiKey,
Subscription: Subscription,
Event: Event,
SharedProvision: SharedProvision,
TrainingSession: TrainingSession,
TrainingTemplate: TrainingTemplate,
TrainingStudent: TrainingStudent,
Webhook: Webhook,
Snapshot: Snapshot,
}
};