@itentialopensource/adapter-utils 5.9.3 → 5.9.5

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 CHANGED
@@ -1,4 +1,20 @@
1
1
 
2
+ ## 5.9.5 [11-06-2024]
3
+
4
+ * more role chain changes for AWS
5
+
6
+ See merge request itentialopensource/adapter-utils!309
7
+
8
+ ---
9
+
10
+ ## 5.9.4 [10-14-2024]
11
+
12
+ * Fix ssl conditional
13
+
14
+ See merge request itentialopensource/adapter-utils!308
15
+
16
+ ---
17
+
2
18
  ## 5.9.3 [10-10-2024]
3
19
 
4
20
  * add sts region
@@ -45,6 +45,115 @@ class AuthenticationHandler {
45
45
  }
46
46
  }
47
47
 
48
+ /**
49
+ * @summary Assume an AWS STS Role
50
+ *
51
+ * @function assumeAWSSTSRole
52
+ * @param {object} [options] - the AWS options
53
+ * @param {object} [stsParams] - STS Parameters to use for authentication.
54
+ *
55
+ * @return {Object} the headers to add to the request
56
+ */
57
+ assumeAWSSTSRole(accessKey, secretKey, sessionT, options, STSParams, provideSign, callback) {
58
+ const meth = 'authenticationHandler-assumeAWSRole';
59
+ const origin = `${this.myid}-${meth}`;
60
+ log.trace(origin);
61
+
62
+ try {
63
+ // set up the config object
64
+ const configObj = {
65
+ sessionToken: this.allProps.authentication.aws_session_token,
66
+ accessKeyId: this.allProps.authentication.aws_access_key,
67
+ secretAccessKey: this.allProps.authentication.aws_secret_key,
68
+ region: options.region
69
+ };
70
+ // override the adapter config (ex. IAM and then Assume Role)
71
+ if (accessKey) {
72
+ configObj.accessKeyId = accessKey;
73
+ }
74
+ if (secretKey) {
75
+ configObj.secretAccessKey = secretKey;
76
+ }
77
+ if (sessionT) {
78
+ configObj.sessionToken = sessionT;
79
+ }
80
+ // Add optional config items (ssl, endpoint, proxy)
81
+ if (this.allProps.authentication.aws_sts) {
82
+ if (this.allProps.authentication.aws_sts.sslEnable === false) {
83
+ configObj.sslEnabled = false;
84
+ }
85
+ if (this.allProps.authentication.aws_sts.endpoint) {
86
+ configObj.endpoint = this.allProps.authentication.aws_sts.endpoint;
87
+ }
88
+ if (this.allProps.authentication.aws_sts.region) {
89
+ configObj.region = this.allProps.authentication.aws_sts.region;
90
+ }
91
+ if (this.allProps.authentication.aws_sts.proxy) {
92
+ configObj.httpOptions = {
93
+ proxy: this.allProps.authentication.aws_sts.proxy
94
+ };
95
+
96
+ if (this.allProps.authentication.aws_sts.proxyagent) {
97
+ configObj.httpOptions.agent = this.allProps.authentication.aws_sts.proxyagent;
98
+ }
99
+ }
100
+ }
101
+ // set the original AWS access information (from properties)
102
+ AWS.config.update(configObj);
103
+ const sts = new AWS.STS();
104
+ log.debug(`STS OPTIONS: ${JSON.stringify(configObj)}`);
105
+
106
+ // use STS to get the AWS access information for the user defined in STWS Params
107
+ const stsData = {
108
+ RoleArn: STSParams.RoleArn,
109
+ RoleSessionName: STSParams.RoleSessionName,
110
+ DurationSeconds: 3600
111
+ };
112
+ if (this.allProps.authentication.aws_sts && this.allProps.authentication.aws_sts.externalId) {
113
+ stsData.ExternalId = this.allProps.authentication.aws_sts.externalId;
114
+ }
115
+ if (STSParams.ExternalId) {
116
+ stsData.ExternalId = STSParams.ExternalId;
117
+ }
118
+
119
+ return sts.assumeRole(stsData, (err, data) => {
120
+ if (err) {
121
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.myid, meth, `AWS Assume Role Error ${err}`, null, null, null, null);
122
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
123
+ return callback(null, errorObj);
124
+ }
125
+ if (!data || !data.Credentials || !data.Credentials.AccessKeyId || !data.Credentials.SecretAccessKey) {
126
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.myid, meth, 'AWS Assume Role did not return credentials', null, null, null, null);
127
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
128
+ return callback(null, errorObj);
129
+ }
130
+
131
+ // if not providing a signature
132
+ if (!provideSign) {
133
+ return callback(data);
134
+ }
135
+
136
+ // extract the user specific info from the response
137
+ const accessKeyId = data.Credentials.AccessKeyId;
138
+ const secretAccessKey = data.Credentials.SecretAccessKey;
139
+ const sessionToken = data.Credentials.SessionToken;
140
+
141
+ // call the signature with the user specific information
142
+ const authOpts = aws4.sign(options, { accessKeyId, secretAccessKey, sessionToken });
143
+ if (sessionToken) {
144
+ authOpts.headers['X-Amz-Security-Token'] = sessionToken;
145
+ }
146
+
147
+ // return the headers
148
+ return callback(authOpts.headers);
149
+ });
150
+ } catch (e) {
151
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.myid, meth, 'Caught Exception', null, null, null, e);
152
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
153
+ return callback(null, errorObj);
154
+ }
155
+ }
156
+
48
157
  /**
49
158
  * @summary Gets the hcma authorization for the call
50
159
  *
@@ -113,77 +222,19 @@ class AuthenticationHandler {
113
222
  }
114
223
  log.debug(`SIG OPTIONS: ${JSON.stringify(options)}`);
115
224
 
116
- /* STS AUTHENTICATION */
117
- if (STSParams) {
225
+ /* BASIC STS AUTHENTICATION */
226
+ // This will use the adapter role via the credentials provided to identify primary role and then assume the role
227
+ // provided in the STSParams. If no adapter role credentials are provided, it will use AWS Environment
228
+ // variables (access and secret key are null) and attempt to assume the role with those.
229
+ // If the role assumption is successful the call is signed with the assumed role. If it fails, the call will error.
230
+ if (STSParams && !roleName && !this.allProps.authentication.aws_iam_role) {
118
231
  log.info('Using STS for AWS Authentication');
119
-
120
- // set up the config object
121
- const configObj = {
122
- sessionToken: this.allProps.authentication.aws_session_token,
123
- accessKeyId: this.allProps.authentication.aws_access_key,
124
- secretAccessKey: this.allProps.authentication.aws_secret_key,
125
- region: options.region
126
- };
127
- // Add optional config items (ssl, endpoint, proxy)
128
- if (this.allProps.authentication.aws_sts) {
129
- if (this.allProps.authentication.aws_sts.sslEnable === false) {
130
- configObj.sslEnabled = false;
131
- }
132
- if (this.allProps.authentication.aws_sts.endpoint) {
133
- configObj.endpoint = this.allProps.authentication.aws_sts.endpoint;
134
- }
135
- if (this.allProps.authentication.aws_sts.region) {
136
- configObj.region = this.allProps.authentication.aws_sts.region;
137
- }
138
- if (this.allProps.authentication.aws_sts.proxy) {
139
- configObj.httpOptions = {
140
- proxy: this.allProps.authentication.aws_sts.proxy
141
- };
142
-
143
- if (this.allProps.authentication.aws_sts.proxyagent) {
144
- configObj.httpOptions.agent = this.allProps.authentication.aws_sts.proxyagent;
145
- }
146
- }
147
- }
148
- // set the original AWS access information (from properties)
149
- AWS.config.update(configObj);
150
- log.debug(`STS OPTIONS: ${JSON.stringify(configObj)}`);
151
-
152
- // use STS to get the AWS access information for the user defined in STWS Params
153
- const sts = new AWS.STS();
154
- const stsData = {
155
- RoleArn: STSParams.RoleArn,
156
- RoleSessionName: STSParams.RoleSessionName,
157
- DurationSeconds: 3600
158
- };
159
- return sts.assumeRole(stsData, (err, data) => {
160
- if (err) {
161
- const errorObj = this.requestHandlerInst.formatErrorObject(this.myid, meth, `AWS Assume Role Error ${err}`, null, null, null, null);
162
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
163
- return callback(null, errorObj);
164
- }
165
- if (!data || !data.Credentials || !data.Credentials.AccessKeyId || !data.Credentials.SecretAccessKey) {
166
- const errorObj = this.requestHandlerInst.formatErrorObject(this.myid, meth, 'AWS Assume Role did not return credentials', null, null, null, null);
167
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
168
- return callback(null, errorObj);
169
- }
170
- // extract the user specific info from the response
171
- const accessKeyId = data.Credentials.AccessKeyId;
172
- const secretAccessKey = data.Credentials.SecretAccessKey;
173
- const sessionToken = data.Credentials.SessionToken;
174
-
175
- // call the signature with the user specific information
176
- const authOpts = aws4.sign(options, { accessKeyId, secretAccessKey, sessionToken });
177
- if (sessionToken) {
178
- authOpts.headers['X-Amz-Security-Token'] = sessionToken;
179
- }
180
-
181
- // return the headers
182
- return callback(authOpts.headers);
183
- });
232
+ return this.assumeAWSSTSRole(null, null, null, options, STSParams, true, callback);
184
233
  }
185
234
 
186
235
  /* ADAPTER PROPERTIES AUTHENTICATION */
236
+ // This will use the adapter role via the credentials provided to sign the call. If no adapter role credentials
237
+ // are provided, it will use AWS Environment variables (access and secret key are null) to sign the call.
187
238
  if (!roleName && !this.allProps.authentication.aws_iam_role) {
188
239
  log.info('Using Adapter PROPERTIES for AWS Authentication');
189
240
 
@@ -198,16 +249,26 @@ class AuthenticationHandler {
198
249
  }
199
250
 
200
251
  /* ROLE NAME AUTHENTICATION */
252
+ // Different scenarios to discuss here
253
+ // 1. IAM to internal AWS Server - either Task Role (roleName) or Adapter Role (aws_iam_role)
254
+ // 2. Adapter Role (aws_iam_role) assumes Task Role (STSParams or roleName)
255
+ // a. IAM to internal AWS Server for Adapter Role
256
+ // b. AWS STS for assuming Task Role(s) using Adapter Role
257
+ // 3. Pod Role assumes Adapter Role (aws_iam_role) assumes Task Role (STSParams, RoleName)
258
+ // a. AWS STS for assuming Adapter Role using AWS Environment (Pod Role)
259
+ // b. AWS STS for assuming Task Role(s) using Adapter Role
201
260
  log.info('Using roleName for AWS Authentication');
202
261
 
203
- // determine where to get roleName (task is higher priority)
262
+ // get the role to use for first credential call
204
263
  let myRole = roleName;
205
- if (!roleName) {
264
+ if (this.allProps.authentication.aws_iam_role) {
206
265
  myRole = this.allProps.authentication.aws_iam_role;
207
266
  }
267
+
268
+ // set up data for first assume role call
269
+ const stsrole = new AWS.STS();
208
270
  const myDate = new Date().getTime();
209
271
  const mySess = `${this.myid}-${myDate}`;
210
- const sts = new AWS.STS();
211
272
  const stsData = {
212
273
  RoleArn: myRole,
213
274
  RoleSessionName: mySess,
@@ -215,7 +276,7 @@ class AuthenticationHandler {
215
276
  };
216
277
 
217
278
  // change role to the role name provided
218
- return sts.assumeRole(stsData, (err, data) => {
279
+ return stsrole.assumeRole(stsData, (err, data) => {
219
280
  if (err) {
220
281
  const errorObj = this.requestHandlerInst.formatErrorObject(this.myid, meth, `AWS Assume Role Error ${err}`, null, null, null, null);
221
282
  log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
@@ -232,6 +293,17 @@ class AuthenticationHandler {
232
293
  const secretAccessKey = data.Credentials.SecretAccessKey;
233
294
  const sessionToken = data.Credentials.SessionToken;
234
295
 
296
+ /* ASSUMING TASK ROLE */
297
+ if (roleName && this.allProps.authentication.aws_iam_role) {
298
+ stsData.RoleArn = roleName;
299
+ log.info('Assuming Task Role after Adapter Role');
300
+ return this.assumeAWSSTSRole(accessKeyId, secretAccessKey, sessionToken, options, stsData, true, callback);
301
+ }
302
+ if (STSParams) {
303
+ log.info('Assuming Task Role (STS) after Adapter Role');
304
+ return this.assumeAWSSTSRole(accessKeyId, secretAccessKey, sessionToken, options, STSParams, true, callback);
305
+ }
306
+
235
307
  // sign the request
236
308
  const authOpts = aws4.sign(options, { accessKeyId, secretAccessKey, sessionToken });
237
309
  if (sessionToken) {
@@ -4617,7 +4617,7 @@ class ConnectorRest {
4617
4617
  return callback(false);
4618
4618
  }
4619
4619
  }
4620
- if (sslEnabled && !sslAcceptInvalid && (!sslCAFile || !sslCAFileContent)) {
4620
+ if (sslEnabled && !sslAcceptInvalid && (!sslCAFile && !sslCAFileContent)) {
4621
4621
  log.error(`${origin}: FAILED TO LOAD - missing required CA File`);
4622
4622
  return callback(false);
4623
4623
  }
@@ -4661,7 +4661,7 @@ class ConnectorRest {
4661
4661
  return callback(false);
4662
4662
  }
4663
4663
  }
4664
- if (sslEnabled && !sslAcceptInvalid && (!sslCAFile || !sslCAFileContent)) {
4664
+ if (sslEnabled && !sslAcceptInvalid && (!sslCAFile && !sslCAFileContent)) {
4665
4665
  log.error(`${origin}: FAILED TO LOAD - missing required CA File`);
4666
4666
  return callback(false);
4667
4667
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itentialopensource/adapter-utils",
3
- "version": "5.9.3",
3
+ "version": "5.9.5",
4
4
  "description": "Itential Adapter Utility Libraries",
5
5
  "scripts": {
6
6
  "postinstall": "node utils/setup.js",
Binary file
@@ -11,6 +11,14 @@
11
11
  "systemx.customer.com"
12
12
  ]
13
13
  },
14
+ "region": {
15
+ "type": "string",
16
+ "description": "region of the server",
17
+ "default": "",
18
+ "examples": [
19
+ "us-east-1"
20
+ ]
21
+ },
14
22
  "port": {
15
23
  "type": "integer",
16
24
  "description": "port on which to connect to the server",
@@ -290,7 +298,9 @@
290
298
  "description": "the protocol to request token from system",
291
299
  "default": "",
292
300
  "enum": [
293
- "http", "https", ""
301
+ "http",
302
+ "https",
303
+ ""
294
304
  ]
295
305
  },
296
306
  "host": {
@@ -339,6 +349,83 @@
339
349
  }
340
350
  }
341
351
  }
352
+ },
353
+ "aws_access_key": {
354
+ "type": "string",
355
+ "description": "AWS access key for authentication",
356
+ "default": "",
357
+ "examples": [
358
+ "accesskey"
359
+ ]
360
+ },
361
+ "aws_secret_key": {
362
+ "type": "string",
363
+ "description": "AWS secret key for authentication",
364
+ "default": "",
365
+ "examples": [
366
+ "secretkey"
367
+ ]
368
+ },
369
+ "aws_session_token": {
370
+ "type": "string",
371
+ "description": "AWS session token for all calls - not all systems require this",
372
+ "default": "",
373
+ "examples": [
374
+ "sessionToken"
375
+ ]
376
+ },
377
+ "aws_iam_role": {
378
+ "type": "string",
379
+ "description": "AWS IAM Role for all calls - not all systems require this",
380
+ "default": "",
381
+ "examples": [
382
+ "roleOnAllCalls"
383
+ ]
384
+ },
385
+ "aws_sts": {
386
+ "type": "object",
387
+ "properties": {
388
+ "region": {
389
+ "type": "string",
390
+ "description": "add a region to calls used for assume role",
391
+ "default": "",
392
+ "examples": [
393
+ "us-east-1"
394
+ ]
395
+ },
396
+ "sslEnable": {
397
+ "type": "boolean",
398
+ "description": "This can disable the ssl for the sts requests",
399
+ "default": true
400
+ },
401
+ "endpoint": {
402
+ "type": "string",
403
+ "description": "change the sts endpoint used for assume role",
404
+ "default": "",
405
+ "enum": [
406
+ "sts.amazonaws.com",
407
+ "sts.us-east-2.amazonaws.com",
408
+ ""
409
+ ]
410
+ },
411
+ "proxy": {
412
+ "type": "string",
413
+ "description": "add a proxy to calls used for assume role",
414
+ "default": "",
415
+ "examples": [
416
+ "https://1.1.1.1"
417
+ ]
418
+ },
419
+ "proxyagent": {
420
+ "type": "string",
421
+ "description": "define a proxy agent for calls to assume role",
422
+ "default": "",
423
+ "examples": [
424
+ "https",
425
+ "http"
426
+ ]
427
+ }
428
+ }
342
429
  }
343
430
  },
344
431
  "required": [
@@ -420,7 +507,7 @@
420
507
  "type": "integer",
421
508
  "description": "How often the healthcheck should run (in milliseconds).",
422
509
  "default": 300000,
423
- "minimum": 60000,
510
+ "minimum": 30000,
424
511
  "maximum": 3600000
425
512
  },
426
513
  "protocol": {
@@ -943,6 +1030,11 @@
943
1030
  "devicebroker": {
944
1031
  "type": "object",
945
1032
  "properties": {
1033
+ "enabled": {
1034
+ "type": "boolean",
1035
+ "description": "Whether or not the device broker calls have been mapped",
1036
+ "default": false
1037
+ },
946
1038
  "getDevice": {
947
1039
  "type": "array",
948
1040
  "description": "Broker call(s) to getDevice",
@@ -963,21 +1055,30 @@
963
1055
  "type": "object",
964
1056
  "description": "The json object with query parameters of the call to getDevice",
965
1057
  "additionalProperties": {
966
- "type": ["string", "number"]
1058
+ "type": [
1059
+ "string",
1060
+ "number"
1061
+ ]
967
1062
  }
968
1063
  },
969
1064
  "body": {
970
1065
  "type": "object",
971
1066
  "description": "The json object with body of the call to getDevice",
972
1067
  "additionalProperties": {
973
- "type": ["string", "number"]
1068
+ "type": [
1069
+ "string",
1070
+ "number"
1071
+ ]
974
1072
  }
975
1073
  },
976
1074
  "headers": {
977
1075
  "type": "object",
978
1076
  "description": "The json object with headers of the call to getDevice",
979
1077
  "additionalProperties": {
980
- "type": ["string", "number"]
1078
+ "type": [
1079
+ "string",
1080
+ "number"
1081
+ ]
981
1082
  }
982
1083
  },
983
1084
  "handleFailure": {
@@ -993,7 +1094,10 @@
993
1094
  "type": "object",
994
1095
  "description": "The json object with response fields of the call to getDevice",
995
1096
  "additionalProperties": {
996
- "type": ["string", "number"]
1097
+ "type": [
1098
+ "string",
1099
+ "number"
1100
+ ]
997
1101
  },
998
1102
  "properties": {}
999
1103
  },
@@ -1006,7 +1110,10 @@
1006
1110
  "type": "object",
1007
1111
  "description": "The json object with response fields of the call to getDevice",
1008
1112
  "additionalProperties": {
1009
- "type": ["string", "number"]
1113
+ "type": [
1114
+ "string",
1115
+ "number"
1116
+ ]
1010
1117
  },
1011
1118
  "properties": {
1012
1119
  "name": {
@@ -1091,21 +1198,30 @@
1091
1198
  "type": "object",
1092
1199
  "description": "The json object with query parameters of the call to getDevicesFiltered",
1093
1200
  "additionalProperties": {
1094
- "type": ["string", "number"]
1201
+ "type": [
1202
+ "string",
1203
+ "number"
1204
+ ]
1095
1205
  }
1096
1206
  },
1097
1207
  "body": {
1098
1208
  "type": "object",
1099
1209
  "description": "The json object with body of the call to getDevicesFiltered",
1100
1210
  "additionalProperties": {
1101
- "type": ["string", "number"]
1211
+ "type": [
1212
+ "string",
1213
+ "number"
1214
+ ]
1102
1215
  }
1103
1216
  },
1104
1217
  "headers": {
1105
1218
  "type": "object",
1106
1219
  "description": "The json object with headers of the call to getDevicesFiltered",
1107
1220
  "additionalProperties": {
1108
- "type": ["string", "number"]
1221
+ "type": [
1222
+ "string",
1223
+ "number"
1224
+ ]
1109
1225
  }
1110
1226
  },
1111
1227
  "handleFailure": {
@@ -1121,7 +1237,10 @@
1121
1237
  "type": "object",
1122
1238
  "description": "The json object with response fields of the call to getDevice",
1123
1239
  "additionalProperties": {
1124
- "type": ["string", "number"]
1240
+ "type": [
1241
+ "string",
1242
+ "number"
1243
+ ]
1125
1244
  },
1126
1245
  "properties": {}
1127
1246
  },
@@ -1134,7 +1253,10 @@
1134
1253
  "type": "object",
1135
1254
  "description": "The json object with response fields of the call to getDevicesFiltered",
1136
1255
  "additionalProperties": {
1137
- "type": ["string", "number"]
1256
+ "type": [
1257
+ "string",
1258
+ "number"
1259
+ ]
1138
1260
  },
1139
1261
  "properties": {
1140
1262
  "name": {
@@ -1187,21 +1309,30 @@
1187
1309
  "type": "object",
1188
1310
  "description": "The json object with query parameters of the call to isAlive",
1189
1311
  "additionalProperties": {
1190
- "type": ["string", "number"]
1312
+ "type": [
1313
+ "string",
1314
+ "number"
1315
+ ]
1191
1316
  }
1192
1317
  },
1193
1318
  "body": {
1194
1319
  "type": "object",
1195
1320
  "description": "The json object with body of the call to isAlive",
1196
1321
  "additionalProperties": {
1197
- "type": ["string", "number"]
1322
+ "type": [
1323
+ "string",
1324
+ "number"
1325
+ ]
1198
1326
  }
1199
1327
  },
1200
1328
  "headers": {
1201
1329
  "type": "object",
1202
1330
  "description": "The json object with headers of the call to isAlive",
1203
1331
  "additionalProperties": {
1204
- "type": ["string", "number"]
1332
+ "type": [
1333
+ "string",
1334
+ "number"
1335
+ ]
1205
1336
  }
1206
1337
  },
1207
1338
  "handleFailure": {
@@ -1217,7 +1348,10 @@
1217
1348
  "type": "object",
1218
1349
  "description": "The json object with response fields of the call to getDevice",
1219
1350
  "additionalProperties": {
1220
- "type": ["string", "number"]
1351
+ "type": [
1352
+ "string",
1353
+ "number"
1354
+ ]
1221
1355
  },
1222
1356
  "properties": {}
1223
1357
  },
@@ -1230,7 +1364,10 @@
1230
1364
  "type": "object",
1231
1365
  "description": "The json object with response fields of the call to isAlive",
1232
1366
  "additionalProperties": {
1233
- "type": ["string", "number"]
1367
+ "type": [
1368
+ "string",
1369
+ "number"
1370
+ ]
1234
1371
  },
1235
1372
  "properties": {
1236
1373
  "status": {
@@ -1268,21 +1405,30 @@
1268
1405
  "type": "object",
1269
1406
  "description": "The json object with query parameters of the call to getConfig",
1270
1407
  "additionalProperties": {
1271
- "type": ["string", "number"]
1408
+ "type": [
1409
+ "string",
1410
+ "number"
1411
+ ]
1272
1412
  }
1273
1413
  },
1274
1414
  "body": {
1275
1415
  "type": "object",
1276
1416
  "description": "The json object with body of the call to getConfig",
1277
1417
  "additionalProperties": {
1278
- "type": ["string", "number"]
1418
+ "type": [
1419
+ "string",
1420
+ "number"
1421
+ ]
1279
1422
  }
1280
1423
  },
1281
1424
  "headers": {
1282
1425
  "type": "object",
1283
1426
  "description": "The json object with headers of the call to getConfig",
1284
1427
  "additionalProperties": {
1285
- "type": ["string", "number"]
1428
+ "type": [
1429
+ "string",
1430
+ "number"
1431
+ ]
1286
1432
  }
1287
1433
  },
1288
1434
  "handleFailure": {
@@ -1298,7 +1444,10 @@
1298
1444
  "type": "object",
1299
1445
  "description": "The json object with response fields of the call to getDevice",
1300
1446
  "additionalProperties": {
1301
- "type": ["string", "number"]
1447
+ "type": [
1448
+ "string",
1449
+ "number"
1450
+ ]
1302
1451
  },
1303
1452
  "properties": {}
1304
1453
  },
@@ -1311,7 +1460,10 @@
1311
1460
  "type": "object",
1312
1461
  "description": "The json object with response fields of the call to getConfig",
1313
1462
  "additionalProperties": {
1314
- "type": ["string", "number"]
1463
+ "type": [
1464
+ "string",
1465
+ "number"
1466
+ ]
1315
1467
  },
1316
1468
  "properties": {}
1317
1469
  }
@@ -1338,21 +1490,30 @@
1338
1490
  "type": "object",
1339
1491
  "description": "The json object with query parameters of the call to getCount",
1340
1492
  "additionalProperties": {
1341
- "type": ["string", "number"]
1493
+ "type": [
1494
+ "string",
1495
+ "number"
1496
+ ]
1342
1497
  }
1343
1498
  },
1344
1499
  "body": {
1345
1500
  "type": "object",
1346
1501
  "description": "The json object with body of the call to getCount",
1347
1502
  "additionalProperties": {
1348
- "type": ["string", "number"]
1503
+ "type": [
1504
+ "string",
1505
+ "number"
1506
+ ]
1349
1507
  }
1350
1508
  },
1351
1509
  "headers": {
1352
1510
  "type": "object",
1353
1511
  "description": "The json object with headers of the call to getCount",
1354
1512
  "additionalProperties": {
1355
- "type": ["string", "number"]
1513
+ "type": [
1514
+ "string",
1515
+ "number"
1516
+ ]
1356
1517
  }
1357
1518
  },
1358
1519
  "handleFailure": {
@@ -1368,7 +1529,10 @@
1368
1529
  "type": "object",
1369
1530
  "description": "The json object with response fields of the call to getDevice",
1370
1531
  "additionalProperties": {
1371
- "type": ["string", "number"]
1532
+ "type": [
1533
+ "string",
1534
+ "number"
1535
+ ]
1372
1536
  },
1373
1537
  "properties": {}
1374
1538
  },
@@ -1381,7 +1545,10 @@
1381
1545
  "type": "object",
1382
1546
  "description": "The json object with response fields of the call to getConfig",
1383
1547
  "additionalProperties": {
1384
- "type": ["string", "number"]
1548
+ "type": [
1549
+ "string",
1550
+ "number"
1551
+ ]
1385
1552
  },
1386
1553
  "properties": {}
1387
1554
  }
@@ -1487,21 +1654,30 @@
1487
1654
  "type": "object",
1488
1655
  "description": "The json object with query parameters of the call to populate the cache",
1489
1656
  "additionalProperties": {
1490
- "type": ["string", "number"]
1657
+ "type": [
1658
+ "string",
1659
+ "number"
1660
+ ]
1491
1661
  }
1492
1662
  },
1493
1663
  "body": {
1494
1664
  "type": "object",
1495
1665
  "description": "The json object with body of the call to populate the cache",
1496
1666
  "additionalProperties": {
1497
- "type": ["string", "number"]
1667
+ "type": [
1668
+ "string",
1669
+ "number"
1670
+ ]
1498
1671
  }
1499
1672
  },
1500
1673
  "headers": {
1501
1674
  "type": "object",
1502
1675
  "description": "The json object with headers of the call to populate the cache",
1503
1676
  "additionalProperties": {
1504
- "type": ["string", "number"]
1677
+ "type": [
1678
+ "string",
1679
+ "number"
1680
+ ]
1505
1681
  }
1506
1682
  },
1507
1683
  "handleFailure": {
@@ -1517,7 +1693,10 @@
1517
1693
  "type": "object",
1518
1694
  "description": "The json object with response fields of the call to populate the cache",
1519
1695
  "additionalProperties": {
1520
- "type": ["string", "number"]
1696
+ "type": [
1697
+ "string",
1698
+ "number"
1699
+ ]
1521
1700
  },
1522
1701
  "properties": {}
1523
1702
  },
@@ -1530,7 +1709,10 @@
1530
1709
  "type": "object",
1531
1710
  "description": "The json object with response fields of the call to populate the cache",
1532
1711
  "additionalProperties": {
1533
- "type": ["string", "number"]
1712
+ "type": [
1713
+ "string",
1714
+ "number"
1715
+ ]
1534
1716
  }
1535
1717
  }
1536
1718
  }