@jupiterone/integration-sdk-cli 8.24.0 → 8.24.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/dist/src/commands/collect.js +5 -5
- package/dist/src/commands/collect.js.map +1 -1
- package/dist/src/commands/diff.d.ts +1 -1
- package/dist/src/commands/diff.js +1 -0
- package/dist/src/commands/diff.js.map +1 -1
- package/dist/src/commands/generate-integration-graph-schema.js +1 -0
- package/dist/src/commands/generate-integration-graph-schema.js.map +1 -1
- package/dist/src/commands/options.d.ts +43 -18
- package/dist/src/commands/options.js +86 -38
- package/dist/src/commands/options.js.map +1 -1
- package/dist/src/commands/run.d.ts +2 -1
- package/dist/src/commands/run.js +21 -36
- package/dist/src/commands/run.js.map +1 -1
- package/dist/src/commands/sync.d.ts +2 -1
- package/dist/src/commands/sync.js +17 -33
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/log.js +1 -0
- package/dist/src/log.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/__tests__/cli-run.test.ts +0 -83
- package/src/__tests__/cli-sync.test.ts +4 -78
- package/src/__tests__/options.test.ts +223 -0
- package/src/commands/collect.ts +7 -13
- package/src/commands/diff.ts +1 -0
- package/src/commands/generate-integration-graph-schema.ts +1 -0
- package/src/commands/options.ts +159 -42
- package/src/commands/run.ts +38 -75
- package/src/commands/sync.ts +35 -68
- package/src/log.ts +1 -0
package/src/commands/run.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createCommand } from 'commander';
|
|
1
|
+
import { Command, createCommand, OptionValues } from 'commander';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
|
|
4
4
|
import { Metric } from '@jupiterone/integration-sdk-core';
|
|
@@ -11,8 +11,6 @@ import {
|
|
|
11
11
|
executeIntegrationInstance,
|
|
12
12
|
FileSystemGraphObjectStore,
|
|
13
13
|
finalizeSynchronization,
|
|
14
|
-
getAccountFromEnvironment,
|
|
15
|
-
getApiKeyFromEnvironment,
|
|
16
14
|
initiateSynchronization,
|
|
17
15
|
synchronizationStatus,
|
|
18
16
|
} from '@jupiterone/integration-sdk-runtime';
|
|
@@ -21,77 +19,40 @@ import { createPersisterApiStepGraphObjectDataUploader } from '@jupiterone/integ
|
|
|
21
19
|
import { loadConfig } from '../config';
|
|
22
20
|
import * as log from '../log';
|
|
23
21
|
import {
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
addApiClientOptionsToCommand,
|
|
23
|
+
addPathOptionsToCommand,
|
|
24
|
+
addSyncOptionsToCommand,
|
|
25
|
+
configureRuntimeFilesystem,
|
|
26
|
+
getApiClientOptions,
|
|
27
|
+
getSyncOptions,
|
|
28
|
+
validateApiClientOptions,
|
|
29
|
+
validateSyncOptions,
|
|
26
30
|
} from './options';
|
|
27
31
|
|
|
28
32
|
const DEFAULT_UPLOAD_CONCURRENCY = 5;
|
|
29
33
|
|
|
30
|
-
export function run() {
|
|
31
|
-
|
|
32
|
-
.description('collect and sync to upload entities and relationships')
|
|
33
|
-
.option(
|
|
34
|
-
'-i, --integrationInstanceId <id>',
|
|
35
|
-
'_integrationInstanceId assigned to uploaded entities and relationships',
|
|
36
|
-
)
|
|
37
|
-
.option(
|
|
38
|
-
'-p, --project-path <directory>',
|
|
39
|
-
'path to integration project directory',
|
|
40
|
-
process.cwd(),
|
|
41
|
-
)
|
|
42
|
-
.option(
|
|
43
|
-
'-d, --development',
|
|
44
|
-
'"true" to target apps.dev.jupiterone.io',
|
|
45
|
-
!!process.env.JUPITERONE_DEV,
|
|
46
|
-
)
|
|
47
|
-
.option('--api-base-url <url>', 'API base URL used during run operation')
|
|
48
|
-
.option('--skip-finalize', 'skip synchronization finalization')
|
|
49
|
-
.option(
|
|
50
|
-
'--source <integration-managed|integration-external|api>',
|
|
51
|
-
'configure the synchronization job source value',
|
|
52
|
-
'integration-managed',
|
|
53
|
-
)
|
|
54
|
-
.option(
|
|
55
|
-
'--scope <anystring>',
|
|
56
|
-
'configure the synchronization job scope value',
|
|
57
|
-
)
|
|
58
|
-
.option('-V, --disable-schema-validation', 'disable schema validation')
|
|
59
|
-
.option(
|
|
60
|
-
'-u, --upload-batch-size <number>',
|
|
61
|
-
'specify number of items per batch for upload (default 250)',
|
|
62
|
-
)
|
|
63
|
-
.option(
|
|
64
|
-
'-ur, --upload-relationship-batch-size <number>',
|
|
65
|
-
'specify number of relationships per batch for upload (default 250)',
|
|
66
|
-
)
|
|
67
|
-
.action(async (options) => {
|
|
68
|
-
const projectPath = path.resolve(options.projectPath);
|
|
69
|
-
// Point `fileSystem.ts` functions to expected location relative to
|
|
70
|
-
// integration project path.
|
|
71
|
-
process.env.JUPITERONE_INTEGRATION_STORAGE_DIRECTORY = path.resolve(
|
|
72
|
-
projectPath,
|
|
73
|
-
'.j1-integration',
|
|
74
|
-
);
|
|
34
|
+
export function run(): Command {
|
|
35
|
+
const command = createCommand('run');
|
|
75
36
|
|
|
76
|
-
|
|
77
|
-
|
|
37
|
+
addPathOptionsToCommand(command);
|
|
38
|
+
addApiClientOptionsToCommand(command);
|
|
39
|
+
addSyncOptionsToCommand(command);
|
|
78
40
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
41
|
+
return command
|
|
42
|
+
.description('collect and sync to upload entities and relationships')
|
|
43
|
+
.option('-V, --disable-schema-validation', 'disable schema validation')
|
|
44
|
+
.action(async (options: OptionValues, actionCommand: Command) => {
|
|
45
|
+
configureRuntimeFilesystem(actionCommand.opts());
|
|
46
|
+
validateApiClientOptions(actionCommand.opts());
|
|
47
|
+
validateSyncOptions(actionCommand.opts());
|
|
84
48
|
|
|
85
49
|
const startTime = Date.now();
|
|
86
50
|
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
account
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const synchronizationJobSourceOptions =
|
|
94
|
-
getSynchronizationJobSourceOptions(options);
|
|
51
|
+
const clientApiOptions = getApiClientOptions(actionCommand.opts());
|
|
52
|
+
const apiClient = createApiClient(clientApiOptions);
|
|
53
|
+
log.debug(
|
|
54
|
+
`Configured JupiterOne API client. (apiBaseUrl: '${clientApiOptions.apiBaseUrl}', account: ${clientApiOptions.account})`,
|
|
55
|
+
);
|
|
95
56
|
|
|
96
57
|
let logger = createIntegrationLogger({
|
|
97
58
|
name: 'local',
|
|
@@ -101,7 +62,7 @@ export function run() {
|
|
|
101
62
|
const synchronizationContext = await initiateSynchronization({
|
|
102
63
|
logger,
|
|
103
64
|
apiClient,
|
|
104
|
-
...
|
|
65
|
+
...getSyncOptions(actionCommand.opts()),
|
|
105
66
|
});
|
|
106
67
|
|
|
107
68
|
logger = synchronizationContext.logger;
|
|
@@ -115,7 +76,9 @@ export function run() {
|
|
|
115
76
|
.on('event', (event) => eventPublishingQueue.enqueue(event))
|
|
116
77
|
.on('metric', (metric) => metrics.push(metric));
|
|
117
78
|
|
|
118
|
-
const invocationConfig = await loadConfig(
|
|
79
|
+
const invocationConfig = await loadConfig(
|
|
80
|
+
path.resolve(options.projectPath, 'src'),
|
|
81
|
+
);
|
|
119
82
|
|
|
120
83
|
const graphObjectStore = new FileSystemGraphObjectStore({
|
|
121
84
|
prettifyFiles: true,
|
|
@@ -130,7 +93,7 @@ export function run() {
|
|
|
130
93
|
invocationConfig,
|
|
131
94
|
{
|
|
132
95
|
current: {
|
|
133
|
-
startedOn:
|
|
96
|
+
startedOn: synchronizationContext.job.startTimestamp,
|
|
134
97
|
},
|
|
135
98
|
},
|
|
136
99
|
{
|
|
@@ -153,18 +116,18 @@ export function run() {
|
|
|
153
116
|
|
|
154
117
|
log.displayExecutionResults(executionResults);
|
|
155
118
|
|
|
156
|
-
if (
|
|
157
|
-
const synchronizationResult = await finalizeSynchronization({
|
|
158
|
-
...synchronizationContext,
|
|
159
|
-
partialDatasets: executionResults.metadata.partialDatasets,
|
|
160
|
-
});
|
|
161
|
-
log.displaySynchronizationResults(synchronizationResult);
|
|
162
|
-
} else {
|
|
119
|
+
if (options.skipFinalize) {
|
|
163
120
|
log.info(
|
|
164
121
|
'Skipping synchronization finalization. Job will remain in "AWAITING_UPLOADS" state.',
|
|
165
122
|
);
|
|
166
123
|
const jobStatus = await synchronizationStatus(synchronizationContext);
|
|
167
124
|
log.displaySynchronizationResults(jobStatus);
|
|
125
|
+
} else {
|
|
126
|
+
const synchronizationResult = await finalizeSynchronization({
|
|
127
|
+
...synchronizationContext,
|
|
128
|
+
partialDatasets: executionResults.metadata.partialDatasets,
|
|
129
|
+
});
|
|
130
|
+
log.displaySynchronizationResults(synchronizationResult);
|
|
168
131
|
}
|
|
169
132
|
} catch (err) {
|
|
170
133
|
await eventPublishingQueue.onIdle();
|
package/src/commands/sync.ts
CHANGED
|
@@ -1,93 +1,60 @@
|
|
|
1
|
-
import { createCommand } from 'commander';
|
|
2
|
-
import path from 'path';
|
|
1
|
+
import { Command, createCommand, OptionValues } from 'commander';
|
|
3
2
|
|
|
4
3
|
import {
|
|
5
4
|
createApiClient,
|
|
6
5
|
createIntegrationLogger,
|
|
7
|
-
getAccountFromEnvironment,
|
|
8
|
-
getApiKeyFromEnvironment,
|
|
9
6
|
synchronizeCollectedData,
|
|
10
7
|
} from '@jupiterone/integration-sdk-runtime';
|
|
11
8
|
|
|
12
9
|
import * as log from '../log';
|
|
13
10
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
addApiClientOptionsToCommand,
|
|
12
|
+
addPathOptionsToCommand,
|
|
13
|
+
addSyncOptionsToCommand,
|
|
14
|
+
configureRuntimeFilesystem,
|
|
15
|
+
getApiClientOptions,
|
|
16
|
+
getSyncOptions,
|
|
17
|
+
validateApiClientOptions,
|
|
18
|
+
validateSyncOptions,
|
|
16
19
|
} from './options';
|
|
17
20
|
|
|
18
|
-
export function sync() {
|
|
19
|
-
|
|
21
|
+
export function sync(): Command {
|
|
22
|
+
const command = createCommand('sync');
|
|
23
|
+
|
|
24
|
+
addPathOptionsToCommand(command);
|
|
25
|
+
addApiClientOptionsToCommand(command);
|
|
26
|
+
addSyncOptionsToCommand(command);
|
|
27
|
+
|
|
28
|
+
return command
|
|
20
29
|
.description(
|
|
21
30
|
'sync collected data with JupiterOne, requires JUPITERONE_API_KEY, JUPITERONE_ACCOUNT',
|
|
22
31
|
)
|
|
23
|
-
.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
.option(
|
|
28
|
-
'-p, --project-path <directory>',
|
|
29
|
-
'path to integration project directory',
|
|
30
|
-
process.cwd(),
|
|
31
|
-
)
|
|
32
|
-
.option(
|
|
33
|
-
'-d, --development',
|
|
34
|
-
'"true" to target apps.dev.jupiterone.io',
|
|
35
|
-
!!process.env.JUPITERONE_DEV,
|
|
36
|
-
)
|
|
37
|
-
.option('--api-base-url <url>', 'API base URL used during sync operation.')
|
|
38
|
-
.option(
|
|
39
|
-
'--source <integration-managed|integration-external|api>',
|
|
40
|
-
'configure the synchronization job source value',
|
|
41
|
-
'integration-managed',
|
|
42
|
-
)
|
|
43
|
-
.option(
|
|
44
|
-
'--scope <anystring>',
|
|
45
|
-
'configure the synchronization job scope value',
|
|
46
|
-
)
|
|
47
|
-
.option(
|
|
48
|
-
'-u, --upload-batch-size <number>',
|
|
49
|
-
'specify number of items per batch for upload (default 250)',
|
|
50
|
-
)
|
|
51
|
-
.option(
|
|
52
|
-
'-ur, --upload-relationship-batch-size <number>',
|
|
53
|
-
'specify number of relationships per batch for upload (default 250)',
|
|
54
|
-
)
|
|
55
|
-
.action(async (options) => {
|
|
56
|
-
// Point `fileSystem.ts` functions to expected location relative to
|
|
57
|
-
// integration project path.
|
|
58
|
-
process.env.JUPITERONE_INTEGRATION_STORAGE_DIRECTORY = path.resolve(
|
|
59
|
-
options.projectPath,
|
|
60
|
-
'.j1-integration',
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
log.debug('Loading API Key from JUPITERONE_API_KEY environment variable');
|
|
64
|
-
const accessToken = getApiKeyFromEnvironment();
|
|
65
|
-
|
|
66
|
-
log.debug('Loading account from JUPITERONE_ACCOUNT environment variable');
|
|
67
|
-
const account = getAccountFromEnvironment();
|
|
32
|
+
.action(async (options: OptionValues, actionCommand: Command) => {
|
|
33
|
+
configureRuntimeFilesystem(actionCommand.opts());
|
|
34
|
+
validateApiClientOptions(actionCommand.opts());
|
|
35
|
+
validateSyncOptions(actionCommand.opts());
|
|
68
36
|
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
account,
|
|
75
|
-
accessToken,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
const synchronizationJobSourceOptions =
|
|
79
|
-
getSynchronizationJobSourceOptions(options);
|
|
37
|
+
const clientApiOptions = getApiClientOptions(actionCommand.opts());
|
|
38
|
+
const apiClient = createApiClient(clientApiOptions);
|
|
39
|
+
log.debug(
|
|
40
|
+
`Configured JupiterOne API client. (apiBaseUrl: '${clientApiOptions.apiBaseUrl}', account: ${clientApiOptions.account})`,
|
|
41
|
+
);
|
|
80
42
|
|
|
81
43
|
const logger = createIntegrationLogger({
|
|
82
44
|
name: 'local',
|
|
83
45
|
pretty: true,
|
|
84
46
|
});
|
|
47
|
+
|
|
48
|
+
const syncOptions = getSyncOptions(actionCommand.opts());
|
|
49
|
+
if (syncOptions.skipFinalize)
|
|
50
|
+
log.info(
|
|
51
|
+
'Skipping synchronization finalization. Job will remain in "AWAITING_UPLOADS" state.',
|
|
52
|
+
);
|
|
53
|
+
|
|
85
54
|
const job = await synchronizeCollectedData({
|
|
86
|
-
logger: logger.child(
|
|
55
|
+
logger: logger.child(syncOptions),
|
|
87
56
|
apiClient,
|
|
88
|
-
|
|
89
|
-
uploadRelationshipBatchSize: options.uploadRelationshipBatchSize,
|
|
90
|
-
...synchronizationJobSourceOptions,
|
|
57
|
+
...syncOptions,
|
|
91
58
|
});
|
|
92
59
|
|
|
93
60
|
log.displaySynchronizationResults(job);
|