chore(deps): bump cloud.google.com/go/storage from 1.40.0 to 1.41.0 (#3171)

Bumps [cloud.google.com/go/storage](https://github.com/googleapis/google-cloud-go) from 1.40.0 to 1.41.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/spanner/v1.40.0...spanner/v1.41.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/storage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
dependabot[bot] 2024-05-20 09:53:50 -07:00 committed by GitHub
parent 96fa5ff99a
commit b64e9a8ebd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 356 additions and 70 deletions

8
go.mod
View File

@ -3,7 +3,7 @@ module github.com/GoogleContainerTools/kaniko
go 1.22 go 1.22
require ( require (
cloud.google.com/go/storage v1.40.0 cloud.google.com/go/storage v1.41.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2
github.com/aws/aws-sdk-go-v2 v1.26.1 github.com/aws/aws-sdk-go-v2 v1.26.1
github.com/aws/aws-sdk-go-v2/config v1.27.13 github.com/aws/aws-sdk-go-v2/config v1.27.13
@ -44,7 +44,7 @@ require github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
require ( require (
cloud.google.com/go v0.112.2 // indirect cloud.google.com/go v0.112.2 // indirect
cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect
cloud.google.com/go/iam v1.1.7 // indirect cloud.google.com/go/iam v1.1.8 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.29 // indirect github.com/Azure/go-autorest/autorest v0.11.29 // indirect
@ -135,7 +135,7 @@ require (
golang.org/x/text v0.15.0 // indirect golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.5.0 // indirect
google.golang.org/api v0.180.0 google.golang.org/api v0.180.0
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda // indirect
google.golang.org/grpc v1.63.2 // indirect google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.34.1 // indirect google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
@ -190,7 +190,7 @@ require (
go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect

24
go.sum
View File

@ -7,10 +7,10 @@ cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKF
cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM= cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0=
cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE=
cloud.google.com/go/storage v1.40.0 h1:VEpDQV5CJxFmJ6ueWNsKxcr1QAYOXEgxDa+sBbJahPw= cloud.google.com/go/storage v1.41.0 h1:RusiwatSu6lHeEXe3kglxakAmAbfV+rhtPqA6i8RBx0=
cloud.google.com/go/storage v1.40.0/go.mod h1:Rrj7/hKlG87BLqDJYtwR0fbPld8uJPbQ2ucUMY7Ir0g= cloud.google.com/go/storage v1.41.0/go.mod h1:J1WCa/Z2FcgdEDuPUY8DxT5I+d9mFKsCepp5vR6Sq80=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
@ -281,8 +281,8 @@ github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+u
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc=
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
github.com/google/slowjam v1.1.1 h1:3Sau9H9JD1v+L4G8RP9aQarp/RytJ2NZrIDwG4OS4AQ= github.com/google/slowjam v1.1.1 h1:3Sau9H9JD1v+L4G8RP9aQarp/RytJ2NZrIDwG4OS4AQ=
@ -502,8 +502,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkE
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I=
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
@ -645,10 +645,10 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWhkkZGohVC6KRrc1oJNr4jwtQMOQXw=
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw=
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be h1:Zz7rLWqp0ApfsR/l7+zSHhY3PMiH2xqgxlfYfAfNpoU= google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae h1:AH34z6WAGVNkllnKs5raNq3yRq93VnjBG6rpfub/jYk=
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be/go.mod h1:dvdCTIoAGbkWbcIKBniID56/7XHTt6WfxXNMxuziJ+w= google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae/go.mod h1:FfiGhwUm6CJviekPrc0oJ+7h29e+DmWU6UtjX0ZvI7Y=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE= google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=

View File

@ -1,6 +1,13 @@
# Changes # Changes
## [1.1.8](https://github.com/googleapis/google-cloud-go/compare/iam/v1.1.7...iam/v1.1.8) (2024-05-01)
### Bug Fixes
* **iam:** Bump x/net to v0.24.0 ([ba31ed5](https://github.com/googleapis/google-cloud-go/commit/ba31ed5fda2c9664f2e1cf972469295e63deb5b4))
## [1.1.7](https://github.com/googleapis/google-cloud-go/compare/iam/v1.1.6...iam/v1.1.7) (2024-03-14) ## [1.1.7](https://github.com/googleapis/google-cloud-go/compare/iam/v1.1.6...iam/v1.1.7) (2024-03-14)

View File

@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.32.0 // protoc-gen-go v1.33.0
// protoc v4.25.2 // protoc v4.25.3
// source: google/iam/v1/iam_policy.proto // source: google/iam/v1/iam_policy.proto
package iampb package iampb

View File

@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.32.0 // protoc-gen-go v1.33.0
// protoc v4.25.2 // protoc v4.25.3
// source: google/iam/v1/options.proto // source: google/iam/v1/options.proto
package iampb package iampb

View File

@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.32.0 // protoc-gen-go v1.33.0
// protoc v4.25.2 // protoc v4.25.3
// source: google/iam/v1/policy.proto // source: google/iam/v1/policy.proto
package iampb package iampb

View File

@ -1,6 +1,30 @@
# Changes # Changes
## [1.41.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.40.0...storage/v1.41.0) (2024-05-13)
### Features
* **storage/control:** Make Managed Folders operations public ([264a6dc](https://github.com/googleapis/google-cloud-go/commit/264a6dcddbffaec987dce1dc00f6550c263d2df7))
* **storage:** Support for soft delete policies and restore ([#9520](https://github.com/googleapis/google-cloud-go/issues/9520)) ([985deb2](https://github.com/googleapis/google-cloud-go/commit/985deb2bdd1c79944cdd960bd3fbfa38cbfa1c91))
### Bug Fixes
* **storage/control:** An existing resource pattern value `projects/{project}/buckets/{bucket}/managedFolders/{managedFolder=**}` to resource definition `storage.googleapis.com/ManagedFolder` is removed ([3e25053](https://github.com/googleapis/google-cloud-go/commit/3e250530567ee81ed4f51a3856c5940dbec35289))
* **storage:** Add internaloption.WithDefaultEndpointTemplate ([3b41408](https://github.com/googleapis/google-cloud-go/commit/3b414084450a5764a0248756e95e13383a645f90))
* **storage:** Bump x/net to v0.24.0 ([ba31ed5](https://github.com/googleapis/google-cloud-go/commit/ba31ed5fda2c9664f2e1cf972469295e63deb5b4))
* **storage:** Disable gax retries for gRPC ([#9747](https://github.com/googleapis/google-cloud-go/issues/9747)) ([bbfc0ac](https://github.com/googleapis/google-cloud-go/commit/bbfc0acc272f21bf1f558ea23648183d5a11cda5))
* **storage:** More strongly match regex ([#9706](https://github.com/googleapis/google-cloud-go/issues/9706)) ([3cfc8eb](https://github.com/googleapis/google-cloud-go/commit/3cfc8eb418e064d734bf3d8708162062dbbe988f)), refs [#9705](https://github.com/googleapis/google-cloud-go/issues/9705)
* **storage:** Retry net.OpError on connection reset ([#10154](https://github.com/googleapis/google-cloud-go/issues/10154)) ([54fab10](https://github.com/googleapis/google-cloud-go/commit/54fab107f98b4f79c9df2959a05b981be0a613c1)), refs [#9478](https://github.com/googleapis/google-cloud-go/issues/9478)
* **storage:** Wrap error when MaxAttempts is hit ([#9767](https://github.com/googleapis/google-cloud-go/issues/9767)) ([9cb262b](https://github.com/googleapis/google-cloud-go/commit/9cb262bb65a162665bfb8bed0022615131bae1f2)), refs [#9720](https://github.com/googleapis/google-cloud-go/issues/9720)
### Documentation
* **storage/control:** Update storage control documentation and add PHP for publishing ([1d757c6](https://github.com/googleapis/google-cloud-go/commit/1d757c66478963d6cbbef13fee939632c742759c))
## [1.40.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.39.1...storage/v1.40.0) (2024-03-29) ## [1.40.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.39.1...storage/v1.40.0) (2024-03-29)

View File

@ -479,6 +479,13 @@ type BucketAttrs struct {
// cannot be modified once the bucket is created. // cannot be modified once the bucket is created.
// ObjectRetention cannot be configured or reported through the gRPC API. // ObjectRetention cannot be configured or reported through the gRPC API.
ObjectRetentionMode string ObjectRetentionMode string
// SoftDeletePolicy contains the bucket's soft delete policy, which defines
// the period of time that soft-deleted objects will be retained, and cannot
// be permanently deleted. By default, new buckets will be created with a
// 7 day retention duration. In order to fully disable soft delete, you need
// to set a policy with a RetentionDuration of 0.
SoftDeletePolicy *SoftDeletePolicy
} }
// BucketPolicyOnly is an alias for UniformBucketLevelAccess. // BucketPolicyOnly is an alias for UniformBucketLevelAccess.
@ -766,6 +773,19 @@ type Autoclass struct {
TerminalStorageClassUpdateTime time.Time TerminalStorageClassUpdateTime time.Time
} }
// SoftDeletePolicy contains the bucket's soft delete policy, which defines the
// period of time that soft-deleted objects will be retained, and cannot be
// permanently deleted.
type SoftDeletePolicy struct {
// EffectiveTime indicates the time from which the policy, or one with a
// greater retention, was effective. This field is read-only.
EffectiveTime time.Time
// RetentionDuration is the amount of time that soft-deleted objects in the
// bucket will be retained and cannot be permanently deleted.
RetentionDuration time.Duration
}
func newBucket(b *raw.Bucket) (*BucketAttrs, error) { func newBucket(b *raw.Bucket) (*BucketAttrs, error) {
if b == nil { if b == nil {
return nil, nil return nil, nil
@ -803,6 +823,7 @@ func newBucket(b *raw.Bucket) (*BucketAttrs, error) {
RPO: toRPO(b), RPO: toRPO(b),
CustomPlacementConfig: customPlacementFromRaw(b.CustomPlacementConfig), CustomPlacementConfig: customPlacementFromRaw(b.CustomPlacementConfig),
Autoclass: toAutoclassFromRaw(b.Autoclass), Autoclass: toAutoclassFromRaw(b.Autoclass),
SoftDeletePolicy: toSoftDeletePolicyFromRaw(b.SoftDeletePolicy),
}, nil }, nil
} }
@ -836,6 +857,7 @@ func newBucketFromProto(b *storagepb.Bucket) *BucketAttrs {
CustomPlacementConfig: customPlacementFromProto(b.GetCustomPlacementConfig()), CustomPlacementConfig: customPlacementFromProto(b.GetCustomPlacementConfig()),
ProjectNumber: parseProjectNumber(b.GetProject()), // this can return 0 the project resource name is ID based ProjectNumber: parseProjectNumber(b.GetProject()), // this can return 0 the project resource name is ID based
Autoclass: toAutoclassFromProto(b.GetAutoclass()), Autoclass: toAutoclassFromProto(b.GetAutoclass()),
SoftDeletePolicy: toSoftDeletePolicyFromProto(b.SoftDeletePolicy),
} }
} }
@ -891,6 +913,7 @@ func (b *BucketAttrs) toRawBucket() *raw.Bucket {
Rpo: b.RPO.String(), Rpo: b.RPO.String(),
CustomPlacementConfig: b.CustomPlacementConfig.toRawCustomPlacement(), CustomPlacementConfig: b.CustomPlacementConfig.toRawCustomPlacement(),
Autoclass: b.Autoclass.toRawAutoclass(), Autoclass: b.Autoclass.toRawAutoclass(),
SoftDeletePolicy: b.SoftDeletePolicy.toRawSoftDeletePolicy(),
} }
} }
@ -951,6 +974,7 @@ func (b *BucketAttrs) toProtoBucket() *storagepb.Bucket {
Rpo: b.RPO.String(), Rpo: b.RPO.String(),
CustomPlacementConfig: b.CustomPlacementConfig.toProtoCustomPlacement(), CustomPlacementConfig: b.CustomPlacementConfig.toProtoCustomPlacement(),
Autoclass: b.Autoclass.toProtoAutoclass(), Autoclass: b.Autoclass.toProtoAutoclass(),
SoftDeletePolicy: b.SoftDeletePolicy.toProtoSoftDeletePolicy(),
} }
} }
@ -1032,6 +1056,7 @@ func (ua *BucketAttrsToUpdate) toProtoBucket() *storagepb.Bucket {
IamConfig: bktIAM, IamConfig: bktIAM,
Rpo: ua.RPO.String(), Rpo: ua.RPO.String(),
Autoclass: ua.Autoclass.toProtoAutoclass(), Autoclass: ua.Autoclass.toProtoAutoclass(),
SoftDeletePolicy: ua.SoftDeletePolicy.toProtoSoftDeletePolicy(),
Labels: ua.setLabels, Labels: ua.setLabels,
} }
} }
@ -1152,6 +1177,9 @@ type BucketAttrsToUpdate struct {
// See https://cloud.google.com/storage/docs/using-autoclass for more information. // See https://cloud.google.com/storage/docs/using-autoclass for more information.
Autoclass *Autoclass Autoclass *Autoclass
// If set, updates the soft delete policy of the bucket.
SoftDeletePolicy *SoftDeletePolicy
// acl is the list of access control rules on the bucket. // acl is the list of access control rules on the bucket.
// It is unexported and only used internally by the gRPC client. // It is unexported and only used internally by the gRPC client.
// Library users should use ACLHandle methods directly. // Library users should use ACLHandle methods directly.
@ -1273,6 +1301,14 @@ func (ua *BucketAttrsToUpdate) toRawBucket() *raw.Bucket {
} }
rb.ForceSendFields = append(rb.ForceSendFields, "Autoclass") rb.ForceSendFields = append(rb.ForceSendFields, "Autoclass")
} }
if ua.SoftDeletePolicy != nil {
if ua.SoftDeletePolicy.RetentionDuration == 0 {
rb.NullFields = append(rb.NullFields, "SoftDeletePolicy")
rb.SoftDeletePolicy = nil
} else {
rb.SoftDeletePolicy = ua.SoftDeletePolicy.toRawSoftDeletePolicy()
}
}
if ua.PredefinedACL != "" { if ua.PredefinedACL != "" {
// Clear ACL or the call will fail. // Clear ACL or the call will fail.
rb.Acl = nil rb.Acl = nil
@ -2053,6 +2089,53 @@ func toAutoclassFromProto(a *storagepb.Bucket_Autoclass) *Autoclass {
} }
} }
func (p *SoftDeletePolicy) toRawSoftDeletePolicy() *raw.BucketSoftDeletePolicy {
if p == nil {
return nil
}
// Excluding read only field EffectiveTime.
return &raw.BucketSoftDeletePolicy{
RetentionDurationSeconds: int64(p.RetentionDuration.Seconds()),
}
}
func (p *SoftDeletePolicy) toProtoSoftDeletePolicy() *storagepb.Bucket_SoftDeletePolicy {
if p == nil {
return nil
}
// Excluding read only field EffectiveTime.
return &storagepb.Bucket_SoftDeletePolicy{
RetentionDuration: durationpb.New(p.RetentionDuration),
}
}
func toSoftDeletePolicyFromRaw(p *raw.BucketSoftDeletePolicy) *SoftDeletePolicy {
if p == nil {
return nil
}
policy := &SoftDeletePolicy{
RetentionDuration: time.Duration(p.RetentionDurationSeconds) * time.Second,
}
// Return EffectiveTime only if parsed to a valid value.
if t, err := time.Parse(time.RFC3339, p.EffectiveTime); err == nil {
policy.EffectiveTime = t
}
return policy
}
func toSoftDeletePolicyFromProto(p *storagepb.Bucket_SoftDeletePolicy) *SoftDeletePolicy {
if p == nil {
return nil
}
return &SoftDeletePolicy{
EffectiveTime: p.GetEffectiveTime().AsTime(),
RetentionDuration: p.GetRetentionDuration().AsDuration(),
}
}
// Objects returns an iterator over the objects in the bucket that match the // Objects returns an iterator over the objects in the bucket that match the
// Query q. If q is nil, no filtering is done. Objects will be iterated over // Query q. If q is nil, no filtering is done. Objects will be iterated over
// lexicographically by name. // lexicographically by name.

View File

@ -59,8 +59,9 @@ type storageClient interface {
// Object metadata methods. // Object metadata methods.
DeleteObject(ctx context.Context, bucket, object string, gen int64, conds *Conditions, opts ...storageOption) error DeleteObject(ctx context.Context, bucket, object string, gen int64, conds *Conditions, opts ...storageOption) error
GetObject(ctx context.Context, bucket, object string, gen int64, encryptionKey []byte, conds *Conditions, opts ...storageOption) (*ObjectAttrs, error) GetObject(ctx context.Context, params *getObjectParams, opts ...storageOption) (*ObjectAttrs, error)
UpdateObject(ctx context.Context, params *updateObjectParams, opts ...storageOption) (*ObjectAttrs, error) UpdateObject(ctx context.Context, params *updateObjectParams, opts ...storageOption) (*ObjectAttrs, error)
RestoreObject(ctx context.Context, params *restoreObjectParams, opts ...storageOption) (*ObjectAttrs, error)
// Default Object ACL methods. // Default Object ACL methods.
@ -182,16 +183,6 @@ type storageOption interface {
Apply(s *settings) Apply(s *settings)
} }
func withGAXOptions(opts ...gax.CallOption) storageOption {
return &gaxOption{opts}
}
type gaxOption struct {
opts []gax.CallOption
}
func (o *gaxOption) Apply(s *settings) { s.gax = o.opts }
func withRetryConfig(rc *retryConfig) storageOption { func withRetryConfig(rc *retryConfig) storageOption {
return &retryOption{rc} return &retryOption{rc}
} }
@ -294,6 +285,14 @@ type newRangeReaderParams struct {
readCompressed bool // Use accept-encoding: gzip. Only works for HTTP currently. readCompressed bool // Use accept-encoding: gzip. Only works for HTTP currently.
} }
type getObjectParams struct {
bucket, object string
gen int64
encryptionKey []byte
conds *Conditions
softDeleted bool
}
type updateObjectParams struct { type updateObjectParams struct {
bucket, object string bucket, object string
uattrs *ObjectAttrsToUpdate uattrs *ObjectAttrsToUpdate
@ -303,6 +302,14 @@ type updateObjectParams struct {
overrideRetention *bool overrideRetention *bool
} }
type restoreObjectParams struct {
bucket, object string
gen int64
encryptionKey []byte
conds *Conditions
copySourceACL bool
}
type composeObjectRequest struct { type composeObjectRequest struct {
dstBucket string dstBucket string
dstObject destinationObject dstObject destinationObject

View File

@ -350,7 +350,7 @@ To create a client which will use gRPC, use the alternate constructor:
// Use client as usual. // Use client as usual.
If the application is running within GCP, users may get better performance by If the application is running within GCP, users may get better performance by
enabling Google Direct Access (enabling requests to skip some proxy steps). To enable, enabling Direct Google Access (enabling requests to skip some proxy steps). To enable,
set the environment variable `GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS=true` and add set the environment variable `GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS=true` and add
the following side-effect imports to your application: the following side-effect imports to your application:
@ -359,6 +359,13 @@ the following side-effect imports to your application:
_ "google.golang.org/grpc/xds/googledirectpath" _ "google.golang.org/grpc/xds/googledirectpath"
) )
# Storage Control API
Certain control plane and long-running operations for Cloud Storage (including Folder
and Managed Folder operations) are supported via the autogenerated Storage Control
client, which is available as a subpackage in this module. See package docs at
[cloud.google.com/go/storage/control/apiv2] or reference the [Storage Control API] docs.
[Cloud Storage IAM docs]: https://cloud.google.com/storage/docs/access-control/iam [Cloud Storage IAM docs]: https://cloud.google.com/storage/docs/access-control/iam
[XML POST Object docs]: https://cloud.google.com/storage/docs/xml-api/post-object [XML POST Object docs]: https://cloud.google.com/storage/docs/xml-api/post-object
[Cloud Storage retry docs]: https://cloud.google.com/storage/docs/retry-strategy [Cloud Storage retry docs]: https://cloud.google.com/storage/docs/retry-strategy
@ -367,5 +374,6 @@ the following side-effect imports to your application:
[impersonation enabled]: https://cloud.google.com/sdk/gcloud/reference#--impersonate-service-account [impersonation enabled]: https://cloud.google.com/sdk/gcloud/reference#--impersonate-service-account
[IAM Service Account Credentials API]: https://console.developers.google.com/apis/api/iamcredentials.googleapis.com/overview [IAM Service Account Credentials API]: https://console.developers.google.com/apis/api/iamcredentials.googleapis.com/overview
[custom audit logging]: https://cloud.google.com/storage/docs/audit-logging#add-custom-metadata [custom audit logging]: https://cloud.google.com/storage/docs/audit-logging#add-custom-metadata
[Storage Control API]: https://cloud.google.com/storage/docs/reference/rpc/google.storage.control.v2
*/ */
package storage // import "cloud.google.com/go/storage" package storage // import "cloud.google.com/go/storage"

View File

@ -28,7 +28,6 @@ import (
"cloud.google.com/go/internal/trace" "cloud.google.com/go/internal/trace"
gapic "cloud.google.com/go/storage/internal/apiv2" gapic "cloud.google.com/go/storage/internal/apiv2"
"cloud.google.com/go/storage/internal/apiv2/storagepb" "cloud.google.com/go/storage/internal/apiv2/storagepb"
"github.com/golang/protobuf/proto"
"github.com/googleapis/gax-go/v2" "github.com/googleapis/gax-go/v2"
"google.golang.org/api/googleapi" "google.golang.org/api/googleapi"
"google.golang.org/api/iterator" "google.golang.org/api/iterator"
@ -40,6 +39,7 @@ import (
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/proto"
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
) )
@ -116,6 +116,8 @@ type grpcStorageClient struct {
func newGRPCStorageClient(ctx context.Context, opts ...storageOption) (storageClient, error) { func newGRPCStorageClient(ctx context.Context, opts ...storageOption) (storageClient, error) {
s := initSettings(opts...) s := initSettings(opts...)
s.clientOption = append(defaultGRPCOptions(), s.clientOption...) s.clientOption = append(defaultGRPCOptions(), s.clientOption...)
// Disable all gax-level retries in favor of retry logic in the veneer client.
s.gax = append(s.gax, gax.WithRetry(nil))
config := newStorageConfig(s.clientOption...) config := newStorageConfig(s.clientOption...)
if config.readAPIWasSet { if config.readAPIWasSet {
@ -365,6 +367,9 @@ func (c *grpcStorageClient) UpdateBucket(ctx context.Context, bucket string, uat
if uattrs.Autoclass != nil { if uattrs.Autoclass != nil {
fieldMask.Paths = append(fieldMask.Paths, "autoclass") fieldMask.Paths = append(fieldMask.Paths, "autoclass")
} }
if uattrs.SoftDeletePolicy != nil {
fieldMask.Paths = append(fieldMask.Paths, "soft_delete_policy")
}
for label := range uattrs.setLabels { for label := range uattrs.setLabels {
fieldMask.Paths = append(fieldMask.Paths, fmt.Sprintf("labels.%s", label)) fieldMask.Paths = append(fieldMask.Paths, fmt.Sprintf("labels.%s", label))
@ -377,6 +382,13 @@ func (c *grpcStorageClient) UpdateBucket(ctx context.Context, bucket string, uat
req.UpdateMask = fieldMask req.UpdateMask = fieldMask
if len(fieldMask.Paths) < 1 {
// Nothing to update. Send a get request for current attrs instead. This
// maintains consistency with JSON bucket updates.
opts = append(opts, idempotent(true))
return c.GetBucket(ctx, bucket, conds, opts...)
}
var battrs *BucketAttrs var battrs *BucketAttrs
err := run(ctx, func(ctx context.Context) error { err := run(ctx, func(ctx context.Context) error {
res, err := c.raw.UpdateBucket(ctx, req, s.gax...) res, err := c.raw.UpdateBucket(ctx, req, s.gax...)
@ -419,6 +431,7 @@ func (c *grpcStorageClient) ListObjects(ctx context.Context, bucket string, q *Q
IncludeTrailingDelimiter: it.query.IncludeTrailingDelimiter, IncludeTrailingDelimiter: it.query.IncludeTrailingDelimiter,
MatchGlob: it.query.MatchGlob, MatchGlob: it.query.MatchGlob,
ReadMask: q.toFieldMask(), // a nil Query still results in a "*" FieldMask ReadMask: q.toFieldMask(), // a nil Query still results in a "*" FieldMask
SoftDeleted: it.query.SoftDeleted,
} }
if s.userProject != "" { if s.userProject != "" {
ctx = setUserProjectMetadata(ctx, s.userProject) ctx = setUserProjectMetadata(ctx, s.userProject)
@ -488,22 +501,25 @@ func (c *grpcStorageClient) DeleteObject(ctx context.Context, bucket, object str
return err return err
} }
func (c *grpcStorageClient) GetObject(ctx context.Context, bucket, object string, gen int64, encryptionKey []byte, conds *Conditions, opts ...storageOption) (*ObjectAttrs, error) { func (c *grpcStorageClient) GetObject(ctx context.Context, params *getObjectParams, opts ...storageOption) (*ObjectAttrs, error) {
s := callSettings(c.settings, opts...) s := callSettings(c.settings, opts...)
req := &storagepb.GetObjectRequest{ req := &storagepb.GetObjectRequest{
Bucket: bucketResourceName(globalProjectAlias, bucket), Bucket: bucketResourceName(globalProjectAlias, params.bucket),
Object: object, Object: params.object,
// ProjectionFull by default. // ProjectionFull by default.
ReadMask: &fieldmaskpb.FieldMask{Paths: []string{"*"}}, ReadMask: &fieldmaskpb.FieldMask{Paths: []string{"*"}},
} }
if err := applyCondsProto("grpcStorageClient.GetObject", gen, conds, req); err != nil { if err := applyCondsProto("grpcStorageClient.GetObject", params.gen, params.conds, req); err != nil {
return nil, err return nil, err
} }
if s.userProject != "" { if s.userProject != "" {
ctx = setUserProjectMetadata(ctx, s.userProject) ctx = setUserProjectMetadata(ctx, s.userProject)
} }
if encryptionKey != nil { if params.encryptionKey != nil {
req.CommonObjectRequestParams = toProtoCommonObjectRequestParams(encryptionKey) req.CommonObjectRequestParams = toProtoCommonObjectRequestParams(params.encryptionKey)
}
if params.softDeleted {
req.SoftDeleted = &params.softDeleted
} }
var attrs *ObjectAttrs var attrs *ObjectAttrs
@ -593,6 +609,17 @@ func (c *grpcStorageClient) UpdateObject(ctx context.Context, params *updateObje
req.UpdateMask = fieldMask req.UpdateMask = fieldMask
if len(fieldMask.Paths) < 1 {
// Nothing to update. To maintain consistency with JSON, we must still
// update the object because metageneration and other fields are
// updated even on an empty update.
// gRPC will fail if the fieldmask is empty, so instead we add an
// output-only field to the update mask. Output-only fields are (and must
// be - see AIP 161) ignored, but allow us to send an empty update because
// any mask that is valid for read (as this one is) must be valid for write.
fieldMask.Paths = append(fieldMask.Paths, "create_time")
}
var attrs *ObjectAttrs var attrs *ObjectAttrs
err := run(ctx, func(ctx context.Context) error { err := run(ctx, func(ctx context.Context) error {
res, err := c.raw.UpdateObject(ctx, req, s.gax...) res, err := c.raw.UpdateObject(ctx, req, s.gax...)
@ -606,6 +633,32 @@ func (c *grpcStorageClient) UpdateObject(ctx context.Context, params *updateObje
return attrs, err return attrs, err
} }
func (c *grpcStorageClient) RestoreObject(ctx context.Context, params *restoreObjectParams, opts ...storageOption) (*ObjectAttrs, error) {
s := callSettings(c.settings, opts...)
req := &storagepb.RestoreObjectRequest{
Bucket: bucketResourceName(globalProjectAlias, params.bucket),
Object: params.object,
CopySourceAcl: &params.copySourceACL,
}
if err := applyCondsProto("grpcStorageClient.RestoreObject", params.gen, params.conds, req); err != nil {
return nil, err
}
if s.userProject != "" {
ctx = setUserProjectMetadata(ctx, s.userProject)
}
var attrs *ObjectAttrs
err := run(ctx, func(ctx context.Context) error {
res, err := c.raw.RestoreObject(ctx, req, s.gax...)
attrs = newObjectFromProto(res)
return err
}, s.retry, s.idempotent)
if s, ok := status.FromError(err); ok && s.Code() == codes.NotFound {
return nil, ErrObjectNotExist
}
return attrs, err
}
// Default Object ACL methods. // Default Object ACL methods.
func (c *grpcStorageClient) DeleteDefaultObjectACL(ctx context.Context, bucket string, entity ACLEntity, opts ...storageOption) error { func (c *grpcStorageClient) DeleteDefaultObjectACL(ctx context.Context, bucket string, entity ACLEntity, opts ...storageOption) error {
@ -735,7 +788,7 @@ func (c *grpcStorageClient) UpdateBucketACL(ctx context.Context, bucket string,
func (c *grpcStorageClient) DeleteObjectACL(ctx context.Context, bucket, object string, entity ACLEntity, opts ...storageOption) error { func (c *grpcStorageClient) DeleteObjectACL(ctx context.Context, bucket, object string, entity ACLEntity, opts ...storageOption) error {
// There is no separate API for PATCH in gRPC. // There is no separate API for PATCH in gRPC.
// Make a GET call first to retrieve ObjectAttrs. // Make a GET call first to retrieve ObjectAttrs.
attrs, err := c.GetObject(ctx, bucket, object, defaultGen, nil, nil, opts...) attrs, err := c.GetObject(ctx, &getObjectParams{bucket, object, defaultGen, nil, nil, false}, opts...)
if err != nil { if err != nil {
return err return err
} }
@ -768,7 +821,7 @@ func (c *grpcStorageClient) DeleteObjectACL(ctx context.Context, bucket, object
// ListObjectACLs retrieves object ACL entries. By default, it operates on the latest generation of this object. // ListObjectACLs retrieves object ACL entries. By default, it operates on the latest generation of this object.
// Selecting a specific generation of this object is not currently supported by the client. // Selecting a specific generation of this object is not currently supported by the client.
func (c *grpcStorageClient) ListObjectACLs(ctx context.Context, bucket, object string, opts ...storageOption) ([]ACLRule, error) { func (c *grpcStorageClient) ListObjectACLs(ctx context.Context, bucket, object string, opts ...storageOption) ([]ACLRule, error) {
o, err := c.GetObject(ctx, bucket, object, defaultGen, nil, nil, opts...) o, err := c.GetObject(ctx, &getObjectParams{bucket, object, defaultGen, nil, nil, false}, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -778,7 +831,7 @@ func (c *grpcStorageClient) ListObjectACLs(ctx context.Context, bucket, object s
func (c *grpcStorageClient) UpdateObjectACL(ctx context.Context, bucket, object string, entity ACLEntity, role ACLRole, opts ...storageOption) error { func (c *grpcStorageClient) UpdateObjectACL(ctx context.Context, bucket, object string, entity ACLEntity, role ACLRole, opts ...storageOption) error {
// There is no separate API for PATCH in gRPC. // There is no separate API for PATCH in gRPC.
// Make a GET call first to retrieve ObjectAttrs. // Make a GET call first to retrieve ObjectAttrs.
attrs, err := c.GetObject(ctx, bucket, object, defaultGen, nil, nil, opts...) attrs, err := c.GetObject(ctx, &getObjectParams{bucket, object, defaultGen, nil, nil, false}, opts...)
if err != nil { if err != nil {
return err return err
} }

View File

@ -107,12 +107,12 @@ func newHTTPStorageClient(ctx context.Context, opts ...storageOption) (storageCl
// Append the emulator host as default endpoint for the user // Append the emulator host as default endpoint for the user
o = append([]option.ClientOption{option.WithoutAuthentication()}, o...) o = append([]option.ClientOption{option.WithoutAuthentication()}, o...)
o = append(o, internaloption.WithDefaultEndpoint(endpoint)) o = append(o, internaloption.WithDefaultEndpointTemplate(endpoint))
o = append(o, internaloption.WithDefaultMTLSEndpoint(endpoint)) o = append(o, internaloption.WithDefaultMTLSEndpoint(endpoint))
} }
s.clientOption = o s.clientOption = o
// htransport selects the correct endpoint among WithEndpoint (user override), WithDefaultEndpoint, and WithDefaultMTLSEndpoint. // htransport selects the correct endpoint among WithEndpoint (user override), WithDefaultEndpointTemplate, and WithDefaultMTLSEndpoint.
hc, ep, err := htransport.NewClient(ctx, s.clientOption...) hc, ep, err := htransport.NewClient(ctx, s.clientOption...)
if err != nil { if err != nil {
return nil, fmt.Errorf("dialing: %w", err) return nil, fmt.Errorf("dialing: %w", err)
@ -337,6 +337,9 @@ func (c *httpStorageClient) ListObjects(ctx context.Context, bucket string, q *Q
} }
fetch := func(pageSize int, pageToken string) (string, error) { fetch := func(pageSize int, pageToken string) (string, error) {
req := c.raw.Objects.List(bucket) req := c.raw.Objects.List(bucket)
if it.query.SoftDeleted {
req.SoftDeleted(it.query.SoftDeleted)
}
setClientHeader(req.Header()) setClientHeader(req.Header())
projection := it.query.Projection projection := it.query.Projection
if projection == ProjectionDefault { if projection == ProjectionDefault {
@ -409,18 +412,22 @@ func (c *httpStorageClient) DeleteObject(ctx context.Context, bucket, object str
return err return err
} }
func (c *httpStorageClient) GetObject(ctx context.Context, bucket, object string, gen int64, encryptionKey []byte, conds *Conditions, opts ...storageOption) (*ObjectAttrs, error) { func (c *httpStorageClient) GetObject(ctx context.Context, params *getObjectParams, opts ...storageOption) (*ObjectAttrs, error) {
s := callSettings(c.settings, opts...) s := callSettings(c.settings, opts...)
req := c.raw.Objects.Get(bucket, object).Projection("full").Context(ctx) req := c.raw.Objects.Get(params.bucket, params.object).Projection("full").Context(ctx)
if err := applyConds("Attrs", gen, conds, req); err != nil { if err := applyConds("Attrs", params.gen, params.conds, req); err != nil {
return nil, err return nil, err
} }
if s.userProject != "" { if s.userProject != "" {
req.UserProject(s.userProject) req.UserProject(s.userProject)
} }
if err := setEncryptionHeaders(req.Header(), encryptionKey, false); err != nil { if err := setEncryptionHeaders(req.Header(), params.encryptionKey, false); err != nil {
return nil, err return nil, err
} }
if params.softDeleted {
req.SoftDeleted(params.softDeleted)
}
var obj *raw.Object var obj *raw.Object
var err error var err error
err = run(ctx, func(ctx context.Context) error { err = run(ctx, func(ctx context.Context) error {
@ -547,6 +554,33 @@ func (c *httpStorageClient) UpdateObject(ctx context.Context, params *updateObje
return newObject(obj), nil return newObject(obj), nil
} }
func (c *httpStorageClient) RestoreObject(ctx context.Context, params *restoreObjectParams, opts ...storageOption) (*ObjectAttrs, error) {
s := callSettings(c.settings, opts...)
req := c.raw.Objects.Restore(params.bucket, params.object, params.gen).Context(ctx)
// Do not set the generation here since it's not an optional condition; it gets set above.
if err := applyConds("RestoreObject", defaultGen, params.conds, req); err != nil {
return nil, err
}
if s.userProject != "" {
req.UserProject(s.userProject)
}
if params.copySourceACL {
req.CopySourceAcl(params.copySourceACL)
}
if err := setEncryptionHeaders(req.Header(), params.encryptionKey, false); err != nil {
return nil, err
}
var obj *raw.Object
var err error
err = run(ctx, func(ctx context.Context) error { obj, err = req.Context(ctx).Do(); return err }, s.retry, s.idempotent)
var e *googleapi.Error
if ok := errors.As(err, &e); ok && e.Code == http.StatusNotFound {
return nil, ErrObjectNotExist
}
return newObject(obj), err
}
// Default Object ACL methods. // Default Object ACL methods.
func (c *httpStorageClient) DeleteDefaultObjectACL(ctx context.Context, bucket string, entity ACLEntity, opts ...storageOption) error { func (c *httpStorageClient) DeleteDefaultObjectACL(ctx context.Context, bucket string, entity ACLEntity, opts ...storageOption) error {

View File

@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.32.0 // protoc-gen-go v1.33.0
// protoc v4.25.2 // protoc v4.25.3
// source: google/storage/v2/storage.proto // source: google/storage/v2/storage.proto
package storagepb package storagepb

View File

@ -15,4 +15,4 @@
package internal package internal
// Version is the current tagged release of the library. // Version is the current tagged release of the library.
const Version = "1.40.0" const Version = "1.41.0"

View File

@ -70,8 +70,8 @@ func run(ctx context.Context, call func(ctx context.Context) error, retry *retry
return internal.Retry(ctx, bo, func() (stop bool, err error) { return internal.Retry(ctx, bo, func() (stop bool, err error) {
ctxWithHeaders := setInvocationHeaders(ctx, invocationID, attempts) ctxWithHeaders := setInvocationHeaders(ctx, invocationID, attempts)
err = call(ctxWithHeaders) err = call(ctxWithHeaders)
if retry.maxAttempts != nil && attempts >= *retry.maxAttempts { if err != nil && retry.maxAttempts != nil && attempts >= *retry.maxAttempts {
return true, err return true, fmt.Errorf("storage: retry failed after %v attempts; last error: %w", *retry.maxAttempts, err)
} }
attempts++ attempts++
return !errorFunc(err), err return !errorFunc(err), err
@ -105,18 +105,16 @@ func ShouldRetry(err error) bool {
if errors.Is(err, io.ErrUnexpectedEOF) { if errors.Is(err, io.ErrUnexpectedEOF) {
return true return true
} }
if errors.Is(err, net.ErrClosed) {
return true
}
switch e := err.(type) { switch e := err.(type) {
case *net.OpError:
if strings.Contains(e.Error(), "use of closed network connection") {
// TODO: check against net.ErrClosed (go 1.16+) instead of string
return true
}
case *googleapi.Error: case *googleapi.Error:
// Retry on 408, 429, and 5xx, according to // Retry on 408, 429, and 5xx, according to
// https://cloud.google.com/storage/docs/exponential-backoff. // https://cloud.google.com/storage/docs/exponential-backoff.
return e.Code == 408 || e.Code == 429 || (e.Code >= 500 && e.Code < 600) return e.Code == 408 || e.Code == 429 || (e.Code >= 500 && e.Code < 600)
case *url.Error: case *net.OpError, *url.Error:
// Retry socket-level errors ECONNREFUSED and ECONNRESET (from syscall). // Retry socket-level errors ECONNREFUSED and ECONNRESET (from syscall).
// Unfortunately the error type is unexported, so we resort to string // Unfortunately the error type is unexported, so we resort to string
// matching. // matching.

View File

@ -116,7 +116,7 @@ func toProtoNotification(n *Notification) *storagepb.NotificationConfig {
} }
} }
var topicRE = regexp.MustCompile("^//pubsub.googleapis.com/projects/([^/]+)/topics/([^/]+)") var topicRE = regexp.MustCompile(`^//pubsub\.googleapis\.com/projects/([^/]+)/topics/([^/]+)`)
// parseNotificationTopic extracts the project and topic IDs from from the full // parseNotificationTopic extracts the project and topic IDs from from the full
// resource name returned by the service. If the name is malformed, it returns // resource name returned by the service. If the name is malformed, it returns

View File

@ -180,12 +180,12 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error
opts = append([]option.ClientOption{ opts = append([]option.ClientOption{
option.WithoutAuthentication(), option.WithoutAuthentication(),
internaloption.SkipDialSettingsValidation(), internaloption.SkipDialSettingsValidation(),
internaloption.WithDefaultEndpoint(endpoint), internaloption.WithDefaultEndpointTemplate(endpoint),
internaloption.WithDefaultMTLSEndpoint(endpoint), internaloption.WithDefaultMTLSEndpoint(endpoint),
}, opts...) }, opts...)
} }
// htransport selects the correct endpoint among WithEndpoint (user override), WithDefaultEndpoint, and WithDefaultMTLSEndpoint. // htransport selects the correct endpoint among WithEndpoint (user override), WithDefaultEndpointTemplate, and WithDefaultMTLSEndpoint.
hc, ep, err := htransport.NewClient(ctx, opts...) hc, ep, err := htransport.NewClient(ctx, opts...)
if err != nil { if err != nil {
return nil, fmt.Errorf("dialing: %w", err) return nil, fmt.Errorf("dialing: %w", err)
@ -232,7 +232,6 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error
// You may configure the client by passing in options from the [google.golang.org/api/option] // You may configure the client by passing in options from the [google.golang.org/api/option]
// package. // package.
func NewGRPCClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { func NewGRPCClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) {
opts = append(defaultGRPCOptions(), opts...)
tc, err := newGRPCStorageClient(ctx, withClientOptions(opts...)) tc, err := newGRPCStorageClient(ctx, withClientOptions(opts...))
if err != nil { if err != nil {
return nil, err return nil, err
@ -898,6 +897,7 @@ type ObjectHandle struct {
readCompressed bool // Accept-Encoding: gzip readCompressed bool // Accept-Encoding: gzip
retry *retryConfig retry *retryConfig
overrideRetention *bool overrideRetention *bool
softDeleted bool
} }
// ACL provides access to the object's access control list. // ACL provides access to the object's access control list.
@ -952,7 +952,7 @@ func (o *ObjectHandle) Attrs(ctx context.Context) (attrs *ObjectAttrs, err error
return nil, err return nil, err
} }
opts := makeStorageOpts(true, o.retry, o.userProject) opts := makeStorageOpts(true, o.retry, o.userProject)
return o.c.tc.GetObject(ctx, o.bucket, o.object, o.gen, o.encryptionKey, o.conds, opts...) return o.c.tc.GetObject(ctx, &getObjectParams{o.bucket, o.object, o.gen, o.encryptionKey, o.conds, o.softDeleted}, opts...)
} }
// Update updates an object with the provided attributes. See // Update updates an object with the provided attributes. See
@ -1057,6 +1057,50 @@ func (o *ObjectHandle) OverrideUnlockedRetention(override bool) *ObjectHandle {
return &o2 return &o2
} }
// SoftDeleted returns an object handle that can be used to get an object that
// has been soft deleted. To get a soft deleted object, the generation must be
// set on the object using ObjectHandle.Generation.
// Note that an error will be returned if a live object is queried using this.
func (o *ObjectHandle) SoftDeleted() *ObjectHandle {
o2 := *o
o2.softDeleted = true
return &o2
}
// RestoreOptions allows you to set options when restoring an object.
type RestoreOptions struct {
/// CopySourceACL indicates whether the restored object should copy the
// access controls of the source object. Only valid for buckets with
// fine-grained access. If uniform bucket-level access is enabled, setting
// CopySourceACL will cause an error.
CopySourceACL bool
}
// Restore will restore a soft-deleted object to a live object.
// Note that you must specify a generation to use this method.
func (o *ObjectHandle) Restore(ctx context.Context, opts *RestoreOptions) (*ObjectAttrs, error) {
if err := o.validate(); err != nil {
return nil, err
}
// Since the generation is required by restore calls, we set the default to
// 0 instead of a negative value, which returns a more descriptive error.
gen := o.gen
if o.gen == defaultGen {
gen = 0
}
// Restore is always idempotent because Generation is a required param.
sOpts := makeStorageOpts(true, o.retry, o.userProject)
return o.c.tc.RestoreObject(ctx, &restoreObjectParams{
bucket: o.bucket,
object: o.object,
gen: gen,
conds: o.conds,
copySourceACL: opts.CopySourceACL,
}, sOpts...)
}
// NewWriter returns a storage Writer that writes to the GCS object // NewWriter returns a storage Writer that writes to the GCS object
// associated with this ObjectHandle. // associated with this ObjectHandle.
// //
@ -1390,6 +1434,21 @@ type ObjectAttrs struct {
// Retention contains the retention configuration for this object. // Retention contains the retention configuration for this object.
// ObjectRetention cannot be configured or reported through the gRPC API. // ObjectRetention cannot be configured or reported through the gRPC API.
Retention *ObjectRetention Retention *ObjectRetention
// SoftDeleteTime is the time when the object became soft-deleted.
// Soft-deleted objects are only accessible on an object handle returned by
// ObjectHandle.SoftDeleted; if ObjectHandle.SoftDeleted has not been set,
// ObjectHandle.Attrs will return ErrObjectNotExist if the object is soft-deleted.
// This field is read-only.
SoftDeleteTime time.Time
// HardDeleteTime is the time when the object will be permanently deleted.
// Only set when an object becomes soft-deleted with a soft delete policy.
// Soft-deleted objects are only accessible on an object handle returned by
// ObjectHandle.SoftDeleted; if ObjectHandle.SoftDeleted has not been set,
// ObjectHandle.Attrs will return ErrObjectNotExist if the object is soft-deleted.
// This field is read-only.
HardDeleteTime time.Time
} }
// ObjectRetention contains the retention configuration for this object. // ObjectRetention contains the retention configuration for this object.
@ -1494,6 +1553,8 @@ func newObject(o *raw.Object) *ObjectAttrs {
CustomTime: convertTime(o.CustomTime), CustomTime: convertTime(o.CustomTime),
ComponentCount: o.ComponentCount, ComponentCount: o.ComponentCount,
Retention: toObjectRetention(o.Retention), Retention: toObjectRetention(o.Retention),
SoftDeleteTime: convertTime(o.SoftDeleteTime),
HardDeleteTime: convertTime(o.HardDeleteTime),
} }
} }
@ -1529,6 +1590,8 @@ func newObjectFromProto(o *storagepb.Object) *ObjectAttrs {
Updated: convertProtoTime(o.GetUpdateTime()), Updated: convertProtoTime(o.GetUpdateTime()),
CustomTime: convertProtoTime(o.GetCustomTime()), CustomTime: convertProtoTime(o.GetCustomTime()),
ComponentCount: int64(o.ComponentCount), ComponentCount: int64(o.ComponentCount),
SoftDeleteTime: convertProtoTime(o.GetSoftDeleteTime()),
HardDeleteTime: convertProtoTime(o.GetHardDeleteTime()),
} }
} }
@ -1637,6 +1700,11 @@ type Query struct {
// prefixes returned by the query. Only applicable if Delimiter is set to /. // prefixes returned by the query. Only applicable if Delimiter is set to /.
// IncludeFoldersAsPrefixes is not yet implemented in the gRPC API. // IncludeFoldersAsPrefixes is not yet implemented in the gRPC API.
IncludeFoldersAsPrefixes bool IncludeFoldersAsPrefixes bool
// SoftDeleted indicates whether to list soft-deleted objects.
// If true, only objects that have been soft-deleted will be listed.
// By default, soft-deleted objects are not listed.
SoftDeleted bool
} }
// attrToFieldMap maps the field names of ObjectAttrs to the underlying field // attrToFieldMap maps the field names of ObjectAttrs to the underlying field
@ -1672,6 +1740,8 @@ var attrToFieldMap = map[string]string{
"CustomTime": "customTime", "CustomTime": "customTime",
"ComponentCount": "componentCount", "ComponentCount": "componentCount",
"Retention": "retention", "Retention": "retention",
"HardDeleteTime": "hardDeleteTime",
"SoftDeleteTime": "softDeleteTime",
} }
// attrToProtoFieldMap maps the field names of ObjectAttrs to the underlying field // attrToProtoFieldMap maps the field names of ObjectAttrs to the underlying field
@ -1704,6 +1774,8 @@ var attrToProtoFieldMap = map[string]string{
"CustomerKeySHA256": "customer_encryption", "CustomerKeySHA256": "customer_encryption",
"CustomTime": "custom_time", "CustomTime": "custom_time",
"ComponentCount": "component_count", "ComponentCount": "component_count",
"HardDeleteTime": "hard_delete_time",
"SoftDeleteTime": "soft_delete_time",
// MediaLink was explicitly excluded from the proto as it is an HTTP-ism. // MediaLink was explicitly excluded from the proto as it is an HTTP-ism.
// "MediaLink": "mediaLink", // "MediaLink": "mediaLink",
// TODO: add object retention - b/308194853 // TODO: add object retention - b/308194853

8
vendor/modules.txt vendored
View File

@ -26,11 +26,11 @@ cloud.google.com/go/auth/oauth2adapt
# cloud.google.com/go/compute/metadata v0.3.0 # cloud.google.com/go/compute/metadata v0.3.0
## explicit; go 1.19 ## explicit; go 1.19
cloud.google.com/go/compute/metadata cloud.google.com/go/compute/metadata
# cloud.google.com/go/iam v1.1.7 # cloud.google.com/go/iam v1.1.8
## explicit; go 1.19 ## explicit; go 1.19
cloud.google.com/go/iam cloud.google.com/go/iam
cloud.google.com/go/iam/apiv1/iampb cloud.google.com/go/iam/apiv1/iampb
# cloud.google.com/go/storage v1.40.0 # cloud.google.com/go/storage v1.41.0
## explicit; go 1.19 ## explicit; go 1.19
cloud.google.com/go/storage cloud.google.com/go/storage
cloud.google.com/go/storage/internal cloud.google.com/go/storage/internal
@ -1199,12 +1199,12 @@ google.golang.org/api/transport
google.golang.org/api/transport/grpc google.golang.org/api/transport/grpc
google.golang.org/api/transport/http google.golang.org/api/transport/http
google.golang.org/api/transport/http/internal/propagation google.golang.org/api/transport/http/internal/propagation
# google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de # google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda
## explicit; go 1.19 ## explicit; go 1.19
google.golang.org/genproto/googleapis/type/date google.golang.org/genproto/googleapis/type/date
google.golang.org/genproto/googleapis/type/expr google.golang.org/genproto/googleapis/type/expr
google.golang.org/genproto/protobuf/field_mask google.golang.org/genproto/protobuf/field_mask
# google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be # google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae
## explicit; go 1.19 ## explicit; go 1.19
google.golang.org/genproto/googleapis/api google.golang.org/genproto/googleapis/api
google.golang.org/genproto/googleapis/api/annotations google.golang.org/genproto/googleapis/api/annotations