@itentialopensource/adapter-gcp_compute 1.0.0 → 1.0.1
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 +33 -4
- package/adapterBase.js +22 -0
- package/entities/.generic/action.json +5 -5
- package/package.json +11 -7
- package/refs?service=git-upload-pack +0 -0
- package/test/unit/adapterBaseTestUnit.js +1 -1
- package/test/unit/adapterTestUnit.js +2 -2
- package/utils/addAuth.js +94 -0
- package/utils/basicGet.js +1 -14
- package/utils/entitiesToDB.js +224 -0
- package/utils/modify.js +1 -1
- package/utils/removeHooks.js +20 -0
- package/utils/tbScript.js +14 -8
- package/utils/tbUtils.js +59 -3
- package/utils/troubleshootingAdapter.js +2 -26
package/CHANGELOG.md
CHANGED
package/adapter.js
CHANGED
|
@@ -34,7 +34,7 @@ class GcpCompute extends AdapterBaseCl {
|
|
|
34
34
|
|
|
35
35
|
// for gtoken documentation see https://googleapis.dev/nodejs/gtoken/latest/index.html
|
|
36
36
|
this.configureGtokenFromProps();
|
|
37
|
-
this.keyObj = this.readPropsKeyFile();
|
|
37
|
+
// this.keyObj = this.readPropsKeyFile(); // jorrok 2021-12-20 this method shoud not be called if we have a key; but as it stands, healthCheck depends on keyObj :-(
|
|
38
38
|
// log.debug(`constructor keyObj is ${JSON.stringify(this.keyObj)}`)
|
|
39
39
|
|
|
40
40
|
// const restFunctionNames = this.getWorkflowFunctions();
|
|
@@ -128,7 +128,8 @@ class GcpCompute extends AdapterBaseCl {
|
|
|
128
128
|
'refreshAccessTokenPromise',
|
|
129
129
|
'refreshAuthorizationHeader',
|
|
130
130
|
'refreshAuthorizationAndIdentifyRequest',
|
|
131
|
-
'getToken'
|
|
131
|
+
'getToken',
|
|
132
|
+
'generateKeyObjFromProps'
|
|
132
133
|
];
|
|
133
134
|
if (!inIgnore && Array.isArray(inIgnore)) {
|
|
134
135
|
myIgnore = inIgnore;
|
|
@@ -602,12 +603,35 @@ class GcpCompute extends AdapterBaseCl {
|
|
|
602
603
|
return args.reduce((subObj, level) => subObj && subObj[level], obj);
|
|
603
604
|
}
|
|
604
605
|
|
|
605
|
-
|
|
606
|
+
generateKeyObjFromProps(someProps) {
|
|
607
|
+
// the blank object comes from https://cloud.google.com/iam/docs/creating-managing-service-account-keys#creating
|
|
608
|
+
// the only properties you should be supplying (at most) are the ones with hyphenated dummy values
|
|
609
|
+
// ie: project_id, private_key_id, private_key, client_email, client_id, client_x509_cert_url
|
|
610
|
+
// of which as of ADAPT-1898 only project_id is used (for the adapter's own healthCheck)
|
|
611
|
+
const blank = {
|
|
612
|
+
type: 'service_account',
|
|
613
|
+
project_id: 'project-id',
|
|
614
|
+
private_key_id: 'key-id',
|
|
615
|
+
private_key: '-----BEGIN PRIVATE KEY-----\nprivate-key\n-----END PRIVATE KEY-----\n',
|
|
616
|
+
client_email: 'service-account-email',
|
|
617
|
+
client_id: 'client-id',
|
|
618
|
+
auth_uri: 'https://accounts.google.com/o/oauth2/auth',
|
|
619
|
+
token_uri: 'https://accounts.google.com/o/oauth2/token',
|
|
620
|
+
auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs',
|
|
621
|
+
client_x509_cert_url: 'https://www.googleapis.com/robot/v1/metadata/x509/service-account-email'
|
|
622
|
+
};
|
|
623
|
+
this.keyObj = Object.keys(blank).reduce((gen, key) => ({
|
|
624
|
+
...gen,
|
|
625
|
+
[key]: someProps.hasOwnProperty(key) ? someProps[key] : blank[key] // eslint-disable-line no-prototype-builtins
|
|
626
|
+
}), {});
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
readPropsKeyFile(keyFile) {
|
|
606
630
|
const meth = 'adapter-readPropsKeyFile';
|
|
607
631
|
const origin = `${this.id}-${meth}`;
|
|
608
632
|
log.trace(origin);
|
|
609
633
|
try {
|
|
610
|
-
const keyFile = this.getNested(this, 'allProps', 'authentication', 'configureGtoken', 'keyFile') || process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
634
|
+
// const keyFile = this.getNested(this, 'allProps', 'authentication', 'configureGtoken', 'keyFile') || process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
611
635
|
// log.debug(`readPropsKeyFile keyFile is ${keyFile}`)
|
|
612
636
|
if (!keyFile) {
|
|
613
637
|
throw new Error('No keyFile specified in Service Config or GOOGLE_APPLICATION_CREDENTIALS');
|
|
@@ -633,7 +657,10 @@ class GcpCompute extends AdapterBaseCl {
|
|
|
633
657
|
const configureGtoken = this.getNested(this, 'allProps', 'authentication', 'configureGtoken') || {};
|
|
634
658
|
if (!configureGtoken.key) {
|
|
635
659
|
configureGtoken.keyFile = configureGtoken.keyFile || process.env.GOOGLE_APPLICATION_CREDENTIALS || null;
|
|
660
|
+
this.keyObj = this.readPropsKeyFile(configureGtoken.keyFile);
|
|
636
661
|
} else {
|
|
662
|
+
const { project_id } = configureGtoken; // eslint-disable-line camelcase
|
|
663
|
+
this.generateKeyObjFromProps({ project_id }); // eslint-disable-line camelcase
|
|
637
664
|
delete configureGtoken.keyFile;
|
|
638
665
|
}
|
|
639
666
|
if (configureGtoken.key || configureGtoken.keyFile) {
|
|
@@ -738,6 +765,7 @@ class GcpCompute extends AdapterBaseCl {
|
|
|
738
765
|
if (kfc && kfc.private_key) {
|
|
739
766
|
keyFile = null; // eslint-disable-line no-param-reassign
|
|
740
767
|
key = kfc.private_key; // eslint-disable-line no-param-reassign
|
|
768
|
+
this.keyObj = kfc;
|
|
741
769
|
} else {
|
|
742
770
|
throw new Error('Did not obtain private_key from keyFileContents');
|
|
743
771
|
}
|
|
@@ -760,6 +788,7 @@ class GcpCompute extends AdapterBaseCl {
|
|
|
760
788
|
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
|
761
789
|
return callback(null, errorObj);
|
|
762
790
|
}
|
|
791
|
+
if (keyFile) this.keyObj = this.readPropsKeyFile(keyFile);
|
|
763
792
|
|
|
764
793
|
// build the options for GoogleToken and call it
|
|
765
794
|
const gOptions = Array.from(arguments).reduce((r, v, i) => { // eslint-disable-line prefer-rest-params
|
package/adapterBase.js
CHANGED
|
@@ -22,6 +22,7 @@ const AjvCl = require('ajv');
|
|
|
22
22
|
const PropUtilCl = require('@itentialopensource/adapter-utils').PropertyUtility;
|
|
23
23
|
const RequestHandlerCl = require('@itentialopensource/adapter-utils').RequestHandler;
|
|
24
24
|
|
|
25
|
+
const entitiesToDB = require(path.join(__dirname, 'utils/entitiesToDB'));
|
|
25
26
|
const troubleshootingAdapter = require(path.join(__dirname, 'utils/troubleshootingAdapter'));
|
|
26
27
|
const tbUtils = require(path.join(__dirname, 'utils/tbUtils'));
|
|
27
28
|
|
|
@@ -1001,6 +1002,27 @@ class AdapterBase extends EventEmitterCl {
|
|
|
1001
1002
|
return [];
|
|
1002
1003
|
}
|
|
1003
1004
|
}
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* @summary moves entities to mongo database
|
|
1008
|
+
*
|
|
1009
|
+
* @function moveEntitiesToDB
|
|
1010
|
+
*
|
|
1011
|
+
* @return {Callback} - containing the response from the mongo transaction
|
|
1012
|
+
*/
|
|
1013
|
+
moveEntitiesToDB(callback) {
|
|
1014
|
+
const meth = 'adapterBase-moveEntitiesToDB';
|
|
1015
|
+
const origin = `${this.id}-${meth}`;
|
|
1016
|
+
log.trace(origin);
|
|
1017
|
+
|
|
1018
|
+
try {
|
|
1019
|
+
return callback(entitiesToDB.moveEntitiesToDB(__dirname, { pronghornProps: this.allProps, id: this.id }), null);
|
|
1020
|
+
} catch (err) {
|
|
1021
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, err);
|
|
1022
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
|
1023
|
+
return callback(null, errorObj);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1004
1026
|
}
|
|
1005
1027
|
|
|
1006
1028
|
module.exports = AdapterBase;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "getGenerics",
|
|
5
5
|
"protocol": "REST",
|
|
6
6
|
"method": "GET",
|
|
7
|
-
"entitypath": "{base_path}/{version}/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}?{query}",
|
|
7
|
+
"entitypath": "{base_path}/{version}/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}/{pathv11}/{pathv12}/{pathv13}/{pathv14}/{pathv15}/{pathv16}/{pathv17}/{pathv18}/{pathv19}/{pathv20}?{query}",
|
|
8
8
|
"requestSchema": "schema.json",
|
|
9
9
|
"responseSchema": "schema.json",
|
|
10
10
|
"timeout": 0,
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"name": "createGeneric",
|
|
26
26
|
"protocol": "REST",
|
|
27
27
|
"method": "POST",
|
|
28
|
-
"entitypath": "{base_path}/{version}/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}?{query}",
|
|
28
|
+
"entitypath": "{base_path}/{version}/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}/{pathv11}/{pathv12}/{pathv13}/{pathv14}/{pathv15}/{pathv16}/{pathv17}/{pathv18}/{pathv19}/{pathv20}?{query}",
|
|
29
29
|
"requestSchema": "schema.json",
|
|
30
30
|
"responseSchema": "schema.json",
|
|
31
31
|
"timeout": 0,
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"name": "updateGeneric",
|
|
47
47
|
"protocol": "REST",
|
|
48
48
|
"method": "PUT",
|
|
49
|
-
"entitypath": "{base_path}/{version}/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}?{query}",
|
|
49
|
+
"entitypath": "{base_path}/{version}/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}/{pathv11}/{pathv12}/{pathv13}/{pathv14}/{pathv15}/{pathv16}/{pathv17}/{pathv18}/{pathv19}/{pathv20}?{query}",
|
|
50
50
|
"requestSchema": "schema.json",
|
|
51
51
|
"responseSchema": "schema.json",
|
|
52
52
|
"timeout": 0,
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"name": "patchGeneric",
|
|
68
68
|
"protocol": "REST",
|
|
69
69
|
"method": "PATCH",
|
|
70
|
-
"entitypath": "{base_path}/{version}/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}?{query}",
|
|
70
|
+
"entitypath": "{base_path}/{version}/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}/{pathv11}/{pathv12}/{pathv13}/{pathv14}/{pathv15}/{pathv16}/{pathv17}/{pathv18}/{pathv19}/{pathv20}?{query}",
|
|
71
71
|
"requestSchema": "schema.json",
|
|
72
72
|
"responseSchema": "schema.json",
|
|
73
73
|
"timeout": 0,
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"name": "deleteGeneric",
|
|
89
89
|
"protocol": "REST",
|
|
90
90
|
"method": "DELETE",
|
|
91
|
-
"entitypath": "{base_path}/{version}/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}?{query}",
|
|
91
|
+
"entitypath": "{base_path}/{version}/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}/{pathv11}/{pathv12}/{pathv13}/{pathv14}/{pathv15}/{pathv16}/{pathv17}/{pathv18}/{pathv19}/{pathv20}?{query}",
|
|
92
92
|
"requestSchema": "schema.json",
|
|
93
93
|
"responseSchema": "schema.json",
|
|
94
94
|
"timeout": 0,
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itentialopensource/adapter-gcp_compute",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "This adapter integrates with system described as: computeEngineApi.",
|
|
5
5
|
"main": "adapter.js",
|
|
6
|
-
"wizardVersion": "2.44.
|
|
7
|
-
"engineVersion": "1.59.
|
|
6
|
+
"wizardVersion": "2.44.7",
|
|
7
|
+
"engineVersion": "1.59.50",
|
|
8
8
|
"adapterType": "http",
|
|
9
9
|
"scripts": {
|
|
10
10
|
"artifactize": "npm i && node utils/packModificationScript.js",
|
|
11
|
-
"preinstall": "node utils/setup.js",
|
|
11
|
+
"preinstall": "node utils/setup.js && npm install --package-lock-only --ignore-scripts && npx npm-force-resolutions",
|
|
12
12
|
"lint": "node --max_old_space_size=4096 ./node_modules/eslint/bin/eslint.js . --ext .json --ext .js",
|
|
13
13
|
"lint:errors": "node --max_old_space_size=4096 ./node_modules/eslint/bin/eslint.js . --ext .json --ext .js --quiet",
|
|
14
14
|
"test:baseunit": "mocha test/unit/adapterBaseTestUnit.js --LOG=error",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"test:integration": "mocha test/integration/adapterTestIntegration.js --LOG=error",
|
|
17
17
|
"test:cover": "nyc --reporter html --reporter text mocha --reporter dot test/*",
|
|
18
18
|
"test": "npm run test:baseunit && npm run test:unit && npm run test:integration",
|
|
19
|
-
"adapter:install": "node utils/tbScript.js install",
|
|
19
|
+
"adapter:install": "npm i && node utils/tbScript.js install",
|
|
20
20
|
"adapter:checkMigrate": "node utils/checkMigrate.js",
|
|
21
21
|
"adapter:findPath": "node utils/findPath.js",
|
|
22
22
|
"adapter:migrate": "node utils/modify.js -m",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"healthcheck": "node utils/tbScript.js healthcheck",
|
|
27
27
|
"basicget": "node utils/tbScript.js basicget",
|
|
28
28
|
"connectivity": "node utils/tbScript.js connectivity",
|
|
29
|
-
"deploy": "npm publish --registry=
|
|
29
|
+
"deploy": "npm publish --registry=https://registry.npmjs.org --access=public",
|
|
30
30
|
"build": "npm run deploy"
|
|
31
31
|
},
|
|
32
32
|
"keywords": [
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"author": "Itential",
|
|
55
55
|
"homepage": "https://gitlab.com/itentialopensource/adapters/cloud/adapter-gcp_compute#readme",
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@itentialopensource/adapter-utils": "^4.44.
|
|
57
|
+
"@itentialopensource/adapter-utils": "^4.44.11",
|
|
58
58
|
"ajv": "^6.12.0",
|
|
59
59
|
"axios": "^0.21.0",
|
|
60
60
|
"commander": "^2.20.0",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"gtoken": "^5.2.1",
|
|
63
63
|
"mocha": "^9.0.1",
|
|
64
64
|
"mocha-param": "^2.0.1",
|
|
65
|
+
"mongodb": "^4.1.0",
|
|
65
66
|
"network-diagnostics": "^0.5.3",
|
|
66
67
|
"nyc": "^15.1.0",
|
|
67
68
|
"readline-sync": "^1.4.10",
|
|
@@ -77,5 +78,8 @@
|
|
|
77
78
|
"package-json-validator": "^0.6.3",
|
|
78
79
|
"testdouble": "^3.16.1"
|
|
79
80
|
},
|
|
81
|
+
"resolutions": {
|
|
82
|
+
"minimist": "^1.2.5"
|
|
83
|
+
},
|
|
80
84
|
"private": false
|
|
81
85
|
}
|
|
Binary file
|
|
@@ -317,7 +317,7 @@ describe('[unit] Adapter Base Test', () => {
|
|
|
317
317
|
});
|
|
318
318
|
it('should return a list of functions', (done) => {
|
|
319
319
|
const returnedFunctions = ['addEntityCache', 'capabilityResults', 'checkActionFiles', 'checkProperties', 'connect', 'encryptProperty',
|
|
320
|
-
'entityInList', 'findPath', 'getAllCapabilities', 'getAllFunctions', 'getQueue', 'getWorkflowFunctions', 'healthCheck',
|
|
320
|
+
'entityInList', 'findPath', 'getAllCapabilities', 'getAllFunctions', 'getQueue', 'getWorkflowFunctions', 'healthCheck', 'moveEntitiesToDB',
|
|
321
321
|
'refreshProperties', 'runBasicGet', 'runConnectivity', 'runHealthcheck', 'suspend', 'troubleshoot', 'unsuspend', 'updateAdapterConfiguration', 'addListener',
|
|
322
322
|
'emit', 'eventNames', 'getMaxListeners', 'listenerCount', 'listeners', 'off', 'on', 'once', 'prependListener',
|
|
323
323
|
'prependOnceListener', 'rawListeners', 'removeAllListeners', 'removeListener', 'setMaxListeners'];
|
|
@@ -362,7 +362,7 @@ describe('[unit] GcpCompute Adapter Test', () => {
|
|
|
362
362
|
assert.notEqual(undefined, packageDotJson.scripts);
|
|
363
363
|
assert.notEqual(null, packageDotJson.scripts);
|
|
364
364
|
assert.notEqual('', packageDotJson.scripts);
|
|
365
|
-
assert.equal('node utils/setup.js', packageDotJson.scripts.preinstall);
|
|
365
|
+
assert.equal('node utils/setup.js && npm install --package-lock-only --ignore-scripts && npx npm-force-resolutions', packageDotJson.scripts.preinstall);
|
|
366
366
|
assert.equal('node --max_old_space_size=4096 ./node_modules/eslint/bin/eslint.js . --ext .json --ext .js', packageDotJson.scripts.lint);
|
|
367
367
|
assert.equal('node --max_old_space_size=4096 ./node_modules/eslint/bin/eslint.js . --ext .json --ext .js --quiet', packageDotJson.scripts['lint:errors']);
|
|
368
368
|
assert.equal('mocha test/unit/adapterBaseTestUnit.js --LOG=error', packageDotJson.scripts['test:baseunit']);
|
|
@@ -370,7 +370,7 @@ describe('[unit] GcpCompute Adapter Test', () => {
|
|
|
370
370
|
assert.equal('mocha test/integration/adapterTestIntegration.js --LOG=error', packageDotJson.scripts['test:integration']);
|
|
371
371
|
assert.equal('nyc --reporter html --reporter text mocha --reporter dot test/*', packageDotJson.scripts['test:cover']);
|
|
372
372
|
assert.equal('npm run test:baseunit && npm run test:unit && npm run test:integration', packageDotJson.scripts.test);
|
|
373
|
-
assert.equal('npm publish --registry=
|
|
373
|
+
assert.equal('npm publish --registry=https://registry.npmjs.org --access=public', packageDotJson.scripts.deploy);
|
|
374
374
|
assert.equal('npm run deploy', packageDotJson.scripts.build);
|
|
375
375
|
done();
|
|
376
376
|
} catch (error) {
|
package/utils/addAuth.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* eslint-disable no-plusplus */
|
|
2
|
+
/* eslint global-require: warn */
|
|
3
|
+
/* eslint import/no-dynamic-require: warn */
|
|
4
|
+
|
|
5
|
+
const rls = require('readline-sync');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
|
|
9
|
+
function getQuestions(props, obj) {
|
|
10
|
+
const questions = props.map((p) => `${p}: ${(obj[p] !== undefined) ? `(${obj[p]})` : ''} `);
|
|
11
|
+
return questions;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// function outputs each property for user to edit/confirm
|
|
15
|
+
// props are the fields that need to be changed depending on what the user selects
|
|
16
|
+
// obj is the JSON object that's being updated
|
|
17
|
+
function confirm(props, obj) {
|
|
18
|
+
// create array of questions
|
|
19
|
+
const updatedObj = obj;
|
|
20
|
+
getQuestions(props, obj).forEach((q) => {
|
|
21
|
+
const answer = rls.question(q);
|
|
22
|
+
// only update the field if the answer is NOT and empty string
|
|
23
|
+
if (answer) {
|
|
24
|
+
updatedObj[q.split(':')[0].trim()] = answer;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return updatedObj;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const updateBasicAuth = (auth) => {
|
|
31
|
+
const propsToUpdate = ['username', 'password', 'auth_field', 'auth_field_format'];
|
|
32
|
+
return confirm(propsToUpdate, auth);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const updateStaticTokenAuth = (auth) => {
|
|
36
|
+
const propsToUpdate = ['token', 'auth_field', 'auth_field_format'];
|
|
37
|
+
return confirm(propsToUpdate, auth);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function updateTokenSchemas(user, pw, token) {
|
|
41
|
+
let schemaPath = path.join(__dirname, '..', 'entities/.system/schemaTokenReq.json');
|
|
42
|
+
const reqSchema = require(schemaPath);
|
|
43
|
+
reqSchema.properties.username.external_name = user;
|
|
44
|
+
reqSchema.properties.password.external_name = pw;
|
|
45
|
+
fs.writeFileSync(schemaPath, JSON.stringify(reqSchema, null, 2));
|
|
46
|
+
schemaPath = path.join(__dirname, '..', 'entities/.system/schemaTokenResp.json');
|
|
47
|
+
const respSchema = require(schemaPath);
|
|
48
|
+
respSchema.properties.token.external_name = token;
|
|
49
|
+
fs.writeFileSync(schemaPath, JSON.stringify(respSchema, null, 2));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function updateRequestToken(auth) {
|
|
53
|
+
const propsToUpdate = [
|
|
54
|
+
'username',
|
|
55
|
+
'password',
|
|
56
|
+
'auth_field',
|
|
57
|
+
'auth_field_format',
|
|
58
|
+
'token_user_field',
|
|
59
|
+
'token_password_field',
|
|
60
|
+
'token_result_field',
|
|
61
|
+
'token_URI_path'
|
|
62
|
+
];
|
|
63
|
+
const newAuth = confirm(propsToUpdate, auth);
|
|
64
|
+
updateTokenSchemas(newAuth.token_user_field, newAuth.token_password_field, newAuth.token_result_field);
|
|
65
|
+
|
|
66
|
+
return newAuth;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// prompt users to pick an auth method from the list above
|
|
70
|
+
const addAuthInfo = (props) => {
|
|
71
|
+
const authOptions = [
|
|
72
|
+
'basic user_password',
|
|
73
|
+
'static_token',
|
|
74
|
+
'request_token',
|
|
75
|
+
'no_authentication'
|
|
76
|
+
];
|
|
77
|
+
const newProps = confirm(['host', 'port', 'base_path'], props);
|
|
78
|
+
|
|
79
|
+
const newAuthMethod = authOptions[rls.keyInSelect(authOptions, 'Which authentication method?')];
|
|
80
|
+
newProps.authentication.auth_method = newAuthMethod;
|
|
81
|
+
|
|
82
|
+
if (newAuthMethod === 'basic user_password') {
|
|
83
|
+
newProps.authentication = updateBasicAuth(newProps.authentication);
|
|
84
|
+
} else if (newAuthMethod === 'static_token') {
|
|
85
|
+
newProps.authentication = updateStaticTokenAuth(newProps.authentication);
|
|
86
|
+
} else if (newAuthMethod === 'request_token') {
|
|
87
|
+
newProps.authentication = updateRequestToken(newProps.authentication);
|
|
88
|
+
}
|
|
89
|
+
console.log('Connectivity and authentication properties have been configured');
|
|
90
|
+
console.log('If you want to make changes, rerun this script to reinstall the adapter');
|
|
91
|
+
return newProps;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
module.exports = { addAuthInfo };
|
package/utils/basicGet.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
/* eslint import/no-extraneous-dependencies: warn */
|
|
5
5
|
/* eslint global-require: warn */
|
|
6
6
|
/* eslint import/no-unresolved: warn */
|
|
7
|
+
/* eslint import/no-dynamic-require: warn */
|
|
7
8
|
|
|
8
9
|
const winston = require('winston');
|
|
9
10
|
|
|
@@ -43,20 +44,6 @@ const basicGet = {
|
|
|
43
44
|
adapter.id,
|
|
44
45
|
adapterProps
|
|
45
46
|
);
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* @summary connect to mongodb
|
|
50
|
-
*
|
|
51
|
-
* @function connect
|
|
52
|
-
* @param {Object} properties - pronghornProps
|
|
53
|
-
*/
|
|
54
|
-
connect: async function connect(properties) {
|
|
55
|
-
// Connect to Mongo
|
|
56
|
-
const { MongoDBConnection } = require('@itential/database');
|
|
57
|
-
const connection = new MongoDBConnection(properties.mongoProps);
|
|
58
|
-
const database = await connection.connect(true);
|
|
59
|
-
return database;
|
|
60
47
|
}
|
|
61
48
|
};
|
|
62
49
|
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/* @copyright Itential, LLC 2021 */
|
|
2
|
+
|
|
3
|
+
// Set globals
|
|
4
|
+
/* global log */
|
|
5
|
+
|
|
6
|
+
/* eslint import/no-dynamic-require: warn */
|
|
7
|
+
/* eslint global-require: warn */
|
|
8
|
+
/* eslint no-unused-vars: warn */
|
|
9
|
+
/* eslint import/no-unresolved: warn */
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This script is used to read through an adapter's entities files
|
|
13
|
+
* and then creates documents and enters them into the IAP mongodb
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const { MongoClient } = require('mongodb');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
// const { argv } = require('process');
|
|
20
|
+
// const { string } = require('yargs');
|
|
21
|
+
|
|
22
|
+
// get the pronghorn database information
|
|
23
|
+
const getPronghornProps = async (iapDir) => {
|
|
24
|
+
log.trace('Retrieving properties.json file...');
|
|
25
|
+
const rawProps = require(path.join(iapDir, 'properties.json'));
|
|
26
|
+
log.trace('Decrypting properties...');
|
|
27
|
+
const { PropertyEncryption } = require('@itential/itential-utils');
|
|
28
|
+
const propertyEncryption = new PropertyEncryption();
|
|
29
|
+
const pronghornProps = await propertyEncryption.decryptProps(rawProps);
|
|
30
|
+
log.trace('Found properties.\n');
|
|
31
|
+
return pronghornProps;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Function used to take a file path to a entity directory and build
|
|
36
|
+
* a document that corresponds to the entity files.
|
|
37
|
+
*/
|
|
38
|
+
const buildDoc = (pathstring) => {
|
|
39
|
+
let files = fs.readdirSync(pathstring);
|
|
40
|
+
|
|
41
|
+
// load the mockdatafiles
|
|
42
|
+
const mockdatafiles = {};
|
|
43
|
+
if (files.includes('mockdatafiles') && fs.lstatSync(`${pathstring}/mockdatafiles`).isDirectory()) {
|
|
44
|
+
fs.readdirSync(`${pathstring}/mockdatafiles`).forEach((file) => {
|
|
45
|
+
if (file.split('.').pop() === 'json') {
|
|
46
|
+
const mockpath = `${pathstring}/mockdatafiles/${file}`;
|
|
47
|
+
const data = JSON.parse(fs.readFileSync(mockpath));
|
|
48
|
+
mockdatafiles[mockpath.split('/').pop()] = data;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// load the action data
|
|
54
|
+
let actions;
|
|
55
|
+
if (files.includes('action.json')) {
|
|
56
|
+
actions = JSON.parse(fs.readFileSync(`${pathstring}/action.json`));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Load schema.json and other schemas in remaining json files
|
|
60
|
+
files = files.filter((f) => (f !== 'action.json') && f.endsWith('.json'));
|
|
61
|
+
const schema = [];
|
|
62
|
+
files.forEach((file) => {
|
|
63
|
+
const data = JSON.parse(fs.readFileSync(`${pathstring}/${file}`));
|
|
64
|
+
schema.push({
|
|
65
|
+
name: file,
|
|
66
|
+
schema: data
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// return the data
|
|
71
|
+
return {
|
|
72
|
+
actions: actions.actions,
|
|
73
|
+
schema,
|
|
74
|
+
mockdatafiles
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Function used to get the database from the options or a provided directory
|
|
80
|
+
*/
|
|
81
|
+
const optionsHandler = (options) => {
|
|
82
|
+
// if the database properties were provided in the options - return them
|
|
83
|
+
if (options.pronghornProps) {
|
|
84
|
+
if (typeof options.pronghornProps === 'string') {
|
|
85
|
+
return JSON.parse(options.pronghornProps);
|
|
86
|
+
}
|
|
87
|
+
return new Promise((resolve, reject) => resolve(options.pronghornProps));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// if the directory was provided, get the pronghorn props from the directory
|
|
91
|
+
if (options.iapDir) {
|
|
92
|
+
return getPronghornProps(options.iapDir);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// if nothing was provided, error
|
|
96
|
+
return new Promise((resolve, reject) => reject(new Error('Neither pronghornProps nor iapDir defined in options!')));
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Function used to put the adapter configuration into the provided database
|
|
101
|
+
*/
|
|
102
|
+
const moveEntitiesToDB = (targetPath, options) => {
|
|
103
|
+
// set local variables
|
|
104
|
+
let myOpts = options;
|
|
105
|
+
let myPath = targetPath;
|
|
106
|
+
|
|
107
|
+
// if we got a string parse into a JSON object
|
|
108
|
+
if (typeof myOpts === 'string') {
|
|
109
|
+
myOpts = JSON.parse(myOpts);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// if there is no target collection - set the collection to the default
|
|
113
|
+
if (!myOpts.targetCollection) {
|
|
114
|
+
myOpts.targetCollection = 'adapter_configs';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// if there is no id error since we need an id for the entities
|
|
118
|
+
if (!myOpts.id) {
|
|
119
|
+
throw new Error('Adapter ID required!');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// get the pronghorn database properties
|
|
123
|
+
optionsHandler(options).then((currentProps) => {
|
|
124
|
+
let mongoUrl;
|
|
125
|
+
let dbName;
|
|
126
|
+
|
|
127
|
+
// find the mongo properties so we can connect
|
|
128
|
+
if (currentProps.mongoProps) {
|
|
129
|
+
mongoUrl = currentProps.mongoProps.url;
|
|
130
|
+
dbName = currentProps.mongoProps.db;
|
|
131
|
+
} else if (currentProps.mongo) {
|
|
132
|
+
if (currentProps.mongo.url) {
|
|
133
|
+
mongoUrl = currentProps.mongo.url;
|
|
134
|
+
} else {
|
|
135
|
+
mongoUrl = `mongodb://${currentProps.mongo.host}:${currentProps.mongo.port}`;
|
|
136
|
+
}
|
|
137
|
+
dbName = currentProps.mongo.database;
|
|
138
|
+
} else {
|
|
139
|
+
throw new Error('Mongo properties are not specified in adapter preferences!');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Check valid filepath provided
|
|
143
|
+
if (!myPath) {
|
|
144
|
+
// if no path use the current directory without the utils
|
|
145
|
+
myPath = path.join(__dirname, '../');
|
|
146
|
+
} else if (myPath.slice(-1) === '/') {
|
|
147
|
+
myPath = myPath.slice(0, -1);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// verify set the entity path
|
|
151
|
+
const entitiesPath = `${myPath}/entities`;
|
|
152
|
+
if (!fs.existsSync(entitiesPath)) {
|
|
153
|
+
throw new Error(`Entities path does not exist in filesystem: ${entitiesPath}`);
|
|
154
|
+
} else {
|
|
155
|
+
log.trace('Target found on filesystem');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Get adapter details
|
|
159
|
+
if (!fs.existsSync(`${myPath}/pronghorn.json`)) {
|
|
160
|
+
throw new Error(`pronghorn.json does not exist in path: ${myPath}`);
|
|
161
|
+
} else {
|
|
162
|
+
log.trace('pronghorn.json found on filesystem');
|
|
163
|
+
}
|
|
164
|
+
const adapterData = JSON.parse(fs.readFileSync(`${myPath}/pronghorn.json`));
|
|
165
|
+
|
|
166
|
+
// Load files from the filesystem
|
|
167
|
+
const docs = [];
|
|
168
|
+
const entities = fs.readdirSync(entitiesPath);
|
|
169
|
+
entities.forEach((entity) => {
|
|
170
|
+
const entityPath = `${entitiesPath}/${entity}`;
|
|
171
|
+
const isDir = fs.lstatSync(entitiesPath).isDirectory();
|
|
172
|
+
|
|
173
|
+
// Build doc for entity
|
|
174
|
+
if (isDir) {
|
|
175
|
+
let doc = buildDoc(entityPath);
|
|
176
|
+
doc = {
|
|
177
|
+
id: myOpts.id,
|
|
178
|
+
type: adapterData.id,
|
|
179
|
+
entity,
|
|
180
|
+
...doc
|
|
181
|
+
};
|
|
182
|
+
docs.push(doc);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Upload documents to db collection
|
|
187
|
+
MongoClient.connect(mongoUrl, (err, db) => {
|
|
188
|
+
if (err) {
|
|
189
|
+
log.error(JSON.stringify(err));
|
|
190
|
+
throw err;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// get the proper collection
|
|
194
|
+
const collection = db.db(dbName).collection(myOpts.targetCollection);
|
|
195
|
+
// insert the documents into the collection
|
|
196
|
+
collection.insertMany(docs, { checkKeys: false }, (error, res) => {
|
|
197
|
+
if (error) {
|
|
198
|
+
log.error(JSON.stringify(error));
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
// log the insertion, close the database and return
|
|
202
|
+
log.debug(`Inserted ${docs.length} documents to ${dbName}.${myOpts.targetCollection} with response ${JSON.stringify(res)}`);
|
|
203
|
+
db.close();
|
|
204
|
+
return res;
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// const args = process.argv.slice(2);
|
|
211
|
+
|
|
212
|
+
// throw new SyntaxError(args[0]);
|
|
213
|
+
|
|
214
|
+
// if (args.length === 0) {
|
|
215
|
+
// console.error('ERROR: target path not specified!');
|
|
216
|
+
// } else if (args[0] === 'help') {
|
|
217
|
+
// log.trace('node ./entitiesToDB <target path> <options object: {iapDir: string, pronghornProps: string, targetCollection: string}>');
|
|
218
|
+
// } else if (args.length === 1) {
|
|
219
|
+
// console.error('ERROR: IAP directory not specified');
|
|
220
|
+
// } else {
|
|
221
|
+
// moveEntitiesToDB(args[0], args[1]);
|
|
222
|
+
// }
|
|
223
|
+
|
|
224
|
+
module.exports = { moveEntitiesToDB };
|
package/utils/modify.js
CHANGED
|
@@ -3,7 +3,7 @@ const Ajv = require('ajv');
|
|
|
3
3
|
const rls = require('readline-sync');
|
|
4
4
|
const { execSync } = require('child_process');
|
|
5
5
|
const { existsSync } = require('fs-extra');
|
|
6
|
-
const { getAdapterConfig } = require('./
|
|
6
|
+
const { getAdapterConfig } = require('./tbUtils');
|
|
7
7
|
const { name } = require('../package.json');
|
|
8
8
|
const propertiesSchema = require('../propertiesSchema.json');
|
|
9
9
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This script will uninstall pre-commit or pre-push hooks in case there's ever a need to
|
|
5
|
+
* commit/push something that has issues
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const precommitPath = '.git/hooks/pre-commit';
|
|
9
|
+
const prepushPath = '.git/hooks/pre-push';
|
|
10
|
+
fs.unlink(precommitPath, (err) => {
|
|
11
|
+
if (err && err.code !== 'ENOENT') {
|
|
12
|
+
console.log(`${err.message}`);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
fs.unlink(prepushPath, (err) => {
|
|
17
|
+
if (err && err.code !== 'ENOENT') {
|
|
18
|
+
console.log(`${err.message}`);
|
|
19
|
+
}
|
|
20
|
+
});
|
package/utils/tbScript.js
CHANGED
|
@@ -15,13 +15,18 @@ const basicGet = require('./basicGet');
|
|
|
15
15
|
const { name } = require('../package.json');
|
|
16
16
|
const sampleProperties = require('../sampleProperties.json');
|
|
17
17
|
const adapterPronghorn = require('../pronghorn.json');
|
|
18
|
+
const { addAuthInfo } = require('./addAuth');
|
|
18
19
|
|
|
19
|
-
const { troubleshoot,
|
|
20
|
+
const { troubleshoot, offline } = require('./troubleshootingAdapter');
|
|
20
21
|
|
|
21
22
|
const main = async (command) => {
|
|
22
|
-
const
|
|
23
|
+
const dirname = utils.getDirname();
|
|
24
|
+
const iapDir = path.join(dirname, '../../../../');
|
|
23
25
|
if (!utils.withinIAP(iapDir)) {
|
|
24
|
-
if (command === '
|
|
26
|
+
if (command === 'install') {
|
|
27
|
+
console.log('Not currently in IAP directory - installation not possible');
|
|
28
|
+
process.exit(0);
|
|
29
|
+
} else if (command === 'connectivity') {
|
|
25
30
|
const { host } = sampleProperties.properties;
|
|
26
31
|
console.log(`perform networking diagnositics to ${host}`);
|
|
27
32
|
await utils.runConnectivity(host);
|
|
@@ -43,7 +48,7 @@ const main = async (command) => {
|
|
|
43
48
|
if (command === undefined) {
|
|
44
49
|
await troubleshoot({}, true, true);
|
|
45
50
|
} else if (command === 'install') {
|
|
46
|
-
const { database, serviceItem, pronghornProps } = await getAdapterConfig();
|
|
51
|
+
const { database, serviceItem, pronghornProps } = await utils.getAdapterConfig();
|
|
47
52
|
const filter = { id: pronghornProps.id };
|
|
48
53
|
const profileItem = await database.collection(utils.IAP_PROFILES_COLLECTION).findOne(filter);
|
|
49
54
|
if (!profileItem) {
|
|
@@ -74,14 +79,16 @@ const main = async (command) => {
|
|
|
74
79
|
process.exit(0);
|
|
75
80
|
}
|
|
76
81
|
} else {
|
|
77
|
-
utils.verifyInstallationDir(
|
|
78
|
-
utils.npmInstall();
|
|
82
|
+
utils.verifyInstallationDir(dirname, name);
|
|
79
83
|
utils.runTest();
|
|
80
84
|
if (rls.keyInYN(`Do you want to install ${name} to IAP?`)) {
|
|
81
85
|
console.log('Creating database entries...');
|
|
82
86
|
const adapter = utils.createAdapter(
|
|
83
87
|
pronghornProps, profileItem, sampleProperties, adapterPronghorn
|
|
84
88
|
);
|
|
89
|
+
|
|
90
|
+
adapter.properties.properties = await addAuthInfo(adapter.properties.properties);
|
|
91
|
+
|
|
85
92
|
await database.collection(utils.SERVICE_CONFIGS_COLLECTION).insertOne(adapter);
|
|
86
93
|
profileItem.services.push(adapter.name);
|
|
87
94
|
const update = { $set: { services: profileItem.services } };
|
|
@@ -94,7 +101,7 @@ const main = async (command) => {
|
|
|
94
101
|
process.exit(0);
|
|
95
102
|
}
|
|
96
103
|
} else if (['healthcheck', 'basicget', 'connectivity'].includes(command)) {
|
|
97
|
-
const { serviceItem } = await getAdapterConfig();
|
|
104
|
+
const { serviceItem } = await utils.getAdapterConfig();
|
|
98
105
|
if (serviceItem) {
|
|
99
106
|
const adapter = serviceItem;
|
|
100
107
|
const a = basicGet.getAdapterInstance(adapter);
|
|
@@ -154,7 +161,6 @@ program.parse(process.argv);
|
|
|
154
161
|
if (process.argv.length < 3) {
|
|
155
162
|
main();
|
|
156
163
|
}
|
|
157
|
-
|
|
158
164
|
const allowedParams = ['install', 'healthcheck', 'basicget', 'connectivity'];
|
|
159
165
|
if (process.argv.length === 3 && !allowedParams.includes(process.argv[2])) {
|
|
160
166
|
console.log(`unknown parameter ${process.argv[2]}`);
|
package/utils/tbUtils.js
CHANGED
|
@@ -178,7 +178,7 @@ module.exports = {
|
|
|
178
178
|
const pathArray = dirname.split(path.sep);
|
|
179
179
|
const expectedPath = `node_modules/${name}`;
|
|
180
180
|
const currentPath = pathArray.slice(pathArray.length - 4, pathArray.length - 1).join('/');
|
|
181
|
-
if (
|
|
181
|
+
if (currentPath.trim() !== expectedPath.trim()) {
|
|
182
182
|
throw new Error(`adapter should be installed under ${expectedPath}`);
|
|
183
183
|
}
|
|
184
184
|
|
|
@@ -304,8 +304,9 @@ module.exports = {
|
|
|
304
304
|
* @param {Object} adapterPronghorn - ./pronghorn.json in adapter dir
|
|
305
305
|
* @param {Object} sampleProperties - './sampleProperties.json' in adapter dir
|
|
306
306
|
*/
|
|
307
|
-
createAdapter: (pronghornProps, profileItem, sampleProperties, adapterPronghorn)
|
|
308
|
-
const
|
|
307
|
+
createAdapter: function createAdapter(pronghornProps, profileItem, sampleProperties, adapterPronghorn) {
|
|
308
|
+
const dirname = this.getDirname();
|
|
309
|
+
const packagePath = `${dirname.split('node_modules')[0]}package.json`;
|
|
309
310
|
const info = JSON.parse(fs.readFileSync(packagePath));
|
|
310
311
|
const version = parseInt(info.version.split('.')[0], 10);
|
|
311
312
|
|
|
@@ -338,6 +339,31 @@ module.exports = {
|
|
|
338
339
|
return adapter;
|
|
339
340
|
},
|
|
340
341
|
|
|
342
|
+
getPronghornProps: function getPronghornProps(iapDir) {
|
|
343
|
+
console.log('Retrieving properties.json file...');
|
|
344
|
+
const rawProps = require(path.join(iapDir, 'properties.json'));
|
|
345
|
+
console.log('Decrypting properties...');
|
|
346
|
+
const { Discovery } = require(path.join(iapDir, 'node_modules/@itential/itential-utils'));
|
|
347
|
+
const discovery = new Discovery();
|
|
348
|
+
const pronghornProps = this.decryptProperties(rawProps, this.getDirname(), discovery);
|
|
349
|
+
console.log('Found properties.\n');
|
|
350
|
+
return pronghornProps;
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
// get database connection and existing adapter config
|
|
354
|
+
getAdapterConfig: async function getAdapterConfig() {
|
|
355
|
+
const iapDir = path.join(this.getDirname(), '../../../../');
|
|
356
|
+
const pronghornProps = this.getPronghornProps(iapDir);
|
|
357
|
+
console.log('Connecting to Database...');
|
|
358
|
+
const database = await this.connect(pronghornProps);
|
|
359
|
+
console.log('Connection established.');
|
|
360
|
+
const { name } = require(path.join(__dirname, '..', 'package.json'));
|
|
361
|
+
const serviceItem = await database.collection(this.SERVICE_CONFIGS_COLLECTION).findOne(
|
|
362
|
+
{ model: name }
|
|
363
|
+
);
|
|
364
|
+
return { database, serviceItem, pronghornProps };
|
|
365
|
+
},
|
|
366
|
+
|
|
341
367
|
/**
|
|
342
368
|
* @summary return async healthcheck result as a Promise
|
|
343
369
|
*
|
|
@@ -385,5 +411,35 @@ module.exports = {
|
|
|
385
411
|
} catch (error) {
|
|
386
412
|
return false;
|
|
387
413
|
}
|
|
414
|
+
},
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* @summary Used to determine the proper dirname to return in case adapter reference is
|
|
418
|
+
* symlinked withink IAP
|
|
419
|
+
* @returns the symlinked path (using pwd command) of the adapter in case properties.json
|
|
420
|
+
* is not found in the original path
|
|
421
|
+
* @function getDirname
|
|
422
|
+
*/
|
|
423
|
+
getDirname: function getDirname() {
|
|
424
|
+
if (this.withinIAP(path.join(__dirname, '../../../../'))) {
|
|
425
|
+
return __dirname;
|
|
426
|
+
}
|
|
427
|
+
const { stdout } = this.systemSync('pwd', true);
|
|
428
|
+
return path.join(stdout, 'utils');
|
|
429
|
+
},
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* @summary connect to mongodb
|
|
433
|
+
*
|
|
434
|
+
* @function connect
|
|
435
|
+
* @param {Object} properties - pronghornProps
|
|
436
|
+
*/
|
|
437
|
+
connect: async function connect(properties) {
|
|
438
|
+
// Connect to Mongo
|
|
439
|
+
const { MongoDBConnection } = require(path.join(this.getDirname(), '../../../', '@itential/database'));
|
|
440
|
+
const connection = new MongoDBConnection(properties.mongoProps);
|
|
441
|
+
const database = await connection.connect(true);
|
|
442
|
+
return database;
|
|
388
443
|
}
|
|
444
|
+
|
|
389
445
|
};
|
|
@@ -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,
|
|
190
|
+
module.exports = { troubleshoot, offline };
|