/
MessageIngestion.js
96 lines (84 loc) · 3.86 KB
/
MessageIngestion.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import {KubernetesCommand} from "../dto/KubernetesCommand.js";
export class MessageIngestion {
constructor(appConfig) {
this.actions = {
DEPLOYMENT: "deploy",
SCALE: "scale"
};
this.botName = appConfig.botName;
this.botToken = appConfig.botToken;
}
async determineCommand(event) {
const message = await this._fetchMessage(event);
return this._interpret(message);
}
async _fetchMessage(event) {
const res = await fetch("https://webexapis.com/v1/messages/" + event.data.id, {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${this.botToken}`
},
method: "GET"
});
const messageData = await res.json();
if(!messageData.text) {
throw new Error("Could not fetch message content.");
}
return messageData.text;
}
_interpret(rawMessageText) {
const messageText = this._stripBotName(rawMessageText);
switch (true) {
case messageText.toLowerCase().startsWith(this.actions.DEPLOYMENT):
// example: "Deploy some/tag:version to deploymentName"
this._validateDeploymentMessage(messageText);
return this._buildDeploymentRequest(messageText);
break;
case messageText.toLowerCase().startsWith(this.actions.SCALE):
// example: "Scale deploymentName-name to X"
this._validateScaleMessage(messageText);
return this._buildScaleRequest(messageText);
break;
default:
throw new Error(`Could not interpret ChatOps command. Please start your message with one of the following: ${Object.values(this.actions).join(", ")} after tagging the bot name ${this.botName}`);
}
}
_stripBotName(str) {
const filteredArray = str.split(' ').filter(x => x !== this.botName);
return filteredArray.join(' ');
}
_validateDeploymentMessage(str) {
const strs = str.split(" ");
if (strs.length !== 4) throw new Error(`Expecting a string in the following format: "Deploy some/tag:version to deployment-name"`);
if (strs[1].indexOf(":") === -1) throw new Error(`Expecting a string in the following format: "Deploy some/tag:version to deployment-name"; received a malformed image tag/version: ${strs[1]}`);
if (strs[2] !== "to") throw new Error(`Expecting a string in the following format: "Deploy some/tag:version to deployment-name"`);
}
_validateScaleMessage(str) {
const strs = str.split(" ");
if (strs.length !== 4) throw new Error(`Expecting a string in the following format: "Scale deployment-name to X"`);
if (isNaN(parseInt(strs[3]))) throw new Error(`Expecting a numerical value for the scale target "X", in the following format: "Scale deployment-name to X"; received ${strs[3]} instead.`)
}
_fetchImageTag(str) {
const strs = str.split(" ");
return strs[1];
}
_fetchDeploymentName(str, type) {
const targetIndex = type === this.actions.DEPLOYMENT ? 3 : 1;
const strs = str.split(" ");
return strs[targetIndex];
}
_fetchNumOfInstances(str) {
const strs = str.split(" ");
return parseInt(strs[3]);
}
_buildDeploymentRequest(str) {
const imageTag = this._fetchImageTag(str);
const deployment = this._fetchDeploymentName(str, this.actions.DEPLOYMENT);
return new KubernetesCommand({type: this.actions.DEPLOYMENT, imageTag, deployment});
}
_buildScaleRequest(str) {
const deploymentName = this._fetchDeploymentName(str, this.actions.SCALE);
const scaleTarget = this._fetchNumOfInstances(str);
return new KubernetesCommand({type: this.actions.SCALE, scaleTarget, deploymentName});
}
}