Files
qmi-cloud/server/routes/api-users.js
Manuel Romero 885f2986ef cli
2020-07-27 13:41:50 +02:00

562 lines
15 KiB
JavaScript

const express = require('express')
const router = express.Router()
const db = require('qmi-cloud-common/mongo');
const passport = require('../passport');
const fs = require('fs-extra');
const azurecli = require('qmi-cloud-common/azurecli');
import { queues, TF_APPLY_QUEUE, TF_APPLY_QSEOK_QUEUE, TF_DESTROY_QUEUE } from 'qmi-cloud-common/queues';
/**
* @swagger
* /users:
* get:
* description: Get all users
* summary: Get all users
* tags:
* - admin
* produces:
* - application/json
* responses:
* 200:
* description: User
*/
router.get('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
try {
const result = await db.user.get();
return res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /users/me:
* get:
* description: Get profile logged-in user
* summary: Get logged-in user
* produces:
* - application/json
* responses:
* 200:
* description: User
*/
router.get('/me', passport.ensureAuthenticated, async (req, res, next) => {
try {
const result = await db.user.getById(req.user._id);
return res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /users/{userId}:
* get:
* description: Get profile for an user
* summary: Get profile for an user
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* produces:
* - application/json
* responses:
* 200:
* description: User
*/
router.get('/:userId', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
const result = await db.user.getById(req.params.userId);
return res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /users/{userId}:
* put:
* description: Update profile for an user
* summary: Update profile for an user
* tags:
* - admin
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* - in: body
* name: body
* description: User object
* required: true
* produces:
* - application/json
* responses:
* 200:
* description: User
*/
router.put('/:userId', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
try {
const result = await db.user.update(req.params.userId, req.body);
return res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /users/{userId}/provisions:
* post:
* description: Start a new Terraform provision
* summary: Start a new Terraform provision
* produces:
* - application/json
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* scenario:
* type: string
* description:
* type: string
* vmImage:
* type: object
* properties:
* vm1:
* type: object
* properties:
* vmType:
* type: string
* version:
* type: object
* properties:
* name:
* type: string
* image:
* type: string
* responses:
* 200:
* description: Provision
* 404:
* description: Scenario not found
* 400:
* description: Invalid vmImage
*/
router.post('/:userId/provisions', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
req.body.user = req.params.userId;
const scenarioSource = await db.scenario.getOne({name: req.body.scenario});
if (!scenarioSource) {
return res.status(404).json({"msg": "Scenario not found "});
}
if (!req.body.vmImage || !req.body.vmImage.vm1 || !req.body.vmImage.vm1.vmType ) {
return res.status(400).json({"msg": "Invalid vmImage"});
}
req.body.scenarioVersion = scenarioSource.version;
if ( req.body.autoShutdownData && req.body.autoShutdownData.is24x7 !== undefined ) {
const autoShutdown = await db.provisionAutoShutdown.add(req.body.autoShutdownData);
req.body.autoShutdown = autoShutdown._id;
}
const provision = await db.provision.add(req.body);
if ( provision.scenario === "azqmi-qseok" ){
queues[TF_APPLY_QSEOK_QUEUE].add("tf_apply_qseok_job", {
scenario: req.body.scenario,
vmType: req.body.vmType,
nodeCount: req.body.nodeCount,
id: provision._id,
user: req.user,
_scenario: scenarioSource
});
} else {
queues[TF_APPLY_QUEUE].add("tf_apply_job", {
scenario: req.body.scenario,
vmType: req.body.vmType,
nodeCount: req.body.nodeCount,
id: provision._id,
user: req.user,
_scenario: scenarioSource
});
}
return res.status(200).json(provision);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /users/{userId}/provisions/{id}:
* put:
* description: Update Provision by ID
* summary: Update Provision by ID
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* - name: id
* in: path
* type: string
* required: true
* - in: body
* name: body
* description: Provision object
* required: true
* produces:
* - application/json
* responses:
* 200:
* description: Provision
*/
router.put('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
const provision = await db.provision.getById(req.params.id);
if (!provision){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
}
try {
var resSchedule;
if ( req.body.autoShutdownData ) {
if ( req.body.autoShutdownData._id ) {
resSchedule = await db.provisionAutoShutdown.update(req.body.autoShutdownData._id, req.body.autoShutdownData);
} else {
resSchedule = await db.provisionAutoShutdown.add(req.body.autoShutdownData);
}
var tagsEdit = {
"24x7": resSchedule.is24x7? " " : false,
"StartupTime": resSchedule.utcTagStartupTime || false,
"ShutdownTime": resSchedule.utcTagShutdownTime || false
}
azurecli.updateVmsTags(provision, tagsEdit);
}
var patch = {};
if ( req.body.user ) {
patch.user = req.body.user;
}
if ( resSchedule ) {
patch.autoShutdown = resSchedule._id;
}
var result = {
provision: await db.provision.update(provision._id, patch)
}
return res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /users/{userId}/provisions/{id}:
* delete:
* description: Delete Provision by ID
* summary: Delete a Terraform Provision by ID
* produces:
* - application/json
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* - name: id
* in: path
* type: string
* required: true
* responses:
* 200:
* description: Provision
* 404:
* description: Not found
*
*/
router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
const provision = await db.provision.getById(req.params.id);
if (!provision){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
}
//var delDest = provision.destroy._id;
//if ( provision.destroy ) {
// delDest = await db.destroy.del(provision.destroy._id);
//}
const delProv = await db.provision.update(req.params.id, {"isDeleted": true});
//Move folder
if (fs.existsSync(`/provisions/${provision.scenario}_${req.params.id}`)) {
fs.moveSync(`/provisions/${provision.scenario}_${req.params.id}`, `/provisions/deleted/${provision.scenario}_${req.params.id}`, { overwrite: true })
}
return res.json({"provision": delProv, "destroy": delProv.destroy});
} catch (error) {
next(error);
}
});
/**
* @swagger
* /users/{userId}/provisions/{id}/deallocatevms:
* post:
* description: Stop all VMs for this provision
* summary: Stop all VMs for this provision
* produces:
* - application/json
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* - name: id
* in: path
* type: string
* required: true
* responses:
* 200:
* description: Provision
* 404:
* description: Not found
*
*/
router.post('/:userId/provisions/:id/deallocatevms', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
let provision = await db.provision.getById(req.params.id);
if (!provision){
return res.status(404).json({"msg": "Not found provision with id "+req.params.id});
}
azurecli.deallocate(provision);
return res.json({"statusVms": "Stopping"});
} catch (error) {
db.provision.update(req.params.id, {"statusVms": "Error_Stopping"});
next(error);
}
});
/**
* @swagger
* /users/{userId}/provisions/{id}/startvms:
* post:
* description: Start all VMs for this provision
* summary: Start all VMs for this provision
* produces:
* - application/json
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* - name: id
* in: path
* type: string
* required: true
* responses:
* 200:
* description: Provision
* 404:
* description: Not found
*
*/
router.post('/:userId/provisions/:id/startvms', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
let provision = await db.provision.getById(req.params.id);
if (!provision){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
}
azurecli.start(provision);
return res.json({"statusVms": "Starting"});
} catch (error) {
db.provision.update(req.params.id, {"statusVms": "Error_Starting"});
next(error);
}
});
/**
* @swagger
* /users/{userId}/provisions/{id}/extend:
* post:
* description: Extend this provision Running more time
* summary: Extend this provision Running more time
* produces:
* - application/json
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* - name: id
* in: path
* type: string
* required: true
* responses:
* 200:
* description: Provision
* 404:
* description: Not found
*
*/
router.post('/:userId/provisions/:id/extend', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
let provision = await db.provision.getById(req.params.id);
if (!provision){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
}
/*if ( provision.countExtend === 5 ) {
return res.status(200).json({"msg": "You have reached the limit for the number of times to extend the Running VMs period."});
}*/
let timeRunning = db.utils.getNewTimeRunning(provision);
let countExtend = db.utils.getNewCountExtend(provision);
provision = await db.provision.update(req.params.id, {"runningFrom":new Date(), "timeRunning": timeRunning, "countExtend": countExtend, "pendingNextAction": undefined});
console.log(`Extending running period fo provision (${provision._id}), new total extends: ${countExtend}`);
return res.json(provision);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /users/{userId}/provisions/{id}/destroy:
* post:
* description: Destroy a Terraform Provision
* summary: Destroy a Terraform Provision
* produces:
* - application/json
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* - name: id
* in: path
* type: string
* required: true
* responses:
* 200:
* description: Provision
* 404:
* description: Not found
*
*/
router.post('/:userId/provisions/:id/destroy', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
let provision = await db.provision.getById(req.params.id);
if (!provision){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
}
const destroyJob = await db.destroy.add({ "user": req.params.userId });
provision = await db.provision.update(req.params.id, {"destroy": destroyJob._id});
const scenarioSource = await db.scenario.getOne({name: provision.scenario});
queues[TF_DESTROY_QUEUE].add("tf_destroy_job", {
scenario: provision.scenario,
provId: provision._id,
user: req.user,
id: destroyJob._id,
_scenario: scenarioSource
});
return res.status(200).json(provision);
} catch (error) {
return res.status(error.output.statusCode).json({"err":error});
}
});
/**
* @swagger
* /users/{userId}/provisions:
* get:
* description: Get all Provisions for an User
* summary: Get all Provisions for an User
* produces:
* - application/json
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* responses:
* 200:
* description: JSON Array
*/
router.get('/:userId/provisions', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
const filter = {"user": req.params.userId, "isDeleted": false};
const result = await db.provision.get(filter);
return res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /users/{userId}/destroyprovisions:
* get:
* description: Get all Destroy Provisions for an User
* summary: Get all Destroy Provisions for an User
* produces:
* - application/json
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* responses:
* 200:
* description: JSON Array
*/
router.get('/:userId/destroyprovisions', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
const result = await db.destroy.get({"user": req.params.userId});
return res.json(result);
} catch (error) {
next(error);
}
});
module.exports = router;