@jupiterone/integration-sdk-cli 6.17.0 → 6.21.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.
- package/dist/src/commands/document.js +31 -2
- package/dist/src/commands/document.js.map +1 -1
- package/dist/src/commands/index.d.ts +1 -0
- package/dist/src/commands/index.js +1 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/validate-question-file.d.ts +2 -0
- package/dist/src/commands/validate-question-file.js +70 -0
- package/dist/src/commands/validate-question-file.js.map +1 -0
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/questions/managedQuestionFileValidator.d.ts +53 -0
- package/dist/src/questions/managedQuestionFileValidator.js +140 -0
- package/dist/src/questions/managedQuestionFileValidator.js.map +1 -0
- package/dist/src/services/queryLanguage.d.ts +21 -0
- package/dist/src/services/queryLanguage.js +34 -0
- package/dist/src/services/queryLanguage.js.map +1 -0
- package/dist/tsconfig.dist.tsbuildinfo +845 -12
- package/package.json +7 -4
- package/src/__tests__/__snapshots__/cli.test.ts.snap +52 -5
- package/src/__tests__/cli/validate-question-file.test.ts +24 -0
- package/src/__tests__/cli.test.ts +4 -0
- package/src/commands/document.ts +39 -2
- package/src/commands/index.ts +1 -0
- package/src/commands/validate-question-file.ts +82 -0
- package/src/index.ts +3 -1
- package/src/questions/__fixtures__/questions/basic.yaml +15 -0
- package/src/questions/__fixtures__/questions/compliance.yaml +41 -0
- package/src/questions/__fixtures__/questions/empty-questions.yaml +4 -0
- package/src/questions/__fixtures__/questions/invalid-yaml.yaml +16 -0
- package/src/questions/__fixtures__/questions/multiple-queries.yaml +17 -0
- package/src/questions/__fixtures__/questions/multiple-questions.yaml +27 -0
- package/src/questions/__fixtures__/questions/non-unique-question-id.yaml +28 -0
- package/src/questions/__fixtures__/questions/non-unique-question-name.yaml +18 -0
- package/src/questions/__fixtures__/questions/non-unique-question-tag.yaml +17 -0
- package/src/questions/__fixtures__/questions/non-unique-question-title.yaml +28 -0
- package/src/questions/managedQuestionFileValidator.test.ts +175 -0
- package/src/questions/managedQuestionFileValidator.ts +180 -0
- package/src/services/queryLanguage.ts +46 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jupiterone/integration-sdk-cli",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.21.0",
|
|
4
4
|
"description": "The SDK for developing JupiterOne integrations",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -22,20 +22,23 @@
|
|
|
22
22
|
"prepack": "yarn build:dist"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@jupiterone/integration-sdk-runtime": "^6.
|
|
25
|
+
"@jupiterone/integration-sdk-runtime": "^6.21.0",
|
|
26
26
|
"commander": "^5.0.0",
|
|
27
27
|
"globby": "^11.0.0",
|
|
28
|
+
"js-yaml": "^4.1.0",
|
|
28
29
|
"json-diff": "^0.5.4",
|
|
29
30
|
"lodash": "^4.17.19",
|
|
30
31
|
"markdown-table": "^2.0.0",
|
|
32
|
+
"runtypes": "5.1.0",
|
|
31
33
|
"upath": "^1.2.0",
|
|
32
34
|
"vis": "^4.21.0-EOL"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
35
|
-
"@jupiterone/integration-sdk-private-test-utils": "^6.
|
|
37
|
+
"@jupiterone/integration-sdk-private-test-utils": "^6.21.0",
|
|
36
38
|
"@pollyjs/adapter-node-http": "^4.0.4",
|
|
37
39
|
"@pollyjs/core": "^4.0.4",
|
|
38
40
|
"@pollyjs/persister-fs": "^4.0.4",
|
|
41
|
+
"@types/js-yaml": "^4.0.3",
|
|
39
42
|
"@types/json-diff": "^0.5.1",
|
|
40
43
|
"@types/lodash": "^4.14.158",
|
|
41
44
|
"@types/pollyjs__adapter-node-http": "^2.0.0",
|
|
@@ -45,5 +48,5 @@
|
|
|
45
48
|
"memfs": "^3.2.0",
|
|
46
49
|
"uuid": "^8.2.0"
|
|
47
50
|
},
|
|
48
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "ab626f6b32950e50ddcd19a05ff6318cda2e5a2e"
|
|
49
52
|
}
|
|
@@ -67,7 +67,7 @@ https://github.com/JupiterOne/sdk/blob/main/docs/integrations/development.md
|
|
|
67
67
|
|
|
68
68
|
### Relationships
|
|
69
69
|
|
|
70
|
-
The following relationships are created
|
|
70
|
+
The following relationships are created:
|
|
71
71
|
|
|
72
72
|
| Source Entity \`_type\` | Relationship \`_class\` | Target Entity \`_type\` |
|
|
73
73
|
| --------------------- | --------------------- | --------------------- |
|
|
@@ -147,7 +147,7 @@ https://github.com/JupiterOne/sdk/blob/main/docs/integrations/development.md
|
|
|
147
147
|
|
|
148
148
|
### Relationships
|
|
149
149
|
|
|
150
|
-
The following relationships are created
|
|
150
|
+
The following relationships are created:
|
|
151
151
|
|
|
152
152
|
| Source Entity \`_type\` | Relationship \`_class\` | Target Entity \`_type\` |
|
|
153
153
|
| --------------------- | --------------------- | --------------------- |
|
|
@@ -194,7 +194,7 @@ The following entities are created:
|
|
|
194
194
|
|
|
195
195
|
### Relationships
|
|
196
196
|
|
|
197
|
-
The following relationships are created
|
|
197
|
+
The following relationships are created:
|
|
198
198
|
|
|
199
199
|
| Source Entity \`_type\` | Relationship \`_class\` | Target Entity \`_type\` |
|
|
200
200
|
| --------------------- | --------------------- | --------------------- |
|
|
@@ -282,7 +282,7 @@ The following entities are created:
|
|
|
282
282
|
|
|
283
283
|
### Relationships
|
|
284
284
|
|
|
285
|
-
The following relationships are created
|
|
285
|
+
The following relationships are created:
|
|
286
286
|
|
|
287
287
|
| Source Entity \`_type\` | Relationship \`_class\` | Target Entity \`_type\` |
|
|
288
288
|
| --------------------- | --------------------- | --------------------- |
|
|
@@ -296,6 +296,53 @@ END OF GENERATED DOCUMENTATION AFTER BELOW MARKER
|
|
|
296
296
|
<!-- {J1_DOCUMENTATION_MARKER_END} -->"
|
|
297
297
|
`;
|
|
298
298
|
|
|
299
|
+
exports[`document loads the integration with entity and mapped relationship and writes documentation results 1`] = `
|
|
300
|
+
"# Integration with JupiterOne
|
|
301
|
+
|
|
302
|
+
## Setup
|
|
303
|
+
|
|
304
|
+
In this section, please provide details about how to set up the integration with
|
|
305
|
+
JupiterOne. This may require provisioning some resources on the provider's side
|
|
306
|
+
(perhaps a role, app, or api key) and passing information over to JupiterOne.
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
<!-- {J1_DOCUMENTATION_MARKER_START} -->
|
|
310
|
+
<!--
|
|
311
|
+
********************************************************************************
|
|
312
|
+
NOTE: ALL OF THE FOLLOWING DOCUMENTATION IS GENERATED USING THE
|
|
313
|
+
\\"j1-integration document\\" COMMAND. DO NOT EDIT BY HAND! PLEASE SEE THE DEVELOPER
|
|
314
|
+
DOCUMENTATION FOR USAGE INFORMATION:
|
|
315
|
+
|
|
316
|
+
https://github.com/JupiterOne/sdk/blob/main/docs/integrations/development.md
|
|
317
|
+
********************************************************************************
|
|
318
|
+
-->
|
|
319
|
+
|
|
320
|
+
## Data Model
|
|
321
|
+
|
|
322
|
+
### Entities
|
|
323
|
+
|
|
324
|
+
The following entities are created:
|
|
325
|
+
|
|
326
|
+
| Resources | Entity \`_type\` | Entity \`_class\` |
|
|
327
|
+
| --------- | -------------- | --------------- |
|
|
328
|
+
| The Group | \`my_group\` | \`Group\` |
|
|
329
|
+
|
|
330
|
+
### Mapped Relationships
|
|
331
|
+
|
|
332
|
+
The following mapped relationships are created:
|
|
333
|
+
|
|
334
|
+
| Source Entity \`_type\` | Relationship \`_class\` | Target Entity \`_type\` | Direction |
|
|
335
|
+
| --------------------- | --------------------- | --------------------- | --------- |
|
|
336
|
+
| \`my_group\` | **HAS** | \`*your_user*\` | FORWARD |
|
|
337
|
+
|
|
338
|
+
<!--
|
|
339
|
+
********************************************************************************
|
|
340
|
+
END OF GENERATED DOCUMENTATION AFTER BELOW MARKER
|
|
341
|
+
********************************************************************************
|
|
342
|
+
-->
|
|
343
|
+
<!-- {J1_DOCUMENTATION_MARKER_END} -->"
|
|
344
|
+
`;
|
|
345
|
+
|
|
299
346
|
exports[`document loads the integration without entities and writes documentation results 1`] = `
|
|
300
347
|
"# Integration with JupiterOne
|
|
301
348
|
|
|
@@ -321,7 +368,7 @@ https://github.com/JupiterOne/sdk/blob/main/docs/integrations/development.md
|
|
|
321
368
|
|
|
322
369
|
### Relationships
|
|
323
370
|
|
|
324
|
-
The following relationships are created
|
|
371
|
+
The following relationships are created:
|
|
325
372
|
|
|
326
373
|
| Source Entity \`_type\` | Relationship \`_class\` | Target Entity \`_type\` |
|
|
327
374
|
| --------------------- | --------------------- | --------------------- |
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { createCli } from '../..';
|
|
3
|
+
import { getDefaultQuestionFilePath } from '../../commands';
|
|
4
|
+
|
|
5
|
+
describe('j1-integration validate-question-file --dry-run', () => {
|
|
6
|
+
test('should validate a provided question file', async () => {
|
|
7
|
+
await createCli().parseAsync([
|
|
8
|
+
'node',
|
|
9
|
+
'j1-integration',
|
|
10
|
+
'validate-question-file',
|
|
11
|
+
'--dry-run',
|
|
12
|
+
'--file-path',
|
|
13
|
+
path.join(__dirname, '../../questions/__fixtures__/questions/basic.yaml'),
|
|
14
|
+
]);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe('#getDefaultQuestionFilePath', () => {
|
|
19
|
+
test('should return expected directory', () => {
|
|
20
|
+
expect(getDefaultQuestionFilePath()).toEqual(
|
|
21
|
+
path.join(process.cwd(), './jupiterone/questions/questions.yaml'),
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -443,6 +443,10 @@ describe('document', () => {
|
|
|
443
443
|
await documentCommandSnapshotTest('docsInstanceRelationshipsAlphabetize');
|
|
444
444
|
});
|
|
445
445
|
|
|
446
|
+
test('loads the integration with entity and mapped relationship and writes documentation results', async () => {
|
|
447
|
+
await documentCommandSnapshotTest('docsInstanceWithMappedRelationships');
|
|
448
|
+
});
|
|
449
|
+
|
|
446
450
|
test('should allow passing a file path for the generated documentation', async () => {
|
|
447
451
|
loadProjectStructure('docsInstanceCustomDocLoc');
|
|
448
452
|
|
package/src/commands/document.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
StepEntityMetadata,
|
|
7
7
|
StepGraphObjectMetadataProperties,
|
|
8
8
|
StepRelationshipMetadata,
|
|
9
|
+
StepMappedRelationshipMetadata,
|
|
9
10
|
} from '@jupiterone/integration-sdk-core';
|
|
10
11
|
|
|
11
12
|
import * as log from '../log';
|
|
@@ -142,11 +143,33 @@ function generateRelationshipTableFromAllStepEntityMetadata(
|
|
|
142
143
|
return generated;
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
function generateMappedRelationshipTableFromAllStepEntityMetadata(
|
|
147
|
+
metadata: StepMappedRelationshipMetadata[],
|
|
148
|
+
): string {
|
|
149
|
+
const generated = table([
|
|
150
|
+
[
|
|
151
|
+
'Source Entity `_type`',
|
|
152
|
+
'Relationship `_class`',
|
|
153
|
+
'Target Entity `_type`',
|
|
154
|
+
'Direction',
|
|
155
|
+
],
|
|
156
|
+
...metadata.map((v) => [
|
|
157
|
+
`\`${v.sourceType}\``,
|
|
158
|
+
`**${v._class}**`,
|
|
159
|
+
`\`*${v.targetType}*\``,
|
|
160
|
+
`${v.direction}`,
|
|
161
|
+
]),
|
|
162
|
+
]);
|
|
163
|
+
|
|
164
|
+
return generated;
|
|
165
|
+
}
|
|
166
|
+
|
|
145
167
|
function generateGraphObjectDocumentationFromStepsMetadata(
|
|
146
168
|
metadata: StepGraphObjectMetadataProperties,
|
|
147
169
|
): string {
|
|
148
170
|
let entitySection = '';
|
|
149
171
|
let relationshipSection = '';
|
|
172
|
+
let mappedRelationshipSection = '';
|
|
150
173
|
|
|
151
174
|
if (metadata.entities.length) {
|
|
152
175
|
const generatedEntityTable = generateEntityTableFromAllStepEntityMetadata(
|
|
@@ -171,11 +194,25 @@ ${generatedEntityTable}`;
|
|
|
171
194
|
|
|
172
195
|
### Relationships
|
|
173
196
|
|
|
174
|
-
The following relationships are created
|
|
197
|
+
The following relationships are created:
|
|
175
198
|
|
|
176
199
|
${generatedRelationshipTable}`;
|
|
177
200
|
}
|
|
178
201
|
|
|
202
|
+
if (metadata.mappedRelationships?.length) {
|
|
203
|
+
const generatedMappedRelationshipTable = generateMappedRelationshipTableFromAllStepEntityMetadata(
|
|
204
|
+
metadata.mappedRelationships,
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
mappedRelationshipSection += `
|
|
208
|
+
|
|
209
|
+
### Mapped Relationships
|
|
210
|
+
|
|
211
|
+
The following mapped relationships are created:
|
|
212
|
+
|
|
213
|
+
${generatedMappedRelationshipTable}`;
|
|
214
|
+
}
|
|
215
|
+
|
|
179
216
|
return `${J1_DOCUMENTATION_MARKER_START}
|
|
180
217
|
<!--
|
|
181
218
|
********************************************************************************
|
|
@@ -187,7 +224,7 @@ https://github.com/JupiterOne/sdk/blob/main/docs/integrations/development.md
|
|
|
187
224
|
********************************************************************************
|
|
188
225
|
-->
|
|
189
226
|
|
|
190
|
-
## Data Model${entitySection}${relationshipSection}
|
|
227
|
+
## Data Model${entitySection}${relationshipSection}${mappedRelationshipSection}
|
|
191
228
|
|
|
192
229
|
<!--
|
|
193
230
|
********************************************************************************
|
package/src/commands/index.ts
CHANGED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { createCommand } from 'commander';
|
|
2
|
+
import * as log from '../log';
|
|
3
|
+
import { TypesCommandArgs } from '../utils/getSortedJupiterOneTypes';
|
|
4
|
+
import { validateManagedQuestionFile } from '../questions/managedQuestionFileValidator';
|
|
5
|
+
import {
|
|
6
|
+
ApiClient,
|
|
7
|
+
createApiClient,
|
|
8
|
+
getApiBaseUrl,
|
|
9
|
+
} from '@jupiterone/integration-sdk-runtime';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
|
|
12
|
+
interface ValidateQuestionFileCommandArgs extends TypesCommandArgs {
|
|
13
|
+
filePath: string;
|
|
14
|
+
jupiteroneAccountId?: string;
|
|
15
|
+
jupiteroneApiKey?: string;
|
|
16
|
+
dryRun?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function getDefaultQuestionFilePath() {
|
|
20
|
+
return path.join(process.cwd(), './jupiterone/questions/questions.yaml');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function validateQuestionFile() {
|
|
24
|
+
return createCommand('validate-question-file')
|
|
25
|
+
.description('validates an integration questions file')
|
|
26
|
+
.requiredOption(
|
|
27
|
+
'-p, --file-path <filePath>',
|
|
28
|
+
'absolute path to managed question file',
|
|
29
|
+
getDefaultQuestionFilePath(),
|
|
30
|
+
)
|
|
31
|
+
.option(
|
|
32
|
+
'-a, --jupiterone-account-id <jupiteroneAccountId>',
|
|
33
|
+
'J1 account ID used to validate J1QL queries',
|
|
34
|
+
)
|
|
35
|
+
.option(
|
|
36
|
+
'-k, --jupiterone-api-key <jupiteroneApiKey>',
|
|
37
|
+
'J1 API key used to validate J1QL queries',
|
|
38
|
+
)
|
|
39
|
+
.option(
|
|
40
|
+
'-d, --dry-run',
|
|
41
|
+
'skip making HTTP requests to validate J1QL queries',
|
|
42
|
+
)
|
|
43
|
+
.action(executeValidateQuestionFileAction);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function executeValidateQuestionFileAction(
|
|
47
|
+
options: ValidateQuestionFileCommandArgs,
|
|
48
|
+
): Promise<void> {
|
|
49
|
+
const { filePath, jupiteroneAccountId, jupiteroneApiKey, dryRun } = options;
|
|
50
|
+
|
|
51
|
+
log.info(
|
|
52
|
+
`\nRunning validate-question-file action (path=${filePath}, accountId=${jupiteroneAccountId}, dryRun=${dryRun})...\n`,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
let apiClient: ApiClient | undefined;
|
|
56
|
+
|
|
57
|
+
if (!dryRun && (!jupiteroneAccountId || !jupiteroneApiKey)) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
'Must provide J1 account ID and API key (except for --dry-run)',
|
|
60
|
+
);
|
|
61
|
+
} else if (!dryRun && jupiteroneAccountId && jupiteroneApiKey) {
|
|
62
|
+
apiClient = createApiClient({
|
|
63
|
+
apiBaseUrl: getApiBaseUrl({
|
|
64
|
+
dev: !!process.env.JUPITERONE_DEV,
|
|
65
|
+
}),
|
|
66
|
+
account: jupiteroneAccountId,
|
|
67
|
+
accessToken: jupiteroneApiKey,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
await validateManagedQuestionFile({
|
|
73
|
+
filePath,
|
|
74
|
+
apiClient,
|
|
75
|
+
});
|
|
76
|
+
} catch (err) {
|
|
77
|
+
log.error('Failed to validate managed question file!');
|
|
78
|
+
throw err;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
log.info('Successfully validated managed question file!');
|
|
82
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
sync,
|
|
9
9
|
visualize,
|
|
10
10
|
visualizeTypes,
|
|
11
|
+
validateQuestionFile,
|
|
11
12
|
} from './commands';
|
|
12
13
|
|
|
13
14
|
export function createCli() {
|
|
@@ -18,5 +19,6 @@ export function createCli() {
|
|
|
18
19
|
.addCommand(sync())
|
|
19
20
|
.addCommand(run())
|
|
20
21
|
.addCommand(visualizeTypes())
|
|
21
|
-
.addCommand(document())
|
|
22
|
+
.addCommand(document())
|
|
23
|
+
.addCommand(validateQuestionFile());
|
|
22
24
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
sourceId: managed:google_cloud
|
|
3
|
+
integrationDefinitionId: "${integration_definition_id}"
|
|
4
|
+
questions:
|
|
5
|
+
- id: integration-question-google-cloud-disabled-project-services
|
|
6
|
+
title: Which Google Cloud API services are disabled for my project?
|
|
7
|
+
description:
|
|
8
|
+
Finds all disabled Google Cloud API services in a specified project
|
|
9
|
+
queries:
|
|
10
|
+
- query: |
|
|
11
|
+
FIND google_cloud_api_service WITH projectId = '{{projectId}}' AND enabled = false
|
|
12
|
+
tags:
|
|
13
|
+
- google-cloud
|
|
14
|
+
- service
|
|
15
|
+
- api
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
sourceId: managed:google_cloud
|
|
3
|
+
integrationDefinitionId: "${integration_definition_id}"
|
|
4
|
+
questions:
|
|
5
|
+
- id: integration-question-google-cloud-iam-not-assigned-user-token-roles-project-level
|
|
6
|
+
title: Ensure that IAM users are not assigned the Service Account User or Service Account Token Creator roles at project level
|
|
7
|
+
description: >
|
|
8
|
+
It is recommended to assign the Service Account User (iam.serviceAccountUser)
|
|
9
|
+
and Service Account Token Creator (iam.serviceAccountTokenCreator) roles to
|
|
10
|
+
a user for a specific service account rather than assigning the role to a
|
|
11
|
+
user at project level.
|
|
12
|
+
queries:
|
|
13
|
+
- name: good
|
|
14
|
+
query: |
|
|
15
|
+
find google_iam_service_account as user
|
|
16
|
+
that ASSIGNED google_iam_role as role
|
|
17
|
+
where
|
|
18
|
+
role.name!="roles/iam.serviceAccountUser" and
|
|
19
|
+
role.name!="roles/iam.serviceAccountTokenCreator"
|
|
20
|
+
return
|
|
21
|
+
user.name,
|
|
22
|
+
role.name
|
|
23
|
+
- name: bad
|
|
24
|
+
query: |
|
|
25
|
+
find google_iam_service_account as user
|
|
26
|
+
that ASSIGNED google_iam_role as role
|
|
27
|
+
where
|
|
28
|
+
role.name="roles/iam.serviceAccountUser" or
|
|
29
|
+
role.name="roles/iam.serviceAccountTokenCreator"
|
|
30
|
+
return
|
|
31
|
+
user.name,
|
|
32
|
+
role.name
|
|
33
|
+
tags:
|
|
34
|
+
- google-cloud
|
|
35
|
+
- service-account
|
|
36
|
+
- access
|
|
37
|
+
- iam
|
|
38
|
+
compliance:
|
|
39
|
+
- standard: CIS Google Cloud Foundations
|
|
40
|
+
requirements:
|
|
41
|
+
- '1.6'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
sourceId: managed:google_cloud
|
|
3
|
+
integrationDefinitionId: "${integration_definition_id}"
|
|
4
|
+
### The following is invalid!
|
|
5
|
+
questions
|
|
6
|
+
- id: integration-question-google-cloud-disabled-project-services
|
|
7
|
+
title: Which Google Cloud API services are disabled for my project?
|
|
8
|
+
description:
|
|
9
|
+
Finds all disabled Google Cloud API services in a specified project
|
|
10
|
+
queries:
|
|
11
|
+
- query: |
|
|
12
|
+
FIND google_cloud_api_service WITH projectId = '{{projectId}}' AND enabled = false
|
|
13
|
+
tags:
|
|
14
|
+
- google-cloud
|
|
15
|
+
- service
|
|
16
|
+
- api
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
sourceId: managed:google_cloud
|
|
3
|
+
integrationDefinitionId: "${integration_definition_id}"
|
|
4
|
+
questions:
|
|
5
|
+
- id: integration-question-google-cloud-corporate-login-credentials
|
|
6
|
+
title: Ensure that corporate login credentials are used
|
|
7
|
+
description:
|
|
8
|
+
Use corporate login credentials instead of personal accounts, such as Gmail accounts.
|
|
9
|
+
queries:
|
|
10
|
+
- name: good
|
|
11
|
+
query: find google_user with email $="@{{domain}}"
|
|
12
|
+
- name: bad
|
|
13
|
+
query: find google_user with email !$="@{{domain}}"
|
|
14
|
+
tags:
|
|
15
|
+
- google-cloud
|
|
16
|
+
- user
|
|
17
|
+
- access
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
sourceId: managed:google_cloud
|
|
3
|
+
integrationDefinitionId: "${integration_definition_id}"
|
|
4
|
+
questions:
|
|
5
|
+
- id: integration-question-google-cloud-disabled-project-services
|
|
6
|
+
title: Which Google Cloud API services are disabled for my project?
|
|
7
|
+
description:
|
|
8
|
+
Finds all disabled Google Cloud API services in a specified project
|
|
9
|
+
queries:
|
|
10
|
+
- query: |
|
|
11
|
+
FIND google_cloud_api_service WITH projectId = '{{projectId}}' AND enabled = false
|
|
12
|
+
tags:
|
|
13
|
+
- google-cloud
|
|
14
|
+
- service
|
|
15
|
+
- api
|
|
16
|
+
|
|
17
|
+
- id: integration-question-google-cloud-corporate-login-credentials
|
|
18
|
+
title: Ensure that corporate login credentials are used
|
|
19
|
+
description:
|
|
20
|
+
Use corporate login credentials instead of personal accounts, such as Gmail accounts.
|
|
21
|
+
queries:
|
|
22
|
+
- query: |
|
|
23
|
+
FIND google_user WITH email $="@{{domain}}"
|
|
24
|
+
tags:
|
|
25
|
+
- google-cloud
|
|
26
|
+
- user
|
|
27
|
+
- access
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
sourceId: managed:google_cloud
|
|
3
|
+
integrationDefinitionId: "${integration_definition_id}"
|
|
4
|
+
questions:
|
|
5
|
+
- id: integration-question-google-cloud-disabled-project-services
|
|
6
|
+
title: Which Google Cloud API services are disabled for my project?
|
|
7
|
+
description:
|
|
8
|
+
Finds all disabled Google Cloud API services in a specified project
|
|
9
|
+
queries:
|
|
10
|
+
- query: |
|
|
11
|
+
FIND google_cloud_api_service WITH projectId = '{{projectId}}' AND enabled = false
|
|
12
|
+
tags:
|
|
13
|
+
- google-cloud
|
|
14
|
+
- service
|
|
15
|
+
- api
|
|
16
|
+
|
|
17
|
+
### NOTE: This ID is _not_ unique and will cause an error to be thrown!
|
|
18
|
+
- id: integration-question-google-cloud-disabled-project-services
|
|
19
|
+
title: Ensure that corporate login credentials are used
|
|
20
|
+
description:
|
|
21
|
+
Use corporate login credentials instead of personal accounts, such as Gmail accounts.
|
|
22
|
+
queries:
|
|
23
|
+
- query: |
|
|
24
|
+
FIND google_user WITH email $="@{{domain}}"
|
|
25
|
+
tags:
|
|
26
|
+
- google-cloud
|
|
27
|
+
- user
|
|
28
|
+
- access
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
sourceId: managed:google_cloud
|
|
3
|
+
integrationDefinitionId: "${integration_definition_id}"
|
|
4
|
+
questions:
|
|
5
|
+
- id: integration-question-google-cloud-corporate-login-credentials
|
|
6
|
+
title: Ensure that corporate login credentials are used
|
|
7
|
+
description:
|
|
8
|
+
Use corporate login credentials instead of personal accounts, such as Gmail accounts.
|
|
9
|
+
queries:
|
|
10
|
+
- name: good
|
|
11
|
+
query: find google_user with email $="@{{domain}}"
|
|
12
|
+
### NOTE: This name is _not_ unique and will cause an error to be thrown!
|
|
13
|
+
- name: good
|
|
14
|
+
query: find google_user with email !$="@{{domain}}"
|
|
15
|
+
tags:
|
|
16
|
+
- google-cloud
|
|
17
|
+
- user
|
|
18
|
+
- access
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
sourceId: managed:google_cloud
|
|
3
|
+
integrationDefinitionId: "${integration_definition_id}"
|
|
4
|
+
questions:
|
|
5
|
+
- id: integration-question-google-cloud-disabled-project-services
|
|
6
|
+
title: Which Google Cloud API services are disabled for my project?
|
|
7
|
+
description:
|
|
8
|
+
Finds all disabled Google Cloud API services in a specified project
|
|
9
|
+
queries:
|
|
10
|
+
- query: |
|
|
11
|
+
FIND google_cloud_api_service WITH projectId = '{{projectId}}' AND enabled = false
|
|
12
|
+
tags:
|
|
13
|
+
- google-cloud
|
|
14
|
+
- service
|
|
15
|
+
### NOTE: This tag is _not_ unique and will cause an error to be thrown!
|
|
16
|
+
- google-cloud
|
|
17
|
+
- api
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
sourceId: managed:google_cloud
|
|
3
|
+
integrationDefinitionId: "${integration_definition_id}"
|
|
4
|
+
questions:
|
|
5
|
+
- id: integration-question-google-cloud-disabled-project-services
|
|
6
|
+
title: Which Google Cloud API services are disabled for my project?
|
|
7
|
+
description:
|
|
8
|
+
Finds all disabled Google Cloud API services in a specified project
|
|
9
|
+
queries:
|
|
10
|
+
- query: |
|
|
11
|
+
FIND google_cloud_api_service WITH projectId = '{{projectId}}' AND enabled = false
|
|
12
|
+
tags:
|
|
13
|
+
- google-cloud
|
|
14
|
+
- service
|
|
15
|
+
- api
|
|
16
|
+
|
|
17
|
+
- id: integration-question-google-cloud-corporate-login-credentials
|
|
18
|
+
### NOTE: This title is _not_ unique and will cause an error to be thrown!
|
|
19
|
+
title: Which Google Cloud API services are disabled for my project?
|
|
20
|
+
description:
|
|
21
|
+
Use corporate login credentials instead of personal accounts, such as Gmail accounts.
|
|
22
|
+
queries:
|
|
23
|
+
- query: |
|
|
24
|
+
FIND google_user WITH email $="@{{domain}}"
|
|
25
|
+
tags:
|
|
26
|
+
- google-cloud
|
|
27
|
+
- user
|
|
28
|
+
- access
|