Skip to content

Commit a5579b5

Browse files
feat: Add Google Drive storage backend with custom endpoint support (#613)
* feat: Add Google Drive storage backend with custom endpoint support - Implement Google Drive storage backend using service account authentication - Add support for custom Google Drive API endpoints for testing - Include comprehensive test setup with mock services - Add configuration options for Google Drive credentials and folder ID - Update documentation with Google Drive configuration examples * remove debug messages * Improve tests * Add mounting tip on documentation * Replace deprecated lib usage * Fix identation * Fix googledrive tests * Fix googledrive support for _FILE credentials * Remove googledrive test unecessary echos
1 parent 4ad98af commit a5579b5

File tree

11 files changed

+596
-26
lines changed

11 files changed

+596
-26
lines changed

cmd/backup/config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ type Config struct {
8787
DropboxAppSecret string `split_words:"true"`
8888
DropboxRemotePath string `split_words:"true"`
8989
DropboxConcurrencyLevel NaturalNumber `split_words:"true" default:"6"`
90+
GoogleDriveCredentialsJSON string `split_words:"true"`
91+
GoogleDriveFolderID string `split_words:"true"`
92+
GoogleDriveImpersonateSubject string `split_words:"true"`
93+
GoogleDriveEndpoint string `split_words:"true"`
94+
GoogleDriveTokenURL string `split_words:"true"`
9095
source string
9196
additionalEnvVars map[string]string
9297
}

cmd/backup/script.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/offen/docker-volume-backup/internal/storage"
1717
"github.com/offen/docker-volume-backup/internal/storage/azure"
1818
"github.com/offen/docker-volume-backup/internal/storage/dropbox"
19+
"github.com/offen/docker-volume-backup/internal/storage/googledrive"
1920
"github.com/offen/docker-volume-backup/internal/storage/local"
2021
"github.com/offen/docker-volume-backup/internal/storage/s3"
2122
"github.com/offen/docker-volume-backup/internal/storage/ssh"
@@ -59,12 +60,13 @@ func newScript(c *Config) *script {
5960
StartTime: time.Now(),
6061
LogOutput: logBuffer,
6162
Storages: map[string]StorageStats{
62-
"S3": {},
63-
"WebDAV": {},
64-
"SSH": {},
65-
"Local": {},
66-
"Azure": {},
67-
"Dropbox": {},
63+
"S3": {},
64+
"WebDAV": {},
65+
"SSH": {},
66+
"Local": {},
67+
"Azure": {},
68+
"Dropbox": {},
69+
"GoogleDrive": {},
6870
},
6971
},
7072
}
@@ -225,6 +227,21 @@ func (s *script) init() error {
225227
s.storages = append(s.storages, dropboxBackend)
226228
}
227229

