@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.
Files changed (38) hide show
  1. package/dist/src/commands/document.js +31 -2
  2. package/dist/src/commands/document.js.map +1 -1
  3. package/dist/src/commands/index.d.ts +1 -0
  4. package/dist/src/commands/index.js +1 -0
  5. package/dist/src/commands/index.js.map +1 -1
  6. package/dist/src/commands/validate-question-file.d.ts +2 -0
  7. package/dist/src/commands/validate-question-file.js +70 -0
  8. package/dist/src/commands/validate-question-file.js.map +1 -0
  9. package/dist/src/index.js +2 -1
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/questions/managedQuestionFileValidator.d.ts +53 -0
  12. package/dist/src/questions/managedQuestionFileValidator.js +140 -0
  13. package/dist/src/questions/managedQuestionFileValidator.js.map +1 -0
  14. package/dist/src/services/queryLanguage.d.ts +21 -0
  15. package/dist/src/services/queryLanguage.js +34 -0
  16. package/dist/src/services/queryLanguage.js.map +1 -0
  17. package/dist/tsconfig.dist.tsbuildinfo +845 -12
  18. package/package.json +7 -4
  19. package/src/__tests__/__snapshots__/cli.test.ts.snap +52 -5
  20. package/src/__tests__/cli/validate-question-file.test.ts +24 -0
  21. package/src/__tests__/cli.test.ts +4 -0
  22. package/src/commands/document.ts +39 -2
  23. package/src/commands/index.ts +1 -0
  24. package/src/commands/validate-question-file.ts +82 -0
  25. package/src/index.ts +3 -1
  26. package/src/questions/__fixtures__/questions/basic.yaml +15 -0
  27. package/src/questions/__fixtures__/questions/compliance.yaml +41 -0
  28. package/src/questions/__fixtures__/questions/empty-questions.yaml +4 -0
  29. package/src/questions/__fixtures__/questions/invalid-yaml.yaml +16 -0
  30. package/src/questions/__fixtures__/questions/multiple-queries.yaml +17 -0
  31. package/src/questions/__fixtures__/questions/multiple-questions.yaml +27 -0
  32. package/src/questions/__fixtures__/questions/non-unique-question-id.yaml +28 -0
  33. package/src/questions/__fixtures__/questions/non-unique-question-name.yaml +18 -0
  34. package/src/questions/__fixtures__/questions/non-unique-question-tag.yaml +17 -0
  35. package/src/questions/__fixtures__/questions/non-unique-question-title.yaml +28 -0
  36. package/src/questions/managedQuestionFileValidator.test.ts +175 -0
  37. package/src/questions/managedQuestionFileValidator.ts +180 -0
  38. 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.17.0",
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.17.0",
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.17.0",
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": "4be45cdd8f6bff0740e473ff1f682078fbc1b51a"
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/mapped:
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/mapped:
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/mapped:
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/mapped:
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/mapped:
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
 
@@ -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/mapped:
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
  ********************************************************************************
@@ -5,3 +5,4 @@ export * from './sync';
5
5
  export * from './run';
6
6
  export * from './document';
7
7
  export * from './visualize-types';
8
+ export * from './validate-question-file';
@@ -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,4 @@
1
+ ---
2
+ sourceId: managed:google_cloud
3
+ integrationDefinitionId: "${integration_definition_id}"
4
+ questions: []
@@ -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