@itentialopensource/adapter-efficientip_solidserver 0.1.1 → 0.2.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.
Files changed (42) hide show
  1. package/AUTH.md +39 -0
  2. package/BROKER.md +199 -0
  3. package/CALLS.md +169 -0
  4. package/CHANGELOG.md +9 -2
  5. package/CODE_OF_CONDUCT.md +12 -17
  6. package/CONTRIBUTING.md +88 -74
  7. package/ENHANCE.md +69 -0
  8. package/PROPERTIES.md +641 -0
  9. package/README.md +221 -571
  10. package/SUMMARY.md +9 -0
  11. package/SYSTEMINFO.md +11 -0
  12. package/TROUBLESHOOT.md +47 -0
  13. package/adapter.js +348 -57
  14. package/adapterBase.js +1021 -245
  15. package/entities/.generic/action.json +110 -5
  16. package/entities/.generic/schema.json +6 -1
  17. package/error.json +6 -0
  18. package/package.json +13 -7
  19. package/pronghorn.json +642 -378
  20. package/propertiesDecorators.json +14 -0
  21. package/propertiesSchema.json +422 -1
  22. package/refs?service=git-upload-pack +0 -0
  23. package/report/adapterInfo.json +10 -0
  24. package/report/updateReport1653233995404.json +120 -0
  25. package/sampleProperties.json +90 -1
  26. package/test/integration/adapterTestBasicGet.js +1 -1
  27. package/test/integration/adapterTestIntegration.js +26 -105
  28. package/test/unit/adapterBaseTestUnit.js +30 -25
  29. package/test/unit/adapterTestUnit.js +174 -159
  30. package/utils/adapterInfo.js +206 -0
  31. package/utils/addAuth.js +94 -0
  32. package/utils/artifactize.js +0 -0
  33. package/utils/basicGet.js +1 -14
  34. package/utils/entitiesToDB.js +179 -0
  35. package/utils/modify.js +1 -1
  36. package/utils/patches2bundledDeps.js +90 -0
  37. package/utils/pre-commit.sh +3 -0
  38. package/utils/removeHooks.js +20 -0
  39. package/utils/tbScript.js +43 -22
  40. package/utils/tbUtils.js +99 -19
  41. package/utils/testRunner.js +16 -16
  42. package/utils/troubleshootingAdapter.js +2 -26
package/utils/tbScript.js CHANGED
@@ -1,4 +1,4 @@
1
- /* eslint no-console: warn */
1
+ /* eslint-disable no-console */
2
2
  /* eslint import/no-unresolved: warn */
3
3
  /* eslint global-require: warn */
4
4
 
@@ -7,7 +7,6 @@
7
7
  /* eslint import/no-extraneous-dependencies: warn */
8
8
  /* eslint import/no-dynamic-require: warn */
9
9
 
10
- const path = require('path');
11
10
  const program = require('commander');
12
11
  const rls = require('readline-sync');
13
12
  const utils = require('./tbUtils');
@@ -15,35 +14,47 @@ const basicGet = require('./basicGet');
15
14
  const { name } = require('../package.json');
16
15
  const sampleProperties = require('../sampleProperties.json');
17
16
  const adapterPronghorn = require('../pronghorn.json');
17
+ const { addAuthInfo } = require('./addAuth');
18
18
 
19
- const { troubleshoot, getAdapterConfig, offline } = require('./troubleshootingAdapter');
19
+ const { troubleshoot, offline } = require('./troubleshootingAdapter');
20
20
 
