Skip to content
This repository has been archived by the owner on Jun 25, 2024. It is now read-only.

Commit

Permalink
feat(INT-5918): add cloud function source repo relationship
Browse files Browse the repository at this point in the history
  • Loading branch information
Gaston Yelmini authored and Gaston Yelmini committed Oct 31, 2022
1 parent ca2cca1 commit b5d4a54
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 34 deletions.
1 change: 1 addition & 0 deletions docs/jupiterone.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ The following relationships are created:
| `internet` | **ALLOWS** | `google_compute_firewall` |
| `google_cloud_folder` | **HAS** | `google_cloud_folder` |
| `google_cloud_function` | **USES** | `google_iam_service_account` |
| `google_cloud_function` | **USES** | `google_cloud_source_repository` |
| `google_cloud_organization` | **HAS** | `google_cloud_folder` |
| `google_cloud_project` | **HAS** | `google_cloud_api_service` |
| `google_cloud_project` | **HAS** | `google_billing_budget` |
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/src/steps/services/functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const functionSteps: StepSpec<IntegrationInstanceConfig>[] = [
},
],
dependsOn: ['fetch-cloud-functions', 'fetch-cloud-source-repositories'],
implemented: false,
implemented: true,
},
{
/**
Expand Down
5 changes: 5 additions & 0 deletions src/getStepStartStates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ import * as enablement from './steps/enablement';
import {
STEP_CLOUD_FUNCTIONS,
STEP_CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS,
STEP_CLOUD_FUNCTIONS_SOURCE_REPO_RELATIONSHIPS,
} from './steps/functions';
import {
STEP_IAM_CUSTOM_ROLES,
Expand Down Expand Up @@ -301,6 +302,7 @@ function getDefaultStepStartStates(params: {
[STEP_CREATE_API_SERVICE_ANY_RESOURCE_RELATIONSHIPS]: { disabled: false },
[STEP_CLOUD_FUNCTIONS]: { disabled: false },
[STEP_CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS]: { disabled: false },
[STEP_CLOUD_FUNCTIONS_SOURCE_REPO_RELATIONSHIPS]: { disabled: false },
[STEP_CLOUD_STORAGE_BUCKETS]: { disabled: false },
[STEP_IAM_CUSTOM_ROLES]: { disabled: false },
[STEP_IAM_CUSTOM_ROLE_SERVICE_API_RELATIONSHIPS]: { disabled: false },
Expand Down Expand Up @@ -591,6 +593,9 @@ async function getStepStartStatesUsingServiceEnablements(params: {
[STEP_CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS]: createStepStartState(
ServiceUsageName.CLOUD_FUNCTIONS,
),
[STEP_CLOUD_FUNCTIONS_SOURCE_REPO_RELATIONSHIPS]: createStepStartState(
ServiceUsageName.CLOUD_FUNCTIONS,
),
[STEP_CLOUD_STORAGE_BUCKETS]: createStepStartState(
ServiceUsageName.STORAGE,
ServiceUsageName.STORAGE_COMPONENT,
Expand Down
12 changes: 8 additions & 4 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,6 @@ import {
STEP_DNS_MANAGED_ZONES,
STEP_DNS_POLICIES,
} from './steps/dns/constants';
import {
STEP_CLOUD_FUNCTIONS,
STEP_CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS,
} from './steps/functions';
import {
STEP_IAM_CUSTOM_ROLES,
STEP_IAM_CUSTOM_ROLE_SERVICE_API_RELATIONSHIPS,
Expand Down Expand Up @@ -175,6 +171,11 @@ import {
import { SqlAdminSteps, STEP_SQL_ADMIN_INSTANCES } from './steps/sql-admin';
import { STEP_CLOUD_STORAGE_BUCKETS } from './steps/storage';
import { IntegrationConfig } from './types';
import {
STEP_CLOUD_FUNCTIONS,
STEP_CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS,
STEP_CLOUD_FUNCTIONS_SOURCE_REPO_RELATIONSHIPS,
} from './steps/functions';

interface ValidateInvocationInvalidConfigTestParams {
instanceConfig?: Partial<IntegrationConfig>;
Expand Down Expand Up @@ -326,6 +327,9 @@ describe('#getStepStartStates success', () => {
[STEP_CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS]: {
disabled: false,
},
[STEP_CLOUD_FUNCTIONS_SOURCE_REPO_RELATIONSHIPS]: {
disabled: false,
},
[STEP_CLOUD_STORAGE_BUCKETS]: {
disabled: false,
},
Expand Down
44 changes: 42 additions & 2 deletions src/steps/functions/constants.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,49 @@
import { RelationshipClass } from '@jupiterone/integration-sdk-core';
import { IAM_SERVICE_ACCOUNT_ENTITY_TYPE } from '../iam';

export const CLOUD_FUNCTION_ENTITY_CLASS = 'Function';
export const CLOUD_FUNCTION_ENTITY_TYPE = 'google_cloud_function';

export const STEP_CLOUD_FUNCTIONS = 'fetch-cloud-functions';
export const STEP_CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS =
'build-cloud-function-service-account-relationships';
export const STEP_CLOUD_FUNCTIONS_SOURCE_REPO_RELATIONSHIPS =
'build-cloud-function-source-repo-relationships';

export const FunctionStepsSpec = {
FETCH_CLOUD_FUNCTIONS: {
id: 'fetch-cloud-functions',
name: 'Cloud Functions',
},
CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS: {
id: 'build-cloud-function-service-account-relationships',
name: 'Cloud Function Service Account Relationships',
},
CLOUD_FUNCTIONS_SOURCE_REPO_RELATIONSHIP: {
id: 'build-cloud-function-source-repo-relationships',
name: 'Build Cloud Function -> Source Repository Relationships',
},
};

export const FunctionEntitiesSpec = {
CLOUD_FUNCTION: {
resourceName: 'Cloud Function',
_type: 'google_cloud_function',
_class: ['Function'],
},
};

export const RELATIONSHIP_TYPE_CLOUD_FUNCTION_USES_IAM_SERVICE_ACCOUNT =
'google_cloud_function_uses_iam_service_account';
export const FunctionsRelationshipsSpec = {
GOOGLE_CLOUD_FUNCTION_USES_IAM_SERVICE_ACCOUNT: {
_class: RelationshipClass.USES,
_type: 'google_cloud_function_uses_iam_service_account',
sourceType: 'google_cloud_function',
targetType: IAM_SERVICE_ACCOUNT_ENTITY_TYPE,
},
GOOGLE_CLOUD_FUNCTION_USES_SOURCE_REPOSITORY: {
_type: 'google_cloud_function_uses_source_repository',
_class: RelationshipClass.USES,
sourceType: 'google_cloud_function',
targetType: 'google_cloud_source_repository',
},
};
1 change: 1 addition & 0 deletions src/steps/functions/converters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export function createCloudFunctionEntity(
status: cloudFunction.status,
active: cloudFunction.status === 'ACTIVE',
serviceAccountEmail: cloudFunction.serviceAccountEmail,
sourceRepoUrl: cloudFunction.sourceRepository?.url,
},
},
});
Expand Down
102 changes: 75 additions & 27 deletions src/steps/functions/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import {
createDirectRelationship,
Entity,
IntegrationStep,
RelationshipClass,
} from '@jupiterone/integration-sdk-core';
import { CloudFunctionsClient } from './client';
import { IntegrationConfig, IntegrationStepContext } from '../../types';
import { createCloudFunctionEntity } from './converters';
import { STEP_IAM_SERVICE_ACCOUNTS } from '../iam';
import {
CLOUD_FUNCTION_ENTITY_TYPE,
STEP_CLOUD_FUNCTIONS,
CLOUD_FUNCTION_ENTITY_CLASS,
RELATIONSHIP_TYPE_CLOUD_FUNCTION_USES_IAM_SERVICE_ACCOUNT,
STEP_CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS,
FunctionEntitiesSpec,
FunctionsRelationshipsSpec,
FunctionStepsSpec,
} from './constants';
import {
IAM_SERVICE_ACCOUNT_ENTITY_TYPE,
STEP_IAM_SERVICE_ACCOUNTS,
} from '../iam';
CloudSourceRepositoriesEntitiesSpec,
CloudSourceRepositoriesStepsSpec,
} from '../cloud-source-repositories/constants';

export * from './constants';

Expand All @@ -38,7 +38,7 @@ export async function buildCloudFunctionServiceAccountRelationships(

await jobState.iterateEntities(
{
_type: CLOUD_FUNCTION_ENTITY_TYPE,
_type: FunctionEntitiesSpec.CLOUD_FUNCTION._type,
},
async (cloudFunctionEntity) => {
const serviceAccountEmail = cloudFunctionEntity.serviceAccountEmail as
Expand Down Expand Up @@ -68,34 +68,82 @@ export async function buildCloudFunctionServiceAccountRelationships(
);
}

export async function buildCloudFunctionSourceRepoRelationships(
context: IntegrationStepContext,
): Promise<void> {
const { jobState } = context;
let sourceRepoEntities: Entity[] = [];

await jobState.iterateEntities(
{
_type: CloudSourceRepositoriesEntitiesSpec.REPOSITORY._type,
},
(sourceRepoEntity) => {
sourceRepoEntities = [...sourceRepoEntities, sourceRepoEntity];
},
);

await jobState.iterateEntities(
{
_type: FunctionEntitiesSpec.CLOUD_FUNCTION._type,
},
async (cloudFunctionEntity) => {
if (!cloudFunctionEntity?.sourceRepoUrl) {
return;
}

const sourceRepoUrl = cloudFunctionEntity?.sourceRepoUrl as string;

const sourceEntity = sourceRepoEntities.find((sourceRepoEntity) =>
sourceRepoUrl.includes(sourceRepoEntity._key),
);

if (sourceEntity) {
await jobState.addRelationship(
createDirectRelationship({
_class: RelationshipClass.USES,
from: cloudFunctionEntity,
to: sourceEntity,
}),
);
}
},
);
}

export const functionsSteps: IntegrationStep<IntegrationConfig>[] = [
{
id: STEP_CLOUD_FUNCTIONS,
name: 'Cloud Functions',
id: FunctionStepsSpec.FETCH_CLOUD_FUNCTIONS.id,
name: FunctionStepsSpec.FETCH_CLOUD_FUNCTIONS.name,
dependsOn: [],
entities: [
{
resourceName: 'Cloud Function',
_type: CLOUD_FUNCTION_ENTITY_TYPE,
_class: CLOUD_FUNCTION_ENTITY_CLASS,
},
],
entities: [FunctionEntitiesSpec.CLOUD_FUNCTION],
relationships: [],
executionHandler: fetchCloudFunctions,
},
{
id: STEP_CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS,
name: 'Cloud Function Service Account Relationships',
dependsOn: [STEP_CLOUD_FUNCTIONS, STEP_IAM_SERVICE_ACCOUNTS],
id: FunctionStepsSpec.CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS.id,
name: FunctionStepsSpec.CLOUD_FUNCTIONS_SERVICE_ACCOUNT_RELATIONSHIPS.name,
dependsOn: [
FunctionStepsSpec.FETCH_CLOUD_FUNCTIONS.id,
STEP_IAM_SERVICE_ACCOUNTS,
],
entities: [],
relationships: [
{
_class: RelationshipClass.USES,
_type: RELATIONSHIP_TYPE_CLOUD_FUNCTION_USES_IAM_SERVICE_ACCOUNT,
sourceType: CLOUD_FUNCTION_ENTITY_TYPE,
targetType: IAM_SERVICE_ACCOUNT_ENTITY_TYPE,
},
FunctionsRelationshipsSpec.GOOGLE_CLOUD_FUNCTION_USES_IAM_SERVICE_ACCOUNT,
],
executionHandler: buildCloudFunctionServiceAccountRelationships,
},
{
id: FunctionStepsSpec.CLOUD_FUNCTIONS_SOURCE_REPO_RELATIONSHIP.id,
name: FunctionStepsSpec.CLOUD_FUNCTIONS_SOURCE_REPO_RELATIONSHIP.name,
dependsOn: [
FunctionStepsSpec.FETCH_CLOUD_FUNCTIONS.id,
CloudSourceRepositoriesStepsSpec.FETCH_REPOSITORIES.id,
],
entities: [],
relationships: [
FunctionsRelationshipsSpec.GOOGLE_CLOUD_FUNCTION_USES_SOURCE_REPOSITORY,
],
executionHandler: buildCloudFunctionSourceRepoRelationships,
},
];

0 comments on commit b5d4a54

Please sign in to comment.