@causa/workspace-google 0.18.0-beta.3 → 0.18.0-beta.4
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 +4 -0
- package/dist/configurations/generated.d.ts +62 -0
- package/dist/configurations/generated.js +112 -0
- package/dist/configurations/schemas/google.yaml +53 -0
- package/dist/functions/event-topic/broker-create-trigger-cloud-run.call.js +12 -4
- package/dist/functions/event-topic/broker-delete-trigger-resource-cloud-run-service.call.d.ts +2 -0
- package/dist/functions/event-topic/broker-delete-trigger-resource-cloud-run-service.call.js +5 -0
- package/dist/functions/event-topic/broker-delete-trigger-resource-cloud-run-service.d.ts +10 -0
- package/dist/functions/event-topic/broker-delete-trigger-resource-cloud-run-service.js +19 -0
- package/dist/functions/event-topic/broker-publish-events-google.call.js +26 -12
- package/dist/functions/event-topic/index.d.ts +1 -0
- package/dist/functions/event-topic/index.js +1 -0
- package/dist/functions/index.js +2 -2
- package/dist/services/cloud-run-pubsub-trigger.d.ts +22 -1
- package/dist/services/cloud-run-pubsub-trigger.js +44 -5
- package/dist/services/cloud-run.d.ts +56 -1
- package/dist/services/cloud-run.js +71 -1
- package/dist/services/cloud-run.utils.d.ts +10 -0
- package/dist/services/cloud-run.utils.js +12 -0
- package/dist/services/google-apis.d.ts +7 -3
- package/dist/services/google-apis.js +1 -2
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +1 -1
- package/package.json +11 -12
package/README.md
CHANGED
|
@@ -62,6 +62,10 @@ Backfilling is supported when `google.pubSub` is set as the `events.broker`. Tem
|
|
|
62
62
|
|
|
63
63
|
When no source is specified, the default is to fetch events to backfill from the BigQuery dataset configured in `google.pubSub.bigQueryStorage`. A custom BigQuery table can also be set as source using the `bq://<projectId>.<datasetId>.<tableId>` format. It should have the `data` and `attributes` columns.
|
|
64
64
|
|
|
65
|
+
The Pub/Sub publish options used when backfilling can be tuned through `google.pubSub.backfillPublishOptions`, which exposes the `maxOutstandingBytes`, `maxOutstandingMessages`, `maxBytes`, `maxMessages`, and `maxMilliseconds` fields.
|
|
66
|
+
|
|
67
|
+
By default, project-scoped triggers send backfill events to the live Cloud Run service. Setting `google.cloudRun.eventBackfillServiceCloneConfig` instead deploys a temporary copy of the service for each trigger, isolating the backfill load (in particular its scaling, and therefore the load on backing resources such as databases) from production. The copy reuses the live service's revision template, restricts its ingress to internal traffic, and applies the `minInstanceCount`, `maxInstanceCount`, and `requestConcurrency` overrides from the configuration (unset fields are inherited from the live service). The copy is deleted as part of the backfill cleanup.
|
|
68
|
+
|
|
65
69
|
### Querying
|
|
66
70
|
|
|
67
71
|
This module implements the `DatabaseQueryRecords`, `ServiceContainerQueryLogs`, and `EventTopicQueryEvents` workspace functions, which expose read-only access to data stored in or emitted by deployed services:
|
|
@@ -37,6 +37,29 @@ export declare class GoogleCloudFunctions {
|
|
|
37
37
|
readonly artefactStorage?: GoogleCloudFunctionsArtefactStorage;
|
|
38
38
|
[property: string]: any;
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* When set, project-scoped backfill triggers do not send events to the live Cloud Run service. Instead, a
|
|
42
|
+
* temporary copy of the service is deployed for each trigger, isolating the backfill load (in particular its
|
|
43
|
+
* scaling) from production. The copy is deleted once the backfill is cleaned up. Ingress is always
|
|
44
|
+
* restricted to internal traffic for the copy. The properties of this object override the scaling settings
|
|
45
|
+
* of the copied service. Unset properties are inherited from the live service.
|
|
46
|
+
*/
|
|
47
|
+
export declare class GoogleCloudRunEventBackfillServiceCloneConfig {
|
|
48
|
+
constructor(init: GoogleCloudRunEventBackfillServiceCloneConfig);
|
|
49
|
+
/**
|
|
50
|
+
* The maximum number of instances for the temporary service copy.
|
|
51
|
+
*/
|
|
52
|
+
readonly maxInstanceCount?: number;
|
|
53
|
+
/**
|
|
54
|
+
* The minimum number of instances for the temporary service copy.
|
|
55
|
+
*/
|
|
56
|
+
readonly minInstanceCount?: number;
|
|
57
|
+
/**
|
|
58
|
+
* The maximum number of concurrent requests per instance for the temporary service copy.
|
|
59
|
+
*/
|
|
60
|
+
readonly requestConcurrency?: number;
|
|
61
|
+
[property: string]: any;
|
|
62
|
+
}
|
|
40
63
|
/**
|
|
41
64
|
* The type of allowed ingress that can reach the container.
|
|
42
65
|
* See https://cloud.google.com/run/docs/securing/ingress#settings for more details.
|
|
@@ -67,6 +90,14 @@ export declare class GoogleCloudRun {
|
|
|
67
90
|
* The Docker repository where Cloud Run containers should be uploaded.
|
|
68
91
|
*/
|
|
69
92
|
readonly dockerRepository?: string;
|
|
93
|
+
/**
|
|
94
|
+
* When set, project-scoped backfill triggers do not send events to the live Cloud Run service. Instead, a
|
|
95
|
+
* temporary copy of the service is deployed for each trigger, isolating the backfill load (in particular its
|
|
96
|
+
* scaling) from production. The copy is deleted once the backfill is cleaned up. Ingress is always
|
|
97
|
+
* restricted to internal traffic for the copy. The properties of this object override the scaling settings
|
|
98
|
+
* of the copied service. Unset properties are inherited from the live service.
|
|
99
|
+
*/
|
|
100
|
+
readonly eventBackfillServiceCloneConfig?: GoogleCloudRunEventBackfillServiceCloneConfig;
|
|
70
101
|
/**
|
|
71
102
|
* For `serviceContainer` projects deployed on Cloud Run, the name of the Cloud Run service that receives
|
|
72
103
|
* events during a backfill targeting a project-scoped trigger. Defaults to the project's name
|
|
@@ -284,6 +315,33 @@ export declare class GoogleLoadBalancing {
|
|
|
284
315
|
readonly customRequestHeaders?: string[];
|
|
285
316
|
[property: string]: any;
|
|
286
317
|
}
|
|
318
|
+
/**
|
|
319
|
+
* Options when publishing events in batches to Pub/Sub during a backfill.
|
|
320
|
+
*/
|
|
321
|
+
export declare class GooglePubSubBackfillPublishOptions {
|
|
322
|
+
constructor(init: GooglePubSubBackfillPublishOptions);
|
|
323
|
+
/**
|
|
324
|
+
* The maximum number of bytes to buffer before publishing a batch.
|
|
325
|
+
*/
|
|
326
|
+
readonly maxBytes?: number;
|
|
327
|
+
/**
|
|
328
|
+
* The maximum number of messages to buffer before publishing a batch.
|
|
329
|
+
*/
|
|
330
|
+
readonly maxMessages?: number;
|
|
331
|
+
/**
|
|
332
|
+
* The maximum duration to wait, in milliseconds, before publishing a batch.
|
|
333
|
+
*/
|
|
334
|
+
readonly maxMilliseconds?: number;
|
|
335
|
+
/**
|
|
336
|
+
* The maximum number of bytes allowed in outstanding (in-flight) publish requests before applying flow control.
|
|
337
|
+
*/
|
|
338
|
+
readonly maxOutstandingBytes?: number;
|
|
339
|
+
/**
|
|
340
|
+
* The maximum number of outstanding (in-flight) messages allowed before applying flow control.
|
|
341
|
+
*/
|
|
342
|
+
readonly maxOutstandingMessages?: number;
|
|
343
|
+
[property: string]: any;
|
|
344
|
+
}
|
|
287
345
|
/**
|
|
288
346
|
* Configuration for the storage of Pub/Sub events in BigQuery.
|
|
289
347
|
*/
|
|
@@ -321,6 +379,10 @@ export declare class GooglePubSubEmulator {
|
|
|
321
379
|
*/
|
|
322
380
|
export declare class GooglePubSub {
|
|
323
381
|
constructor(init: GooglePubSub);
|
|
382
|
+
/**
|
|
383
|
+
* Options when publishing events in batches to Pub/Sub during a backfill.
|
|
384
|
+
*/
|
|
385
|
+
readonly backfillPublishOptions?: GooglePubSubBackfillPublishOptions;
|
|
324
386
|
/**
|
|
325
387
|
* Configuration for the storage of Pub/Sub events in BigQuery.
|
|
326
388
|
*/
|
|
@@ -76,6 +76,45 @@ __decorate([
|
|
|
76
76
|
AllowMissing(),
|
|
77
77
|
__metadata("design:type", GoogleCloudFunctionsArtefactStorage)
|
|
78
78
|
], GoogleCloudFunctions.prototype, "artefactStorage", void 0);
|
|
79
|
+
/**
|
|
80
|
+
* When set, project-scoped backfill triggers do not send events to the live Cloud Run service. Instead, a
|
|
81
|
+
* temporary copy of the service is deployed for each trigger, isolating the backfill load (in particular its
|
|
82
|
+
* scaling) from production. The copy is deleted once the backfill is cleaned up. Ingress is always
|
|
83
|
+
* restricted to internal traffic for the copy. The properties of this object override the scaling settings
|
|
84
|
+
* of the copied service. Unset properties are inherited from the live service.
|
|
85
|
+
*/
|
|
86
|
+
export class GoogleCloudRunEventBackfillServiceCloneConfig {
|
|
87
|
+
constructor(init) {
|
|
88
|
+
Object.assign(this, init);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The maximum number of instances for the temporary service copy.
|
|
92
|
+
*/
|
|
93
|
+
maxInstanceCount;
|
|
94
|
+
/**
|
|
95
|
+
* The minimum number of instances for the temporary service copy.
|
|
96
|
+
*/
|
|
97
|
+
minInstanceCount;
|
|
98
|
+
/**
|
|
99
|
+
* The maximum number of concurrent requests per instance for the temporary service copy.
|
|
100
|
+
*/
|
|
101
|
+
requestConcurrency;
|
|
102
|
+
}
|
|
103
|
+
__decorate([
|
|
104
|
+
AllowMissing(),
|
|
105
|
+
IsNumber(),
|
|
106
|
+
__metadata("design:type", Number)
|
|
107
|
+
], GoogleCloudRunEventBackfillServiceCloneConfig.prototype, "maxInstanceCount", void 0);
|
|
108
|
+
__decorate([
|
|
109
|
+
AllowMissing(),
|
|
110
|
+
IsNumber(),
|
|
111
|
+
__metadata("design:type", Number)
|
|
112
|
+
], GoogleCloudRunEventBackfillServiceCloneConfig.prototype, "minInstanceCount", void 0);
|
|
113
|
+
__decorate([
|
|
114
|
+
AllowMissing(),
|
|
115
|
+
IsNumber(),
|
|
116
|
+
__metadata("design:type", Number)
|
|
117
|
+
], GoogleCloudRunEventBackfillServiceCloneConfig.prototype, "requestConcurrency", void 0);
|
|
79
118
|
/**
|
|
80
119
|
* The type of allowed ingress that can reach the container.
|
|
81
120
|
* See https://cloud.google.com/run/docs/securing/ingress#settings for more details.
|
|
@@ -110,6 +149,14 @@ export class GoogleCloudRun {
|
|
|
110
149
|
* The Docker repository where Cloud Run containers should be uploaded.
|
|
111
150
|
*/
|
|
112
151
|
dockerRepository;
|
|
152
|
+
/**
|
|
153
|
+
* When set, project-scoped backfill triggers do not send events to the live Cloud Run service. Instead, a
|
|
154
|
+
* temporary copy of the service is deployed for each trigger, isolating the backfill load (in particular its
|
|
155
|
+
* scaling) from production. The copy is deleted once the backfill is cleaned up. Ingress is always
|
|
156
|
+
* restricted to internal traffic for the copy. The properties of this object override the scaling settings
|
|
157
|
+
* of the copied service. Unset properties are inherited from the live service.
|
|
158
|
+
*/
|
|
159
|
+
eventBackfillServiceCloneConfig;
|
|
113
160
|
/**
|
|
114
161
|
* For `serviceContainer` projects deployed on Cloud Run, the name of the Cloud Run service that receives
|
|
115
162
|
* events during a backfill targeting a project-scoped trigger. Defaults to the project's name
|
|
@@ -162,6 +209,10 @@ __decorate([
|
|
|
162
209
|
IsString(),
|
|
163
210
|
__metadata("design:type", String)
|
|
164
211
|
], GoogleCloudRun.prototype, "dockerRepository", void 0);
|
|
212
|
+
__decorate([
|
|
213
|
+
AllowMissing(),
|
|
214
|
+
__metadata("design:type", GoogleCloudRunEventBackfillServiceCloneConfig)
|
|
215
|
+
], GoogleCloudRun.prototype, "eventBackfillServiceCloneConfig", void 0);
|
|
165
216
|
__decorate([
|
|
166
217
|
AllowMissing(),
|
|
167
218
|
IsString(),
|
|
@@ -493,6 +544,59 @@ __decorate([
|
|
|
493
544
|
IsString({ each: true }),
|
|
494
545
|
__metadata("design:type", Array)
|
|
495
546
|
], GoogleLoadBalancing.prototype, "customRequestHeaders", void 0);
|
|
547
|
+
/**
|
|
548
|
+
* Options when publishing events in batches to Pub/Sub during a backfill.
|
|
549
|
+
*/
|
|
550
|
+
export class GooglePubSubBackfillPublishOptions {
|
|
551
|
+
constructor(init) {
|
|
552
|
+
Object.assign(this, init);
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* The maximum number of bytes to buffer before publishing a batch.
|
|
556
|
+
*/
|
|
557
|
+
maxBytes;
|
|
558
|
+
/**
|
|
559
|
+
* The maximum number of messages to buffer before publishing a batch.
|
|
560
|
+
*/
|
|
561
|
+
maxMessages;
|
|
562
|
+
/**
|
|
563
|
+
* The maximum duration to wait, in milliseconds, before publishing a batch.
|
|
564
|
+
*/
|
|
565
|
+
maxMilliseconds;
|
|
566
|
+
/**
|
|
567
|
+
* The maximum number of bytes allowed in outstanding (in-flight) publish requests before applying flow control.
|
|
568
|
+
*/
|
|
569
|
+
maxOutstandingBytes;
|
|
570
|
+
/**
|
|
571
|
+
* The maximum number of outstanding (in-flight) messages allowed before applying flow control.
|
|
572
|
+
*/
|
|
573
|
+
maxOutstandingMessages;
|
|
574
|
+
}
|
|
575
|
+
__decorate([
|
|
576
|
+
AllowMissing(),
|
|
577
|
+
IsNumber(),
|
|
578
|
+
__metadata("design:type", Number)
|
|
579
|
+
], GooglePubSubBackfillPublishOptions.prototype, "maxBytes", void 0);
|
|
580
|
+
__decorate([
|
|
581
|
+
AllowMissing(),
|
|
582
|
+
IsNumber(),
|
|
583
|
+
__metadata("design:type", Number)
|
|
584
|
+
], GooglePubSubBackfillPublishOptions.prototype, "maxMessages", void 0);
|
|
585
|
+
__decorate([
|
|
586
|
+
AllowMissing(),
|
|
587
|
+
IsNumber(),
|
|
588
|
+
__metadata("design:type", Number)
|
|
589
|
+
], GooglePubSubBackfillPublishOptions.prototype, "maxMilliseconds", void 0);
|
|
590
|
+
__decorate([
|
|
591
|
+
AllowMissing(),
|
|
592
|
+
IsNumber(),
|
|
593
|
+
__metadata("design:type", Number)
|
|
594
|
+
], GooglePubSubBackfillPublishOptions.prototype, "maxOutstandingBytes", void 0);
|
|
595
|
+
__decorate([
|
|
596
|
+
AllowMissing(),
|
|
597
|
+
IsNumber(),
|
|
598
|
+
__metadata("design:type", Number)
|
|
599
|
+
], GooglePubSubBackfillPublishOptions.prototype, "maxOutstandingMessages", void 0);
|
|
496
600
|
/**
|
|
497
601
|
* Configuration for the storage of Pub/Sub events in BigQuery.
|
|
498
602
|
*/
|
|
@@ -554,6 +658,10 @@ export class GooglePubSub {
|
|
|
554
658
|
constructor(init) {
|
|
555
659
|
Object.assign(this, init);
|
|
556
660
|
}
|
|
661
|
+
/**
|
|
662
|
+
* Options when publishing events in batches to Pub/Sub during a backfill.
|
|
663
|
+
*/
|
|
664
|
+
backfillPublishOptions;
|
|
557
665
|
/**
|
|
558
666
|
* Configuration for the storage of Pub/Sub events in BigQuery.
|
|
559
667
|
*/
|
|
@@ -575,6 +683,10 @@ export class GooglePubSub {
|
|
|
575
683
|
*/
|
|
576
684
|
topicConfigurationsDirectory;
|
|
577
685
|
}
|
|
686
|
+
__decorate([
|
|
687
|
+
AllowMissing(),
|
|
688
|
+
__metadata("design:type", GooglePubSubBackfillPublishOptions)
|
|
689
|
+
], GooglePubSub.prototype, "backfillPublishOptions", void 0);
|
|
578
690
|
__decorate([
|
|
579
691
|
AllowMissing(),
|
|
580
692
|
__metadata("design:type", GooglePubSubBigQueryStorage)
|
|
@@ -242,6 +242,30 @@ properties:
|
|
|
242
242
|
|
|
243
243
|
See https://cloud.google.com/bigquery/docs/locations for more
|
|
244
244
|
details.
|
|
245
|
+
backfillPublishOptions:
|
|
246
|
+
title: GooglePubSubBackfillPublishOptions
|
|
247
|
+
type: object
|
|
248
|
+
description: Options when publishing events in batches to Pub/Sub during a
|
|
249
|
+
backfill.
|
|
250
|
+
properties:
|
|
251
|
+
maxOutstandingBytes:
|
|
252
|
+
type: number
|
|
253
|
+
description: The maximum number of bytes allowed in outstanding (in-flight)
|
|
254
|
+
publish requests before applying flow control.
|
|
255
|
+
maxOutstandingMessages:
|
|
256
|
+
type: number
|
|
257
|
+
description: The maximum number of outstanding (in-flight) messages allowed
|
|
258
|
+
before applying flow control.
|
|
259
|
+
maxBytes:
|
|
260
|
+
type: number
|
|
261
|
+
description: The maximum number of bytes to buffer before publishing a batch.
|
|
262
|
+
maxMessages:
|
|
263
|
+
type: number
|
|
264
|
+
description: The maximum number of messages to buffer before publishing a batch.
|
|
265
|
+
maxMilliseconds:
|
|
266
|
+
type: number
|
|
267
|
+
description: The maximum duration to wait, in milliseconds, before publishing a
|
|
268
|
+
batch.
|
|
245
269
|
spanner:
|
|
246
270
|
title: GoogleSpanner
|
|
247
271
|
type: object
|
|
@@ -389,6 +413,35 @@ properties:
|
|
|
389
413
|
Defaults to the project's name
|
|
390
414
|
|
|
391
415
|
(`project.name`) when unset.
|
|
416
|
+
eventBackfillServiceCloneConfig:
|
|
417
|
+
title: GoogleCloudRunEventBackfillServiceCloneConfig
|
|
418
|
+
type: object
|
|
419
|
+
description: >-
|
|
420
|
+
When set, project-scoped backfill triggers do not send events to
|
|
421
|
+
the live Cloud Run service. Instead, a
|
|
422
|
+
|
|
423
|
+
temporary copy of the service is deployed for each trigger,
|
|
424
|
+
isolating the backfill load (in particular its
|
|
425
|
+
|
|
426
|
+
scaling) from production. The copy is deleted once the backfill is
|
|
427
|
+
cleaned up. Ingress is always
|
|
428
|
+
|
|
429
|
+
restricted to internal traffic for the copy. The properties of
|
|
430
|
+
this object override the scaling settings
|
|
431
|
+
|
|
432
|
+
of the copied service. Unset properties are inherited from the
|
|
433
|
+
live service.
|
|
434
|
+
properties:
|
|
435
|
+
minInstanceCount:
|
|
436
|
+
type: number
|
|
437
|
+
description: The minimum number of instances for the temporary service copy.
|
|
438
|
+
maxInstanceCount:
|
|
439
|
+
type: number
|
|
440
|
+
description: The maximum number of instances for the temporary service copy.
|
|
441
|
+
requestConcurrency:
|
|
442
|
+
type: number
|
|
443
|
+
description: The maximum number of concurrent requests per instance for the
|
|
444
|
+
temporary service copy.
|
|
392
445
|
secretEnvironmentVariables:
|
|
393
446
|
type: object
|
|
394
447
|
description: >-
|
|
@@ -45,10 +45,18 @@ function resolveFromObject(context, trigger) {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
export default async function call() {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
// Cloning is only supported for project-scoped triggers, where the service is defined by the project's configuration.
|
|
49
|
+
// Raw URI triggers keep targeting the live service.
|
|
50
|
+
const isProjectScoped = typeof this.trigger !== 'string';
|
|
51
|
+
const { serviceId, path } = isProjectScoped
|
|
52
|
+
? resolveFromObject(this._context, this.trigger)
|
|
53
|
+
: resolveFromString(this._context, this.trigger);
|
|
54
|
+
const clone = isProjectScoped
|
|
55
|
+
? this._context
|
|
56
|
+
.asConfiguration()
|
|
57
|
+
.get('google.cloudRun.eventBackfillServiceCloneConfig')
|
|
58
|
+
: undefined;
|
|
51
59
|
return await this._context
|
|
52
60
|
.service(CloudRunPubSubTriggerService)
|
|
53
|
-
.create(this.backfillId, this.topicId, serviceId, path);
|
|
61
|
+
.create(this.backfillId, this.topicId, serviceId, path, { clone });
|
|
54
62
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EventTopicBrokerDeleteTriggerResource } from '@causa/workspace-core';
|
|
2
|
+
/**
|
|
3
|
+
* Implements {@link EventTopicBrokerDeleteTriggerResource} for Cloud Run services.
|
|
4
|
+
* When `google.cloudRun.eventBackfillServiceCloneConfig` is set, a temporary copy of the Cloud Run service is created
|
|
5
|
+
* for each project-scoped trigger, isolating the backfill load from production. This function deletes that copy.
|
|
6
|
+
*/
|
|
7
|
+
export declare class EventTopicBrokerDeleteTriggerResourceForCloudRunService extends EventTopicBrokerDeleteTriggerResource {
|
|
8
|
+
_call(): Promise<void>;
|
|
9
|
+
_supports(): boolean;
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { callDeferred } from '@causa/workspace';
|
|
2
|
+
import { EventTopicBrokerDeleteTriggerResource, } from '@causa/workspace-core';
|
|
3
|
+
import { CLOUD_RUN_SERVICE_ID_REGEX } from '../../services/cloud-run.utils.js';
|
|
4
|
+
/**
|
|
5
|
+
* Implements {@link EventTopicBrokerDeleteTriggerResource} for Cloud Run services.
|
|
6
|
+
* When `google.cloudRun.eventBackfillServiceCloneConfig` is set, a temporary copy of the Cloud Run service is created
|
|
7
|
+
* for each project-scoped trigger, isolating the backfill load from production. This function deletes that copy.
|
|
8
|
+
*/
|
|
9
|
+
export class EventTopicBrokerDeleteTriggerResourceForCloudRunService extends EventTopicBrokerDeleteTriggerResource {
|
|
10
|
+
async _call() {
|
|
11
|
+
return await callDeferred(this, import.meta.url);
|
|
12
|
+
}
|
|
13
|
+
_supports() {
|
|
14
|
+
return (CLOUD_RUN_SERVICE_ID_REGEX.test(this.id) &&
|
|
15
|
+
this._context
|
|
16
|
+
.asConfiguration()
|
|
17
|
+
.get('events.broker') === 'google.pubSub');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -5,23 +5,37 @@ import { PubSubService } from '../../services/index.js';
|
|
|
5
5
|
*/
|
|
6
6
|
const PUBLISH_PROGRESS_LOG_INTERVAL = 10000;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Default options when publishing events in batches to Pub/Sub.
|
|
9
|
+
* These can be overridden through the `google.pubSub.backfillPublishOptions` configuration.
|
|
9
10
|
*/
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
maxBytes: 10 * 1024 * 1024,
|
|
17
|
-
maxMessages: 1000,
|
|
18
|
-
maxMilliseconds: 1000,
|
|
19
|
-
},
|
|
11
|
+
const DEFAULT_PUBLISH_OPTIONS = {
|
|
12
|
+
maxOutstandingBytes: 10 * 1024 * 1024,
|
|
13
|
+
maxOutstandingMessages: 1000,
|
|
14
|
+
maxBytes: 10 * 1024 * 1024,
|
|
15
|
+
maxMessages: 1000,
|
|
16
|
+
maxMilliseconds: 1000,
|
|
20
17
|
};
|
|
21
18
|
export default async function call() {
|
|
19
|
+
const publishOptions = {
|
|
20
|
+
...DEFAULT_PUBLISH_OPTIONS,
|
|
21
|
+
...this._context
|
|
22
|
+
.asConfiguration()
|
|
23
|
+
.get('google.pubSub.backfillPublishOptions'),
|
|
24
|
+
};
|
|
25
|
+
const options = {
|
|
26
|
+
flowControlOptions: {
|
|
27
|
+
maxOutstandingBytes: publishOptions.maxOutstandingBytes,
|
|
28
|
+
maxOutstandingMessages: publishOptions.maxOutstandingMessages,
|
|
29
|
+
},
|
|
30
|
+
batching: {
|
|
31
|
+
maxBytes: publishOptions.maxBytes,
|
|
32
|
+
maxMessages: publishOptions.maxMessages,
|
|
33
|
+
maxMilliseconds: publishOptions.maxMilliseconds,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
22
36
|
const publisher = this._context
|
|
23
37
|
.service(PubSubService)
|
|
24
|
-
.pubSub.topic(this.topicId,
|
|
38
|
+
.pubSub.topic(this.topicId, options)
|
|
25
39
|
.flowControlled();
|
|
26
40
|
this._context.logger.info('📫 Publishing events.');
|
|
27
41
|
let numEvents = 0;
|
|
@@ -2,6 +2,7 @@ export { EventTopicBrokerCreateTopicForPubSub } from './broker-create-topic-pubs
|
|
|
2
2
|
export { EventTopicBrokerCreateTriggerForCloudRun } from './broker-create-trigger-cloud-run.js';
|
|
3
3
|
export { EventTopicBrokerDeleteTopicForPubSub } from './broker-delete-topic-pubsub.js';
|
|
4
4
|
export { EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole } from './broker-delete-trigger-resource-cloud-run-invoker-role.js';
|
|
5
|
+
export { EventTopicBrokerDeleteTriggerResourceForCloudRunService } from './broker-delete-trigger-resource-cloud-run-service.js';
|
|
5
6
|
export { EventTopicBrokerDeleteTriggerResourceForPubSubSubscription } from './broker-delete-trigger-resource-pubsub-subscription.js';
|
|
6
7
|
export { EventTopicBrokerDeleteTriggerResourceForServiceAccount } from './broker-delete-trigger-resource-service-account.js';
|
|
7
8
|
export { EventTopicBrokerGetTopicIdForPubSub } from './broker-get-topic-id-pubsub.js';
|
|
@@ -2,6 +2,7 @@ export { EventTopicBrokerCreateTopicForPubSub } from './broker-create-topic-pubs
|
|
|
2
2
|
export { EventTopicBrokerCreateTriggerForCloudRun } from './broker-create-trigger-cloud-run.js';
|
|
3
3
|
export { EventTopicBrokerDeleteTopicForPubSub } from './broker-delete-topic-pubsub.js';
|
|
4
4
|
export { EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole } from './broker-delete-trigger-resource-cloud-run-invoker-role.js';
|
|
5
|
+
export { EventTopicBrokerDeleteTriggerResourceForCloudRunService } from './broker-delete-trigger-resource-cloud-run-service.js';
|
|
5
6
|
export { EventTopicBrokerDeleteTriggerResourceForPubSubSubscription } from './broker-delete-trigger-resource-pubsub-subscription.js';
|
|
6
7
|
export { EventTopicBrokerDeleteTriggerResourceForServiceAccount } from './broker-delete-trigger-resource-service-account.js';
|
|
7
8
|
export { EventTopicBrokerGetTopicIdForPubSub } from './broker-get-topic-id-pubsub.js';
|
package/dist/functions/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CausaListConfigurationSchemasForGoogle } from './causa/index.js';
|
|
2
2
|
import { EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, } from './emulator/index.js';
|
|
3
|
-
import { EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, EventTopicBrokerWaitForProcessingForPubSub, EventTopicCreateBackfillSourceForBigQuery, EventTopicQueryEventsForBigQuery, } from './event-topic/index.js';
|
|
3
|
+
import { EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForCloudRunService, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, EventTopicBrokerWaitForProcessingForPubSub, EventTopicCreateBackfillSourceForBigQuery, EventTopicQueryEventsForBigQuery, } from './event-topic/index.js';
|
|
4
4
|
import { GoogleAppCheckGenerateToken } from './google-app-check/index.js';
|
|
5
5
|
import { GoogleFirebaseStorageMergeRules } from './google-firebase-storage/index.js';
|
|
6
6
|
import { DatabaseQueryRecordsForFirestore, GoogleFirestoreMergeRules, ModelGenerateTypeScriptDecoratorsForGoogleFirestore, ModelSchemaExtractDatabaseForGoogleFirestore, } from './google-firestore/index.js';
|
|
@@ -12,5 +12,5 @@ import { ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDesti
|
|
|
12
12
|
import { SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager, } from './secret/index.js';
|
|
13
13
|
import { ServiceContainerQueryLogsForCloudRun } from './service-container/index.js';
|
|
14
14
|
export function registerFunctions(context) {
|
|
15
|
-
context.registerFunctionImplementations(CausaListConfigurationSchemasForGoogle, DatabaseQueryRecordsForFirestore, DatabaseQueryRecordsForSpanner, EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, EventTopicBrokerWaitForProcessingForPubSub, EventTopicCreateBackfillSourceForBigQuery, EventTopicQueryEventsForBigQuery, GoogleAppCheckGenerateToken, GoogleFirebaseStorageMergeRules, GoogleFirestoreMergeRules, GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, GooglePubSubWriteTopics, GoogleServicesEnable, GoogleSpannerListDatabases, GoogleSpannerWriteDatabases, ModelGenerateTypeScriptDecoratorsForGoogleFirestore, ModelGenerateTypeScriptDecoratorsForGoogleSpanner, ModelSchemaExtractDatabaseForGoogleFirestore, ModelSchemaExtractDatabaseForGoogleSpanner, ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager, ServiceContainerQueryLogsForCloudRun);
|
|
15
|
+
context.registerFunctionImplementations(CausaListConfigurationSchemasForGoogle, DatabaseQueryRecordsForFirestore, DatabaseQueryRecordsForSpanner, EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForCloudRunService, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, EventTopicBrokerWaitForProcessingForPubSub, EventTopicCreateBackfillSourceForBigQuery, EventTopicQueryEventsForBigQuery, GoogleAppCheckGenerateToken, GoogleFirebaseStorageMergeRules, GoogleFirestoreMergeRules, GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, GooglePubSubWriteTopics, GoogleServicesEnable, GoogleSpannerListDatabases, GoogleSpannerWriteDatabases, ModelGenerateTypeScriptDecoratorsForGoogleFirestore, ModelGenerateTypeScriptDecoratorsForGoogleSpanner, ModelSchemaExtractDatabaseForGoogleFirestore, ModelSchemaExtractDatabaseForGoogleSpanner, ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager, ServiceContainerQueryLogsForCloudRun);
|
|
16
16
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WorkspaceContext } from '@causa/workspace';
|
|
2
|
+
import { type CloudRunServiceOverrides } from './cloud-run.js';
|
|
2
3
|
/**
|
|
3
4
|
* A service that manages (creates) Pub/Sub triggers pointing to Cloud Run services.
|
|
4
5
|
* This is used for backfilling operations. The reason it is a service is to persist temporary service accounts and IAM
|
|
@@ -82,6 +83,15 @@ export declare class CloudRunPubSubTriggerService {
|
|
|
82
83
|
* as part of the backfill cleaning.
|
|
83
84
|
*/
|
|
84
85
|
private createSubscription;
|
|
86
|
+
/**
|
|
87
|
+
* Creates a temporary copy of a Cloud Run service to receive backfill traffic in isolation.
|
|
88
|
+
*
|
|
89
|
+
* @param backfillId The ID of the backfilling operation.
|
|
90
|
+
* @param sourceService The ID of the Cloud Run service to copy.
|
|
91
|
+
* @param overrides The overrides to apply to the copy.
|
|
92
|
+
* @returns The ID of the created service copy.
|
|
93
|
+
*/
|
|
94
|
+
private createServiceCopy;
|
|
85
95
|
/**
|
|
86
96
|
* Creates a Pub/Sub trigger (push subscription) pointing to a Cloud Run service.
|
|
87
97
|
* This requires several resources, such as:
|
|
@@ -90,12 +100,23 @@ export declare class CloudRunPubSubTriggerService {
|
|
|
90
100
|
* - A Pub/Sub subscription that will push messages to the Cloud Run service.
|
|
91
101
|
* The IDs of these resources are returned, and should be deleted as part of the backfill cleaning.
|
|
92
102
|
*
|
|
103
|
+
* When `options.clone` is set, a temporary copy of the Cloud Run service is created and used as the trigger target
|
|
104
|
+
* instead of the live service. This isolates the backfill load (in particular its scaling) from production. The copy
|
|
105
|
+
* is added to the list of resources to clean up. The invoker IAM binding is not tracked separately because deleting
|
|
106
|
+
* the service removes it.
|
|
107
|
+
*
|
|
93
108
|
* @param backfillId The ID of the backfilling operation.
|
|
94
109
|
* @param topicId The ID of the Pub/Sub topic to subscribe to.
|
|
95
110
|
* @param serviceId The ID of the Cloud Run service to invoke.
|
|
96
111
|
* @param path The HTTP endpoint of the Cloud Run service to invoke.
|
|
112
|
+
* @param options Options for the trigger creation.
|
|
97
113
|
* @returns The IDs of the resources that were created. They should be added to the list of resources to delete as
|
|
98
114
|
* part of the backfill cleaning.
|
|
99
115
|
*/
|
|
100
|
-
create(backfillId: string, topicId: string, serviceId: string, path: string
|
|
116
|
+
create(backfillId: string, topicId: string, serviceId: string, path: string, options?: {
|
|
117
|
+
/**
|
|
118
|
+
* When set, a temporary copy of the service is created with these overrides and used as the trigger target.
|
|
119
|
+
*/
|
|
120
|
+
clone?: CloudRunServiceOverrides;
|
|
121
|
+
}): Promise<string[]>;
|
|
101
122
|
}
|
|
@@ -3,7 +3,7 @@ import { EventTopicTriggerCreationError } from '@causa/workspace-core';
|
|
|
3
3
|
import { Subscription } from '@google-cloud/pubsub';
|
|
4
4
|
import { randomBytes } from 'crypto';
|
|
5
5
|
import { grpc } from 'google-gax';
|
|
6
|
-
import { CloudRunService } from './cloud-run.js';
|
|
6
|
+
import { CloudRunService, IngressTraffic, shortServiceId, } from './cloud-run.js';
|
|
7
7
|
import { IamService } from './iam.js';
|
|
8
8
|
import { PubSubService } from './pubsub.js';
|
|
9
9
|
/**
|
|
@@ -143,6 +143,32 @@ export class CloudRunPubSubTriggerService {
|
|
|
143
143
|
});
|
|
144
144
|
return subscriptionId;
|
|
145
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Creates a temporary copy of a Cloud Run service to receive backfill traffic in isolation.
|
|
148
|
+
*
|
|
149
|
+
* @param backfillId The ID of the backfilling operation.
|
|
150
|
+
* @param sourceService The ID of the Cloud Run service to copy.
|
|
151
|
+
* @param overrides The overrides to apply to the copy.
|
|
152
|
+
* @returns The ID of the created service copy.
|
|
153
|
+
*/
|
|
154
|
+
async createServiceCopy(backfillId, sourceService, overrides) {
|
|
155
|
+
const sourceName = shortServiceId(sourceService);
|
|
156
|
+
const suffix = randomBytes(3).toString('hex');
|
|
157
|
+
const maxSourceNameLength = 63 - `backfill-${backfillId}--${suffix}`.length;
|
|
158
|
+
const truncatedSourceName = sourceName
|
|
159
|
+
.slice(0, maxSourceNameLength)
|
|
160
|
+
.replace(/-+$/, '');
|
|
161
|
+
const name = `backfill-${backfillId}-${truncatedSourceName}-${suffix}`;
|
|
162
|
+
this.logger.info(`🚀 Creating temporary Cloud Run service '${name}' as a copy of '${sourceService}' for the backfill.`);
|
|
163
|
+
const service = await this.cloudRunService.copy(sourceService, name, {
|
|
164
|
+
overrides: {
|
|
165
|
+
...overrides,
|
|
166
|
+
ingress: IngressTraffic.INGRESS_TRAFFIC_INTERNAL_ONLY,
|
|
167
|
+
labels: { 'causa-backfill-id': backfillId },
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
return service.name ?? '';
|
|
171
|
+
}
|
|
146
172
|
/**
|
|
147
173
|
* Creates a Pub/Sub trigger (push subscription) pointing to a Cloud Run service.
|
|
148
174
|
* This requires several resources, such as:
|
|
@@ -151,26 +177,39 @@ export class CloudRunPubSubTriggerService {
|
|
|
151
177
|
* - A Pub/Sub subscription that will push messages to the Cloud Run service.
|
|
152
178
|
* The IDs of these resources are returned, and should be deleted as part of the backfill cleaning.
|
|
153
179
|
*
|
|
180
|
+
* When `options.clone` is set, a temporary copy of the Cloud Run service is created and used as the trigger target
|
|
181
|
+
* instead of the live service. This isolates the backfill load (in particular its scaling) from production. The copy
|
|
182
|
+
* is added to the list of resources to clean up. The invoker IAM binding is not tracked separately because deleting
|
|
183
|
+
* the service removes it.
|
|
184
|
+
*
|
|
154
185
|
* @param backfillId The ID of the backfilling operation.
|
|
155
186
|
* @param topicId The ID of the Pub/Sub topic to subscribe to.
|
|
156
187
|
* @param serviceId The ID of the Cloud Run service to invoke.
|
|
157
188
|
* @param path The HTTP endpoint of the Cloud Run service to invoke.
|
|
189
|
+
* @param options Options for the trigger creation.
|
|
158
190
|
* @returns The IDs of the resources that were created. They should be added to the list of resources to delete as
|
|
159
191
|
* part of the backfill cleaning.
|
|
160
192
|
*/
|
|
161
|
-
async create(backfillId, topicId, serviceId, path) {
|
|
193
|
+
async create(backfillId, topicId, serviceId, path, options = {}) {
|
|
194
|
+
const { clone } = options;
|
|
162
195
|
const resourceIds = [];
|
|
163
196
|
try {
|
|
197
|
+
let targetServiceId = serviceId;
|
|
198
|
+
if (clone) {
|
|
199
|
+
targetServiceId = await this.createServiceCopy(backfillId, serviceId, clone);
|
|
200
|
+
resourceIds.push(targetServiceId);
|
|
201
|
+
}
|
|
164
202
|
const pubSubInvokerServiceAccount = await this.getBackfillInvokerServiceAccount(backfillId);
|
|
165
203
|
if (pubSubInvokerServiceAccount.resourceId) {
|
|
166
204
|
resourceIds.push(pubSubInvokerServiceAccount.resourceId);
|
|
167
205
|
}
|
|
168
206
|
const { serviceAccountEmail } = pubSubInvokerServiceAccount;
|
|
169
|
-
const iamResourceId = await this.grantPubSubInvokerRole(
|
|
170
|
-
|
|
207
|
+
const iamResourceId = await this.grantPubSubInvokerRole(targetServiceId, serviceAccountEmail);
|
|
208
|
+
// For a temporary service copy, deleting the service removes the binding along with it.
|
|
209
|
+
if (iamResourceId && !clone) {
|
|
171
210
|
resourceIds.push(iamResourceId);
|
|
172
211
|
}
|
|
173
|
-
const subscriptionId = await this.createSubscription(backfillId, topicId,
|
|
212
|
+
const subscriptionId = await this.createSubscription(backfillId, topicId, targetServiceId, path, serviceAccountEmail);
|
|
174
213
|
resourceIds.push(subscriptionId);
|
|
175
214
|
return resourceIds;
|
|
176
215
|
}
|
|
@@ -1,4 +1,34 @@
|
|
|
1
|
-
import { ServicesClient } from '@google-cloud/run';
|
|
1
|
+
import { ServicesClient, protos } from '@google-cloud/run';
|
|
2
|
+
export { CLOUD_RUN_SERVICE_ID_REGEX, shortServiceId, } from './cloud-run.utils.js';
|
|
3
|
+
/**
|
|
4
|
+
* The possible ingress settings for a Cloud Run service.
|
|
5
|
+
*/
|
|
6
|
+
export declare const IngressTraffic: typeof protos.google.cloud.run.v2.IngressTraffic;
|
|
7
|
+
/**
|
|
8
|
+
* Overrides that can be applied to a Cloud Run service copy.
|
|
9
|
+
*/
|
|
10
|
+
export type CloudRunServiceOverrides = {
|
|
11
|
+
/**
|
|
12
|
+
* The minimum number of instances for the service.
|
|
13
|
+
*/
|
|
14
|
+
minInstanceCount?: number;
|
|
15
|
+
/**
|
|
16
|
+
* The maximum number of instances for the service.
|
|
17
|
+
*/
|
|
18
|
+
maxInstanceCount?: number;
|
|
19
|
+
/**
|
|
20
|
+
* The maximum number of concurrent requests per instance.
|
|
21
|
+
*/
|
|
22
|
+
requestConcurrency?: number;
|
|
23
|
+
/**
|
|
24
|
+
* The ingress setting for the copy. Defaults to the source service's ingress when not set.
|
|
25
|
+
*/
|
|
26
|
+
ingress?: protos.google.cloud.run.v2.IngressTraffic;
|
|
27
|
+
/**
|
|
28
|
+
* Labels to set on the copy, merged on top of the source service's labels.
|
|
29
|
+
*/
|
|
30
|
+
labels?: Record<string, string>;
|
|
31
|
+
};
|
|
2
32
|
/**
|
|
3
33
|
* A service to manage Cloud Run services.
|
|
4
34
|
*/
|
|
@@ -16,6 +46,31 @@ export declare class CloudRunService {
|
|
|
16
46
|
* @returns The URI at which the service is available.
|
|
17
47
|
*/
|
|
18
48
|
getServiceUri(serviceId: string): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* Creates a copy of an existing Cloud Run service.
|
|
51
|
+
* The copy reuses the source service's revision template (image, environment, runtime service account, etc.), ingress,
|
|
52
|
+
* and labels, unless overridden through the options.
|
|
53
|
+
*
|
|
54
|
+
* @param sourceService The ID of the Cloud Run service to copy.
|
|
55
|
+
* This should be in the format `projects/<projectId>/locations/<location>/services/<name>`.
|
|
56
|
+
* @param name The name of the service copy to create.
|
|
57
|
+
* @param options Options for the copy.
|
|
58
|
+
* @returns The created service copy.
|
|
59
|
+
*/
|
|
60
|
+
copy(sourceService: string, name: string, options?: {
|
|
61
|
+
/**
|
|
62
|
+
* Overrides to apply to the copy. Unset scaling properties are inherited from the source service.
|
|
63
|
+
*/
|
|
64
|
+
overrides?: CloudRunServiceOverrides;
|
|
65
|
+
}): Promise<protos.google.cloud.run.v2.IService>;
|
|
66
|
+
/**
|
|
67
|
+
* Deletes a Cloud Run service.
|
|
68
|
+
* This tolerates the service not existing (e.g. when it was already deleted).
|
|
69
|
+
*
|
|
70
|
+
* @param name The ID of the Cloud Run service to delete.
|
|
71
|
+
* This should be in the format `projects/<projectId>/locations/<location>/services/<name>`.
|
|
72
|
+
*/
|
|
73
|
+
delete(name: string): Promise<void>;
|
|
19
74
|
/**
|
|
20
75
|
* Allows a service account to call a Cloud Run service by editing the IAM policy bindings.
|
|
21
76
|
*
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import { ServicesClient } from '@google-cloud/run';
|
|
1
|
+
import { ServicesClient, protos } from '@google-cloud/run';
|
|
2
2
|
import { grpc } from 'google-gax';
|
|
3
|
+
import { CLOUD_RUN_SERVICE_ID_REGEX } from './cloud-run.utils.js';
|
|
4
|
+
export { CLOUD_RUN_SERVICE_ID_REGEX, shortServiceId, } from './cloud-run.utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* The possible ingress settings for a Cloud Run service.
|
|
7
|
+
*/
|
|
8
|
+
export const IngressTraffic = protos.google.cloud.run.v2.IngressTraffic;
|
|
3
9
|
/**
|
|
4
10
|
* The role used to allow a service account to call a Cloud Run service.
|
|
5
11
|
*/
|
|
@@ -26,6 +32,70 @@ export class CloudRunService {
|
|
|
26
32
|
const [service] = await this.servicesClient.getService({ name: serviceId });
|
|
27
33
|
return service.uri ?? '';
|
|
28
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Creates a copy of an existing Cloud Run service.
|
|
37
|
+
* The copy reuses the source service's revision template (image, environment, runtime service account, etc.), ingress,
|
|
38
|
+
* and labels, unless overridden through the options.
|
|
39
|
+
*
|
|
40
|
+
* @param sourceService The ID of the Cloud Run service to copy.
|
|
41
|
+
* This should be in the format `projects/<projectId>/locations/<location>/services/<name>`.
|
|
42
|
+
* @param name The name of the service copy to create.
|
|
43
|
+
* @param options Options for the copy.
|
|
44
|
+
* @returns The created service copy.
|
|
45
|
+
*/
|
|
46
|
+
async copy(sourceService, name, options = {}) {
|
|
47
|
+
const match = sourceService.match(CLOUD_RUN_SERVICE_ID_REGEX);
|
|
48
|
+
if (!match?.groups) {
|
|
49
|
+
throw new Error(`Invalid Cloud Run service ID '${sourceService}'.`);
|
|
50
|
+
}
|
|
51
|
+
const { parent } = match.groups;
|
|
52
|
+
const [source] = await this.servicesClient.getService({
|
|
53
|
+
name: sourceService,
|
|
54
|
+
});
|
|
55
|
+
const { revision, ...template } = { ...source.template };
|
|
56
|
+
const { minInstanceCount, maxInstanceCount, requestConcurrency, ingress, labels, } = options.overrides ?? {};
|
|
57
|
+
if (minInstanceCount !== undefined || maxInstanceCount !== undefined) {
|
|
58
|
+
template.scaling = {
|
|
59
|
+
...template.scaling,
|
|
60
|
+
...(minInstanceCount !== undefined ? { minInstanceCount } : {}),
|
|
61
|
+
...(maxInstanceCount !== undefined ? { maxInstanceCount } : {}),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (requestConcurrency !== undefined) {
|
|
65
|
+
template.maxInstanceRequestConcurrency = requestConcurrency;
|
|
66
|
+
}
|
|
67
|
+
const service = {
|
|
68
|
+
template,
|
|
69
|
+
ingress: ingress ?? source.ingress,
|
|
70
|
+
labels: { ...source.labels, ...labels },
|
|
71
|
+
};
|
|
72
|
+
const [operation] = await this.servicesClient.createService({
|
|
73
|
+
parent,
|
|
74
|
+
serviceId: name,
|
|
75
|
+
service,
|
|
76
|
+
});
|
|
77
|
+
const [created] = await operation.promise();
|
|
78
|
+
return created;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Deletes a Cloud Run service.
|
|
82
|
+
* This tolerates the service not existing (e.g. when it was already deleted).
|
|
83
|
+
*
|
|
84
|
+
* @param name The ID of the Cloud Run service to delete.
|
|
85
|
+
* This should be in the format `projects/<projectId>/locations/<location>/services/<name>`.
|
|
86
|
+
*/
|
|
87
|
+
async delete(name) {
|
|
88
|
+
try {
|
|
89
|
+
const [operation] = await this.servicesClient.deleteService({ name });
|
|
90
|
+
await operation.promise();
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (error.code === grpc.status.NOT_FOUND) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
29
99
|
/**
|
|
30
100
|
* Allows a service account to call a Cloud Run service by editing the IAM policy bindings.
|
|
31
101
|
*
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The regular expression matching a Cloud Run service resource ID
|
|
3
|
+
* (e.g. `projects/<projectId>/locations/<location>/services/<name>`).
|
|
4
|
+
* The `parent` and `name` named groups respectively capture the parent location resource and the short service name.
|
|
5
|
+
*/
|
|
6
|
+
export declare const CLOUD_RUN_SERVICE_ID_REGEX: RegExp;
|
|
7
|
+
/**
|
|
8
|
+
* Returns the short service ID (the last path segment) for a full service resource name.
|
|
9
|
+
*/
|
|
10
|
+
export declare function shortServiceId(id: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The regular expression matching a Cloud Run service resource ID
|
|
3
|
+
* (e.g. `projects/<projectId>/locations/<location>/services/<name>`).
|
|
4
|
+
* The `parent` and `name` named groups respectively capture the parent location resource and the short service name.
|
|
5
|
+
*/
|
|
6
|
+
export const CLOUD_RUN_SERVICE_ID_REGEX = /^(?<parent>projects\/[\w-]+\/locations\/[\w-]+)\/services\/(?<name>[\w-]+)$/;
|
|
7
|
+
/**
|
|
8
|
+
* Returns the short service ID (the last path segment) for a full service resource name.
|
|
9
|
+
*/
|
|
10
|
+
export function shortServiceId(id) {
|
|
11
|
+
return id.split('/').at(-1) ?? id;
|
|
12
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { WorkspaceContext } from '@causa/workspace';
|
|
2
|
-
import {
|
|
3
|
-
import { GoogleApis } from 'googleapis';
|
|
2
|
+
import { Common, GoogleApis } from 'googleapis';
|
|
4
3
|
import type { ApiClient, OptionsOfApiClient } from './google-apis.types.js';
|
|
4
|
+
/**
|
|
5
|
+
* The type of authentication client returned by `googleapis`.
|
|
6
|
+
*/
|
|
7
|
+
type AnyAuthClient = Awaited<ReturnType<Common.GoogleAuth['getClient']>>;
|
|
5
8
|
/**
|
|
6
9
|
* A service that exposes the lowest level of Google API clients, from `googleapis`.
|
|
7
10
|
* Those might be needed in last resort, when no higher level client exists for an API.
|
|
@@ -21,7 +24,7 @@ export declare class GoogleApisService {
|
|
|
21
24
|
*
|
|
22
25
|
* @returns The auth client.
|
|
23
26
|
*/
|
|
24
|
-
getAuthClient(): Promise<
|
|
27
|
+
getAuthClient(): Promise<AnyAuthClient>;
|
|
25
28
|
/**
|
|
26
29
|
* Creates a new client for one of Google's APIs.
|
|
27
30
|
* Authentication is automatically configured.
|
|
@@ -33,3 +36,4 @@ export declare class GoogleApisService {
|
|
|
33
36
|
*/
|
|
34
37
|
getClient<const T extends keyof GoogleApis, const V extends string>(api: T, version: V, arg: Omit<OptionsOfApiClient<T, V>, 'auth' | 'version'>): Promise<ApiClient<T, V>>;
|
|
35
38
|
}
|
|
39
|
+
export {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { WorkspaceContext } from '@causa/workspace';
|
|
2
|
-
import {
|
|
3
|
-
import { GoogleApis, google } from 'googleapis';
|
|
2
|
+
import { Common, GoogleApis, google } from 'googleapis';
|
|
4
3
|
/**
|
|
5
4
|
* A service that exposes the lowest level of Google API clients, from `googleapis`.
|
|
6
5
|
* Those might be needed in last resort, when no higher level client exists for an API.
|
package/dist/services/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { BigQueryService } from './bigquery.js';
|
|
2
2
|
export { CloudMonitoringService, type MetricPoint, } from './cloud-monitoring.js';
|
|
3
3
|
export { CloudRunPubSubTriggerService } from './cloud-run-pubsub-trigger.js';
|
|
4
|
-
export { CloudRunService } from './cloud-run.js';
|
|
4
|
+
export { CLOUD_RUN_SERVICE_ID_REGEX, CloudRunService, IngressTraffic, shortServiceId, type CloudRunServiceOverrides, } from './cloud-run.js';
|
|
5
5
|
export * from './firebase-app.errors.js';
|
|
6
6
|
export { FirebaseAppService } from './firebase-app.js';
|
|
7
7
|
export type { FirebaseAppType } from './firebase-app.js';
|
package/dist/services/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { BigQueryService } from './bigquery.js';
|
|
2
2
|
export { CloudMonitoringService, } from './cloud-monitoring.js';
|
|
3
3
|
export { CloudRunPubSubTriggerService } from './cloud-run-pubsub-trigger.js';
|
|
4
|
-
export { CloudRunService } from './cloud-run.js';
|
|
4
|
+
export { CLOUD_RUN_SERVICE_ID_REGEX, CloudRunService, IngressTraffic, shortServiceId, } from './cloud-run.js';
|
|
5
5
|
export * from './firebase-app.errors.js';
|
|
6
6
|
export { FirebaseAppService } from './firebase-app.js';
|
|
7
7
|
export { FirebaseEmulatorService } from './firebase-emulator.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@causa/workspace-google",
|
|
3
|
-
"version": "0.18.0-beta.
|
|
3
|
+
"version": "0.18.0-beta.4",
|
|
4
4
|
"description": "The Causa workspace module providing many functionalities related to GCP and its services.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -42,22 +42,21 @@
|
|
|
42
42
|
"@google-cloud/apikeys": "^2.2.2",
|
|
43
43
|
"@google-cloud/bigquery": "^8.3.1",
|
|
44
44
|
"@google-cloud/iam-credentials": "^4.2.2",
|
|
45
|
-
"@google-cloud/logging": "^11.2.
|
|
46
|
-
"@google-cloud/monitoring": "^5.3.
|
|
47
|
-
"@google-cloud/pubsub": "^5.3.
|
|
45
|
+
"@google-cloud/logging": "^11.2.2",
|
|
46
|
+
"@google-cloud/monitoring": "^5.3.3",
|
|
47
|
+
"@google-cloud/pubsub": "^5.3.1",
|
|
48
48
|
"@google-cloud/resource-manager": "^6.2.2",
|
|
49
49
|
"@google-cloud/run": "^3.2.1",
|
|
50
|
-
"@google-cloud/secret-manager": "^6.1.
|
|
50
|
+
"@google-cloud/secret-manager": "^6.1.3",
|
|
51
51
|
"@google-cloud/service-usage": "^4.2.2",
|
|
52
52
|
"@google-cloud/spanner": "^8.7.1",
|
|
53
53
|
"@google-cloud/storage": "^7.19.0",
|
|
54
54
|
"class-validator": "^0.15.1",
|
|
55
|
-
"firebase": "^12.
|
|
55
|
+
"firebase": "^12.14.0",
|
|
56
56
|
"firebase-admin": "^13.10.0",
|
|
57
57
|
"globby": "^16.2.0",
|
|
58
|
-
"google-auth-library": "^10.6.2",
|
|
59
58
|
"google-gax": "5.0.6",
|
|
60
|
-
"googleapis": "^
|
|
59
|
+
"googleapis": "^173.0.0",
|
|
61
60
|
"micromatch": "^4.0.8",
|
|
62
61
|
"pino": "^10.3.1"
|
|
63
62
|
},
|
|
@@ -67,16 +66,16 @@
|
|
|
67
66
|
"@tsconfig/node22": "^22.0.5",
|
|
68
67
|
"@types/jest": "^30.0.0",
|
|
69
68
|
"@types/micromatch": "^4.0.10",
|
|
70
|
-
"@types/node": "^20.19.
|
|
69
|
+
"@types/node": "^20.19.42",
|
|
71
70
|
"copyfiles": "^2.4.1",
|
|
72
|
-
"eslint": "^10.4.
|
|
71
|
+
"eslint": "^10.4.1",
|
|
73
72
|
"eslint-config-prettier": "^10.1.8",
|
|
74
|
-
"eslint-plugin-prettier": "^5.5.
|
|
73
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
75
74
|
"jest": "^30.4.2",
|
|
76
75
|
"jest-extended": "^7.0.0",
|
|
77
76
|
"rimraf": "^6.1.3",
|
|
78
77
|
"typescript": "^6.0.3",
|
|
79
|
-
"typescript-eslint": "^8.60.
|
|
78
|
+
"typescript-eslint": "^8.60.1",
|
|
80
79
|
"yaml": "^2.9.0"
|
|
81
80
|
}
|
|
82
81
|
}
|