diff --git a/src/steps/cloud-run/__snapshots__/converters.test.ts.snap b/src/steps/cloud-run/__snapshots__/converters.test.ts.snap index 27ef0106..63f0c22b 100644 --- a/src/steps/cloud-run/__snapshots__/converters.test.ts.snap +++ b/src/steps/cloud-run/__snapshots__/converters.test.ts.snap @@ -197,7 +197,7 @@ Object { "_class": Array [ "Service", ], - "_key": "cloudrun_service:fce2d165-9ccb-4b6c-9204-67362d41aadd", + "_key": "projects/j1-gc-integration-dev-v2/locations/us-central1/services/example-cloud-run-service", "_rawData": Array [ Object { "name": "default", diff --git a/src/steps/cloud-run/__snapshots__/index.test.ts.snap b/src/steps/cloud-run/__snapshots__/index.test.ts.snap index d7dd8bfb..aa72be30 100644 --- a/src/steps/cloud-run/__snapshots__/index.test.ts.snap +++ b/src/steps/cloud-run/__snapshots__/index.test.ts.snap @@ -7,7 +7,7 @@ Object { "_class": Array [ "Service", ], - "_key": "cloudrun_service:fce2d165-9ccb-4b6c-9204-67362d41aadd", + "_key": "projects/j1-gc-integration-dev-v2/locations/us-central1/services/example-cloud-run-service", "_rawData": Array [ Object { "name": "default", @@ -231,8 +231,8 @@ Object { "collectedRelationships": Array [ Object { "_class": "MANAGES", - "_fromEntityKey": "cloudrun_service:fce2d165-9ccb-4b6c-9204-67362d41aadd", - "_key": "cloudrun_service:fce2d165-9ccb-4b6c-9204-67362d41aadd|manages|cloudrun_configuration:f190d809-4de1-4eb3-80bb-ad0ac9954f85", + "_fromEntityKey": "projects/j1-gc-integration-dev-v2/locations/us-central1/services/example-cloud-run-service", + "_key": "projects/j1-gc-integration-dev-v2/locations/us-central1/services/example-cloud-run-service|manages|cloudrun_configuration:f190d809-4de1-4eb3-80bb-ad0ac9954f85", "_toEntityKey": "cloudrun_configuration:f190d809-4de1-4eb3-80bb-ad0ac9954f85", "_type": "google_cloud_run_service_manages_configuration", "displayName": "MANAGES", @@ -255,7 +255,7 @@ Object { "_class": Array [ "Service", ], - "_key": "cloudrun_service:fce2d165-9ccb-4b6c-9204-67362d41aadd", + "_key": "projects/j1-gc-integration-dev-v2/locations/us-central1/services/example-cloud-run-service", "_rawData": Array [ Object { "name": "default", @@ -457,8 +457,8 @@ Object { "collectedRelationships": Array [ Object { "_class": "MANAGES", - "_fromEntityKey": "cloudrun_service:fce2d165-9ccb-4b6c-9204-67362d41aadd", - "_key": "cloudrun_service:fce2d165-9ccb-4b6c-9204-67362d41aadd|manages|cloudrun_route:f538487c-6e93-4038-9f6a-b7936cc4dd04", + "_fromEntityKey": "projects/j1-gc-integration-dev-v2/locations/us-central1/services/example-cloud-run-service", + "_key": "projects/j1-gc-integration-dev-v2/locations/us-central1/services/example-cloud-run-service|manages|cloudrun_route:f538487c-6e93-4038-9f6a-b7936cc4dd04", "_toEntityKey": "cloudrun_route:f538487c-6e93-4038-9f6a-b7936cc4dd04", "_type": "google_cloud_run_service_manages_route", "displayName": "MANAGES", @@ -481,7 +481,7 @@ Object { "_class": Array [ "Service", ], - "_key": "cloudrun_service:fce2d165-9ccb-4b6c-9204-67362d41aadd", + "_key": "projects/j1-gc-integration-dev-v2/locations/us-central1/services/example-cloud-run-service", "_rawData": Array [ Object { "name": "default", diff --git a/src/steps/cloud-run/converters.test.ts b/src/steps/cloud-run/converters.test.ts index 602dbe79..bb0c2410 100644 --- a/src/steps/cloud-run/converters.test.ts +++ b/src/steps/cloud-run/converters.test.ts @@ -16,6 +16,8 @@ describe('#createCloudRunServiceEntity', () => { createCloudRunServiceEntity( getMockCloudRunService(), DEFAULT_INTEGRATION_CONFIG_PROJECT_ID, + // This would otherwise be returned by cacheCloudRunServiceKeyAndUid() + `projects/${DEFAULT_INTEGRATION_CONFIG_PROJECT_ID}/locations/us-central1/services/example-cloud-run-service`, ), ).toMatchSnapshot(); }); diff --git a/src/steps/cloud-run/converters.ts b/src/steps/cloud-run/converters.ts index b8751ca6..73104055 100644 --- a/src/steps/cloud-run/converters.ts +++ b/src/steps/cloud-run/converters.ts @@ -20,8 +20,12 @@ export interface MetadataComputedPropertyData { duplicateProperties: string[]; } -export function getCloudRunServiceKey(uid: string) { - return `cloudrun_service:${uid}`; +export function getCloudRunServiceKey( + projectId: string, + location: string, + name: string, +) { + return `projects/${projectId}/locations/${location}/services/${name}`; } export function getCloudRunRouteKey(uid: string) { @@ -35,6 +39,7 @@ export function getCloudRunConfigurationKey(uid: string) { export function createCloudRunServiceEntity( data: run_v1.Schema$Service, projectId: string, + key: string, ) { // Build webLink let webLink = ''; @@ -54,7 +59,7 @@ export function createCloudRunServiceEntity( assign: { _class: ENTITY_CLASS_CLOUD_RUN_SERVICE, _type: ENTITY_TYPE_CLOUD_RUN_SERVICE, - _key: getCloudRunServiceKey(data.metadata?.uid as string), + _key: key, name: data.metadata?.name, function: ['workload-management'], displayName: data.metadata?.name as string, diff --git a/src/steps/cloud-run/index.ts b/src/steps/cloud-run/index.ts index 411aa0f0..d47a29af 100644 --- a/src/steps/cloud-run/index.ts +++ b/src/steps/cloud-run/index.ts @@ -4,6 +4,10 @@ import { RelationshipClass, } from '@jupiterone/integration-sdk-core'; import { IntegrationConfig, IntegrationStepContext } from '../../types'; +import { + cacheCloudRunServiceKeyAndUid, + getCloudRunServiceKeyFromUid, +} from '../../utils/jobState'; import { CloudRunClient } from './client'; import { STEP_CLOUD_RUN_SERVICES, @@ -22,7 +26,6 @@ import { createCloudRunConfigurationEntity, createCloudRunRouteEntity, createCloudRunServiceEntity, - getCloudRunServiceKey, MetadataComputedPropertyData, } from './converters'; @@ -37,10 +40,17 @@ export async function fetchCloudRunServices( const client = new CloudRunClient({ config }); await client.iterateCloudRunServices(async (service) => { + const key = await cacheCloudRunServiceKeyAndUid( + jobState, + service, + client.projectId, + ); const serviceEntity = createCloudRunServiceEntity( service, client.projectId, + key, ); + await jobState.addEntity(serviceEntity); }); } @@ -63,9 +73,11 @@ export async function fetchCloudRunRoutes( (owner) => owner.kind === 'Service', ); if (ownerService) { - const serviceEntity = await jobState.findEntity( - getCloudRunServiceKey(ownerService.uid as string), + const serviceKey = await getCloudRunServiceKeyFromUid( + jobState, + ownerService.uid as string, ); + const serviceEntity = await jobState.findEntity(serviceKey); if (serviceEntity) { await jobState.addRelationship( createDirectRelationship({ @@ -115,9 +127,11 @@ export async function fetchCloudRunConfigurations( (owner) => owner.kind === 'Service', ); if (ownerService) { - const serviceEntity = await jobState.findEntity( - getCloudRunServiceKey(ownerService.uid as string), + const serviceKey = await getCloudRunServiceKeyFromUid( + jobState, + ownerService.uid as string, ); + const serviceEntity = await jobState.findEntity(serviceKey); if (serviceEntity) { await jobState.addRelationship( createDirectRelationship({ diff --git a/src/utils/iamBindings/__snapshots__/getTypeAndKeyFromResourceIdentifier.test.ts.snap b/src/utils/iamBindings/__snapshots__/getTypeAndKeyFromResourceIdentifier.test.ts.snap index bb41ba36..0facd20b 100644 --- a/src/utils/iamBindings/__snapshots__/getTypeAndKeyFromResourceIdentifier.test.ts.snap +++ b/src/utils/iamBindings/__snapshots__/getTypeAndKeyFromResourceIdentifier.test.ts.snap @@ -59,7 +59,7 @@ Object { exports[`getTypeAndKeyFromResourceIdentifier should find the correct keys for all available resources 8`] = ` Object { "identifier": "//run.googleapis.com/projects/12345/locations/us-east1/services/abcdef12345", - "key": "cloudrun_service:abcdef12345", + "key": "projects/12345/locations/us-east1/services/abcdef12345", "type": "google_cloud_run_service", } `; diff --git a/src/utils/iamBindings/typeToKeyGeneratorMap.ts b/src/utils/iamBindings/typeToKeyGeneratorMap.ts index 537cd7a1..bd971f3b 100644 --- a/src/utils/iamBindings/typeToKeyGeneratorMap.ts +++ b/src/utils/iamBindings/typeToKeyGeneratorMap.ts @@ -13,7 +13,6 @@ import { BIG_QUERY_TABLE_ENTITY_TYPE, } from '../../steps/big-query'; import { ENTITY_TYPE_CLOUD_RUN_SERVICE } from '../../steps/cloud-run/constants'; -import { getCloudRunServiceKey } from '../../steps/cloud-run/converters'; import { ENTITY_TYPE_COMPUTE_BACKEND_BUCKET, ENTITY_TYPE_COMPUTE_BACKEND_SERVICE, @@ -115,9 +114,7 @@ export const J1_TYPE_TO_KEY_GENERATOR_MAP: { context!.jobState, finalIdentifierKeyMap(id), )) ?? finalIdentifierKeyMap(id), - [ENTITY_TYPE_CLOUD_RUN_SERVICE]: customPrefixAndIdKeyMap( - getCloudRunServiceKey, - ), + [ENTITY_TYPE_CLOUD_RUN_SERVICE]: fullPathKeyMap, [ENTITY_TYPE_COMPUTE_BACKEND_BUCKET]: selfLinkKeyMap, [ENTITY_TYPE_COMPUTE_BACKEND_SERVICE]: selfLinkKeyMap, [ENTITY_TYPE_COMPUTE_DISK]: customPrefixAndIdKeyMap(getComputeDiskKey), diff --git a/src/utils/jobState.ts b/src/utils/jobState.ts index c4ac57e6..d0010a3e 100644 --- a/src/utils/jobState.ts +++ b/src/utils/jobState.ts @@ -1,5 +1,6 @@ import { JobState } from '@jupiterone/integration-sdk-core'; -import { cloudresourcemanager_v3, compute_v1 } from 'googleapis'; +import { cloudresourcemanager_v3, compute_v1, run_v1 } from 'googleapis'; +import { getCloudRunServiceKey } from '../steps/cloud-run/converters'; export const PEERED_NETWORKS = 'network:all_peerings'; @@ -25,6 +26,31 @@ export async function getProjectNameFromId( return jobState.getData(`projectId:${projectId}`); } +export async function cacheCloudRunServiceKeyAndUid( + jobState, + cloudRunService: run_v1.Schema$Service, + projectId: string, +): Promise { + const location = cloudRunService.metadata?.labels + ? cloudRunService.metadata?.labels['cloud.googleapis.com/location'] + : ''; + const name = cloudRunService.metadata?.name; + + const uid = cloudRunService.metadata?.uid; + const key = getCloudRunServiceKey(projectId, location, name as string); + + await jobState.setData(`cloudRunServiceUid:${uid}`, key); + + return key; +} + +export async function getCloudRunServiceKeyFromUid( + jobState: JobState, + uid: string, +) { + return jobState.getData(`cloudRunServiceUid:${uid}`); +} + export async function getPeeredNetworks(jobState: JobState) { return jobState.getData(PEERED_NETWORKS); }