diff --git a/.env.example b/.env.example index 440c1030..dd1df426 100644 --- a/.env.example +++ b/.env.example @@ -3,4 +3,5 @@ SERVICE_ACCOUNT_KEY_FILE={} PROJECT_ID="" ORGANIZATION_ID="" CONFIGURE_ORGANIZATION_PROJECTS=false -FOLDER_ID="" \ No newline at end of file +FOLDER_ID="" +COMPUTE_INSTANCE_METADATA_FIELDS_TO_INGEST="" \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eb9308a..345c6b08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# v3.3.4 (Fri May 03 2024) + +#### 🐛 Bug Fix + +- INT-8094: ingest compute instance metadata fields [#659](https://github.com/JupiterOne/graph-google-cloud/pull/659) ([@gastonyelmini](https://github.com/gastonyelmini)) + +#### Authors: 1 + +- Gaston Yelmini ([@gastonyelmini](https://github.com/gastonyelmini)) + +--- + # v3.3.3 (Tue Apr 09 2024) #### 🐛 Bug Fix diff --git a/package.json b/package.json index dd995459..5ce3cb41 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@jupiterone/graph-google-cloud", - "version": "3.3.3", + "version": "3.3.4", "description": "A graph conversion tool for https://cloud.google.com/", "repository": { "type": "git", diff --git a/src/index.ts b/src/index.ts index 95639647..0f0f2978 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,6 +32,10 @@ export const invocationConfig: IntegrationInvocationConfig = type: 'boolean', optional: true, }, + computeInstanceMetadataFieldsToIngest: { + type: 'string', + optional: true, + }, }, getStepStartStates, integrationSteps: steps, diff --git a/src/steps/compute/converters.ts b/src/steps/compute/converters.ts index 2e6efee2..0495a2da 100644 --- a/src/steps/compute/converters.ts +++ b/src/steps/compute/converters.ts @@ -62,6 +62,7 @@ import { ENTITY_TYPE_COMPUTE_TARGET_SSL_PROXY, MAPPED_RELATIONSHIP_FIREWALL_RULE_TYPE, } from './constants'; +import { camelCase } from 'lodash'; export function createComputeProjectEntity(data: compute_v1.Schema$Project) { return createGoogleCloudIntegrationEntity(data, { @@ -434,10 +435,45 @@ function isShieldedVM( : false; } +function getComputeInstanceMetadataFieldsToIngest( + computeInstanceMetadataFieldsToIngest: string | undefined, + computeInstanceMetadata: + | { key?: string | undefined; value?: string | undefined }[] + | null + | undefined, +) { + const parsedcomputeInstanceMetadataFieldsToIngest: string[] | undefined = + computeInstanceMetadataFieldsToIngest?.split(','); + + if ( + !parsedcomputeInstanceMetadataFieldsToIngest || + !parsedcomputeInstanceMetadataFieldsToIngest.length || + !computeInstanceMetadata || + !computeInstanceMetadata.length + ) { + return {}; + } + + const metadataObject = {}; + + for (const metadata of computeInstanceMetadata) { + if ( + metadata.key && + parsedcomputeInstanceMetadataFieldsToIngest.includes(metadata.key) + ) { + const parsedKey = `metadata.${camelCase(metadata.key)}`; + metadataObject[parsedKey] = metadata.value; + } + } + + return metadataObject; +} + export function createComputeInstanceEntity( data: compute_v1.Schema$Instance, instanceInventory: osconfig_v1.Schema$Inventory | undefined, projectId: string, + computeInstanceMetadataFieldsToIngest: string | undefined, ) { const ipAddresses = getIpAddressesForComputeInstance(data); const zone = getLastUrlPart(data.zone!); @@ -501,6 +537,10 @@ export function createComputeInstanceEntity( webLink: getGoogleCloudConsoleWebLink( `/compute/instancesDetail/zones/${zone}/instances/${data.name}?project=${projectId}`, ), + ...getComputeInstanceMetadataFieldsToIngest( + computeInstanceMetadataFieldsToIngest, + data.metadata?.items, + ), osHostname: instanceInventory?.osInfo?.hostname, osLongName: instanceInventory?.osInfo?.longName, osShortName: instanceInventory?.osInfo?.shortName, diff --git a/src/steps/compute/steps/fetch-compute-instances.ts b/src/steps/compute/steps/fetch-compute-instances.ts index deefe177..5481cb6a 100644 --- a/src/steps/compute/steps/fetch-compute-instances.ts +++ b/src/steps/compute/steps/fetch-compute-instances.ts @@ -144,6 +144,7 @@ export async function fetchComputeInstances( computeInstance, instanceInventory, client.projectId, + context.instance.config.computeInstanceMetadataFieldsToIngest, ), ); diff --git a/src/types.ts b/src/types.ts index abc53691..911ef6d7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -25,6 +25,7 @@ export interface SerializedIntegrationConfig extends IntegrationInstanceConfig { configureOrganizationProjects?: boolean; folderId?: string; useEnablementsForStepStartStates?: boolean; + computeInstanceMetadataFieldsToIngest?: string; } export interface IntegrationConfig extends SerializedIntegrationConfig {