cisco-perfmon 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +68 -0
- package/main.js +856 -0
- package/package.json +30 -0
- package/test/tests.js +108 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 Jeremy Worden
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Cisco RisPort Library
|
|
2
|
+
|
|
3
|
+
Simple library to pull Perfmon stats from a Cisco CUCM via SOAP.
|
|
4
|
+
|
|
5
|
+
Perfmon information can be found at
|
|
6
|
+
[PerfMon API Reference](https://developer.cisco.com/docs/sxml/#!perfmon-api-reference).
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
Using npm:
|
|
11
|
+
|
|
12
|
+
```javascript
|
|
13
|
+
npm i -g npm
|
|
14
|
+
npm i --save cisco-perfmon
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
This package uses the built in Fetch API of Node. This feature was first introduced in Node v16.15.0. You may need to enable expermential vm module. Also you can disable warnings with an optional enviromental variable.
|
|
20
|
+
|
|
21
|
+
Also if you are using self signed certificates on Cisco VOS products you may need to disable TLS verification. This makes TLS, and HTTPS by extension, insecure. The use of this environment variable is strongly discouraged. Please only do this in a lab enviroment.
|
|
22
|
+
|
|
23
|
+
Suggested enviromental variables:
|
|
24
|
+
|
|
25
|
+
```env
|
|
26
|
+
NODE_OPTIONS=--experimental-vm-modules
|
|
27
|
+
NODE_NO_WARNINGS=1
|
|
28
|
+
NODE_TLS_REJECT_UNAUTHORIZED=0
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
Note: Rather than use string with backslashes i.e. "\\cucm3\Cisco CallManager\CallsActive", opted to pass these via JSON to the functions. See below:
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
const perfMonService = require("../main");
|
|
37
|
+
|
|
38
|
+
// Set up new PerfMon service
|
|
39
|
+
let service = new perfMonService(
|
|
40
|
+
"10.10.20.1",
|
|
41
|
+
"administrator",
|
|
42
|
+
"ciscopsdt"
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
var counterObj = {
|
|
46
|
+
host: "cucm01-pub",
|
|
47
|
+
object: "Cisco CallManager",
|
|
48
|
+
counter: "CallsActive",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
console.log("Let's get a description of our counter.");
|
|
52
|
+
service
|
|
53
|
+
.queryCounterDescription(counterObj)
|
|
54
|
+
.then((results) => {
|
|
55
|
+
console.log("queryCounterDescription", results);
|
|
56
|
+
})
|
|
57
|
+
.catch((error) => {
|
|
58
|
+
console.log(error);
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Examples
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
npm run test
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Note: Test are using Cisco's DevNet sandbox information. Find more information here: [Cisco DevNet](https://devnetsandbox.cisco.com/)
|
package/main.js
ADDED
|
@@ -0,0 +1,856 @@
|
|
|
1
|
+
const util = require("util");
|
|
2
|
+
const parseString = require("xml2js").parseString;
|
|
3
|
+
const stripPrefix = require("xml2js").processors.stripPrefix;
|
|
4
|
+
|
|
5
|
+
var XML_ADD_COUNTER_ENVELOPE = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.cisco.com/ast/soap">
|
|
6
|
+
<soapenv:Header/>
|
|
7
|
+
<soapenv:Body>
|
|
8
|
+
<soap:perfmonAddCounter>
|
|
9
|
+
<soap:SessionHandle>%s</soap:SessionHandle>
|
|
10
|
+
<soap:ArrayOfCounter>%s</soap:ArrayOfCounter>
|
|
11
|
+
</soap:perfmonAddCounter>
|
|
12
|
+
</soapenv:Body>
|
|
13
|
+
</soapenv:Envelope>`;
|
|
14
|
+
|
|
15
|
+
var XML_CLOSE_SESSION_ENVELOPE = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.cisco.com/ast/soap">
|
|
16
|
+
<soapenv:Header/>
|
|
17
|
+
<soapenv:Body>
|
|
18
|
+
<soap:perfmonCloseSession>
|
|
19
|
+
<soap:SessionHandle>%s</soap:SessionHandle>
|
|
20
|
+
</soap:perfmonCloseSession>
|
|
21
|
+
</soapenv:Body>
|
|
22
|
+
</soapenv:Envelope>`;
|
|
23
|
+
|
|
24
|
+
var XML_COLLECT_COUNTER_ENVELOPE = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.cisco.com/ast/soap">
|
|
25
|
+
<soapenv:Header/>
|
|
26
|
+
<soapenv:Body>
|
|
27
|
+
<soap:perfmonCollectCounterData>
|
|
28
|
+
<soap:Host>%s</soap:Host>
|
|
29
|
+
<soap:Object>%s</soap:Object>
|
|
30
|
+
</soap:perfmonCollectCounterData>
|
|
31
|
+
</soapenv:Body>
|
|
32
|
+
</soapenv:Envelope>`;
|
|
33
|
+
|
|
34
|
+
var XML_COLLECT_SESSION_ENVELOPE = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.cisco.com/ast/soap">
|
|
35
|
+
<soapenv:Header/>
|
|
36
|
+
<soapenv:Body>
|
|
37
|
+
<soap:perfmonCollectSessionData>
|
|
38
|
+
<soap:SessionHandle>%s</soap:SessionHandle>
|
|
39
|
+
</soap:perfmonCollectSessionData>
|
|
40
|
+
</soapenv:Body>
|
|
41
|
+
</soapenv:Envelope>`;
|
|
42
|
+
|
|
43
|
+
var XML_LIST_COUNTER_ENVELOPE = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.cisco.com/ast/soap">
|
|
44
|
+
<soapenv:Header/>
|
|
45
|
+
<soapenv:Body>
|
|
46
|
+
<soap:perfmonListCounter>
|
|
47
|
+
<soap:Host>%s</soap:Host>
|
|
48
|
+
</soap:perfmonListCounter>
|
|
49
|
+
</soapenv:Body>
|
|
50
|
+
</soapenv:Envelope>`;
|
|
51
|
+
|
|
52
|
+
var XML_LIST_INSTANCE_ENVELOPE = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.cisco.com/ast/soap">
|
|
53
|
+
<soapenv:Header/>
|
|
54
|
+
<soapenv:Body>
|
|
55
|
+
<soap:perfmonListInstance>
|
|
56
|
+
<soap:Host>%s</soap:Host>
|
|
57
|
+
<soap:Object>%s</soap:Object>
|
|
58
|
+
</soap:perfmonListInstance>
|
|
59
|
+
</soapenv:Body>
|
|
60
|
+
</soapenv:Envelope>`;
|
|
61
|
+
|
|
62
|
+
var XML_OPEN_SESSION_ENVELOPE = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.cisco.com/ast/soap">
|
|
63
|
+
<soapenv:Header/>
|
|
64
|
+
<soapenv:Body>
|
|
65
|
+
<soap:perfmonOpenSession/>
|
|
66
|
+
</soapenv:Body>
|
|
67
|
+
</soapenv:Envelope>`;
|
|
68
|
+
|
|
69
|
+
var XML_QUERY_COUNTER_ENVELOPE = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.cisco.com/ast/soap">
|
|
70
|
+
<soapenv:Header/>
|
|
71
|
+
<soapenv:Body>
|
|
72
|
+
<soap:perfmonQueryCounterDescription>%s</soap:perfmonQueryCounterDescription>
|
|
73
|
+
</soapenv:Body>
|
|
74
|
+
</soapenv:Envelope>`;
|
|
75
|
+
|
|
76
|
+
var XML_REMOVE_COUNTER_ENVELOPE = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.cisco.com/ast/soap">
|
|
77
|
+
<soapenv:Header/>
|
|
78
|
+
<soapenv:Body>
|
|
79
|
+
<soap:perfmonRemoveCounter>
|
|
80
|
+
<soap:SessionHandle>%s</soap:SessionHandle>
|
|
81
|
+
<soap:ArrayOfCounter>%s</soap:ArrayOfCounter>
|
|
82
|
+
</soap:perfmonRemoveCounter>
|
|
83
|
+
</soapenv:Body>
|
|
84
|
+
</soapenv:Envelope>`;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Cisco Perfmon Service
|
|
88
|
+
* This is a service class that uses fetch and promises to pull Perfmon data from Cisco CUCM
|
|
89
|
+
*
|
|
90
|
+
*
|
|
91
|
+
* @class perfMonService
|
|
92
|
+
*/
|
|
93
|
+
class perfMonService {
|
|
94
|
+
constructor(host, username, password) {
|
|
95
|
+
this._OPTIONS = {
|
|
96
|
+
method: "POST",
|
|
97
|
+
headers: {
|
|
98
|
+
Authorization:
|
|
99
|
+
"Basic " + Buffer.from(username + ":" + password).toString("base64"),
|
|
100
|
+
"Content-Type": "text/xml;charset=UTF-8",
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
this._HOST = host;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Post Fetch using Cisco PerfMon API
|
|
107
|
+
*
|
|
108
|
+
* @collectCounterData
|
|
109
|
+
var service = new perfMonService();
|
|
110
|
+
service.collectCounterData().then((success => {
|
|
111
|
+
console.log(success);
|
|
112
|
+
}))
|
|
113
|
+
* @memberof perfMonService
|
|
114
|
+
* @returns {promise} returns a Promise
|
|
115
|
+
*/
|
|
116
|
+
collectCounterData(host, object) {
|
|
117
|
+
var XML;
|
|
118
|
+
var options = this._OPTIONS;
|
|
119
|
+
options.SOAPAction = `perfmonCollectCounterData`;
|
|
120
|
+
var server = this._HOST;
|
|
121
|
+
|
|
122
|
+
XML = util.format(XML_COLLECT_COUNTER_ENVELOPE, host, object);
|
|
123
|
+
|
|
124
|
+
var soapBody = Buffer.from(XML);
|
|
125
|
+
options.body = soapBody;
|
|
126
|
+
|
|
127
|
+
return new Promise((resolve, reject) => {
|
|
128
|
+
// We fetch the API endpoint
|
|
129
|
+
fetch(
|
|
130
|
+
`https://${server}:8443/perfmonservice2/services/PerfmonService/`,
|
|
131
|
+
options
|
|
132
|
+
)
|
|
133
|
+
.then(async (response) => {
|
|
134
|
+
// console.log(response.body);
|
|
135
|
+
var data = []; // create an array to save chunked data from server
|
|
136
|
+
// response.body is a ReadableStream
|
|
137
|
+
const reader = response.body.getReader();
|
|
138
|
+
for await (const chunk of readChunks(reader)) {
|
|
139
|
+
data.push(Buffer.from(chunk));
|
|
140
|
+
}
|
|
141
|
+
var buffer = Buffer.concat(data); // create buffer of data
|
|
142
|
+
let xmlOutput = buffer.toString("binary").trim();
|
|
143
|
+
let output = await parseXml(xmlOutput);
|
|
144
|
+
// Remove unnecessary keys
|
|
145
|
+
removeKeys(output, "$");
|
|
146
|
+
|
|
147
|
+
if (keyExists(output, "perfmonCollectCounterDataReturn")) {
|
|
148
|
+
var returnResults =
|
|
149
|
+
output.Body.perfmonCollectCounterDataResponse
|
|
150
|
+
.perfmonCollectCounterDataReturn;
|
|
151
|
+
if (returnResults) {
|
|
152
|
+
var newOutput;
|
|
153
|
+
if (Array.isArray(returnResults)) {
|
|
154
|
+
newOutput = returnResults.map((item) => {
|
|
155
|
+
let arr = item.Name.split("\\").filter((element) => element);
|
|
156
|
+
return {
|
|
157
|
+
host: arr[0],
|
|
158
|
+
object: arr[1],
|
|
159
|
+
counter: arr[2],
|
|
160
|
+
value: item.Value,
|
|
161
|
+
cstatus: item.CStatus,
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
} else {
|
|
165
|
+
let arr = returnResults.Name.split("\\").filter(
|
|
166
|
+
(element) => element
|
|
167
|
+
);
|
|
168
|
+
newOutput = {
|
|
169
|
+
host: arr[0],
|
|
170
|
+
object: arr[1],
|
|
171
|
+
counter: arr[2],
|
|
172
|
+
value: returnResults.Value,
|
|
173
|
+
cstatus: returnResults.CStatus,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
resolve(clean(newOutput));
|
|
177
|
+
} else {
|
|
178
|
+
reject(output.Body.Fault);
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
reject({ response: "empty" });
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
.catch((error) => {
|
|
185
|
+
reject(error);
|
|
186
|
+
}); // catches the error and logs it
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Post Fetch using Cisco PerfMon API
|
|
191
|
+
*
|
|
192
|
+
* @collectSessionData
|
|
193
|
+
var service = new perfMonService();
|
|
194
|
+
service.collectSessionData().then((success => {
|
|
195
|
+
console.log(success);
|
|
196
|
+
}))
|
|
197
|
+
* @memberof perfMonService
|
|
198
|
+
* @returns {promise} returns a Promise
|
|
199
|
+
*/
|
|
200
|
+
collectSessionData(SessionHandle) {
|
|
201
|
+
var XML;
|
|
202
|
+
var options = this._OPTIONS;
|
|
203
|
+
options.SOAPAction = `perfmonCollectSessionData`;
|
|
204
|
+
var server = this._HOST;
|
|
205
|
+
|
|
206
|
+
XML = util.format(XML_COLLECT_SESSION_ENVELOPE, SessionHandle);
|
|
207
|
+
|
|
208
|
+
var soapBody = Buffer.from(XML);
|
|
209
|
+
options.body = soapBody;
|
|
210
|
+
|
|
211
|
+
return new Promise((resolve, reject) => {
|
|
212
|
+
// We fetch the API endpoint
|
|
213
|
+
fetch(
|
|
214
|
+
`https://${server}:8443/perfmonservice2/services/PerfmonService/`,
|
|
215
|
+
options
|
|
216
|
+
)
|
|
217
|
+
.then(async (response) => {
|
|
218
|
+
// console.log(response.body);
|
|
219
|
+
var data = []; // create an array to save chunked data from server
|
|
220
|
+
// response.body is a ReadableStream
|
|
221
|
+
const reader = response.body.getReader();
|
|
222
|
+
for await (const chunk of readChunks(reader)) {
|
|
223
|
+
data.push(Buffer.from(chunk));
|
|
224
|
+
}
|
|
225
|
+
var buffer = Buffer.concat(data); // create buffer of data
|
|
226
|
+
let xmlOutput = buffer.toString("binary").trim();
|
|
227
|
+
let output = await parseXml(xmlOutput);
|
|
228
|
+
// Remove unnecessary keys
|
|
229
|
+
removeKeys(output, "$");
|
|
230
|
+
|
|
231
|
+
if (keyExists(output, "perfmonCollectSessionDataReturn")) {
|
|
232
|
+
var returnResults =
|
|
233
|
+
output.Body.perfmonCollectSessionDataResponse
|
|
234
|
+
.perfmonCollectSessionDataReturn;
|
|
235
|
+
|
|
236
|
+
if (returnResults) {
|
|
237
|
+
var newOutput;
|
|
238
|
+
if (Array.isArray(returnResults)) {
|
|
239
|
+
newOutput = returnResults.map((item) => {
|
|
240
|
+
let arr = item.Name.split("\\").filter((element) => element);
|
|
241
|
+
return {
|
|
242
|
+
host: arr[0],
|
|
243
|
+
object: arr[1],
|
|
244
|
+
counter: arr[2],
|
|
245
|
+
value: item.Value,
|
|
246
|
+
cstatus: item.CStatus,
|
|
247
|
+
};
|
|
248
|
+
});
|
|
249
|
+
} else {
|
|
250
|
+
let arr = returnResults.Name.split("\\").filter(
|
|
251
|
+
(element) => element
|
|
252
|
+
);
|
|
253
|
+
newOutput = {
|
|
254
|
+
host: arr[0],
|
|
255
|
+
object: arr[1],
|
|
256
|
+
counter: arr[2],
|
|
257
|
+
value: returnResults.Value,
|
|
258
|
+
cstatus: returnResults.CStatus,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
resolve(clean(newOutput));
|
|
262
|
+
} else {
|
|
263
|
+
reject(output.Body.Fault);
|
|
264
|
+
}
|
|
265
|
+
} else {
|
|
266
|
+
reject({ response: "empty" });
|
|
267
|
+
}
|
|
268
|
+
})
|
|
269
|
+
.catch((error) => {
|
|
270
|
+
reject(error);
|
|
271
|
+
}); // catches the error and logs it
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Post Fetch using Cisco PerfMon API
|
|
276
|
+
*
|
|
277
|
+
* @listCounter
|
|
278
|
+
var service = new perfMonService();
|
|
279
|
+
service.listCounter().then((success => {
|
|
280
|
+
console.log(success);
|
|
281
|
+
}))
|
|
282
|
+
* @memberof perfMonService
|
|
283
|
+
* @returns {promise} returns a Promise
|
|
284
|
+
*/
|
|
285
|
+
listCounter(host) {
|
|
286
|
+
var XML;
|
|
287
|
+
var options = this._OPTIONS;
|
|
288
|
+
options.SOAPAction = `perfmonListCounter`;
|
|
289
|
+
var server = this._HOST;
|
|
290
|
+
|
|
291
|
+
XML = util.format(XML_LIST_COUNTER_ENVELOPE, host);
|
|
292
|
+
|
|
293
|
+
var soapBody = Buffer.from(XML);
|
|
294
|
+
options.body = soapBody;
|
|
295
|
+
|
|
296
|
+
return new Promise((resolve, reject) => {
|
|
297
|
+
// We fetch the API endpoint
|
|
298
|
+
fetch(
|
|
299
|
+
`https://${server}:8443/perfmonservice2/services/PerfmonService/`,
|
|
300
|
+
options
|
|
301
|
+
)
|
|
302
|
+
.then(async (response) => {
|
|
303
|
+
var data = []; // create an array to save chunked data from server
|
|
304
|
+
// response.body is a ReadableStream
|
|
305
|
+
const reader = response.body.getReader();
|
|
306
|
+
for await (const chunk of readChunks(reader)) {
|
|
307
|
+
data.push(Buffer.from(chunk));
|
|
308
|
+
}
|
|
309
|
+
var buffer = Buffer.concat(data); // create buffer of data
|
|
310
|
+
let xmlOutput = buffer.toString("binary").trim();
|
|
311
|
+
let output = await parseXml(xmlOutput);
|
|
312
|
+
// Remove unnecessary keys
|
|
313
|
+
removeKeys(output, "$");
|
|
314
|
+
|
|
315
|
+
if (keyExists(output, "perfmonListCounterReturn")) {
|
|
316
|
+
var returnResults =
|
|
317
|
+
output.Body.perfmonListCounterResponse.perfmonListCounterReturn;
|
|
318
|
+
|
|
319
|
+
if (returnResults) {
|
|
320
|
+
resolve(clean(returnResults));
|
|
321
|
+
} else {
|
|
322
|
+
reject(output.Body.Fault);
|
|
323
|
+
}
|
|
324
|
+
} else {
|
|
325
|
+
reject({ response: "empty" });
|
|
326
|
+
}
|
|
327
|
+
})
|
|
328
|
+
.catch((error) => {
|
|
329
|
+
reject(error);
|
|
330
|
+
}); // catches the error and logs it
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Post Fetch using Cisco PerfMon API
|
|
335
|
+
*
|
|
336
|
+
* @listInstance
|
|
337
|
+
var service = new perfMonService();
|
|
338
|
+
service.listInstance().then((success => {
|
|
339
|
+
console.log(success);
|
|
340
|
+
}))
|
|
341
|
+
* @memberof perfMonService
|
|
342
|
+
* @returns {promise} returns a Promise
|
|
343
|
+
*/
|
|
344
|
+
listInstance(host, object) {
|
|
345
|
+
var XML;
|
|
346
|
+
var options = this._OPTIONS;
|
|
347
|
+
options.SOAPAction = `perfmonListInstance`;
|
|
348
|
+
var server = this._HOST;
|
|
349
|
+
|
|
350
|
+
XML = util.format(XML_LIST_INSTANCE_ENVELOPE, host, object);
|
|
351
|
+
|
|
352
|
+
var soapBody = Buffer.from(XML);
|
|
353
|
+
options.body = soapBody;
|
|
354
|
+
|
|
355
|
+
return new Promise((resolve, reject) => {
|
|
356
|
+
// We fetch the API endpoint
|
|
357
|
+
fetch(
|
|
358
|
+
`https://${server}:8443/perfmonservice2/services/PerfmonService/`,
|
|
359
|
+
options
|
|
360
|
+
)
|
|
361
|
+
.then(async (response) => {
|
|
362
|
+
var data = []; // create an array to save chunked data from server
|
|
363
|
+
// response.body is a ReadableStream
|
|
364
|
+
const reader = response.body.getReader();
|
|
365
|
+
for await (const chunk of readChunks(reader)) {
|
|
366
|
+
data.push(Buffer.from(chunk));
|
|
367
|
+
}
|
|
368
|
+
var buffer = Buffer.concat(data); // create buffer of data
|
|
369
|
+
let xmlOutput = buffer.toString("binary").trim();
|
|
370
|
+
let output = await parseXml(xmlOutput);
|
|
371
|
+
// Remove unnecessary keys
|
|
372
|
+
removeKeys(output, "$");
|
|
373
|
+
|
|
374
|
+
if (keyExists(output, "perfmonListInstanceReturn")) {
|
|
375
|
+
var returnResults =
|
|
376
|
+
output.Body.perfmonListInstanceResponse.perfmonListInstanceReturn;
|
|
377
|
+
|
|
378
|
+
if (returnResults) {
|
|
379
|
+
resolve(clean(returnResults));
|
|
380
|
+
} else {
|
|
381
|
+
reject(output.Body.Fault);
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
reject({ response: "empty" });
|
|
385
|
+
}
|
|
386
|
+
})
|
|
387
|
+
.catch((error) => {
|
|
388
|
+
reject(error);
|
|
389
|
+
}); // catches the error and logs it
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Post Fetch using Cisco PerfMon API
|
|
394
|
+
*
|
|
395
|
+
* @openSession
|
|
396
|
+
var service = new perfMonService();
|
|
397
|
+
service.openSession().then((success => {
|
|
398
|
+
console.log(success);
|
|
399
|
+
}))
|
|
400
|
+
* @memberof perfMonService
|
|
401
|
+
* @returns {promise} returns a Promise
|
|
402
|
+
*/
|
|
403
|
+
openSession() {
|
|
404
|
+
var XML;
|
|
405
|
+
var options = this._OPTIONS;
|
|
406
|
+
options.SOAPAction = `perfmonOpenSession`;
|
|
407
|
+
var server = this._HOST;
|
|
408
|
+
XML = util.format(XML_OPEN_SESSION_ENVELOPE);
|
|
409
|
+
|
|
410
|
+
var soapBody = Buffer.from(XML);
|
|
411
|
+
options.body = soapBody;
|
|
412
|
+
|
|
413
|
+
return new Promise((resolve, reject) => {
|
|
414
|
+
// We fetch the API endpoint
|
|
415
|
+
fetch(
|
|
416
|
+
`https://${server}:8443/perfmonservice2/services/PerfmonService/`,
|
|
417
|
+
options
|
|
418
|
+
)
|
|
419
|
+
.then(async (response) => {
|
|
420
|
+
var data = []; // create an array to save chunked data from server
|
|
421
|
+
// response.body is a ReadableStream
|
|
422
|
+
const reader = response.body.getReader();
|
|
423
|
+
for await (const chunk of readChunks(reader)) {
|
|
424
|
+
data.push(Buffer.from(chunk));
|
|
425
|
+
}
|
|
426
|
+
var buffer = Buffer.concat(data); // create buffer of data
|
|
427
|
+
let xmlOutput = buffer.toString("binary").trim();
|
|
428
|
+
let output = await parseXml(xmlOutput);
|
|
429
|
+
// Remove unnecessary keys
|
|
430
|
+
removeKeys(output, "$");
|
|
431
|
+
|
|
432
|
+
if (keyExists(output, "perfmonOpenSessionReturn")) {
|
|
433
|
+
var returnResults =
|
|
434
|
+
output.Body.perfmonOpenSessionResponse.perfmonOpenSessionReturn;
|
|
435
|
+
|
|
436
|
+
if (returnResults) {
|
|
437
|
+
resolve(clean(returnResults));
|
|
438
|
+
} else {
|
|
439
|
+
reject(output.Body.Fault);
|
|
440
|
+
}
|
|
441
|
+
} else {
|
|
442
|
+
reject({ response: "empty" });
|
|
443
|
+
}
|
|
444
|
+
})
|
|
445
|
+
.catch((error) => {
|
|
446
|
+
reject(error);
|
|
447
|
+
}); // catches the error and logs it
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Post Fetch using Cisco PerfMon API
|
|
452
|
+
*
|
|
453
|
+
* @closeSession
|
|
454
|
+
var service = new perfMonService();
|
|
455
|
+
service.closeSession().then((success => {
|
|
456
|
+
console.log(success);
|
|
457
|
+
}))
|
|
458
|
+
* @memberof perfMonService
|
|
459
|
+
* @returns {promise} returns a Promise
|
|
460
|
+
*/
|
|
461
|
+
closeSession(sessionHandle) {
|
|
462
|
+
var XML;
|
|
463
|
+
var options = this._OPTIONS;
|
|
464
|
+
options.SOAPAction = `perfmonCloseSession`;
|
|
465
|
+
var server = this._HOST;
|
|
466
|
+
XML = util.format(XML_CLOSE_SESSION_ENVELOPE, sessionHandle);
|
|
467
|
+
|
|
468
|
+
var soapBody = Buffer.from(XML);
|
|
469
|
+
options.body = soapBody;
|
|
470
|
+
|
|
471
|
+
return new Promise((resolve, reject) => {
|
|
472
|
+
// We fetch the API endpoint
|
|
473
|
+
fetch(
|
|
474
|
+
`https://${server}:8443/perfmonservice2/services/PerfmonService/`,
|
|
475
|
+
options
|
|
476
|
+
)
|
|
477
|
+
.then(async (response) => {
|
|
478
|
+
var data = []; // create an array to save chunked data from server
|
|
479
|
+
// response.body is a ReadableStream
|
|
480
|
+
const reader = response.body.getReader();
|
|
481
|
+
for await (const chunk of readChunks(reader)) {
|
|
482
|
+
data.push(Buffer.from(chunk));
|
|
483
|
+
}
|
|
484
|
+
var buffer = Buffer.concat(data); // create buffer of data
|
|
485
|
+
let xmlOutput = buffer.toString("binary").trim();
|
|
486
|
+
let output = await parseXml(xmlOutput);
|
|
487
|
+
// Remove unnecessary keys
|
|
488
|
+
removeKeys(output, "$");
|
|
489
|
+
|
|
490
|
+
if (keyExists(output, "perfmonCloseSessionResponse")) {
|
|
491
|
+
var returnResults = output.Body.perfmonCloseSessionResponse;
|
|
492
|
+
if (returnResults) {
|
|
493
|
+
resolve({ response: "success" });
|
|
494
|
+
} else {
|
|
495
|
+
reject(output.Body.Fault);
|
|
496
|
+
}
|
|
497
|
+
} else {
|
|
498
|
+
reject({ response: "empty" });
|
|
499
|
+
}
|
|
500
|
+
})
|
|
501
|
+
.catch((error) => {
|
|
502
|
+
reject(error);
|
|
503
|
+
}); // catches the error and logs it
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Post Fetch using Cisco PerfMon API
|
|
508
|
+
*
|
|
509
|
+
* @addCounter
|
|
510
|
+
var service = new perfMonService();
|
|
511
|
+
service.addCounter().then((success => {
|
|
512
|
+
console.log(success);
|
|
513
|
+
}))
|
|
514
|
+
* @memberof perfMonService
|
|
515
|
+
* @returns {promise} returns a Promise
|
|
516
|
+
*/
|
|
517
|
+
addCounter(sessionHandle, counter) {
|
|
518
|
+
var XML;
|
|
519
|
+
var counterStr;
|
|
520
|
+
var options = this._OPTIONS;
|
|
521
|
+
options.SOAPAction = `perfmonAddCounter`;
|
|
522
|
+
var server = this._HOST;
|
|
523
|
+
|
|
524
|
+
if (Array.isArray(counter)) {
|
|
525
|
+
counterStr = counter.map(
|
|
526
|
+
(item) =>
|
|
527
|
+
"<soap:Counter>" +
|
|
528
|
+
"<soap:Name>" +
|
|
529
|
+
"\\\\" +
|
|
530
|
+
item.host +
|
|
531
|
+
"\\" +
|
|
532
|
+
item.object +
|
|
533
|
+
"\\" +
|
|
534
|
+
item.counter +
|
|
535
|
+
"</soap:Name>" +
|
|
536
|
+
"</soap:Counter>"
|
|
537
|
+
);
|
|
538
|
+
} else {
|
|
539
|
+
counterStr =
|
|
540
|
+
"<soap:Counter>" +
|
|
541
|
+
"<soap:Name>" +
|
|
542
|
+
"\\\\" +
|
|
543
|
+
counter.host +
|
|
544
|
+
"\\" +
|
|
545
|
+
counter.object +
|
|
546
|
+
"\\" +
|
|
547
|
+
counter.counter +
|
|
548
|
+
"</soap:Name>" +
|
|
549
|
+
"</soap:Counter>";
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
XML = util.format(XML_ADD_COUNTER_ENVELOPE, sessionHandle, counterStr);
|
|
553
|
+
|
|
554
|
+
var soapBody = Buffer.from(XML);
|
|
555
|
+
options.body = soapBody;
|
|
556
|
+
|
|
557
|
+
return new Promise((resolve, reject) => {
|
|
558
|
+
// We fetch the API endpoint
|
|
559
|
+
fetch(
|
|
560
|
+
`https://${server}:8443/perfmonservice2/services/PerfmonService/`,
|
|
561
|
+
options
|
|
562
|
+
)
|
|
563
|
+
.then(async (response) => {
|
|
564
|
+
var data = []; // create an array to save chunked data from server
|
|
565
|
+
// response.body is a ReadableStream
|
|
566
|
+
const reader = response.body.getReader();
|
|
567
|
+
for await (const chunk of readChunks(reader)) {
|
|
568
|
+
data.push(Buffer.from(chunk));
|
|
569
|
+
}
|
|
570
|
+
var buffer = Buffer.concat(data); // create buffer of data
|
|
571
|
+
let xmlOutput = buffer.toString("binary").trim();
|
|
572
|
+
let output = await parseXml(xmlOutput);
|
|
573
|
+
// Remove unnecessary keys
|
|
574
|
+
removeKeys(output, "$");
|
|
575
|
+
|
|
576
|
+
if (keyExists(output, "perfmonAddCounterResponse")) {
|
|
577
|
+
var returnResults = output.Body.perfmonAddCounterResponse;
|
|
578
|
+
if (returnResults) {
|
|
579
|
+
resolve({ response: "success" });
|
|
580
|
+
} else {
|
|
581
|
+
reject(output.Body.Fault);
|
|
582
|
+
}
|
|
583
|
+
} else {
|
|
584
|
+
reject({ response: "empty" });
|
|
585
|
+
}
|
|
586
|
+
})
|
|
587
|
+
.catch((error) => {
|
|
588
|
+
reject(error);
|
|
589
|
+
}); // catches the error and logs it
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Post Fetch using Cisco PerfMon API
|
|
594
|
+
*
|
|
595
|
+
* @removeCounter
|
|
596
|
+
var service = new perfMonService();
|
|
597
|
+
service.removeCounter().then((success => {
|
|
598
|
+
console.log(success);
|
|
599
|
+
}))
|
|
600
|
+
* @memberof perfMonService
|
|
601
|
+
* @returns {promise} returns a Promise
|
|
602
|
+
*/
|
|
603
|
+
removeCounter(sessionHandle, counter) {
|
|
604
|
+
var XML;
|
|
605
|
+
var counterStr;
|
|
606
|
+
var options = this._OPTIONS;
|
|
607
|
+
options.SOAPAction = `perfmonRemoveCounter`;
|
|
608
|
+
var server = this._HOST;
|
|
609
|
+
|
|
610
|
+
if (Array.isArray(counter)) {
|
|
611
|
+
counterStr = counter.map(
|
|
612
|
+
(item) =>
|
|
613
|
+
"<soap:Counter>" +
|
|
614
|
+
"<soap:Name>" +
|
|
615
|
+
"\\\\" +
|
|
616
|
+
item.host +
|
|
617
|
+
"\\" +
|
|
618
|
+
item.object +
|
|
619
|
+
"\\" +
|
|
620
|
+
item.counter +
|
|
621
|
+
"</soap:Name>" +
|
|
622
|
+
"</soap:Counter>"
|
|
623
|
+
);
|
|
624
|
+
} else {
|
|
625
|
+
counterStr =
|
|
626
|
+
"<soap:Counter>" +
|
|
627
|
+
"<soap:Name>" +
|
|
628
|
+
"\\\\" +
|
|
629
|
+
counter.host +
|
|
630
|
+
"\\" +
|
|
631
|
+
counter.object +
|
|
632
|
+
"\\" +
|
|
633
|
+
counter.counter +
|
|
634
|
+
"</soap:Name>" +
|
|
635
|
+
"</soap:Counter>";
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
XML = util.format(XML_REMOVE_COUNTER_ENVELOPE, sessionHandle, counterStr);
|
|
639
|
+
|
|
640
|
+
var soapBody = Buffer.from(XML);
|
|
641
|
+
options.body = soapBody;
|
|
642
|
+
|
|
643
|
+
return new Promise((resolve, reject) => {
|
|
644
|
+
// We fetch the API endpoint
|
|
645
|
+
fetch(
|
|
646
|
+
`https://${server}:8443/perfmonservice2/services/PerfmonService/`,
|
|
647
|
+
options
|
|
648
|
+
)
|
|
649
|
+
.then(async (response) => {
|
|
650
|
+
var data = []; // create an array to save chunked data from server
|
|
651
|
+
// response.body is a ReadableStream
|
|
652
|
+
const reader = response.body.getReader();
|
|
653
|
+
for await (const chunk of readChunks(reader)) {
|
|
654
|
+
data.push(Buffer.from(chunk));
|
|
655
|
+
}
|
|
656
|
+
var buffer = Buffer.concat(data); // create buffer of data
|
|
657
|
+
let xmlOutput = buffer.toString("binary").trim();
|
|
658
|
+
let output = await parseXml(xmlOutput);
|
|
659
|
+
// Remove unnecessary keys
|
|
660
|
+
removeKeys(output, "$");
|
|
661
|
+
|
|
662
|
+
if (keyExists(output, "perfmonRemoveCounterResponse")) {
|
|
663
|
+
var returnResults = output.Body.perfmonRemoveCounterResponse;
|
|
664
|
+
if (returnResults) {
|
|
665
|
+
resolve({ response: "success" });
|
|
666
|
+
} else {
|
|
667
|
+
reject(output.Body.Fault);
|
|
668
|
+
}
|
|
669
|
+
} else {
|
|
670
|
+
reject({ response: "empty" });
|
|
671
|
+
}
|
|
672
|
+
})
|
|
673
|
+
.catch((error) => {
|
|
674
|
+
reject(error);
|
|
675
|
+
}); // catches the error and logs it
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Post Fetch using Cisco PerfMon API
|
|
680
|
+
*
|
|
681
|
+
* @queryCounterDescription
|
|
682
|
+
var service = new perfMonService();
|
|
683
|
+
service.queryCounterDescription().then((success => {
|
|
684
|
+
console.log(success);
|
|
685
|
+
}))
|
|
686
|
+
* @memberof perfMonService
|
|
687
|
+
* @returns {promise} returns a Promise
|
|
688
|
+
*/
|
|
689
|
+
queryCounterDescription(counter) {
|
|
690
|
+
var XML;
|
|
691
|
+
var options = this._OPTIONS;
|
|
692
|
+
options.SOAPAction = `perfmonQueryCounterDescription`;
|
|
693
|
+
var server = this._HOST;
|
|
694
|
+
|
|
695
|
+
var counterStr =
|
|
696
|
+
"<soap:Counter>" +
|
|
697
|
+
"\\\\" +
|
|
698
|
+
counter.host +
|
|
699
|
+
"\\" +
|
|
700
|
+
counter.object +
|
|
701
|
+
"\\" +
|
|
702
|
+
counter.counter +
|
|
703
|
+
"</soap:Counter>";
|
|
704
|
+
|
|
705
|
+
XML = util.format(XML_QUERY_COUNTER_ENVELOPE, counterStr);
|
|
706
|
+
|
|
707
|
+
var soapBody = Buffer.from(XML);
|
|
708
|
+
options.body = soapBody;
|
|
709
|
+
|
|
710
|
+
return new Promise((resolve, reject) => {
|
|
711
|
+
// We fetch the API endpoint
|
|
712
|
+
fetch(
|
|
713
|
+
`https://${server}:8443/perfmonservice2/services/PerfmonService/`,
|
|
714
|
+
options
|
|
715
|
+
)
|
|
716
|
+
.then(async (response) => {
|
|
717
|
+
var data = []; // create an array to save chunked data from server
|
|
718
|
+
// response.body is a ReadableStream
|
|
719
|
+
const reader = response.body.getReader();
|
|
720
|
+
for await (const chunk of readChunks(reader)) {
|
|
721
|
+
data.push(Buffer.from(chunk));
|
|
722
|
+
}
|
|
723
|
+
var buffer = Buffer.concat(data); // create buffer of data
|
|
724
|
+
let xmlOutput = buffer.toString("binary").trim();
|
|
725
|
+
let output = await parseXml(xmlOutput);
|
|
726
|
+
|
|
727
|
+
// Remove unnecessary keys
|
|
728
|
+
removeKeys(output, "$");
|
|
729
|
+
|
|
730
|
+
if (keyExists(output, "perfmonQueryCounterDescriptionReturn")) {
|
|
731
|
+
var returnResults =
|
|
732
|
+
output.Body.perfmonQueryCounterDescriptionResponse.perfmonQueryCounterDescriptionReturn;
|
|
733
|
+
|
|
734
|
+
if (returnResults) {
|
|
735
|
+
resolve(clean(returnResults));
|
|
736
|
+
} else {
|
|
737
|
+
reject(output.Body.Fault);
|
|
738
|
+
}
|
|
739
|
+
} else {
|
|
740
|
+
reject({ response: "empty" });
|
|
741
|
+
}
|
|
742
|
+
})
|
|
743
|
+
.catch((error) => {
|
|
744
|
+
reject(error);
|
|
745
|
+
}); // catches the error and logs it
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// readChunks() reads from the provided reader and yields the results into an async iterable
|
|
751
|
+
const readChunks = (reader) => {
|
|
752
|
+
return {
|
|
753
|
+
async *[Symbol.asyncIterator]() {
|
|
754
|
+
let readResult = await reader.read();
|
|
755
|
+
while (!readResult.done) {
|
|
756
|
+
yield readResult.value;
|
|
757
|
+
readResult = await reader.read();
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
};
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
const keyExists = (obj, key) => {
|
|
764
|
+
if (!obj || (typeof obj !== "object" && !Array.isArray(obj))) {
|
|
765
|
+
return false;
|
|
766
|
+
} else if (obj.hasOwnProperty(key)) {
|
|
767
|
+
return true;
|
|
768
|
+
} else if (Array.isArray(obj)) {
|
|
769
|
+
for (let i = 0; i < obj.length; i++) {
|
|
770
|
+
const result = keyExists(obj[i], key);
|
|
771
|
+
if (result) {
|
|
772
|
+
return result;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
} else {
|
|
776
|
+
for (const k in obj) {
|
|
777
|
+
const result = keyExists(obj[k], key);
|
|
778
|
+
if (result) {
|
|
779
|
+
return result;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
return false;
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Remove all specified keys from an object, no matter how deep they are.
|
|
789
|
+
* The removal is done in place, so run it on a copy if you don't want to modify the original object.
|
|
790
|
+
* This function has no limit so circular objects will probably crash the browser
|
|
791
|
+
*
|
|
792
|
+
* @param obj The object from where you want to remove the keys
|
|
793
|
+
* @param keys An array of property names (strings) to remove
|
|
794
|
+
*/
|
|
795
|
+
const removeKeys = (obj, keys) => {
|
|
796
|
+
for (var prop in obj) {
|
|
797
|
+
if (obj.hasOwnProperty(prop)) {
|
|
798
|
+
switch (typeof obj[prop]) {
|
|
799
|
+
case "object":
|
|
800
|
+
if (keys.indexOf(prop) > -1) {
|
|
801
|
+
delete obj[prop];
|
|
802
|
+
} else {
|
|
803
|
+
removeKeys(obj[prop], keys);
|
|
804
|
+
}
|
|
805
|
+
break;
|
|
806
|
+
default:
|
|
807
|
+
if (keys.indexOf(prop) > -1) {
|
|
808
|
+
delete obj[prop];
|
|
809
|
+
}
|
|
810
|
+
break;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
const clean = (object) => {
|
|
817
|
+
Object.entries(object).forEach(([k, v]) => {
|
|
818
|
+
if (v && typeof v === "object") {
|
|
819
|
+
clean(v);
|
|
820
|
+
}
|
|
821
|
+
if (
|
|
822
|
+
(v && typeof v === "object" && !Object.keys(v).length) ||
|
|
823
|
+
v === null ||
|
|
824
|
+
v === undefined
|
|
825
|
+
) {
|
|
826
|
+
if (Array.isArray(object)) {
|
|
827
|
+
object.splice(k, 1);
|
|
828
|
+
} else {
|
|
829
|
+
delete object[k];
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
});
|
|
833
|
+
return object;
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
const parseXml = (xmlPart) => {
|
|
837
|
+
return new Promise((resolve, reject) => {
|
|
838
|
+
parseString(
|
|
839
|
+
xmlPart,
|
|
840
|
+
{
|
|
841
|
+
explicitArray: false,
|
|
842
|
+
explicitRoot: false,
|
|
843
|
+
tagNameProcessors: [stripPrefix],
|
|
844
|
+
},
|
|
845
|
+
(err, result) => {
|
|
846
|
+
if (err) {
|
|
847
|
+
reject(err);
|
|
848
|
+
} else {
|
|
849
|
+
resolve(result);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
);
|
|
853
|
+
});
|
|
854
|
+
};
|
|
855
|
+
|
|
856
|
+
module.exports = perfMonService;
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cisco-perfmon",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "A library to pull Perfmon data from Cisco VOS applications via SOAP",
|
|
5
|
+
"main": "main.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 NODE_TLS_REJECT_UNAUTHORIZED=0 node ./test/tests.js"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/sieteunoseis/cisco-perfmon.git"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"cisco",
|
|
15
|
+
"node",
|
|
16
|
+
"perfmon",
|
|
17
|
+
"cucm",
|
|
18
|
+
"vos"
|
|
19
|
+
],
|
|
20
|
+
"author": "Jeremy Worden <jeremy@automate.builders> (https://automate.builders/)",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/sieteunoseis/cisco-perfmon/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/sieteunoseis/cisco-perfmon#readme",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"util": "*",
|
|
28
|
+
"xml2js": "*"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/test/tests.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const perfMonService = require("../main");
|
|
2
|
+
|
|
3
|
+
// Set up new PerfMon service
|
|
4
|
+
let service = new perfMonService(
|
|
5
|
+
"10.10.20.1",
|
|
6
|
+
"administrator",
|
|
7
|
+
"ciscopsdt"
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
// Variables to hold our SessionID and our Session Counter
|
|
11
|
+
var SessionID;
|
|
12
|
+
var counterObj = {
|
|
13
|
+
host: "cucm01-pub",
|
|
14
|
+
object: "Cisco CallManager",
|
|
15
|
+
counter: "CallsActive",
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
console.log("Let's get a description of our counter.");
|
|
19
|
+
service
|
|
20
|
+
.queryCounterDescription(counterObj)
|
|
21
|
+
.then((results) => {
|
|
22
|
+
console.log("queryCounterDescription", results);
|
|
23
|
+
})
|
|
24
|
+
.catch((error) => {
|
|
25
|
+
console.log(error);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
console.log(
|
|
29
|
+
"Let's open a session, add a counter, wait 30 seconds, collect the session data, remove the counter and finally close the session"
|
|
30
|
+
);
|
|
31
|
+
service
|
|
32
|
+
.openSession()
|
|
33
|
+
.then((results) => {
|
|
34
|
+
console.log("SessionID", results);
|
|
35
|
+
SessionID = results;
|
|
36
|
+
service
|
|
37
|
+
.addCounter(SessionID, counterObj)
|
|
38
|
+
.then(async (results) => {
|
|
39
|
+
console.log("addCounter", results);
|
|
40
|
+
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
41
|
+
console.log("Wait 30 seconds");
|
|
42
|
+
await delay(30000); /// waiting 30 second.
|
|
43
|
+
service
|
|
44
|
+
.collectSessionData(SessionID)
|
|
45
|
+
.then((results) => {
|
|
46
|
+
console.log("collectSessionData", results);
|
|
47
|
+
service
|
|
48
|
+
.removeCounter(SessionID, counterObj)
|
|
49
|
+
.then((results) => {
|
|
50
|
+
console.log("removeCounter", results);
|
|
51
|
+
service
|
|
52
|
+
.closeSession(SessionID)
|
|
53
|
+
.then((results) => {
|
|
54
|
+
console.log("closeSession", results);
|
|
55
|
+
})
|
|
56
|
+
.catch((error) => {
|
|
57
|
+
console.log(error);
|
|
58
|
+
});
|
|
59
|
+
})
|
|
60
|
+
.catch((error) => {
|
|
61
|
+
console.log(error);
|
|
62
|
+
});
|
|
63
|
+
})
|
|
64
|
+
.catch((error) => {
|
|
65
|
+
console.log(error);
|
|
66
|
+
});
|
|
67
|
+
})
|
|
68
|
+
.catch((error) => {
|
|
69
|
+
console.log(error);
|
|
70
|
+
});
|
|
71
|
+
})
|
|
72
|
+
.catch((error) => {
|
|
73
|
+
console.log(error);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
console.log("Let's collect some non session counter data.");
|
|
77
|
+
service
|
|
78
|
+
.collectCounterData("cucm01-pub", "Cisco CallManager")
|
|
79
|
+
.then((results) => {
|
|
80
|
+
console.log("collectCounterData", results);
|
|
81
|
+
})
|
|
82
|
+
.catch((error) => {
|
|
83
|
+
console.log(error);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
console.log(
|
|
87
|
+
"Let's returns the list of available PerfMon objects and counters on a particular host"
|
|
88
|
+
);
|
|
89
|
+
service
|
|
90
|
+
.listCounter("cucm01-pub")
|
|
91
|
+
.then((results) => {
|
|
92
|
+
console.log("listCounter", results);
|
|
93
|
+
})
|
|
94
|
+
.catch((error) => {
|
|
95
|
+
console.log(error);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
console.log(
|
|
99
|
+
"Let's return a list of instances of a PerfMon object on a particular host. Instances of an object can dynamically change. This operation returns the most recent list."
|
|
100
|
+
);
|
|
101
|
+
service
|
|
102
|
+
.listInstance("cucm01-pub","Partition")
|
|
103
|
+
.then((results) => {
|
|
104
|
+
console.log("listInstance", results);
|
|
105
|
+
})
|
|
106
|
+
.catch((error) => {
|
|
107
|
+
console.log(error);
|
|
108
|
+
});
|