21
- const main = async (command) => {
22
- const iapDir = path.join(__dirname, '../../../../');
23
- if (!utils.withinIAP(iapDir)) {
24
- if (command === 'connectivity') {
21
+ const executeInStandaloneMode = async (command) => {
22
+ console.info('\n> Executing the script outside of IAP installation directory');
23
+ console.info('> Using sampleProperties.json configuration');
24
+ switch (command) {
25
+ case 'install': {
26
+ console.error('Not currently in IAP directory - installation not possible');
27
+ break;
28
+ }
29
+ case 'connectivity': {
25
30
  const { host } = sampleProperties.properties;
26
31
  console.log(`perform networking diagnositics to ${host}`);
27
- await utils.runConnectivity(host);
28
- process.exit(0);
29
- } else if (command === 'healthcheck') {
32
+ utils.runConnectivity(host);
33
+ break;
34
+ }
35
+ case 'healthcheck': {
30
36
  const a = basicGet.getAdapterInstance({ properties: sampleProperties });
31
37
  await utils.healthCheck(a);
32
- process.exit(0);
33
- } else if (command === 'basicget') {
34
- await utils.runBasicGet();
35
- process.exit(0);
38
+ break;
39
+ }
40
+ case 'basicget': {
41
+ utils.runBasicGet();
42
+ break;
36
43
  }
37
- if (rls.keyInYN('Troubleshooting without IAP?')) {
38
- await offline();
44
+ default: {
45
+ if (rls.keyInYN('Troubleshooting without IAP?')) {
46
+ await offline();
47
+ }
39
48
  }
40
- process.exit(0);
41
49
  }
50
+ process.exit(0);
51
+ };
42
52
 
53
+ const executeUnderIAPInstallationDirectory = async (command) => {
43
54
  if (command === undefined) {
44
55
  await troubleshoot({}, true, true);
45
56
  } else if (command === 'install') {
46
- const { database, serviceItem, pronghornProps } = await getAdapterConfig();
57
+ const { database, serviceItem, pronghornProps } = await utils.getAdapterConfig();
47
58
  const filter = { id: pronghornProps.id };
48
59
  const profileItem = await database.collection(utils.IAP_PROFILES_COLLECTION).findOne(filter);
49
60
  if (!profileItem) {
@@ -74,14 +85,17 @@ const main = async (command) => {
74
85
  process.exit(0);
75
86
  }
76
87
  } else {
77
- utils.verifyInstallationDir(__dirname, name);
78
- utils.npmInstall();
88
+ const dirname = utils.getCurrentExecutionPath();
89
+ utils.verifyInstallationDir(dirname, name);
79
90
  utils.runTest();
80
91
  if (rls.keyInYN(`Do you want to install ${name} to IAP?`)) {
81
92
  console.log('Creating database entries...');
82
93
  const adapter = utils.createAdapter(
83
94
  pronghornProps, profileItem, sampleProperties, adapterPronghorn
84
95
  );
96
+
97
+ adapter.properties.properties = await addAuthInfo(adapter.properties.properties);
98
+
85
99
  await database.collection(utils.SERVICE_CONFIGS_COLLECTION).insertOne(adapter);
86
100
  profileItem.services.push(adapter.name);
87
101
  const update = { $set: { services: profileItem.services } };
@@ -94,7 +108,7 @@ const main = async (command) => {
94
108
  process.exit(0);
95
109
  }
96
110
  } else if (['healthcheck', 'basicget', 'connectivity'].includes(command)) {
97
- const { serviceItem } = await getAdapterConfig();
111
+ const { serviceItem } = await utils.getAdapterConfig();
98
112
  if (serviceItem) {
99
113
  const adapter = serviceItem;
100
114
  const a = basicGet.getAdapterInstance(adapter);
@@ -116,6 +130,14 @@ const main = async (command) => {
116
130
  }
117
131
  };
118
132
 
133
+ const main = async (command) => {
134
+ if (!utils.areWeUnderIAPinstallationDirectory()) {
135
+ executeInStandaloneMode(command); // configuration from sampleproperties.json
136
+ } else {
137
+ executeUnderIAPInstallationDirectory(command); // configuration from $IAP_HOME/properties.json
138
+ }
139
+ };
140
+
119
141
  program
120
142
  .command('connectivity')
121
143
  .alias('c')
@@ -154,7 +176,6 @@ program.parse(process.argv);
154
176
  if (process.argv.length < 3) {
155
177
  main();
156
178
  }
157
-
158
179
  const allowedParams = ['install', 'healthcheck', 'basicget', 'connectivity'];
159
180
  if (process.argv.length === 3 && !allowedParams.includes(process.argv[2])) {
160
181
  console.log(`unknown parameter ${process.argv[2]}`);
package/utils/tbUtils.js CHANGED
@@ -3,6 +3,7 @@
3
3
  /* eslint import/no-extraneous-dependencies: warn */
4
4
  /* eslint global-require: warn */
5
5
  /* eslint import/no-dynamic-require: warn */
6
+ /* eslint-disable no-console */
6
7
 
7
8
  const path = require('path');
8
9
  const fs = require('fs-extra');
@@ -100,8 +101,8 @@ module.exports = {
100
101
  *
101
102
  * @function decryptProperties
102
103
  */
103
- decryptProperties: (props, dirname, discovery) => {
104
- const propertyEncryptionClassPath = path.join(dirname, '../../../@itential/pronghorn-core/core/PropertyEncryption.js');
104
+ decryptProperties: (props, iapDir, discovery) => {
105
+ const propertyEncryptionClassPath = path.join(iapDir, 'node_modules/@itential/pronghorn-core/core/PropertyEncryption.js');
105
106
  const isEncrypted = props.pathProps.encrypted;
106
107
  const PropertyEncryption = discovery.require(propertyEncryptionClassPath, isEncrypted);
107
108
  const propertyEncryption = new PropertyEncryption({
@@ -177,12 +178,12 @@ module.exports = {
177
178
  verifyInstallationDir: (dirname, name) => {
178
179
  const pathArray = dirname.split(path.sep);
179
180
  const expectedPath = `node_modules/${name}`;
180
- const currentPath = pathArray.slice(pathArray.length - 4, pathArray.length - 1).join('/');
181
- if (expectedPath !== currentPath) {
182
- throw new Error(`adapter should be installed under ${expectedPath}`);
181
+ const currentPath = pathArray.slice(pathArray.length - 3, pathArray.length).join('/');
182
+ if (currentPath.trim() !== expectedPath.trim()) {
183
+ throw new Error(`adapter should be installed under ${expectedPath} but is installed under ${currentPath}`);
183
184
  }
184
185
 
185
- const serverFile = path.join(dirname, '../../../..', 'server.js');
186
+ const serverFile = path.join(dirname, '../../../', 'server.js');
186
187
  if (!fs.existsSync(serverFile)) {
187
188
  throw new Error(`adapter should be installed under IAP/${expectedPath}`);
188
189
  }
@@ -304,9 +305,10 @@ module.exports = {
304
305
  * @param {Object} adapterPronghorn - ./pronghorn.json in adapter dir
305
306
  * @param {Object} sampleProperties - './sampleProperties.json' in adapter dir
306
307
  */
307
- createAdapter: (pronghornProps, profileItem, sampleProperties, adapterPronghorn) => {
308
- const packagePath = `${__dirname.split('node_modules')[0]}package.json`;
309
- const info = JSON.parse(fs.readFileSync(packagePath));
308
+ createAdapter: function createAdapter(pronghornProps, profileItem, sampleProperties, adapterPronghorn) {
309
+ const iapDir = this.getIAPHome();
310
+ const packageFile = path.join(iapDir, 'package.json');
311
+ const info = JSON.parse(fs.readFileSync(packageFile));
310
312
  const version = parseInt(info.version.split('.')[0], 10);
311
313
 
312
314
  let adapter = {};
@@ -338,6 +340,31 @@ module.exports = {
338
340
  return adapter;
339
341
  },
340
342
 
343
+ getPronghornProps: function getPronghornProps(iapDir) {
344
+ console.log('Retrieving properties.json file...');
345
+ const rawProps = require(path.join(iapDir, 'properties.json'));
346
+ console.log('Decrypting properties...');
347
+ const { Discovery } = require(path.join(iapDir, 'node_modules/@itential/itential-utils'));
348
+ const discovery = new Discovery();
349
+ const pronghornProps = this.decryptProperties(rawProps, iapDir, discovery);
350
+ console.log('Found properties.\n');
351
+ return pronghornProps;
352
+ },
353
+
354
+ // get database connection and existing adapter config
355
+ getAdapterConfig: async function getAdapterConfig() {
356
+ const iapDir = this.getIAPHome();
357
+ const pronghornProps = this.getPronghornProps(iapDir);
358
+ console.log('Connecting to Database...');
359
+ const database = await this.connect(iapDir, pronghornProps);
360
+ console.log('Connection established.');
361
+ const { name } = require(path.join(__dirname, '..', 'package.json'));
362
+ const serviceItem = await database.collection(this.SERVICE_CONFIGS_COLLECTION).findOne(
363
+ { model: name }
364
+ );
365
+ return { database, serviceItem, pronghornProps };
366
+ },
367
+
341
368
  /**
342
369
  * @summary return async healthcheck result as a Promise
343
370
  *
@@ -373,17 +400,70 @@ module.exports = {
373
400
  },
374
401
 
375
402
  /**
376
- * @summary Check whether adapter is located within IAP node_modules
377
- * by loading properties.json. If not, return false.
378
- * @function withinIAP
379
- * @param {String} iapDir root directory of IAP
403
+ * @summary Obtain the IAP installation directory depending on how adapter is used:
404
+ * by IAP, or by npm run CLI interface
405
+ * @returns IAP installation directory or null if adapter running without IAP
406
+ * @function getIAPHome
380
407
  */
381
- withinIAP: (iapDir) => {
382
- try {
383
- const rawProps = require(path.join(iapDir, 'properties.json'));
384
- return rawProps;
385
- } catch (error) {
386
- return false;
408
+ getIAPHome: function getIAPHome() {
409
+ let IAPHomePath = null;
410
+ // check if adapter started via IAP, use path injected by core
411
+ if (process.env.iap_home) IAPHomePath = process.env.iap_home;
412
+ // check if adapter started via CLI `npm run <command>` so we have to be located under
413
+ // <IAP_HOME>/node_modules/@itentialopensource/<adapter_name>/ directory
414
+ const currentExecutionPath = this.getCurrentExecutionPath();
415
+ if (currentExecutionPath.indexOf('/node_modules') >= 0) {
416
+ [IAPHomePath] = currentExecutionPath.split('/node_modules');
387
417
  }
418
+ return IAPHomePath;
419
+ },
420
+
421
+ /**
422
+ * @summary get current execution path without resolving symbolic links,
423
+ * use `pwd` command wihout '-P' option (resolving symlinks) https://linux.die.net/man/1/pwd
424
+ * @returns
425
+ * @function getCurrentExecutionPAth
426
+ */
427
+ getCurrentExecutionPath: function getCurrentExecutionPAth() {
428
+ const { stdout } = this.systemSync('pwd', true);
429
+ return stdout.trim();
430
+ },
431
+
432
+ /**
433
+ * @summary checks if command executed from <IAP_HOME>/node_modules/@itentialopensource/<adapter_name>/ location
434
+ * @returns true if command executed under <IAP_HOME>/node_modules/@itentialopensource/<adapter_name>/ path
435
+ * @function areWeUnderIAPinstallationDirectory
436
+ */
437
+ areWeUnderIAPinstallationDirectory: function areWeUnderIAPinstallationDirectory() {
438
+ return path.join(this.getCurrentExecutionPath(), '../../..') === this.getIAPHome();
439
+ },
440
+
441
+ /**
442
+ * @summary connect to mongodb
443
+ *
444
+ * @function connect
445
+ * @param {Object} properties - pronghornProps
446
+ */
447
+ connect: async function connect(iapDir, properties) {
448
+ let dbConnectionProperties = {};
449
+ if (properties.mongoProps) {
450
+ dbConnectionProperties = properties.mongoProps;
451
+ } else if (properties.mongo) {
452
+ if (properties.mongo.url) {
453
+ dbConnectionProperties.url = properties.mongo.url;
454
+ } else {
455
+ dbConnectionProperties.url = `mongodb://${properties.mongo.host}:${properties.mongo.port}`;
456
+ }
457
+ dbConnectionProperties.db = properties.mongo.database;
458
+ }
459
+ if (!dbConnectionProperties.url || !dbConnectionProperties.db) {
460
+ throw new Error('Mongo properties are not specified in IAP configuration!');
461
+ }
462
+
463
+ const { MongoDBConnection } = require(path.join(iapDir, 'node_modules/@itential/database'));
464
+ const connection = new MongoDBConnection(dbConnectionProperties);
465
+ const database = await connection.connect(true);
466
+ return database;
388
467
  }
468
+
389
469
  };
@@ -47,11 +47,11 @@ function replaceTestVars(test) {
47
47
  let intTest = fs.readFileSync(test, 'utf8');
48
48
 
49
49
  // replace stub variable but check if it exists first
50
- let sindex = intTest.indexOf('const stub');
50
+ let sindex = intTest.indexOf('samProps.stub');
51
51
  let eindex = intTest.indexOf(';', sindex);
52
52
  let replStr = intTest.substring(sindex, eindex + 1);
53
53
  if (sindex > -1) {
54
- intTest = intTest.replace(replStr, `const stub = ${stub};`);
54
+ intTest = intTest.replace(replStr, `samProps.stub = ${stub};`);
55
55
  }
56
56
 
57
57
  // replace isRapidFail variable but check if it exists first
@@ -71,46 +71,46 @@ function replaceTestVars(test) {
71
71
  }
72
72
 
73
73
  // replace host variable
74
- sindex = intTest.indexOf('const host');
74
+ sindex = intTest.indexOf('samProps.host');
75
75
  eindex = intTest.indexOf(';', sindex);
76
76
  replStr = intTest.substring(sindex, eindex + 1);
77
- intTest = intTest.replace(replStr, `const host = '${host}';`);
77
+ intTest = intTest.replace(replStr, `samProps.host = '${host}';`);
78
78
 
79
79
  // replace username variable
80
- sindex = intTest.indexOf('const username');
80
+ sindex = intTest.indexOf('samProps.authentication.username');
81
81
  eindex = intTest.indexOf(';', sindex);
82
82
  replStr = intTest.substring(sindex, eindex + 1);
83
- intTest = intTest.replace(replStr, `const username = '${username}';`);
83
+ intTest = intTest.replace(replStr, `samProps.authentication.username = '${username}';`);
84
84
 
85
85
  // replace password variable
86
- sindex = intTest.indexOf('const password');
86
+ sindex = intTest.indexOf('samProps.authentication.password');
87
87
  eindex = intTest.indexOf(';', sindex);
88
88
  replStr = intTest.substring(sindex, eindex + 1);
89
- intTest = intTest.replace(replStr, `const password = '${password}';`);
89
+ intTest = intTest.replace(replStr, `samProps.authentication.password = '${password}';`);
90
90
 
91
91
  // replace protocol variable
92
- sindex = intTest.indexOf('const protocol');
92
+ sindex = intTest.indexOf('samProps.protocol');
93
93
  eindex = intTest.indexOf(';', sindex);
94
94
  replStr = intTest.substring(sindex, eindex + 1);
95
- intTest = intTest.replace(replStr, `const protocol = '${protocol}';`);
95
+ intTest = intTest.replace(replStr, `samProps.protocol = '${protocol}';`);
96
96
 
97
97
  // replace port variable
98
- sindex = intTest.indexOf('const port');
98
+ sindex = intTest.indexOf('samProps.port');
99
99
  eindex = intTest.indexOf(';', sindex);
100
100
  replStr = intTest.substring(sindex, eindex + 1);
101
- intTest = intTest.replace(replStr, `const port = ${port};`);
101
+ intTest = intTest.replace(replStr, `samProps.port = ${port};`);
102
102
 
103
103
  // replace sslenable variable
104
- sindex = intTest.indexOf('const sslenable');
104
+ sindex = intTest.indexOf('samProps.ssl.enabled');
105
105
  eindex = intTest.indexOf(';', sindex);
106
106
  replStr = intTest.substring(sindex, eindex + 1);
107
- intTest = intTest.replace(replStr, `const sslenable = ${sslenable};`);
107
+ intTest = intTest.replace(replStr, `samProps.ssl.enabled = ${sslenable};`);
108
108
 
109
109
  // replace sslinvalid variable
110
- sindex = intTest.indexOf('const sslinvalid');
110
+ sindex = intTest.indexOf('samProps.ssl.accept_invalid_cert');
111
111
  eindex = intTest.indexOf(';', sindex);
112
112
  replStr = intTest.substring(sindex, eindex + 1);
113
- intTest = intTest.replace(replStr, `const sslinvalid = ${sslinvalid};`);
113
+ intTest = intTest.replace(replStr, `samProps.ssl.accept_invalid_cert = ${sslinvalid};`);
114
114
 
115
115
  console.log(`Updates to ${test} complete`);
116
116
  fs.writeFileSync(test, intTest);
@@ -117,30 +117,6 @@ const VerifyHealthCheckEndpoint = (serviceItem, props, scriptFlag) => {
117
117
  return { result, updatedAdapter };
118
118
  };
119
119
 
120
- const getPronghornProps = (iapDir) => {
121
- console.log('Retrieving properties.json file...');
122
- const rawProps = require(path.join(iapDir, 'properties.json'));
123
- console.log('Decrypting properties...');
124
- const { Discovery } = require('@itential/itential-utils');
125
- const discovery = new Discovery();
126
- const pronghornProps = utils.decryptProperties(rawProps, __dirname, discovery);
127
- console.log('Found properties.\n');
128
- return pronghornProps;
129
- };
130
-
131
- // get database connection and existing adapter config
132
- const getAdapterConfig = async () => {
133
- const iapDir = path.join(__dirname, '../../../../');
134
- const pronghornProps = getPronghornProps(iapDir);
135
- console.log('Connecting to Database...');
136
- const database = await basicGet.connect(pronghornProps);
137
- console.log('Connection established.');
138
- const serviceItem = await database.collection(utils.SERVICE_CONFIGS_COLLECTION).findOne(
139
- { model: name }
140
- );
141
- return { database, serviceItem, pronghornProps };
142
- };
143
-
144
120
  const offline = async () => {
145
121
  console.log('Start offline troubleshooting');
146
122
  const { updatedAdapter } = VerifyHealthCheckEndpoint({ properties: sampleProperties }, {}, true);
@@ -159,7 +135,7 @@ const offline = async () => {
159
135
 
160
136
  const troubleshoot = async (props, scriptFlag, persistFlag, adapter) => {
161
137
  // get database connection and existing adapter config
162
- const { database, serviceItem } = await getAdapterConfig();
138
+ const { database, serviceItem } = await utils.getAdapterConfig();
163
139
  // where troubleshoot should start
164
140
  if (serviceItem) {
165
141
  if (!scriptFlag || rls.keyInYN(`Start verifying the connection and authentication properties for ${name}?`)) {
@@ -211,4 +187,4 @@ const troubleshoot = async (props, scriptFlag, persistFlag, adapter) => {
211
187
  return null;
212
188
  };
213
189
 
214
- module.exports = { troubleshoot, getAdapterConfig, offline };
190
+ module.exports = { troubleshoot, offline };