@itentialopensource/adapter-meraki 0.8.1 → 0.8.2
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/CHANGELOG.md +8 -0
- package/adapter.js +179 -519
- package/adapterBase.js +272 -2
- package/package.json +3 -3
- package/propertiesDecorators.json +14 -0
- package/propertiesSchema.json +339 -195
- package/refs?service=git-upload-pack +0 -0
- package/report/updateReport1651511176919.json +115 -0
- package/test/unit/adapterBaseTestUnit.js +1 -1
- package/test/unit/adapterTestUnit.js +5 -5
- package/utils/tbUtils.js +20 -7
package/adapterBase.js
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
/* eslint no-cond-assign: warn */
|
9
9
|
/* eslint global-require: warn */
|
10
10
|
/* eslint no-unused-vars: warn */
|
11
|
+
/* eslint prefer-destructuring: warn */
|
11
12
|
|
12
13
|
/* Required libraries. */
|
13
14
|
const fs = require('fs-extra');
|
@@ -154,6 +155,9 @@ class AdapterBase extends EventEmitterCl {
|
|
154
155
|
// Instantiate the EventEmitter super class
|
155
156
|
super();
|
156
157
|
|
158
|
+
// IAP home directory injected by core when running the adapter within IAP
|
159
|
+
process.env.iap_home = process.argv[3];
|
160
|
+
|
157
161
|
try {
|
158
162
|
// Capture the adapter id
|
159
163
|
this.id = prongid;
|
@@ -746,7 +750,7 @@ class AdapterBase extends EventEmitterCl {
|
|
746
750
|
try {
|
747
751
|
const { serviceItem } = await tbUtils.getAdapterConfig();
|
748
752
|
const { host } = serviceItem.properties.properties;
|
749
|
-
const result = tbUtils.
|
753
|
+
const result = tbUtils.runConnectivity(host, false);
|
750
754
|
if (result.failCount > 0) {
|
751
755
|
return callback(null, result);
|
752
756
|
}
|
@@ -764,7 +768,7 @@ class AdapterBase extends EventEmitterCl {
|
|
764
768
|
*/
|
765
769
|
iapRunAdapterBasicGet(callback) {
|
766
770
|
try {
|
767
|
-
const result = tbUtils.
|
771
|
+
const result = tbUtils.runBasicGet(false);
|
768
772
|
if (result.failCount > 0) {
|
769
773
|
return callback(null, result);
|
770
774
|
}
|
@@ -1024,6 +1028,272 @@ class AdapterBase extends EventEmitterCl {
|
|
1024
1028
|
return [];
|
1025
1029
|
}
|
1026
1030
|
}
|
1031
|
+
|
1032
|
+
/**
|
1033
|
+
* @summary Make one of the needed Broker calls - could be one of many
|
1034
|
+
*
|
1035
|
+
* @function iapMakeBrokerCall
|
1036
|
+
* @param {string} brokCall - the name of the broker call (required)
|
1037
|
+
* @param {object} callProps - the proeprties for the broker call (required)
|
1038
|
+
* @param {object} devResp - the device details to extract needed inputs (required)
|
1039
|
+
* @param {string} filterName - any filter to search on (required)
|
1040
|
+
*
|
1041
|
+
* @param {getCallback} callback - a callback function to return the result of the call
|
1042
|
+
*/
|
1043
|
+
iapMakeBrokerCall(brokCall, callProps, devResp, filterName, callback) {
|
1044
|
+
const meth = 'adapter-iapMakeBrokerCall';
|
1045
|
+
const origin = `${this.id}-${meth}`;
|
1046
|
+
log.trace(origin);
|
1047
|
+
|
1048
|
+
try {
|
1049
|
+
let uriPath = '';
|
1050
|
+
let uriMethod = 'GET';
|
1051
|
+
let callQuery = {};
|
1052
|
+
let callBody = {};
|
1053
|
+
let callHeaders = {};
|
1054
|
+
let handleFail = 'fail';
|
1055
|
+
let ostypePrefix = '';
|
1056
|
+
let statusValue = 'true';
|
1057
|
+
if (callProps.path) {
|
1058
|
+
uriPath = `${callProps.path}`;
|
1059
|
+
|
1060
|
+
// make any necessary changes to the path
|
1061
|
+
if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
|
1062
|
+
const rqKeys = Object.keys(callProps.requestFields);
|
1063
|
+
|
1064
|
+
// get the field from the provided device
|
1065
|
+
for (let rq = 0; rq < rqKeys.length; rq += 1) {
|
1066
|
+
// get the request field we are retrieving
|
1067
|
+
const loopField = callProps.requestFields[rqKeys[rq]];
|
1068
|
+
const loopArray = loopField.split('.');
|
1069
|
+
let nestedValue = devResp;
|
1070
|
+
|
1071
|
+
// loops through incase the field is nested
|
1072
|
+
for (let i = 0; i < loopArray.length; i += 1) {
|
1073
|
+
if (Object.hasOwnProperty.call(nestedValue, loopArray[i])) {
|
1074
|
+
nestedValue = nestedValue[loopArray[i]];
|
1075
|
+
} else {
|
1076
|
+
// failed to traverse
|
1077
|
+
nestedValue = loopField;
|
1078
|
+
break;
|
1079
|
+
}
|
1080
|
+
}
|
1081
|
+
|
1082
|
+
// put the value into the path - if it has been specified in the path
|
1083
|
+
uriPath = uriPath.replace(`{${rqKeys[rq]}}`, nestedValue);
|
1084
|
+
}
|
1085
|
+
}
|
1086
|
+
}
|
1087
|
+
if (callProps.method) {
|
1088
|
+
uriMethod = callProps.method;
|
1089
|
+
}
|
1090
|
+
if (callProps.query) {
|
1091
|
+
callQuery = callProps.query;
|
1092
|
+
|
1093
|
+
// go through the query params to check for variable values
|
1094
|
+
const cpKeys = Object.keys(callQuery);
|
1095
|
+
for (let cp = 0; cp < cpKeys.length; cp += 1) {
|
1096
|
+
if (callQuery[cpKeys[cp]].startsWith('{') && callQuery[cpKeys[cp]].endsWith('}')) {
|
1097
|
+
// make any necessary changes to the query params
|
1098
|
+
if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
|
1099
|
+
const rqKeys = Object.keys(callProps.requestFields);
|
1100
|
+
|
1101
|
+
// get the uuid from the device
|
1102
|
+
for (let rq = 0; rq < rqKeys.length; rq += 1) {
|
1103
|
+
if (cpKeys[cp] === rqKeys[rq]) {
|
1104
|
+
// get the request field we are retrieving
|
1105
|
+
const loopField = callProps.requestFields[rqKeys[rq]];
|
1106
|
+
const loopArray = loopField.split('.');
|
1107
|
+
let nestedValue = devResp;
|
1108
|
+
|
1109
|
+
// loops through incase the field is nested
|
1110
|
+
for (let i = 0; i < loopArray.length; i += 1) {
|
1111
|
+
if (Object.hasOwnProperty.call(nestedValue, loopArray[i])) {
|
1112
|
+
nestedValue = nestedValue[loopArray[i]];
|
1113
|
+
} else {
|
1114
|
+
// failed to traverse
|
1115
|
+
nestedValue = loopField;
|
1116
|
+
break;
|
1117
|
+
}
|
1118
|
+
}
|
1119
|
+
|
1120
|
+
// put the value into the query - if it has been specified in the query
|
1121
|
+
callQuery[cpKeys[cp]] = nestedValue;
|
1122
|
+
}
|
1123
|
+
}
|
1124
|
+
}
|
1125
|
+
}
|
1126
|
+
}
|
1127
|
+
}
|
1128
|
+
if (callProps.body) {
|
1129
|
+
callBody = callProps.body;
|
1130
|
+
}
|
1131
|
+
if (callProps.headers) {
|
1132
|
+
callHeaders = callProps.headers;
|
1133
|
+
}
|
1134
|
+
if (callProps.handleFailure) {
|
1135
|
+
handleFail = callProps.handleFailure;
|
1136
|
+
}
|
1137
|
+
if (callProps.responseFields && callProps.responseFields.ostypePrefix) {
|
1138
|
+
ostypePrefix = callProps.responseFields.ostypePrefix;
|
1139
|
+
}
|
1140
|
+
if (callProps.responseFields && callProps.responseFields.statusValue) {
|
1141
|
+
statusValue = callProps.responseFields.statusValue;
|
1142
|
+
}
|
1143
|
+
|
1144
|
+
// !! using Generic makes it easier on the Adapter Builder (just need to change the path)
|
1145
|
+
// !! you can also replace with a specific call if that is easier
|
1146
|
+
return this.genericAdapterRequest(uriPath, uriMethod, callQuery, callBody, callHeaders, (result, error) => {
|
1147
|
+
// if we received an error or their is no response on the results return an error
|
1148
|
+
if (error) {
|
1149
|
+
if (handleFail === 'fail') {
|
1150
|
+
return callback(null, error);
|
1151
|
+
}
|
1152
|
+
return callback({}, null);
|
1153
|
+
}
|
1154
|
+
if (!result.response) {
|
1155
|
+
if (handleFail === 'fail') {
|
1156
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', [brokCall], null, null, null);
|
1157
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1158
|
+
return callback(null, errorObj);
|
1159
|
+
}
|
1160
|
+
return callback({}, null);
|
1161
|
+
}
|
1162
|
+
|
1163
|
+
// get the keys for the response fields
|
1164
|
+
let rfKeys = [];
|
1165
|
+
if (callProps.responseFields && Object.keys(callProps.responseFields).length > 0) {
|
1166
|
+
rfKeys = Object.keys(callProps.responseFields);
|
1167
|
+
}
|
1168
|
+
|
1169
|
+
// if we got an array returned (e.g. getDevicesFitered)
|
1170
|
+
if (Array.isArray(result.response)) {
|
1171
|
+
const listDevices = [];
|
1172
|
+
for (let a = 0; a < result.response.length; a += 1) {
|
1173
|
+
const thisDevice = result.response[a];
|
1174
|
+
for (let rf = 0; rf < rfKeys.length; rf += 1) {
|
1175
|
+
if (rfKeys[rf] !== 'ostypePrefix') {
|
1176
|
+
// get the response field we are retrieving
|
1177
|
+
const loopField = callProps.responseFields[rfKeys[rf]];
|
1178
|
+
const loopArray = loopField.split('.');
|
1179
|
+
let nestedValue = thisDevice;
|
1180
|
+
|
1181
|
+
// loops through incase the field is nested
|
1182
|
+
for (let i = 0; i < loopArray.length; i += 1) {
|
1183
|
+
if (Object.hasOwnProperty.call(nestedValue, loopArray[i])) {
|
1184
|
+
nestedValue = nestedValue[loopArray[i]];
|
1185
|
+
} else {
|
1186
|
+
// failed to traverse
|
1187
|
+
nestedValue = '';
|
1188
|
+
break;
|
1189
|
+
}
|
1190
|
+
}
|
1191
|
+
// if the field is ostype - need to add prefix
|
1192
|
+
if (rfKeys[rf] === 'ostype' && typeof nestedValue === 'string') {
|
1193
|
+
nestedValue = ostypePrefix + nestedValue;
|
1194
|
+
}
|
1195
|
+
// if there is a status to set, set it
|
1196
|
+
if (rfKeys[rf] === 'status') {
|
1197
|
+
// if really looking for just a good response
|
1198
|
+
if (loopField === 'return2xx' && result.icode === statusValue.toString()) {
|
1199
|
+
thisDevice.isAlive = true;
|
1200
|
+
} else if (nestedValue.toString() === statusValue.toString()) {
|
1201
|
+
thisDevice.isAlive = true;
|
1202
|
+
} else {
|
1203
|
+
thisDevice.isAlive = false;
|
1204
|
+
}
|
1205
|
+
}
|
1206
|
+
// if we found a good value
|
1207
|
+
thisDevice[rfKeys[rf]] = nestedValue;
|
1208
|
+
}
|
1209
|
+
}
|
1210
|
+
|
1211
|
+
// if there is no filter - add the device to the list
|
1212
|
+
if (!filterName || filterName.length === 0) {
|
1213
|
+
listDevices.push(thisDevice);
|
1214
|
+
} else {
|
1215
|
+
// if we have to match a filter
|
1216
|
+
let found = false;
|
1217
|
+
for (let f = 0; f < filterName.length; f += 1) {
|
1218
|
+
if (thisDevice.name.indexOf(filterName[f]) >= 0) {
|
1219
|
+
found = true;
|
1220
|
+
break;
|
1221
|
+
}
|
1222
|
+
}
|
1223
|
+
// matching device
|
1224
|
+
if (found) {
|
1225
|
+
listDevices.push(thisDevice);
|
1226
|
+
}
|
1227
|
+
}
|
1228
|
+
}
|
1229
|
+
|
1230
|
+
// return the array of devices
|
1231
|
+
return callback(listDevices, null);
|
1232
|
+
}
|
1233
|
+
|
1234
|
+
// if this is not an array - just about everything else, just handle as a single object
|
1235
|
+
let thisDevice = result.response;
|
1236
|
+
for (let rf = 0; rf < rfKeys.length; rf += 1) {
|
1237
|
+
// skip ostypePrefix since it is not a field
|
1238
|
+
if (rfKeys[rf] !== 'ostypePrefix') {
|
1239
|
+
// get the response field we are retrieving
|
1240
|
+
const loopField = callProps.responseFields[rfKeys[rf]];
|
1241
|
+
const loopArray = loopField.split('.');
|
1242
|
+
let nestedValue = thisDevice;
|
1243
|
+
|
1244
|
+
// loops through incase the field is nested
|
1245
|
+
for (let i = 0; i < loopArray.length; i += 1) {
|
1246
|
+
if (Object.hasOwnProperty.call(nestedValue, loopArray[i])) {
|
1247
|
+
nestedValue = nestedValue[loopArray[i]];
|
1248
|
+
} else {
|
1249
|
+
// failed to traverse
|
1250
|
+
nestedValue = '';
|
1251
|
+
break;
|
1252
|
+
}
|
1253
|
+
}
|
1254
|
+
// if the field is ostype - need to add prefix
|
1255
|
+
if (rfKeys[rf] === 'ostype' && typeof nestedValue === 'string') {
|
1256
|
+
nestedValue = ostypePrefix + nestedValue;
|
1257
|
+
}
|
1258
|
+
// if there is a status to set, set it
|
1259
|
+
if (rfKeys[rf] === 'status') {
|
1260
|
+
// if really looking for just a good response
|
1261
|
+
if (loopField === 'return2xx' && result.icode === statusValue.toString()) {
|
1262
|
+
thisDevice.isAlive = true;
|
1263
|
+
} else if (nestedValue.toString() === statusValue.toString()) {
|
1264
|
+
thisDevice.isAlive = true;
|
1265
|
+
} else {
|
1266
|
+
thisDevice.isAlive = false;
|
1267
|
+
}
|
1268
|
+
}
|
1269
|
+
// if we found a good value
|
1270
|
+
thisDevice[rfKeys[rf]] = nestedValue;
|
1271
|
+
}
|
1272
|
+
}
|
1273
|
+
|
1274
|
+
// if there is a filter - check the device is in the list
|
1275
|
+
if (filterName && filterName.length > 0) {
|
1276
|
+
let found = false;
|
1277
|
+
for (let f = 0; f < filterName.length; f += 1) {
|
1278
|
+
if (thisDevice.name.indexOf(filterName[f]) >= 0) {
|
1279
|
+
found = true;
|
1280
|
+
break;
|
1281
|
+
}
|
1282
|
+
}
|
1283
|
+
// no matching device - clear the device
|
1284
|
+
if (!found) {
|
1285
|
+
thisDevice = {};
|
1286
|
+
}
|
1287
|
+
}
|
1288
|
+
|
1289
|
+
return callback(thisDevice, null);
|
1290
|
+
});
|
1291
|
+
} catch (e) {
|
1292
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, e);
|
1293
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1294
|
+
return callback(null, errorObj);
|
1295
|
+
}
|
1296
|
+
}
|
1027
1297
|
}
|
1028
1298
|
|
1029
1299
|
module.exports = AdapterBase;
|
package/package.json
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
{
|
2
2
|
"name": "@itentialopensource/adapter-meraki",
|
3
|
-
"version": "0.8.
|
3
|
+
"version": "0.8.2",
|
4
4
|
"description": "This adapter integrates with system described as: merakiDashboardApi.",
|
5
5
|
"main": "adapter.js",
|
6
6
|
"wizardVersion": "2.44.7",
|
7
|
-
"engineVersion": "1.
|
7
|
+
"engineVersion": "1.61.2",
|
8
8
|
"adapterType": "http",
|
9
9
|
"scripts": {
|
10
10
|
"artifactize": "npm i && node utils/packModificationScript.js",
|
@@ -52,7 +52,7 @@
|
|
52
52
|
"author": "Itential",
|
53
53
|
"homepage": "https://gitlab.com/itentialopensource/adapters/sd-wan/adapter-meraki#readme",
|
54
54
|
"dependencies": {
|
55
|
-
"@itentialopensource/adapter-utils": "^4.
|
55
|
+
"@itentialopensource/adapter-utils": "^4.45.4",
|
56
56
|
"ajv": "^6.12.0",
|
57
57
|
"axios": "^0.21.0",
|
58
58
|
"commander": "^2.20.0",
|