230+
if s.c.GoogleDriveCredentialsJSON != "" {
231+
googleDriveConfig := googledrive.Config{
232+
CredentialsJSON: s.c.GoogleDriveCredentialsJSON,
233+
FolderID: s.c.GoogleDriveFolderID,
234+
ImpersonateSubject: s.c.GoogleDriveImpersonateSubject,
235+
Endpoint: s.c.GoogleDriveEndpoint,
236+
TokenURL: s.c.GoogleDriveTokenURL,
237+
}
238+
googleDriveBackend, err := googledrive.NewStorageBackend(googleDriveConfig, logFunc)
239+
if err != nil {
240+
return errwrap.Wrap(err, "error creating googledrive storage backend")
241+
}
242+
s.storages = append(s.storages, googleDriveBackend)
243+
}
244+
228245
if s.c.EmailNotificationRecipient != "" {
229246
emailURL := fmt.Sprintf(
230247
"smtp://%s:%s@%s:%d/?from=%s&to=%s",

docs/reference/index.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,57 @@ The values for each key currently match its default.
386386
387387
# DROPBOX_REFRESH_TOKEN=""
388388
389+
########### GOOGLE DRIVE STORAGE
390+
391+
# The JSON credentials for a Google service account with access to Google Drive.
392+
# You can provide either:
393+
# 1. The actual JSON content directly
394+
# 2. Use the _FILE suffix to load from a file (e.g., GOOGLE_DRIVE_CREDENTIALS_JSON_FILE)
395+
#
396+
# Examples:
397+
# Option 1 - JSON content:
398+
# docker run [...] \
399+
# -e GOOGLE_DRIVE_CREDENTIALS_JSON='{"type":"service_account",...}'
400+
#
401+
# Option 2 - Using _FILE suffix (recommended for Docker Secrets):
402+
# docker run [...] \
403+
# -v ./credentials.json:/creds/google-credentials.json \
404+
# -e GOOGLE_DRIVE_CREDENTIALS_JSON_FILE=/creds/google-credentials.json
405+
#
406+
# GOOGLE_DRIVE_CREDENTIALS_JSON=""
407+
408+
# ---
409+
410+
# The ID of the Google Drive folder where backups will be uploaded.
411+
# You can find the folder ID in the URL when viewing the folder in Google Drive.
412+
#
413+
# Example: "1A2B3C4D5E6F7G8H9I0J"
414+
#
415+
# GOOGLE_DRIVE_FOLDER_ID=""
416+
417+
# ---
418+
419+
# The email address of the user to impersonate when accessing Google Drive (domain-wide delegation).
420+
# This is required becasue your service account needs to act on behalf of a user in your organization in order to upload files.
421+
# How to: https://support.google.com/a/answer/162106
422+
# Example: "[email protected]"
423+
#
424+
# GOOGLE_DRIVE_IMPERSONATE_SUBJECT=""
425+
426+
# ---
427+
428+
# (Optional) Custom Google Drive API endpoint. This is primarily for testing with a mock server.
429+
# Example: "http://localhost:8080/drive/v3"
430+
#
431+
# GOOGLE_DRIVE_ENDPOINT=""
432+
433+
# ---
434+
435+
# (Optional) Custom token URL for Google Drive authentication. This is primarily for testing with a mock server.
436+
# Example: "http://localhost:8080/token"
437+
#
438+
# GOOGLE_DRIVE_TOKEN_URL=""
439+
389440
########### LOCAL FILE STORAGE
390441
391442
# In addition to storing backups remotely, you can also keep local copies.

go.mod

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@ require (
2323
golang.org/x/crypto v0.39.0
2424
golang.org/x/oauth2 v0.30.0
2525
golang.org/x/sync v0.16.0
26+
google.golang.org/api v0.242.0
2627
mvdan.cc/sh/v3 v3.12.0
2728
)
2829

2930
require (
31+
cloud.google.com/go/auth v0.16.2 // indirect
32+
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
33+
cloud.google.com/go/compute/metadata v0.7.0 // indirect
3034
filippo.io/edwards25519 v1.1.0 // indirect
3135
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
3236
github.com/cloudflare/circl v1.6.1 // indirect
@@ -40,23 +44,25 @@ require (
4044
github.com/go-logr/stdr v1.2.2 // indirect
4145
github.com/goccy/go-json v0.10.5 // indirect
4246
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
43-
github.com/golang/protobuf v1.5.4 // indirect
47+
github.com/google/s2a-go v0.1.9 // indirect
48+
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
49+
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
4450
github.com/minio/crc64nvme v1.0.2 // indirect
4551
github.com/moby/docker-image-spec v1.3.1 // indirect
4652
github.com/moby/sys/atomicwriter v0.1.0 // indirect
4753
github.com/otiai10/mint v1.6.3 // indirect
4854
github.com/philhofer/fwd v1.2.0 // indirect
4955
github.com/tinylib/msgp v1.3.0 // indirect
5056
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
51-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
57+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
5258
go.opentelemetry.io/otel v1.36.0 // indirect
5359
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect
5460
go.opentelemetry.io/otel/metric v1.36.0 // indirect
55-
go.opentelemetry.io/otel/sdk v1.26.0 // indirect
5661
go.opentelemetry.io/otel/trace v1.36.0 // indirect
57-
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
58-
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
59-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
62+
golang.org/x/time v0.12.0 // indirect
63+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
64+
google.golang.org/grpc v1.73.0 // indirect
65+
google.golang.org/protobuf v1.36.6 // indirect
6066
)
6167

6268
require (

go.sum

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,18 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
1515
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
1616
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
1717
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
18+
cloud.google.com/go/auth v0.16.2 h1:QvBAGFPLrDeoiNjyfVunhQ10HKNYuOwZ5noee0M5df4=
19+
cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA=
20+
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
21+
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
1822
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
1923
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
2024
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
2125
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
2226
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
2327
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
28+
cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
29+
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
2430
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
2531
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
2632
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
@@ -184,10 +190,16 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
184190
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
185191
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
186192
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
193+
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
194+
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
187195
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
188196
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
197+
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
198+
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
189199
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
190200
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
201+
github.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0=
202+
github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w=
191203
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is=
192204
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM=
193205
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -311,8 +323,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
311323
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
312324
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
313325
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
314-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
315-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc=
326+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
327+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
316328
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
317329
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
318330
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE=
@@ -321,8 +333,10 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/g
321333
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38=
322334
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
323335
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
324-
go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8=
325-
go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs=
336+
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
337+
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
338+
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
339+
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
326340
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
327341
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
328342
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
@@ -508,8 +522,8 @@ golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
508522
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
509523
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
510524
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
511-
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
512-
golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
525+
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
526+
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
513527
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
514528
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
515529
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -579,6 +593,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
579593
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
580594
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
581595
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
596+
google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg=
597+
google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50=
582598
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
583599
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
584600
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -614,10 +630,12 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
614630
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
615631
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
616632
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
617-
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0=
618-
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8=
619-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
620-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
633+
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78=
634+
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk=
635+
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0=
636+
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw=
637+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
638+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
621639
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
622640
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
623641
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -630,8 +648,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
630648
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
631649
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
632650
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
633-
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
634-
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
651+
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
652+
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
635653
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
636654
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
637655
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -642,8 +660,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
642660
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
643661
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
644662
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
645-
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
646-
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
663+
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
664+
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
647665
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
648666
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
649667
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=

0 commit comments

Comments
 (0)