webhook
This commit is contained in:
12
gitlab-ci.sh
12
gitlab-ci.sh
@@ -3,10 +3,12 @@ echo "--- Building QMI Cloud docker images for branch $CI_COMMIT_REF_NAME"
|
||||
export VERSION_APP=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]')
|
||||
export VERSION_WORKER=$(cat qmi-cloud-worker/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]')
|
||||
export VERSION_CLI=$(cat qmi-cloud-cli/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]')
|
||||
export VERSION_WEBHOOK=$(cat qmi-cloud-webhook/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]')
|
||||
|
||||
export TAG_APP=$VERSION_APP
|
||||
export TAG_WORKER=$VERSION_WORKER
|
||||
export TAG_CLI=$VERSION_CLI
|
||||
export TAG_WEBHOOK=$VERSION_WEBHOOK
|
||||
export STABLE_TAG="latest"
|
||||
export BUILD_ENV=""
|
||||
|
||||
@@ -14,6 +16,7 @@ if [ "$CI_COMMIT_REF_NAME" != "master" ]; then
|
||||
TAG_APP="$VERSION_APP-$CI_COMMIT_REF_NAME"
|
||||
TAG_WORKER="$VERSION_WORKER-$CI_COMMIT_REF_NAME"
|
||||
TAG_CLI="$VERSION_CLI-$CI_COMMIT_REF_NAME"
|
||||
TAG_WEBHOOK="$VERSION_WEBHOOK-$CI_COMMIT_REF_NAME"
|
||||
STABLE_TAG="latestdev"
|
||||
BUILD_ENV="staging"
|
||||
fi
|
||||
@@ -44,3 +47,12 @@ docker push qlikgear/qmi-cloud-app:$TAG_APP
|
||||
docker image tag qlikgear/qmi-cloud-app:$TAG_APP qlikgear/qmi-cloud-app:$STABLE_TAG
|
||||
#docker build -f ./Dockerfile -t qlikgear/qmi-cloud-app:$STABLE_TAG ./
|
||||
docker push qlikgear/qmi-cloud-app:$STABLE_TAG
|
||||
|
||||
|
||||
echo "--- Building image: qlikgear/qmi-cloud-webhook:$TAG_WEBHOOK"
|
||||
docker build -f ./qmi-cloud-webhook/Dockerfile -t qlikgear/qmi-cloud-webhook:$TAG_WEBHOOK ./
|
||||
echo "--- Pushing image: qlikgear/qmi-cloud-webhook:$TAG_WEBHOOK"
|
||||
docker push qlikgear/qmi-cloud-webhook:$TAG_WEBHOOK
|
||||
docker image tag qlikgear/qmi-cloud-webhook:$TAG_WEBHOOK qlikgear/qmi-cloud-webhook:$STABLE_TAG
|
||||
#docker build -f ./qmi-cloud-webhook/Dockerfile -t qlikgear/qmi-cloud-webhook:$STABLE_TAG ./
|
||||
docker push qlikgear/qmi-cloud-webhook:$STABLE_TAG
|
||||
|
||||
20
qmi-cloud-webhook/Dockerfile
Normal file
20
qmi-cloud-webhook/Dockerfile
Normal file
@@ -0,0 +1,20 @@
|
||||
# Stage 1:
|
||||
FROM node:20.14-alpine AS sources
|
||||
|
||||
RUN apk --no-cache add yarn git
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ADD ./qmi-cloud-webhook ./
|
||||
ADD ./qmi-cloud-common ../qmi-cloud-common
|
||||
|
||||
RUN yarn install --production
|
||||
|
||||
# Stage 2:
|
||||
FROM node:20.14-alpine AS production
|
||||
WORKDIR /app
|
||||
COPY --from=sources /app ./
|
||||
|
||||
EXPOSE 5050
|
||||
|
||||
CMD ["node", "index.js"]
|
||||
84
qmi-cloud-webhook/app.js
Normal file
84
qmi-cloud-webhook/app.js
Normal file
@@ -0,0 +1,84 @@
|
||||
'use strict'
|
||||
/* dependencies */
|
||||
const express = require('express');
|
||||
const NodeCache = require( "node-cache" );
|
||||
const TRIGGER_STATUS = process.env.TRIGGER_STATUS || "Stopped";
|
||||
const LOGEVENT_NAME = process.env.LOGEVENT_NAME || "AzureWebhook";
|
||||
const SERVICE_NAME = process.env.SERVICE_NAME || "QMI Automation";
|
||||
|
||||
const processEvent = require('./process-event');
|
||||
|
||||
// Create an Express application.
|
||||
const app = express();
|
||||
|
||||
const myCache = new NodeCache( { stdTTL: 300 } ); //5 minutes cache
|
||||
|
||||
// Add body parser.
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
|
||||
// Add routers
|
||||
app.post('/', (req, res) => {
|
||||
|
||||
var now = new Date();
|
||||
now = now.toISOString();
|
||||
|
||||
const event = req.body;
|
||||
|
||||
if ( event.data && event.data.context && event.data.context.activityLog ) {
|
||||
var rgName = event.data.context.activityLog.resourceGroupName;
|
||||
|
||||
var provId = rgName.split("-")[rgName.split("-").length-1];
|
||||
var sendData = {
|
||||
"provID": provId,
|
||||
"rgName": rgName,
|
||||
"cloudName": SERVICE_NAME,
|
||||
"instanceState": TRIGGER_STATUS,
|
||||
"logEvent": LOGEVENT_NAME
|
||||
};
|
||||
|
||||
|
||||
if ( !myCache.get( provId ) ) {
|
||||
|
||||
myCache.set(provId, sendData);
|
||||
|
||||
console.log(`${now}# ProvId (${provId}). Sending '${sendData.instanceState}' to QMICLOUD (${process.env.QMICLOUD_API_URL})...`, sendData);
|
||||
|
||||
processEvent.onEvent(sendData);
|
||||
|
||||
|
||||
/*axios({
|
||||
method: 'post',
|
||||
url: process.env.QMICLOUD_API_URL,
|
||||
headers: { 'QMI-ApiKey' : process.env.QMICLOUD_KEY },
|
||||
data: sendData
|
||||
}).then(function (response) {
|
||||
myCache.set(provId, sendData);
|
||||
}).catch(function(err){
|
||||
myCache.del(provId);
|
||||
console.log('Error# ', err);
|
||||
});*/
|
||||
|
||||
} else {
|
||||
console.log(`${now}# ProvId (${provId}) recently sent. Won't be sent again.`);
|
||||
}
|
||||
|
||||
}
|
||||
res.json(event);
|
||||
})
|
||||
|
||||
app.post('/test', (req, res) => {
|
||||
console.log("Calling /test POST endpoint");
|
||||
res.send("OK");
|
||||
});
|
||||
|
||||
app.use((req, res, next) => res.send("404"))
|
||||
app.use((err, req, res, next) => {
|
||||
console.error(err)
|
||||
if (res.headerSent) return next(err)
|
||||
return res.send("500")
|
||||
})
|
||||
|
||||
|
||||
module.exports = app;
|
||||
|
||||
11
qmi-cloud-webhook/index.js
Normal file
11
qmi-cloud-webhook/index.js
Normal file
@@ -0,0 +1,11 @@
|
||||
let port = process.env.PORT || 5050;
|
||||
|
||||
const app = require('./app');
|
||||
|
||||
// Start listening for requests.
|
||||
app.listen(port, ()=>{
|
||||
console.log("Server is running on port ", port);
|
||||
});
|
||||
|
||||
process.on('uncaughtException', err => console.error('uncaught exception:', err.toString()));
|
||||
process.on('unhandledRejection', error => console.error('unhandled rejection:', error.toString()));
|
||||
14
qmi-cloud-webhook/package.json
Normal file
14
qmi-cloud-webhook/package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "qmi-cloud-webhook",
|
||||
"version": "1.0.0",
|
||||
"description": "qmi-cloud-webhook",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node ./index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.19.2",
|
||||
"node-cache": "^5.1.2",
|
||||
"qmi-cloud-common": "../qmi-cloud-common"
|
||||
}
|
||||
}
|
||||
132
qmi-cloud-webhook/process-event.js
Normal file
132
qmi-cloud-webhook/process-event.js
Normal file
@@ -0,0 +1,132 @@
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const MYQUEUES = require('qmi-cloud-common/queues');
|
||||
const queues = MYQUEUES.queues;
|
||||
const SYNAPSE_QUEUE = MYQUEUES.SYNAPSE_QUEUE;
|
||||
|
||||
const onEvent = async function (event) {
|
||||
|
||||
const dateNow = new Date();
|
||||
const now = dateNow.toISOString();
|
||||
const logEvent = event && event.logEvent || 'DivvyCloud';
|
||||
|
||||
try {
|
||||
|
||||
if (event.cloudName === 'QMI Automation') {
|
||||
|
||||
console.log(`${logEvent} (${now})# event received for subscription (${event.cloudName}) - provision (${event.provID}) -> new status (${event.instanceState})`);
|
||||
|
||||
if (event.provID && event.provID !== 'None') {
|
||||
|
||||
let provision = await db.provision.getById(event.provID);
|
||||
|
||||
if (provision) {
|
||||
|
||||
var type = "vms";
|
||||
if (logEvent.indexOf("RDS") !== -1) {
|
||||
type = "db";
|
||||
}
|
||||
|
||||
let id = provision._id.toString();
|
||||
|
||||
console.log(`${logEvent} (${now})# provision (${id}) - scenario is (${provision.scenario} - v${provision.scenarioVersion})`);
|
||||
|
||||
if (provision.status === 'provisioned' || provision.status === 'error') {
|
||||
|
||||
if (event.instanceState === 'Stopped') {
|
||||
|
||||
//Check active children provisions
|
||||
let children = await db.provision.get({ "parent": provision._id, "isDestroyed": false, "isDeleted": false });
|
||||
if (children.results.length > 0) {
|
||||
let result = await db.apiKey.getOne({ "apiKey": process.env.QMICLOUD_KEY });
|
||||
var user;
|
||||
if (result) {
|
||||
user = result.user;
|
||||
}
|
||||
children.results.forEach(function (child) {
|
||||
if (child.scenario === 'azqmi-synapse') {
|
||||
queues[SYNAPSE_QUEUE].add("synapse_job", {
|
||||
provId: child._id,
|
||||
user: user,
|
||||
tasktype: 'pause'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (provision.statusVms === 'Stopped') {
|
||||
console.log(`${logEvent} (${now})# provision (${id}) - were already Stopped!`);
|
||||
} else {
|
||||
|
||||
let timeRunning = db.utils.getNewTimeRunning(provision);
|
||||
let patch = {
|
||||
"statusVms": "Stopped",
|
||||
"timeRunning": timeRunning,
|
||||
"stoppedFrom": dateNow,
|
||||
"pendingNextAction": null
|
||||
};
|
||||
|
||||
if (provision.schedule && !provision.schedule.is24x7) {
|
||||
patch["endDateOnSchedule"] = dateNow;
|
||||
|
||||
//This is temporary, only to make sure there is value
|
||||
if (!provision["startDateOnSchedule"]) {
|
||||
patch["startDateOnSchedule"] = dateNow;
|
||||
}
|
||||
}
|
||||
|
||||
await db.provision.update(id, patch);
|
||||
console.log(`${logEvent} (${now})# provision (${id}) - changed to Stopped!`);
|
||||
db.event.add({ provision: provision._id, type: `${type}.stop`, message: `[Divvy] TotalTimeRunning: ${timeRunning} mins` });
|
||||
}
|
||||
|
||||
} else if (event.instanceState === 'Running') {
|
||||
|
||||
if (provision.statusVms === 'Running') {
|
||||
console.log(`${logEvent} (${now})# provision (${id}) - were already Running!`);
|
||||
} else {
|
||||
let patch = {
|
||||
"statusVms": "Running",
|
||||
"runningFrom": dateNow,
|
||||
"pendingNextAction": null
|
||||
};
|
||||
|
||||
// This is temporary, only to make sure there are values soon
|
||||
if (provision.schedule && !provision.schedule.is24x7) {
|
||||
if (!provision["startDateOnSchedule"]) {
|
||||
patch["startDateOnSchedule"] = dateNow;
|
||||
patch["endDateOnSchedule"] = dateNow;
|
||||
}
|
||||
}
|
||||
|
||||
await db.provision.update(id, patch);
|
||||
console.log(`${logEvent} (${now})# provision (${id}) - changed to Running!`);
|
||||
|
||||
db.event.add({ provision: provision._id, type: `${type}.start`, message: `[Divvy] TotalTimeRunning: ${provision.timeRunning} mins` });
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log(`${logEvent} (${now})# provision (${event.provID}) - Scenario not yet 'provisioned'`);
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log(`${logEvent} (${now})# provision (${event.provID}) - Provision not found.`);
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log(`${logEvent} (${now})# 'provID' attribute is missing.`);
|
||||
}
|
||||
|
||||
} else {
|
||||
//console.log(`${logEvent} (${now}): event received for subscription (${event.cloudName}) --> won't be processed`);
|
||||
}
|
||||
|
||||
return res.json(event);
|
||||
|
||||
} catch (error) {
|
||||
console.log(`${logEvent} (${now})# error!!!!`, error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports.onEvent = onEvent;
|
||||
2659
qmi-cloud-webhook/yarn.lock
Normal file
2659
qmi-cloud-webhook/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user