@causa/workspace-google 0.3.1 → 0.5.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/README.md +14 -0
- package/dist/backfilling/bigquery.d.ts +53 -0
- package/dist/backfilling/bigquery.js +99 -0
- package/dist/backfilling/index.d.ts +2 -0
- package/dist/backfilling/index.js +2 -0
- package/dist/backfilling/pubsub.d.ts +34 -0
- package/dist/backfilling/pubsub.js +63 -0
- package/dist/configurations/google.d.ts +81 -0
- package/dist/functions/emulator/index.d.ts +10 -0
- package/dist/functions/emulator/index.js +10 -0
- package/dist/functions/{emulator-start-firebase-storage.js → emulator/start-firebase-storage.js} +4 -4
- package/dist/functions/{emulator-start-firestore.js → emulator/start-firestore.js} +3 -3
- package/dist/functions/{emulator-start-identity-platform.js → emulator/start-identity-platform.js} +3 -3
- package/dist/functions/{emulator-start-pubsub.js → emulator/start-pubsub.js} +3 -3
- package/dist/functions/{emulator-start-spanner.js → emulator/start-spanner.js} +5 -5
- package/dist/functions/{emulator-stop-firebase-storage.js → emulator/stop-firebase-storage.js} +1 -1
- package/dist/functions/{emulator-stop-firestore.js → emulator/stop-firestore.js} +1 -1
- package/dist/functions/{emulator-stop-identity-platform.js → emulator/stop-identity-platform.js} +1 -1
- package/dist/functions/{emulator-stop-pubsub.js → emulator/stop-pubsub.js} +1 -1
- package/dist/functions/{emulator-stop-spanner.js → emulator/stop-spanner.js} +1 -1
- package/dist/functions/event-topic/broker-create-topic-pubsub.d.ts +11 -0
- package/dist/functions/event-topic/broker-create-topic-pubsub.js +27 -0
- package/dist/functions/event-topic/broker-create-trigger-cloud-run.d.ts +11 -0
- package/dist/functions/event-topic/broker-create-trigger-cloud-run.js +38 -0
- package/dist/functions/event-topic/broker-delete-topic-pubsub.d.ts +10 -0
- package/dist/functions/event-topic/broker-delete-topic-pubsub.js +26 -0
- package/dist/functions/event-topic/broker-delete-trigger-resource-cloud-run-invoker-role.d.ts +11 -0
- package/dist/functions/event-topic/broker-delete-trigger-resource-cloud-run-invoker-role.js +29 -0
- package/dist/functions/event-topic/broker-delete-trigger-resource-pubsub-subscription.d.ts +10 -0
- package/dist/functions/event-topic/broker-delete-trigger-resource-pubsub-subscription.js +31 -0
- package/dist/functions/event-topic/broker-delete-trigger-resource-service-account.d.ts +11 -0
- package/dist/functions/event-topic/broker-delete-trigger-resource-service-account.js +28 -0
- package/dist/functions/event-topic/broker-get-topic-id-pubsub.d.ts +10 -0
- package/dist/functions/event-topic/broker-get-topic-id-pubsub.js +16 -0
- package/dist/functions/event-topic/broker-publish-events-google.d.ts +17 -0
- package/dist/functions/event-topic/broker-publish-events-google.js +45 -0
- package/dist/functions/event-topic/index.d.ts +8 -0
- package/dist/functions/event-topic/index.js +8 -0
- package/dist/functions/{google-app-check-generate-token.js → google-app-check/generate-token.js} +2 -2
- package/dist/functions/google-app-check/index.d.ts +1 -0
- package/dist/functions/google-app-check/index.js +1 -0
- package/dist/functions/google-firebase-storage/index.d.ts +1 -0
- package/dist/functions/google-firebase-storage/index.js +1 -0
- package/dist/functions/{google-firebase-storage-merge-rules.d.ts → google-firebase-storage/merge-rules.d.ts} +1 -1
- package/dist/functions/{google-firebase-storage-merge-rules.js → google-firebase-storage/merge-rules.js} +2 -2
- package/dist/functions/google-firestore/index.d.ts +1 -0
- package/dist/functions/google-firestore/index.js +1 -0
- package/dist/functions/{google-firestore-merge-rules.d.ts → google-firestore/merge-rules.d.ts} +1 -1
- package/dist/functions/{google-firestore-merge-rules.js → google-firestore/merge-rules.js} +2 -2
- package/dist/functions/{google-identity-platform-generate-custom-token.js → google-identity-platform/generate-custom-token.js} +1 -1
- package/dist/functions/{google-identity-platform-generate-token.js → google-identity-platform/generate-token.js} +3 -3
- package/dist/functions/google-identity-platform/index.d.ts +2 -0
- package/dist/functions/google-identity-platform/index.js +2 -0
- package/dist/functions/google-pubsub/index.d.ts +1 -0
- package/dist/functions/google-pubsub/index.js +1 -0
- package/dist/functions/google-pubsub/write-topics.d.ts +22 -0
- package/dist/functions/google-pubsub/write-topics.js +80 -0
- package/dist/functions/{google-services-enable.d.ts → google-services/enable.d.ts} +1 -1
- package/dist/functions/{google-services-enable.js → google-services/enable.js} +1 -1
- package/dist/functions/google-services/index.d.ts +1 -0
- package/dist/functions/google-services/index.js +1 -0
- package/dist/functions/google-spanner/index.d.ts +2 -0
- package/dist/functions/google-spanner/index.js +2 -0
- package/dist/functions/google-spanner/write-databases.d.ts +22 -0
- package/dist/functions/google-spanner/write-databases.js +73 -0
- package/dist/functions/index.js +12 -22
- package/dist/functions/project/index.d.ts +3 -0
- package/dist/functions/project/index.js +3 -0
- package/dist/functions/{project-push-artefact-cloud-functions.js → project/push-artefact-cloud-functions.js} +1 -1
- package/dist/functions/{secret-fetch-secret-manager.js → secret/fetch-secret-manager.js} +1 -1
- package/dist/functions/secret/index.d.ts +1 -0
- package/dist/functions/secret/index.js +1 -0
- package/dist/services/bigquery.d.ts +16 -0
- package/dist/services/bigquery.js +19 -0
- package/dist/services/cloud-run-pubsub-trigger.d.ts +101 -0
- package/dist/services/cloud-run-pubsub-trigger.js +177 -0
- package/dist/services/cloud-run.d.ts +35 -0
- package/dist/services/cloud-run.js +72 -0
- package/dist/services/iam.d.ts +43 -0
- package/dist/services/iam.js +65 -0
- package/dist/services/index.d.ts +6 -0
- package/dist/services/index.js +6 -0
- package/dist/services/pubsub.d.ts +41 -0
- package/dist/services/pubsub.js +62 -0
- package/dist/services/resource-manager.d.ts +18 -0
- package/dist/services/resource-manager.js +35 -0
- package/package.json +26 -22
- /package/dist/functions/{emulator-start-firebase-storage.d.ts → emulator/start-firebase-storage.d.ts} +0 -0
- /package/dist/functions/{emulator-start-firestore.d.ts → emulator/start-firestore.d.ts} +0 -0
- /package/dist/functions/{emulator-start-identity-platform.d.ts → emulator/start-identity-platform.d.ts} +0 -0
- /package/dist/functions/{emulator-start-pubsub.d.ts → emulator/start-pubsub.d.ts} +0 -0
- /package/dist/functions/{emulator-start-spanner.d.ts → emulator/start-spanner.d.ts} +0 -0
- /package/dist/functions/{emulator-stop-firebase-storage.d.ts → emulator/stop-firebase-storage.d.ts} +0 -0
- /package/dist/functions/{emulator-stop-firestore.d.ts → emulator/stop-firestore.d.ts} +0 -0
- /package/dist/functions/{emulator-stop-identity-platform.d.ts → emulator/stop-identity-platform.d.ts} +0 -0
- /package/dist/functions/{emulator-stop-pubsub.d.ts → emulator/stop-pubsub.d.ts} +0 -0
- /package/dist/functions/{emulator-stop-spanner.d.ts → emulator/stop-spanner.d.ts} +0 -0
- /package/dist/functions/{google-app-check-generate-token.d.ts → google-app-check/generate-token.d.ts} +0 -0
- /package/dist/functions/{google-identity-platform-generate-custom-token.d.ts → google-identity-platform/generate-custom-token.d.ts} +0 -0
- /package/dist/functions/{google-identity-platform-generate-token.d.ts → google-identity-platform/generate-token.d.ts} +0 -0
- /package/dist/functions/{google-spanner-list-databases.d.ts → google-spanner/list-databases.d.ts} +0 -0
- /package/dist/functions/{google-spanner-list-databases.js → google-spanner/list-databases.js} +0 -0
- /package/dist/functions/{project-get-artefact-destination-cloud-functions.d.ts → project/get-artefact-destination-cloud-functions.d.ts} +0 -0
- /package/dist/functions/{project-get-artefact-destination-cloud-functions.js → project/get-artefact-destination-cloud-functions.js} +0 -0
- /package/dist/functions/{project-get-artefact-destination-cloud-run.d.ts → project/get-artefact-destination-cloud-run.d.ts} +0 -0
- /package/dist/functions/{project-get-artefact-destination-cloud-run.js → project/get-artefact-destination-cloud-run.js} +0 -0
- /package/dist/functions/{project-push-artefact-cloud-functions.d.ts → project/push-artefact-cloud-functions.d.ts} +0 -0
- /package/dist/functions/{secret-fetch-secret-manager.d.ts → secret/fetch-secret-manager.d.ts} +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { WorkspaceFunction, } from '@causa/workspace';
|
|
11
|
+
import { CAUSA_FOLDER } from '@causa/workspace/initialization';
|
|
12
|
+
import { AllowMissing } from '@causa/workspace/validation';
|
|
13
|
+
import { IsBoolean } from 'class-validator';
|
|
14
|
+
import { mkdir, rm, writeFile } from 'fs/promises';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
import { GoogleSpannerListDatabases } from './list-databases.js';
|
|
17
|
+
/**
|
|
18
|
+
* The default directory where Spanner database configurations are written, relative to the workspace root.
|
|
19
|
+
*/
|
|
20
|
+
const DEFAULT_DATABASE_CONFIGURATIONS_DIRECTORY = join(CAUSA_FOLDER, 'spanner-databases');
|
|
21
|
+
/**
|
|
22
|
+
* A function that uses {@link GoogleSpannerListDatabases} to find all the Spanner databases in the workspace, and
|
|
23
|
+
* writes their configurations to a directory.
|
|
24
|
+
* The `google.spanner.databaseConfigurationsDirectory` configuration can be used to specify the output location of the
|
|
25
|
+
* database configurations.
|
|
26
|
+
* This function returns a partial configuration, such that it can be used as a processor.
|
|
27
|
+
*/
|
|
28
|
+
export class GoogleSpannerWriteDatabases extends WorkspaceFunction {
|
|
29
|
+
tearDown;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the path to the directory where Spanner databases configurations should be written.
|
|
32
|
+
* It is either fetched from the workspace configuration, or the default value is used.
|
|
33
|
+
*
|
|
34
|
+
* @param context The {@link WorkspaceContext}.
|
|
35
|
+
* @returns The path to the directory where database configurations should be written.
|
|
36
|
+
*/
|
|
37
|
+
getConfigurationsDirectory(context) {
|
|
38
|
+
return (context
|
|
39
|
+
.asConfiguration()
|
|
40
|
+
.get('google.spanner.databaseConfigurationsDirectory') ??
|
|
41
|
+
DEFAULT_DATABASE_CONFIGURATIONS_DIRECTORY);
|
|
42
|
+
}
|
|
43
|
+
async _call(context) {
|
|
44
|
+
const databaseConfigurationsDirectory = this.getConfigurationsDirectory(context);
|
|
45
|
+
const absoluteDir = join(context.rootPath, databaseConfigurationsDirectory);
|
|
46
|
+
await rm(absoluteDir, { recursive: true, force: true });
|
|
47
|
+
if (this.tearDown) {
|
|
48
|
+
context.logger.debug(`️🗃️ Tore down Spanner database configurations directory '${absoluteDir}'.`);
|
|
49
|
+
return { configuration: {} };
|
|
50
|
+
}
|
|
51
|
+
context.logger.info('🗃️ Listing and writing Spanner database configurations.');
|
|
52
|
+
const databases = await context.call(GoogleSpannerListDatabases, {});
|
|
53
|
+
await mkdir(absoluteDir, { recursive: true });
|
|
54
|
+
context.logger.debug(`🗃️ Writing configurations for Spanner databases: ${databases
|
|
55
|
+
.map((d) => `'${d.id}'`)
|
|
56
|
+
.join(', ')}.`);
|
|
57
|
+
await Promise.all(databases.map((database) => writeFile(join(absoluteDir, `${database.id}.json`), JSON.stringify(database))));
|
|
58
|
+
context.logger.debug(`🗃️ Wrote Spanner database configurations in '${absoluteDir}'.`);
|
|
59
|
+
return {
|
|
60
|
+
configuration: {
|
|
61
|
+
google: { spanner: { databaseConfigurationsDirectory } },
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
_supports() {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
__decorate([
|
|
70
|
+
IsBoolean(),
|
|
71
|
+
AllowMissing(),
|
|
72
|
+
__metadata("design:type", Boolean)
|
|
73
|
+
], GoogleSpannerWriteDatabases.prototype, "tearDown", void 0);
|
package/dist/functions/index.js
CHANGED
|
@@ -1,24 +1,14 @@
|
|
|
1
|
-
import { EmulatorStartForFirebaseStorage } from './emulator
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { GoogleFirebaseStorageMergeRules } from './google-firebase-storage-merge-rules.js';
|
|
13
|
-
import { GoogleFirestoreMergeRules } from './google-firestore-merge-rules.js';
|
|
14
|
-
import { GoogleIdentityPlatformGenerateCustomToken } from './google-identity-platform-generate-custom-token.js';
|
|
15
|
-
import { GoogleIdentityPlatformGenerateToken } from './google-identity-platform-generate-token.js';
|
|
16
|
-
import { GoogleServicesEnable } from './google-services-enable.js';
|
|
17
|
-
import { GoogleSpannerListDatabases } from './google-spanner-list-databases.js';
|
|
18
|
-
import { ProjectGetArtefactDestinationForCloudFunctions } from './project-get-artefact-destination-cloud-functions.js';
|
|
19
|
-
import { ProjectGetArtefactDestinationForCloudRun } from './project-get-artefact-destination-cloud-run.js';
|
|
20
|
-
import { ProjectPushArtefactForCloudFunctions } from './project-push-artefact-cloud-functions.js';
|
|
21
|
-
import { SecretFetchForGoogleSecretManager } from './secret-fetch-secret-manager.js';
|
|
1
|
+
import { EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, } from './emulator/index.js';
|
|
2
|
+
import { EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, } from './event-topic/index.js';
|
|
3
|
+
import { GoogleAppCheckGenerateToken } from './google-app-check/index.js';
|
|
4
|
+
import { GoogleFirebaseStorageMergeRules } from './google-firebase-storage/index.js';
|
|
5
|
+
import { GoogleFirestoreMergeRules } from './google-firestore/index.js';
|
|
6
|
+
import { GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, } from './google-identity-platform/index.js';
|
|
7
|
+
import { GooglePubSubWriteTopics } from './google-pubsub/index.js';
|
|
8
|
+
import { GoogleServicesEnable } from './google-services/index.js';
|
|
9
|
+
import { GoogleSpannerListDatabases, GoogleSpannerWriteDatabases, } from './google-spanner/index.js';
|
|
10
|
+
import { ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, } from './project/index.js';
|
|
11
|
+
import { SecretFetchForGoogleSecretManager } from './secret/index.js';
|
|
22
12
|
export function registerFunctions(context) {
|
|
23
|
-
context.registerFunctionImplementations(EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, GoogleAppCheckGenerateToken, GoogleFirebaseStorageMergeRules, GoogleFirestoreMergeRules, GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, GoogleServicesEnable, GoogleSpannerListDatabases, ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, SecretFetchForGoogleSecretManager);
|
|
13
|
+
context.registerFunctionImplementations(EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, GoogleAppCheckGenerateToken, GoogleFirebaseStorageMergeRules, GoogleFirestoreMergeRules, GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, GooglePubSubWriteTopics, GoogleServicesEnable, GoogleSpannerListDatabases, GoogleSpannerWriteDatabases, ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, SecretFetchForGoogleSecretManager);
|
|
24
14
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { ProjectGetArtefactDestinationForCloudFunctions } from './get-artefact-destination-cloud-functions.js';
|
|
2
|
+
export { ProjectGetArtefactDestinationForCloudRun } from './get-artefact-destination-cloud-run.js';
|
|
3
|
+
export { ProjectPushArtefactForCloudFunctions } from './push-artefact-cloud-functions.js';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { ProjectGetArtefactDestinationForCloudFunctions } from './get-artefact-destination-cloud-functions.js';
|
|
2
|
+
export { ProjectGetArtefactDestinationForCloudRun } from './get-artefact-destination-cloud-run.js';
|
|
3
|
+
export { ProjectPushArtefactForCloudFunctions } from './push-artefact-cloud-functions.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ArtefactAlreadyExistsError, ProjectPushArtefact, } from '@causa/workspace-core';
|
|
2
2
|
import { rm } from 'fs/promises';
|
|
3
|
-
import { CloudStorageService } from '
|
|
3
|
+
import { CloudStorageService } from '../../services/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Implements the {@link ProjectPushArtefact} function for Cloud Functions projects.
|
|
6
6
|
* This copies the local archive of the Cloud Functions project to the Google Cloud Storage URI set in
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InvalidSecretDefinitionError, SecretFetch, } from '@causa/workspace';
|
|
2
|
-
import { GoogleSecretManagerService } from '
|
|
2
|
+
import { GoogleSecretManagerService } from '../../services/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* The regular expression used to match the (Secret Manager) secret ID/name, and possibly its version and project.
|
|
5
5
|
* [projects/<projectId>/secrets]<secretName>[/versions/<version>]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SecretFetchForGoogleSecretManager } from './fetch-secret-manager.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SecretFetchForGoogleSecretManager } from './fetch-secret-manager.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { WorkspaceContext } from '@causa/workspace';
|
|
2
|
+
import { BigQuery } from '@google-cloud/bigquery';
|
|
3
|
+
/**
|
|
4
|
+
* A service that provides access to BigQuery.
|
|
5
|
+
*/
|
|
6
|
+
export declare class BigQueryService {
|
|
7
|
+
/**
|
|
8
|
+
* The BigQuery client configured with the GCP project ID.
|
|
9
|
+
*/
|
|
10
|
+
readonly bigQuery: BigQuery;
|
|
11
|
+
/**
|
|
12
|
+
* The GCP project ID.
|
|
13
|
+
*/
|
|
14
|
+
readonly projectId: string;
|
|
15
|
+
constructor(context: WorkspaceContext);
|
|
16
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BigQuery } from '@google-cloud/bigquery';
|
|
2
|
+
/**
|
|
3
|
+
* A service that provides access to BigQuery.
|
|
4
|
+
*/
|
|
5
|
+
export class BigQueryService {
|
|
6
|
+
/**
|
|
7
|
+
* The BigQuery client configured with the GCP project ID.
|
|
8
|
+
*/
|
|
9
|
+
bigQuery;
|
|
10
|
+
/**
|
|
11
|
+
* The GCP project ID.
|
|
12
|
+
*/
|
|
13
|
+
projectId;
|
|
14
|
+
constructor(context) {
|
|
15
|
+
const googleConf = context.asConfiguration();
|
|
16
|
+
this.projectId = googleConf.getOrThrow('google.project');
|
|
17
|
+
this.bigQuery = new BigQuery({ projectId: this.projectId });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { WorkspaceContext } from '@causa/workspace';
|
|
2
|
+
/**
|
|
3
|
+
* A service that manages (creates) Pub/Sub triggers pointing to Cloud Run services.
|
|
4
|
+
* This is used for backfilling operations. The reason it is a service is to persist temporary service accounts and IAM
|
|
5
|
+
* grants, such that they can be reused within the same backfilling operation.
|
|
6
|
+
*/
|
|
7
|
+
export declare class CloudRunPubSubTriggerService {
|
|
8
|
+
/**
|
|
9
|
+
* The service managing Cloud Run resources.
|
|
10
|
+
*/
|
|
11
|
+
private readonly cloudRunService;
|
|
12
|
+
/**
|
|
13
|
+
* The service managing Pub/Sub resources.
|
|
14
|
+
*/
|
|
15
|
+
private readonly pubSubService;
|
|
16
|
+
/**
|
|
17
|
+
* The service managing IAM permissions.
|
|
18
|
+
*/
|
|
19
|
+
private readonly iamService;
|
|
20
|
+
/**
|
|
21
|
+
* A set of IAM bindings that have already been created.
|
|
22
|
+
* This is used to avoid creating the same bindings multiple times within a single backfill operation.
|
|
23
|
+
* An IAM binding allows the service account used by Pub/Sub for a single backfill operation to invoke a Cloud Run
|
|
24
|
+
* service. The format of strings in this set is the one used to reference bindings during deletion as well, i.e.
|
|
25
|
+
* `projects/<projectId>/locations/<location>/services/<name>/invokerBindings/<serviceAccountEmail>`.
|
|
26
|
+
*/
|
|
27
|
+
private readonly invokerBindingIds;
|
|
28
|
+
/**
|
|
29
|
+
* A map of backfill IDs to promises resolving to the service account email used by Pub/Sub to invoke Cloud Run
|
|
30
|
+
* services for the backfill.
|
|
31
|
+
*/
|
|
32
|
+
private readonly backfillInvokerServiceAccounts;
|
|
33
|
+
/**
|
|
34
|
+
* The logger used by this service.
|
|
35
|
+
*/
|
|
36
|
+
private readonly logger;
|
|
37
|
+
/**
|
|
38
|
+
* The ID of the GCP project in which resources should be created.
|
|
39
|
+
*/
|
|
40
|
+
readonly projectId: string;
|
|
41
|
+
constructor(context: WorkspaceContext);
|
|
42
|
+
/**
|
|
43
|
+
* Creates a service account that should be used by Pub/Sub to invoke Cloud Run services for a given backfill
|
|
44
|
+
* operation.
|
|
45
|
+
*
|
|
46
|
+
* @param backfillId The ID of the backfilling operation.
|
|
47
|
+
* @returns The service account email that should be used by Pub/Sub when pushing messages to Cloud Run services,
|
|
48
|
+
* along with the corresponding resource ID that should be deleted as part of the backfill cleaning.
|
|
49
|
+
*/
|
|
50
|
+
private createBackfillInvokerServiceAccount;
|
|
51
|
+
/**
|
|
52
|
+
* Gets or creates a service account that should be used by Pub/Sub to invoke Cloud Run services for a given backfill
|
|
53
|
+
* operation.
|
|
54
|
+
*
|
|
55
|
+
* @param backfillId The ID of the backfilling operation.
|
|
56
|
+
* @returns The service account email that should be used by Pub/Sub when pushing messages to Cloud Run services.
|
|
57
|
+
* If `resourceId` is not `null`, it should be added to the list of resources to delete as part of the backfill
|
|
58
|
+
* cleaning.
|
|
59
|
+
*/
|
|
60
|
+
private getBackfillInvokerServiceAccount;
|
|
61
|
+
/**
|
|
62
|
+
* Grants the invoker role to a service account for a given Cloud Run service.
|
|
63
|
+
* This is used to allow Pub/Sub to invoke the Cloud Run service.
|
|
64
|
+
* If a resource ID string is returned, it should be added to the list of resources to delete as part of the backfill
|
|
65
|
+
* cleaning.
|
|
66
|
+
*
|
|
67
|
+
* @param serviceId The ID of the Cloud Run service.
|
|
68
|
+
* @param pubSubServiceAccount The service account email for which the invoker role should be granted.
|
|
69
|
+
* @returns The resource ID of the IAM binding that was created, or `null` if the binding already existed.
|
|
70
|
+
*/
|
|
71
|
+
private grantPubSubInvokerRole;
|
|
72
|
+
/**
|
|
73
|
+
* Creates a Pub/Sub subscription that will push messages to a Cloud Run service.
|
|
74
|
+
*
|
|
75
|
+
* @param backfillId The ID of the backfilling operation.
|
|
76
|
+
* @param topicId The ID of the Pub/Sub topic to subscribe to.
|
|
77
|
+
* @param serviceId The ID of the Cloud Run service to invoke.
|
|
78
|
+
* @param path The HTTP endpoint of the Cloud Run service to invoke.
|
|
79
|
+
* @param serviceAccountEmail The service account email that should be used by Pub/Sub when pushing messages to the
|
|
80
|
+
* Cloud Run service.
|
|
81
|
+
* @returns The ID of the Pub/Sub subscription that was created. It should be added to the list of resources to delete
|
|
82
|
+
* as part of the backfill cleaning.
|
|
83
|
+
*/
|
|
84
|
+
private createSubscription;
|
|
85
|
+
/**
|
|
86
|
+
* Creates a Pub/Sub trigger (push subscription) pointing to a Cloud Run service.
|
|
87
|
+
* This requires several resources, such as:
|
|
88
|
+
* - A service account that should be used by Pub/Sub to invoke Cloud Run services for the backfill.
|
|
89
|
+
* - An IAM binding allowing the service account to invoke the Cloud Run service.
|
|
90
|
+
* - A Pub/Sub subscription that will push messages to the Cloud Run service.
|
|
91
|
+
* The IDs of these resources are returned, and should be deleted as part of the backfill cleaning.
|
|
92
|
+
*
|
|
93
|
+
* @param backfillId The ID of the backfilling operation.
|
|
94
|
+
* @param topicId The ID of the Pub/Sub topic to subscribe to.
|
|
95
|
+
* @param serviceId The ID of the Cloud Run service to invoke.
|
|
96
|
+
* @param path The HTTP endpoint of the Cloud Run service to invoke.
|
|
97
|
+
* @returns The IDs of the resources that were created. They should be added to the list of resources to delete as
|
|
98
|
+
* part of the backfill cleaning.
|
|
99
|
+
*/
|
|
100
|
+
create(backfillId: string, topicId: string, serviceId: string, path: string): Promise<string[]>;
|
|
101
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { EventTopicTriggerCreationError } from '@causa/workspace-core';
|
|
2
|
+
import { Subscription } from '@google-cloud/pubsub';
|
|
3
|
+
import { randomBytes } from 'crypto';
|
|
4
|
+
import { CloudRunService } from './cloud-run.js';
|
|
5
|
+
import { IamService } from './iam.js';
|
|
6
|
+
import { PubSubService } from './pubsub.js';
|
|
7
|
+
/**
|
|
8
|
+
* A service that manages (creates) Pub/Sub triggers pointing to Cloud Run services.
|
|
9
|
+
* This is used for backfilling operations. The reason it is a service is to persist temporary service accounts and IAM
|
|
10
|
+
* grants, such that they can be reused within the same backfilling operation.
|
|
11
|
+
*/
|
|
12
|
+
export class CloudRunPubSubTriggerService {
|
|
13
|
+
/**
|
|
14
|
+
* The service managing Cloud Run resources.
|
|
15
|
+
*/
|
|
16
|
+
cloudRunService;
|
|
17
|
+
/**
|
|
18
|
+
* The service managing Pub/Sub resources.
|
|
19
|
+
*/
|
|
20
|
+
pubSubService;
|
|
21
|
+
/**
|
|
22
|
+
* The service managing IAM permissions.
|
|
23
|
+
*/
|
|
24
|
+
iamService;
|
|
25
|
+
/**
|
|
26
|
+
* A set of IAM bindings that have already been created.
|
|
27
|
+
* This is used to avoid creating the same bindings multiple times within a single backfill operation.
|
|
28
|
+
* An IAM binding allows the service account used by Pub/Sub for a single backfill operation to invoke a Cloud Run
|
|
29
|
+
* service. The format of strings in this set is the one used to reference bindings during deletion as well, i.e.
|
|
30
|
+
* `projects/<projectId>/locations/<location>/services/<name>/invokerBindings/<serviceAccountEmail>`.
|
|
31
|
+
*/
|
|
32
|
+
invokerBindingIds = new Set();
|
|
33
|
+
/**
|
|
34
|
+
* A map of backfill IDs to promises resolving to the service account email used by Pub/Sub to invoke Cloud Run
|
|
35
|
+
* services for the backfill.
|
|
36
|
+
*/
|
|
37
|
+
backfillInvokerServiceAccounts = {};
|
|
38
|
+
/**
|
|
39
|
+
* The logger used by this service.
|
|
40
|
+
*/
|
|
41
|
+
logger;
|
|
42
|
+
/**
|
|
43
|
+
* The ID of the GCP project in which resources should be created.
|
|
44
|
+
*/
|
|
45
|
+
projectId;
|
|
46
|
+
constructor(context) {
|
|
47
|
+
this.cloudRunService = context.service(CloudRunService);
|
|
48
|
+
this.pubSubService = context.service(PubSubService);
|
|
49
|
+
this.iamService = context.service(IamService);
|
|
50
|
+
this.logger = context.logger;
|
|
51
|
+
this.projectId = context
|
|
52
|
+
.asConfiguration()
|
|
53
|
+
.getOrThrow('google.project');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Creates a service account that should be used by Pub/Sub to invoke Cloud Run services for a given backfill
|
|
57
|
+
* operation.
|
|
58
|
+
*
|
|
59
|
+
* @param backfillId The ID of the backfilling operation.
|
|
60
|
+
* @returns The service account email that should be used by Pub/Sub when pushing messages to Cloud Run services,
|
|
61
|
+
* along with the corresponding resource ID that should be deleted as part of the backfill cleaning.
|
|
62
|
+
*/
|
|
63
|
+
async createBackfillInvokerServiceAccount(backfillId) {
|
|
64
|
+
const serviceAccountId = `backfill-pubsub-${backfillId}`;
|
|
65
|
+
const bindings = await this.pubSubService.getPushServiceAccountBindings();
|
|
66
|
+
this.logger.info(`🛂 Creating Pub/Sub backfilling service account '${serviceAccountId}'.`);
|
|
67
|
+
const serviceAccount = await this.iamService.createServiceAccount(this.projectId, serviceAccountId, { bindings });
|
|
68
|
+
return {
|
|
69
|
+
serviceAccountEmail: serviceAccount.email ?? '',
|
|
70
|
+
resourceId: serviceAccount.name ?? null,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Gets or creates a service account that should be used by Pub/Sub to invoke Cloud Run services for a given backfill
|
|
75
|
+
* operation.
|
|
76
|
+
*
|
|
77
|
+
* @param backfillId The ID of the backfilling operation.
|
|
78
|
+
* @returns The service account email that should be used by Pub/Sub when pushing messages to Cloud Run services.
|
|
79
|
+
* If `resourceId` is not `null`, it should be added to the list of resources to delete as part of the backfill
|
|
80
|
+
* cleaning.
|
|
81
|
+
*/
|
|
82
|
+
async getBackfillInvokerServiceAccount(backfillId) {
|
|
83
|
+
const existingServiceAccountPromise = this.backfillInvokerServiceAccounts[backfillId];
|
|
84
|
+
if (existingServiceAccountPromise) {
|
|
85
|
+
return {
|
|
86
|
+
serviceAccountEmail: await existingServiceAccountPromise,
|
|
87
|
+
resourceId: null,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const creationPromise = this.createBackfillInvokerServiceAccount(backfillId);
|
|
91
|
+
this.backfillInvokerServiceAccounts[backfillId] = creationPromise.then((result) => result.serviceAccountEmail);
|
|
92
|
+
return await creationPromise;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Grants the invoker role to a service account for a given Cloud Run service.
|
|
96
|
+
* This is used to allow Pub/Sub to invoke the Cloud Run service.
|
|
97
|
+
* If a resource ID string is returned, it should be added to the list of resources to delete as part of the backfill
|
|
98
|
+
* cleaning.
|
|
99
|
+
*
|
|
100
|
+
* @param serviceId The ID of the Cloud Run service.
|
|
101
|
+
* @param pubSubServiceAccount The service account email for which the invoker role should be granted.
|
|
102
|
+
* @returns The resource ID of the IAM binding that was created, or `null` if the binding already existed.
|
|
103
|
+
*/
|
|
104
|
+
async grantPubSubInvokerRole(serviceId, pubSubServiceAccount) {
|
|
105
|
+
const invokerBindingId = `${serviceId}/invokerBindings/${pubSubServiceAccount}`;
|
|
106
|
+
if (this.invokerBindingIds.has(invokerBindingId)) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
this.invokerBindingIds.add(invokerBindingId);
|
|
110
|
+
this.logger.info(`🛂 Granting invoker IAM role to backfilling service account '${pubSubServiceAccount}' for Cloud Run service '${serviceId}'.`);
|
|
111
|
+
await this.cloudRunService.addInvokerBinding(serviceId, pubSubServiceAccount);
|
|
112
|
+
return invokerBindingId;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Creates a Pub/Sub subscription that will push messages to a Cloud Run service.
|
|
116
|
+
*
|
|
117
|
+
* @param backfillId The ID of the backfilling operation.
|
|
118
|
+
* @param topicId The ID of the Pub/Sub topic to subscribe to.
|
|
119
|
+
* @param serviceId The ID of the Cloud Run service to invoke.
|
|
120
|
+
* @param path The HTTP endpoint of the Cloud Run service to invoke.
|
|
121
|
+
* @param serviceAccountEmail The service account email that should be used by Pub/Sub when pushing messages to the
|
|
122
|
+
* Cloud Run service.
|
|
123
|
+
* @returns The ID of the Pub/Sub subscription that was created. It should be added to the list of resources to delete
|
|
124
|
+
* as part of the backfill cleaning.
|
|
125
|
+
*/
|
|
126
|
+
async createSubscription(backfillId, topicId, serviceId, path, serviceAccountEmail) {
|
|
127
|
+
const serviceUri = await this.cloudRunService.getServiceUri(serviceId);
|
|
128
|
+
const pushEndpoint = `${serviceUri}${path}`;
|
|
129
|
+
const subscriptionId = Subscription.formatName_(this.projectId, `backfill-${backfillId}-${randomBytes(3).toString('hex')}`);
|
|
130
|
+
this.logger.info(`📫 Creating Pub/Sub subscription '${subscriptionId}' for Cloud Run service '${serviceId}'.`);
|
|
131
|
+
await this.pubSubService.pubSub.createSubscription(topicId, subscriptionId, {
|
|
132
|
+
pushConfig: { pushEndpoint, oidcToken: { serviceAccountEmail } },
|
|
133
|
+
expirationPolicy: {},
|
|
134
|
+
ackDeadlineSeconds: 60 * 10,
|
|
135
|
+
retryPolicy: {
|
|
136
|
+
minimumBackoff: { seconds: 1, nanos: 0 },
|
|
137
|
+
maximumBackoff: { seconds: 60, nanos: 0 },
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
return subscriptionId;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Creates a Pub/Sub trigger (push subscription) pointing to a Cloud Run service.
|
|
144
|
+
* This requires several resources, such as:
|
|
145
|
+
* - A service account that should be used by Pub/Sub to invoke Cloud Run services for the backfill.
|
|
146
|
+
* - An IAM binding allowing the service account to invoke the Cloud Run service.
|
|
147
|
+
* - A Pub/Sub subscription that will push messages to the Cloud Run service.
|
|
148
|
+
* The IDs of these resources are returned, and should be deleted as part of the backfill cleaning.
|
|
149
|
+
*
|
|
150
|
+
* @param backfillId The ID of the backfilling operation.
|
|
151
|
+
* @param topicId The ID of the Pub/Sub topic to subscribe to.
|
|
152
|
+
* @param serviceId The ID of the Cloud Run service to invoke.
|
|
153
|
+
* @param path The HTTP endpoint of the Cloud Run service to invoke.
|
|
154
|
+
* @returns The IDs of the resources that were created. They should be added to the list of resources to delete as
|
|
155
|
+
* part of the backfill cleaning.
|
|
156
|
+
*/
|
|
157
|
+
async create(backfillId, topicId, serviceId, path) {
|
|
158
|
+
const resourceIds = [];
|
|
159
|
+
try {
|
|
160
|
+
const pubSubInvokerServiceAccount = await this.getBackfillInvokerServiceAccount(backfillId);
|
|
161
|
+
if (pubSubInvokerServiceAccount.resourceId) {
|
|
162
|
+
resourceIds.push(pubSubInvokerServiceAccount.resourceId);
|
|
163
|
+
}
|
|
164
|
+
const { serviceAccountEmail } = pubSubInvokerServiceAccount;
|
|
165
|
+
const iamResourceId = await this.grantPubSubInvokerRole(serviceId, serviceAccountEmail);
|
|
166
|
+
if (iamResourceId) {
|
|
167
|
+
resourceIds.push(iamResourceId);
|
|
168
|
+
}
|
|
169
|
+
const subscriptionId = await this.createSubscription(backfillId, topicId, serviceId, path, serviceAccountEmail);
|
|
170
|
+
resourceIds.push(subscriptionId);
|
|
171
|
+
return resourceIds;
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
throw new EventTopicTriggerCreationError(error, resourceIds);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ServicesClient } from '@google-cloud/run';
|
|
2
|
+
/**
|
|
3
|
+
* A service to manage Cloud Run services.
|
|
4
|
+
*/
|
|
5
|
+
export declare class CloudRunService {
|
|
6
|
+
/**
|
|
7
|
+
* The Cloud Run client.
|
|
8
|
+
*/
|
|
9
|
+
readonly servicesClient: ServicesClient;
|
|
10
|
+
constructor();
|
|
11
|
+
/**
|
|
12
|
+
* Retrieves the URI at which a Cloud Run service is available and can be requested.
|
|
13
|
+
*
|
|
14
|
+
* @param serviceId The ID of the Cloud Run service.
|
|
15
|
+
* This should be in the format `projects/<projectId>/locations/<location>/services/<name>`.
|
|
16
|
+
* @returns The URI at which the service is available.
|
|
17
|
+
*/
|
|
18
|
+
getServiceUri(serviceId: string): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Allows a service account to call a Cloud Run service by editing the IAM policy bindings.
|
|
21
|
+
*
|
|
22
|
+
* @param serviceId The ID of the Cloud Run service.
|
|
23
|
+
* This should be in the format `projects/<projectId>/locations/<location>/services/<name>`.
|
|
24
|
+
* @param serviceAccountEmail The email of the service account that should be allowed to call the service.
|
|
25
|
+
*/
|
|
26
|
+
addInvokerBinding(serviceId: string, serviceAccountEmail: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Removes a service account from the list of allowed invokers of a Cloud Run service.
|
|
29
|
+
*
|
|
30
|
+
* @param serviceId The ID of the Cloud Run service.
|
|
31
|
+
* This should be in the format `projects/<projectId>/locations/<location>/services/<name>`.
|
|
32
|
+
* @param serviceAccountEmail The email of the service account that should be removed from the allowed invokers.
|
|
33
|
+
*/
|
|
34
|
+
removeInvokerBinding(serviceId: string, serviceAccountEmail: string): Promise<void>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ServicesClient } from '@google-cloud/run';
|
|
2
|
+
/**
|
|
3
|
+
* The role used to allow a service account to call a Cloud Run service.
|
|
4
|
+
*/
|
|
5
|
+
const INVOKER_ROLE = 'roles/run.invoker';
|
|
6
|
+
/**
|
|
7
|
+
* A service to manage Cloud Run services.
|
|
8
|
+
*/
|
|
9
|
+
export class CloudRunService {
|
|
10
|
+
/**
|
|
11
|
+
* The Cloud Run client.
|
|
12
|
+
*/
|
|
13
|
+
servicesClient;
|
|
14
|
+
constructor() {
|
|
15
|
+
this.servicesClient = new ServicesClient();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Retrieves the URI at which a Cloud Run service is available and can be requested.
|
|
19
|
+
*
|
|
20
|
+
* @param serviceId The ID of the Cloud Run service.
|
|
21
|
+
* This should be in the format `projects/<projectId>/locations/<location>/services/<name>`.
|
|
22
|
+
* @returns The URI at which the service is available.
|
|
23
|
+
*/
|
|
24
|
+
async getServiceUri(serviceId) {
|
|
25
|
+
const [service] = await this.servicesClient.getService({ name: serviceId });
|
|
26
|
+
return service.uri ?? '';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Allows a service account to call a Cloud Run service by editing the IAM policy bindings.
|
|
30
|
+
*
|
|
31
|
+
* @param serviceId The ID of the Cloud Run service.
|
|
32
|
+
* This should be in the format `projects/<projectId>/locations/<location>/services/<name>`.
|
|
33
|
+
* @param serviceAccountEmail The email of the service account that should be allowed to call the service.
|
|
34
|
+
*/
|
|
35
|
+
async addInvokerBinding(serviceId, serviceAccountEmail) {
|
|
36
|
+
const [policy] = await this.servicesClient.getIamPolicy({
|
|
37
|
+
resource: serviceId,
|
|
38
|
+
});
|
|
39
|
+
const members = [`serviceAccount:${serviceAccountEmail}`];
|
|
40
|
+
const binding = { role: INVOKER_ROLE, members };
|
|
41
|
+
policy.bindings = [...(policy.bindings ?? []), binding];
|
|
42
|
+
await this.servicesClient.setIamPolicy({
|
|
43
|
+
resource: serviceId,
|
|
44
|
+
policy,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Removes a service account from the list of allowed invokers of a Cloud Run service.
|
|
49
|
+
*
|
|
50
|
+
* @param serviceId The ID of the Cloud Run service.
|
|
51
|
+
* This should be in the format `projects/<projectId>/locations/<location>/services/<name>`.
|
|
52
|
+
* @param serviceAccountEmail The email of the service account that should be removed from the allowed invokers.
|
|
53
|
+
*/
|
|
54
|
+
async removeInvokerBinding(serviceId, serviceAccountEmail) {
|
|
55
|
+
const [policy] = await this.servicesClient.getIamPolicy({
|
|
56
|
+
resource: serviceId,
|
|
57
|
+
});
|
|
58
|
+
policy.bindings = (policy.bindings ?? []).flatMap((binding) => {
|
|
59
|
+
if (binding.role !== INVOKER_ROLE || binding.condition) {
|
|
60
|
+
return binding;
|
|
61
|
+
}
|
|
62
|
+
// `includes` ensures that deleted service accounts (in the form of `deleted:serviceAccount:...`) are also removed
|
|
63
|
+
// from the list.
|
|
64
|
+
binding.members = binding.members?.filter((member) => !member.includes(`serviceAccount:${serviceAccountEmail}`));
|
|
65
|
+
return binding.members?.length ? binding : [];
|
|
66
|
+
});
|
|
67
|
+
await this.servicesClient.setIamPolicy({
|
|
68
|
+
resource: serviceId,
|
|
69
|
+
policy,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { WorkspaceContext } from '@causa/workspace';
|
|
2
|
+
import { iam_v1 } from 'googleapis';
|
|
3
|
+
/**
|
|
4
|
+
* A service for interacting with the IAM API.
|
|
5
|
+
*/
|
|
6
|
+
export declare class IamService {
|
|
7
|
+
/**
|
|
8
|
+
* The underlying {@link GoogleApisService} used to get the IAM client.
|
|
9
|
+
*/
|
|
10
|
+
private readonly googleApisService;
|
|
11
|
+
/**
|
|
12
|
+
* A promise that resolves to the singleton IAM client.
|
|
13
|
+
*/
|
|
14
|
+
private iam;
|
|
15
|
+
constructor(context: WorkspaceContext);
|
|
16
|
+
/**
|
|
17
|
+
* Gets or creates the singleton IAM client.
|
|
18
|
+
*
|
|
19
|
+
* @returns The singleton IAM client.
|
|
20
|
+
*/
|
|
21
|
+
private getIam;
|
|
22
|
+
/**
|
|
23
|
+
* Creates a service account, optionally setting the IAM policy bindings for it.
|
|
24
|
+
*
|
|
25
|
+
* @param projectId The ID of the project in which to create the service account.
|
|
26
|
+
* @param accountId The ID of the service account to create.
|
|
27
|
+
* @param options Additional options when creating the account.
|
|
28
|
+
* @returns The created service account.
|
|
29
|
+
*/
|
|
30
|
+
createServiceAccount(projectId: string, accountId: string, options?: {
|
|
31
|
+
/**
|
|
32
|
+
* The IAM policy bindings to set for the service account after its creation.
|
|
33
|
+
*/
|
|
34
|
+
bindings?: iam_v1.Schema$Binding[];
|
|
35
|
+
}): Promise<iam_v1.Schema$ServiceAccount>;
|
|
36
|
+
/**
|
|
37
|
+
* Deletes a service account.
|
|
38
|
+
*
|
|
39
|
+
* @param name The full resource name of the service account to delete, in the format
|
|
40
|
+
* `projects/<projectId>/serviceAccounts/<accountId>`.
|
|
41
|
+
*/
|
|
42
|
+
deleteServiceAccount(name: string): Promise<void>;
|
|
43
|
+
}
|