vendor: make vendor-update

This commit is contained in:
Aliaksandr Valialkin 2023-07-18 16:13:52 -07:00
parent 163572ea97
commit bf17424245
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
220 changed files with 5366 additions and 721 deletions

52
go.mod
View file

@ -4,8 +4,8 @@ go 1.19
require (
cloud.google.com/go/storage v1.31.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0
github.com/VictoriaMetrics/fastcache v1.12.1
// Do not use the original github.com/valyala/fasthttp because of issues
@ -13,10 +13,10 @@ require (
github.com/VictoriaMetrics/fasthttp v1.2.0
github.com/VictoriaMetrics/metrics v1.24.0
github.com/VictoriaMetrics/metricsql v0.59.1
github.com/aws/aws-sdk-go-v2 v1.18.1
github.com/aws/aws-sdk-go-v2/config v1.18.27
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.71
github.com/aws/aws-sdk-go-v2/service/s3 v1.36.0
github.com/aws/aws-sdk-go-v2 v1.19.0
github.com/aws/aws-sdk-go-v2/config v1.18.28
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.72
github.com/aws/aws-sdk-go-v2/service/s3 v1.37.0
github.com/cespare/xxhash/v2 v2.2.0
github.com/cheggaaa/pb/v3 v3.1.4
github.com/gogo/protobuf v1.3.2
@ -35,15 +35,15 @@ require (
golang.org/x/net v0.12.0
golang.org/x/oauth2 v0.10.0
golang.org/x/sys v0.10.0
google.golang.org/api v0.130.0
google.golang.org/api v0.132.0
gopkg.in/yaml.v2 v2.4.0
)
require github.com/bmatcuk/doublestar/v4 v4.6.0
require (
cloud.google.com/go v0.110.4 // indirect
cloud.google.com/go/compute v1.20.1 // indirect
cloud.google.com/go v0.110.6 // indirect
cloud.google.com/go/compute v1.22.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 // indirect
@ -51,21 +51,21 @@ require (
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/aws/aws-sdk-go v1.44.297 // indirect
github.com/aws/aws-sdk-go v1.44.302 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.26 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.27 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.36 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.27 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.30 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.29 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.12.13 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.13 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.19.3 // indirect
github.com/aws/smithy-go v1.13.5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
@ -115,15 +115,15 @@ require (
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/goleak v1.2.1 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130 // indirect
google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 // indirect
google.golang.org/grpc v1.56.2 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

105
go.sum
View file

@ -13,16 +13,16 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk=
cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q=
cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
cloud.google.com/go/compute v1.22.0 h1:cB8R6FtUtT1TYGl5R3xuxnW6OUIc/DrT2aiR16TTG7Y=
cloud.google.com/go/compute v1.22.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
@ -42,14 +42,15 @@ cloud.google.com/go/storage v1.31.0 h1:+S3LjjEN2zZ+L5hOwj4+1OkGCsLVe0NzpXKQ1pSdT
cloud.google.com/go/storage v1.31.0/go.mod h1:81ams1PrhW16L4kF7qg+4mTq7SRs5HsbDTM0bWvrwJ0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1 h1:SEy2xmstIphdPwNBUi7uhvjyjhVKISfwjfOJmuy7kg4=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 h1:8q4SaHjFsClSvuVne0ID/5Ka8u3fcIHyqkLjcFpNRHQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 h1:u/LLAOFgsMv7HmNL4Qufg58y+qElGOt5qv0z1mURkRY=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0/go.mod h1:2e8rMJtl2+2j+HXbTBwnyGpm5Nou7KhvSfxOq8JpTag=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0 h1:Ma67P/GGprNwsslzEH6+Kb8nybI8jpDTm4Wmzu2ReK8=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0 h1:nVocQV40OQne5613EeLayJiRAJuKlBGy+m22qWG+WRg=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0/go.mod h1:7QJP7dr2wznCMeqIrhMgWGf7XpAQnVrJqDm9nvV3Cu4=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw=
github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8=
@ -87,44 +88,44 @@ github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.44.297 h1:uL4EV0gQxotQVYegIoBqK079328MOJqgG95daFYSkAM=
github.com/aws/aws-sdk-go v1.44.297/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v1.18.1 h1:+tefE750oAb7ZQGzla6bLkOwfcQCEtC5y2RqoqCeqKo=
github.com/aws/aws-sdk-go-v2 v1.18.1/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
github.com/aws/aws-sdk-go v1.44.302 h1:ST3ko6GrJKn3Xi+nAvxjG3uk/V1pW8KC52WLeIxqqNk=
github.com/aws/aws-sdk-go v1.44.302/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v1.19.0 h1:klAT+y3pGFBU/qVf1uzwttpBbiuozJYWzNLHioyDJ+k=
github.com/aws/aws-sdk-go-v2 v1.19.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno=
github.com/aws/aws-sdk-go-v2/config v1.18.27 h1:Az9uLwmssTE6OGTpsFqOnaGpLnKDqNYOJzWuC6UAYzA=
github.com/aws/aws-sdk-go-v2/config v1.18.27/go.mod h1:0My+YgmkGxeqjXZb5BYme5pc4drjTnM+x1GJ3zv42Nw=
github.com/aws/aws-sdk-go-v2/credentials v1.13.26 h1:qmU+yhKmOCyujmuPY7tf5MxR/RKyZrOPO3V4DobiTUk=
github.com/aws/aws-sdk-go-v2/credentials v1.13.26/go.mod h1:GoXt2YC8jHUBbA4jr+W3JiemnIbkXOfxSXcisUsZ3os=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 h1:LxK/bitrAr4lnh9LnIS6i7zWbCOdMsfzKFBI6LUCS0I=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4/go.mod h1:E1hLXN/BL2e6YizK1zFlYd8vsfi2GTjbjBazinMmeaM=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.71 h1:SAB1UAVaf6nGCu3zyIrV+VWsendXrms1GqtW4zBotKA=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.71/go.mod h1:ZNo5H4PR3/fwsXYqb+Ld5YAfvHcYCbltaTTtSay4l2o=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 h1:A5UqQEmPaCFpedKouS4v+dHCTUo2sKqhoKO9U5kxyWo=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34/go.mod h1:wZpTEecJe0Btj3IYnDx/VlUzor9wm3fJHyvLpQF0VwY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 h1:srIVS45eQuewqz6fKKu6ZGXaq6FuFg5NzgQBAM6g8Y4=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28/go.mod h1:7VRpKQQedkfIEXb4k52I7swUnZP0wohVajJMRn3vsUw=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 h1:LWA+3kDM8ly001vJ1X1waCuLJdtTl48gwkPKWy9sosI=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35/go.mod h1:0Eg1YjxE0Bhn56lx+SHJwCzhW+2JGtizsrx+lCqrfm0=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26 h1:wscW+pnn3J1OYnanMnza5ZVYXLX4cKk5rAvUAl4Qu+c=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26/go.mod h1:MtYiox5gvyB+OyP0Mr0Sm/yzbEAIPL9eijj/ouHAPw0=
github.com/aws/aws-sdk-go-v2/config v1.18.28 h1:TINEaKyh1Td64tqFvn09iYpKiWjmHYrG1fa91q2gnqw=
github.com/aws/aws-sdk-go-v2/config v1.18.28/go.mod h1:nIL+4/8JdAuNHEjn/gPEXqtnS02Q3NXB/9Z7o5xE4+A=
github.com/aws/aws-sdk-go-v2/credentials v1.13.27 h1:dz0yr/yR1jweAnsCx+BmjerUILVPQ6FS5AwF/OyG1kA=
github.com/aws/aws-sdk-go-v2/credentials v1.13.27/go.mod h1:syOqAek45ZXZp29HlnRS/BNgMIW6uiRmeuQsz4Qh2UE=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.5 h1:kP3Me6Fy3vdi+9uHd7YLr6ewPxRL+PU6y15urfTaamU=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.5/go.mod h1:Gj7tm95r+QsDoN2Fhuz/3npQvcZbkEf5mL70n3Xfluc=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.72 h1:m0MmP89v1B0t3b8W8rtATU76KNsodak69QtiokHyEvo=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.72/go.mod h1:ylOTxIuoTL+XjH46Omv2iPjHdeGUk3SQ4hxYho4EHMA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35 h1:hMUCiE3Zi5AHrRNGf5j985u0WyqI6r2NULhUfo0N/No=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35/go.mod h1:ipR5PvpSPqIqL5Mi82BxLnfMkHVbmco8kUwO2xrCi0M=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29 h1:yOpYx+FTBdpk/g+sBU6Cb1H0U/TLEcYYp66mYqsPpcc=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29/go.mod h1:M/eUABlDbw2uVrdAn+UsI6M727qp2fxkp8K0ejcBDUY=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.36 h1:8r5m1BoAWkn0TDC34lUculryf7nUF25EgIMdjvGCkgo=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.36/go.mod h1:Rmw2M1hMVTwiUhjwMoIBFWFJMhvJbct06sSidxInkhY=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.27 h1:cZG7psLfqpkB6H+fIrgUDWmlzM474St1LP0jcz272yI=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.27/go.mod h1:ZdjYvJpDlefgh8/hWelJhqgqJeodxu4SmbVsSdBlL7E=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC6Zh2ojtV2LoC0MNwHWc6qXv/j2vrQtlftkdA=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29 h1:zZSLP3v3riMOP14H7b4XP0uyfREDQOYv2cqIrvTXDNQ=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29/go.mod h1:z7EjRjVwZ6pWcWdI2H64dKttvzaP99jRIj5hphW0M5U=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 h1:bkRyG4a929RCnpVSTvLM2j/T4ls015ZhhYApbmYs15s=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28/go.mod h1:jj7znCIg05jXlaGBlFMGP8+7UN3VtCkRBG2spnmRQkU=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 h1:dBL3StFxHtpBzJJ/mNEsjXVgfO+7jR0dAIEwLqMapEA=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3/go.mod h1:f1QyiAsvIv4B49DmCqrhlXqyaR+0IxMmyX+1P+AnzOM=
github.com/aws/aws-sdk-go-v2/service/s3 v1.36.0 h1:lEmQ1XSD9qLk+NZXbgvLJI/IiTz7OIR2TYUTFH25EI4=
github.com/aws/aws-sdk-go-v2/service/s3 v1.36.0/go.mod h1:aVbf0sko/TsLWHx30c/uVu7c62+0EAJ3vbxaJga0xCw=
github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 h1:nneMBM2p79PGWBQovYO/6Xnc2ryRMw3InnDJq1FHkSY=
github.com/aws/aws-sdk-go-v2/service/sso v1.12.12/go.mod h1:HuCOxYsF21eKrerARYO6HapNeh9GBNq7fius2AcwodY=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 h1:2qTR7IFk7/0IN/adSFhYu9Xthr0zVFTgBrmPldILn80=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12/go.mod h1:E4VrHCPzmVB/KFXtqBGKb3c8zpbNBgKe3fisDNLAW5w=
github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 h1:XFJ2Z6sNUUcAz9poj+245DMkrHE4h2j5I9/xD50RHfE=
github.com/aws/aws-sdk-go-v2/service/sts v1.19.2/go.mod h1:dp0yLPsLBOi++WTxzCjA/oZqi6NPIhoR+uF7GeMU9eg=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.30 h1:Bje8Xkh2OWpjBdNfXLrnn8eZg569dUQmhgtydxAYyP0=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.30/go.mod h1:qQtIBl5OVMfmeQkz8HaVyh5DzFmmFXyvK27UgIgOr4c=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.29 h1:IiDolu/eLmuB18DRZibj77n1hHQT7z12jnGO7Ze3pLc=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.29/go.mod h1:fDbkK4o7fpPXWn8YAPmTieAMuB9mk/VgvW64uaUqxd4=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.4 h1:hx4WksB0NRQ9utR+2c3gEGzl6uKj3eM6PMQ6tN3lgXs=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.4/go.mod h1:JniVpqvw90sVjNqanGLufrVapWySL28fhBlYgl96Q/w=
github.com/aws/aws-sdk-go-v2/service/s3 v1.37.0 h1:PalLOEGZ/4XfQxpGZFTLaoJSmPoybnqJYotaIZEf/Rg=
github.com/aws/aws-sdk-go-v2/service/s3 v1.37.0/go.mod h1:PwyKKVL0cNkC37QwLcrhyeCrAk+5bY8O2ou7USyAS2A=
github.com/aws/aws-sdk-go-v2/service/sso v1.12.13 h1:sWDv7cMITPcZ21QdreULwxOOAmE05JjEsT6fCDtDA9k=
github.com/aws/aws-sdk-go-v2/service/sso v1.12.13/go.mod h1:DfX0sWuT46KpcqbMhJ9QWtxAIP1VozkDWf8VAkByjYY=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.13 h1:BFubHS/xN5bjl818QaroN6mQdjneYQ+AOx44KNXlyH4=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.13/go.mod h1:BzqsVVFduubEmzrVtUFQQIQdFqvUItF8XUq2EnS8Wog=
github.com/aws/aws-sdk-go-v2/service/sts v1.19.3 h1:e5mnydVdCVWxP+5rPAGi2PYxC7u2OZgH1ypC114H04U=
github.com/aws/aws-sdk-go-v2/service/sts v1.19.3/go.mod h1:yVGZA1CPkmUhBdA039jXNJJG7/6t+G+EBWmFq23xqnY=
github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8=
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@ -502,8 +503,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -719,8 +720,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.130.0 h1:A50ujooa1h9iizvfzA4rrJr2B7uRmWexwbekQ2+5FPQ=
google.golang.org/api v0.130.0/go.mod h1:J/LCJMYSDFvAVREGCbrESb53n4++NMBDetSHGL5I5RY=
google.golang.org/api v0.132.0 h1:8t2/+qZ26kAOGSmOiHwVycqVaDg7q3JDILrNi/Z6rvc=
google.golang.org/api v0.132.0/go.mod h1:AeTBC6GpJnJSRJjktDcPX0QwtS8pGYZOV6MSuSCusw0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -759,12 +760,12 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8=
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y=
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU=
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130 h1:2FZP5XuJY9zQyGM5N0rtovnoXjiMUEIUMvw0m9wlpLc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:8mL13HKkDa+IuJ8yruA3ci0q+0vsUz4m//+ottjwS5o=
google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 h1:+VoAg+OKmWaommL56xmZSE2sUK8A7m6SUO7X89F2tbw=
google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753/go.mod h1:iqkVr8IRpZ53gx1dEnWlCUIEwDWqWARWrbzpasaTNYM=
google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753 h1:lCbbUxUDD+DiXx9Q6F/ttL0aAu7N2pz8XnmMm8ZW4NE=
google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 h1:XUODHrpzJEUeWmVo/jfNTLj0YyVveOo28oE6vkFbkO4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=

View file

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

View file

@ -29,6 +29,16 @@
"release_level": "preview",
"library_type": "GAPIC_AUTO"
},
"cloud.google.com/go/ai/generativelanguage/apiv1beta2": {
"api_shortname": "generativelanguage",
"distribution_name": "cloud.google.com/go/ai/generativelanguage/apiv1beta2",
"description": "Generative Language API",
"language": "go",
"client_library_type": "generated",
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/ai/latest/generativelanguage/apiv1beta2",
"release_level": "preview",
"library_type": "GAPIC_AUTO"
},
"cloud.google.com/go/aiplatform/apiv1": {
"api_shortname": "aiplatform",
"distribution_name": "cloud.google.com/go/aiplatform/apiv1",
@ -1059,26 +1069,6 @@
"release_level": "preview",
"library_type": "CORE"
},
"cloud.google.com/go/gaming/apiv1": {
"api_shortname": "gameservices",
"distribution_name": "cloud.google.com/go/gaming/apiv1",
"description": "Game Services API",
"language": "go",
"client_library_type": "generated",
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/gaming/latest/apiv1",
"release_level": "stable",
"library_type": "GAPIC_AUTO"
},
"cloud.google.com/go/gaming/apiv1beta": {
"api_shortname": "gameservices",
"distribution_name": "cloud.google.com/go/gaming/apiv1beta",
"description": "Game Services API",
"language": "go",
"client_library_type": "generated",
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/gaming/latest/apiv1beta",
"release_level": "preview",
"library_type": "GAPIC_AUTO"
},
"cloud.google.com/go/gkebackup/apiv1": {
"api_shortname": "gkebackup",
"distribution_name": "cloud.google.com/go/gkebackup/apiv1",

View file

@ -1,11 +1,50 @@
# Release History
## 1.7.0 (2023-07-12)
### Features Added
* Added method `WithClientName()` to type `azcore.Client` to support shallow cloning of a client with a new name used for tracing.
### Breaking Changes
> These changes affect only code written against beta versions v1.7.0-beta.1 or v1.7.0-beta.2
* The beta features for CAE, tracing, and fakes have been omitted for this release.
## 1.7.0-beta.2 (2023-06-06)
### Breaking Changes
> These changes affect only code written against beta version v1.7.0-beta.1
* Method `SpanFromContext()` on type `tracing.Tracer` had the `bool` return value removed.
* This includes the field `SpanFromContext` in supporting type `tracing.TracerOptions`.
* Method `AddError()` has been removed from type `tracing.Span`.
* Method `Span.End()` now requires an argument of type `*tracing.SpanEndOptions`.
## 1.6.1 (2023-06-06)
### Bugs Fixed
* Fixed an issue in `azcore.NewClient()` and `arm.NewClient()` that could cause an incorrect module name to be used in telemetry.
### Other Changes
* This version contains all bug fixes from `v1.7.0-beta.1`
## 1.7.0-beta.1 (2023-05-24)
### Features Added
* Restored CAE support for ARM clients.
* Added supporting features to enable distributed tracing.
* Added func `runtime.StartSpan()` for use by SDKs to start spans.
* Added method `WithContext()` to `runtime.Request` to support shallow cloning with a new context.
* Added field `TracingNamespace` to `runtime.PipelineOptions`.
* Added field `Tracer` to `runtime.NewPollerOptions` and `runtime.NewPollerFromResumeTokenOptions` types.
* Added field `SpanFromContext` to `tracing.TracerOptions`.
* Added methods `Enabled()`, `SetAttributes()`, and `SpanFromContext()` to `tracing.Tracer`.
* Added supporting pipeline policies to include HTTP spans when creating clients.
* Added package `fake` to support generated fakes packages in SDKs.
* The package contains public surface area exposed by fake servers and supporting APIs intended only for use by the fake server implementations.
* Added an internal fake poller implementation.
### Bugs Fixed
* Retry policy always clones the underlying `*http.Request` before invoking the next policy.
* Added some non-standard error codes to the list of error codes for unregistered resource providers.
* Fixed an issue in `azcore.NewClient()` and `arm.NewClient()` that could cause an incorrect module name to be used in telemetry.
## 1.6.0 (2023-05-04)

View file

@ -73,6 +73,10 @@ type ClientOptions = policy.ClientOptions
type Client struct {
pl runtime.Pipeline
tr tracing.Tracer
// cached on the client to support shallow copying with new values
tp tracing.Provider
modVer string
}
// NewClient creates a new Client instance with the provided values.
@ -100,7 +104,13 @@ func NewClient(clientName, moduleVersion string, plOpts runtime.PipelineOptions,
pl := runtime.NewPipeline(mod, moduleVersion, plOpts, options)
tr := options.TracingProvider.NewTracer(client, moduleVersion)
return &Client{pl: pl, tr: tr}, nil
return &Client{
pl: pl,
tr: tr,
tp: options.TracingProvider,
modVer: moduleVersion,
}, nil
}
// Pipeline returns the pipeline for this client.
@ -112,3 +122,11 @@ func (c *Client) Pipeline() runtime.Pipeline {
func (c *Client) Tracer() tracing.Tracer {
return c.tr
}
// WithClientName returns a shallow copy of the Client with its tracing client name changed to clientName.
// Note that the values for module name and version will be preserved from the source Client.
// - clientName - the fully qualified name of the client ("package.Client"); this is used by the tracing provider when creating spans
func (c *Client) WithClientName(clientName string) *Client {
tr := c.tp.NewTracer(clientName, c.modVer)
return &Client{pl: c.pl, tr: tr, tp: c.tp, modVer: c.modVer}
}

View file

@ -32,5 +32,5 @@ const (
Module = "azcore"
// Version is the semantic version (see http://semver.org) of this module.
Version = "v1.6.1"
Version = "v1.7.0"
)

View file

@ -1,5 +1,44 @@
# Release History
## 1.1.0 (2023-07-13)
### Features Added
* Added [Blob Batch API](https://learn.microsoft.com/rest/api/storageservices/blob-batch).
* Added support for bearer challenge for identity based managed disks.
* Added support for GetAccountInfo to container and blob level clients.
* Added [UploadBlobFromURL API](https://learn.microsoft.com/rest/api/storageservices/put-blob-from-url).
* Added support for CopySourceAuthorization to appendblob.AppendBlockFromURL
* Added support for tag permission in Container SAS.
### Bugs Fixed
* Fixed time formatting for the conditional request headers. Fixes [#20475](https://github.com/Azure/azure-sdk-for-go/issues/20475).
* Fixed an issue where passing a blob tags map of length 0 would result in the x-ms-tags header to be sent to the service with an empty string as value.
* Fixed block size and number of blocks calculation in `UploadBuffer` and `UploadFile`. Fixes [#20735](https://github.com/Azure/azure-sdk-for-go/issues/20735).
### Other Changes
* Add `dragonfly` to the list of build constraints for `blockblob`.
* Updating version of azcore to 1.6.0 and azidentity to 1.3.0
## 1.1.0-beta.1 (2023-05-09)
### Features Added
* Added [Blob Batch API](https://learn.microsoft.com/rest/api/storageservices/blob-batch).
* Added support for bearer challenge for identity based managed disks.
* Added support for GetAccountInfo to container and blob level clients.
* Added [UploadBlobFromURL API](https://learn.microsoft.com/rest/api/storageservices/put-blob-from-url).
* Added support for CopySourceAuthorization to appendblob.AppendBlockFromURL
* Added support for tag permission in Container SAS.
### Bugs Fixed
* Fixed time formatting for the conditional request headers. Fixes [#20475](https://github.com/Azure/azure-sdk-for-go/issues/20475).
* Fixed an issue where passing a blob tags map of length 0 would result in the x-ms-tags header to be sent to the service with an empty string as value.
## 1.0.0 (2023-02-07)
### Features Added

View file

@ -1,47 +1,51 @@
# Azure Blob Storage SDK for Go
# Azure Blob Storage module for Go
> Server Version: 2020-10-02
> Service Version: 2020-10-02
Azure Blob storage is Microsoft's object storage solution for the cloud. Blob
storage is optimized for storing massive amounts of unstructured data.
Unstructured data is data that does not adhere to a particular data model or
definition, such as text or binary data.
Azure Blob Storage is Microsoft's object storage solution for the cloud. Blob
Storage is optimized for storing massive amounts of unstructured data - data that does not adhere to a particular data model or
definition, such as text or binary data. For more information, see [Introduction to Azure Blob Storage](https://learn.microsoft.com/azure/storage/blobs/storage-blobs-introduction).
[Source code][source] | [API reference documentation][docs] | [REST API documentation][rest_docs] | [Product documentation][product_docs]
Use the Azure Blob Storage client module `github.com/Azure/azure-sdk-for-go/sdk/storage/azblob` to:
* Authenticate clients with Azure Blob Storage
* Manipulate containers and blobs in an Azure storage account
Key links:
[Source code][source] | [API reference documentation][docs] | [REST API documentation][rest_docs] | [Product documentation][product_docs] | [Samples][go_samples]
## Getting started
### Install the package
Install the Azure Blob Storage SDK for Go with [go get][goget]:
```Powershell
go get github.com/Azure/azure-sdk-for-go/sdk/storage/azblob
```
If you're going to authenticate with Azure Active Directory (recommended), install the [azidentity][azidentity] module.
```Powershell
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity
```
### Prerequisites
A supported [Go][godevdl] version (the Azure SDK supports the two most recent Go releases).
You need an [Azure subscription][azure_sub] and a
[Storage Account][storage_account_docs] to use this package.
To create a new Storage Account, you can use the [Azure Portal][storage_account_create_portal],
- Go, version 1.18 or higher - [Install Go](https://go.dev/doc/install)
- Azure subscription - [Create a free account](https://azure.microsoft.com/free/)
- Azure storage account - To create a storage account, use tools including the [Azure portal][storage_account_create_portal],
[Azure PowerShell][storage_account_create_ps], or the [Azure CLI][storage_account_create_cli].
Here's an example using the Azure CLI:
```Powershell
```bash
az storage account create --name MyStorageAccount --resource-group MyResourceGroup --location westus --sku Standard_LRS
```
### Install the package
Install the Azure Blob Storage client module for Go with [go get][goget]:
```bash
go get github.com/Azure/azure-sdk-for-go/sdk/storage/azblob
```
If you plan to authenticate with Azure Active Directory (recommended), also install the [azidentity][azidentity] module.
```bash
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity
```
### Authenticate the client
In order to interact with the Azure Blob Storage service, you'll need to create an instance of the `azblob.Client` type. The [azidentity][azidentity] module makes it easy to add Azure Active Directory support for authenticating Azure SDK clients with their corresponding Azure services.
To interact with the Azure Blob Storage service, you'll need to create an instance of the `azblob.Client` type. The [azidentity][azidentity] module makes it easy to add Azure Active Directory support for authenticating Azure SDK clients with their corresponding Azure services.
```go
// create a credential for authenticating with Azure Active Directory
@ -53,11 +57,17 @@ client, err := azblob.NewClient("https://MYSTORAGEACCOUNT.blob.core.windows.net/
// TODO: handle err
```
Learn more about enabling Azure Active Directory for authentication with Azure Storage in [our documentation][storage_ad] and [our samples](#next-steps).
Learn more about enabling Azure Active Directory for authentication with Azure Storage:
* [Authorize access to blobs using Azure Active Directory][storage_ad]
Other options for authentication include connection strings, shared key, shared access signatures (SAS), and anonymous public access. Use the appropriate client constructor function for the authentication mechanism you wish to use. For examples, see:
* [Blob samples][samples]
## Key concepts
Blob storage is designed for:
Blob Storage is designed for:
- Serving images or documents directly to a browser.
- Storing files for distributed access.
@ -66,23 +76,41 @@ Blob storage is designed for:
- Storing data for backup and restore, disaster recovery, and archiving.
- Storing data for analysis by an on-premises or Azure-hosted service.
Blob storage offers three types of resources:
Blob Storage offers three types of resources:
- The _storage account_
- One or more _containers_ in a storage account
- One ore more _blobs_ in a container
- One or more _blobs_ in a container
Instances of the `azblob.Client` type provide methods for manipulating containers and blobs within a storage account.
The storage account is specified when the `azblob.Client` is constructed.
Use the appropriate client constructor function for the authentication mechanism you wish to use.
Learn more about options for authentication _(including Connection Strings, Shared Key, Shared Access Signatures (SAS), Azure Active Directory (AAD), and anonymous public access)_ [in our examples.](https://github.com/Azure/azure-sdk-for-go/blob/main/sdk/storage/azblob/examples_test.go)
### Specialized clients
The Azure Blob Storage client module for Go also provides specialized clients in various subpackages. Use these clients when you need to interact with a specific kind of blob. Learn more about [block blobs, append blobs, and page blobs](https://learn.microsoft.com/rest/api/storageservices/understanding-block-blobs--append-blobs--and-page-blobs).
- [appendblob][append_blob]
- [blockblob][block_blob]
- [pageblob][page_blob]
The [blob][blob] package contains APIs common to all blob types. This includes APIs for deleting and undeleting a blob, setting metadata, and more.
The [lease][lease] package contains clients for managing leases on blobs and containers. See the [REST API reference](https://learn.microsoft.com/rest/api/storageservices/lease-blob#remarks) for general information on leases.
The [container][container] package contains APIs specific to containers. This includes APIs for setting access policies or properties, and more.
The [service][service] package contains APIs specific to the Blob service. This includes APIs for manipulating containers, retrieving account information, and more.
The [sas][sas] package contains utilities to aid in the creation and manipulation of shared access signature (SAS) tokens.
See the package's documentation for more information.
### Goroutine safety
We guarantee that all client instance methods are goroutine-safe and independent of each other ([guideline](https://azure.github.io/azure-sdk/golang_introduction.html#thread-safety)). This ensures that the recommendation of reusing client instances is always safe, even across goroutines.
### About blob metadata
Blob metadata name/value pairs are valid HTTP headers and should adhere to all restrictions governing HTTP headers. Metadata names must be valid HTTP header names, may contain only ASCII characters, and should be treated as case-insensitive. Base64-encode or URL-encode metadata values containing non-ASCII characters.
We guarantee that all client instance methods are goroutine-safe and independent of each other (see [guideline](https://azure.github.io/azure-sdk/golang_introduction.html#thread-safety)). This ensures that the recommendation to reuse client instances is always safe, even across goroutines.
### Blob metadata
Blob metadata name-value pairs are valid HTTP headers and should adhere to all restrictions governing HTTP headers. Metadata names must be valid HTTP header names, may contain only ASCII characters, and should be treated as case-insensitive. Base64-encode or URL-encode metadata values containing non-ASCII characters.
### Additional concepts
<!-- CLIENT COMMON BAR -->
@ -94,7 +122,7 @@ Blob metadata name/value pairs are valid HTTP headers and should adhere to all r
## Examples
### Uploading a blob
### Upload a blob
```go
const (
@ -122,7 +150,7 @@ _, err = client.UploadFile(context.TODO(), containerName, blobName, file, nil)
// TODO: handle error
```
### Downloading a blob
### Download a blob
```go
// this example accesses a public blob via anonymous access, so no credentials are required
@ -139,7 +167,7 @@ _, err = client.DownloadFile(context.TODO(), "samples", "cloud.jpg", file, nil)
// TODO: handle error
```
### Enumerating blobs
### Enumerate blobs
```go
const (
@ -177,7 +205,7 @@ All Blob service operations will return an
[*azcore.ResponseError][azcore_response_error] on failure with a
populated `ErrorCode` field. Many of these errors are recoverable.
The [bloberror][blob_error] package provides the possible Storage error codes
along with various helper facilities for error handling.
along with helper facilities for error handling.
```go
const (
@ -201,28 +229,7 @@ if bloberror.HasCode(err, bloberror.ContainerBeingDeleted, bloberror.ContainerNo
## Next steps
Get started with our [Blob samples][samples]. They contain complete examples of the above snippets and more.
### Specialized clients
The Azure Blob Storage SDK for Go also provides specialized clients in various subpackages.
Use these clients when you need to interact with a specific kind of blob.
Learn more about the various types of blobs from the following links.
- [appendblob][append_blob] - [REST docs](https://docs.microsoft.com/rest/api/storageservices/understanding-block-blobs--append-blobs--and-page-blobs#about-append-blobs)
- [blockblob][block_blob] - [REST docs](https://docs.microsoft.com/rest/api/storageservices/understanding-block-blobs--append-blobs--and-page-blobs#about-block-blobs)
- [pageblob][page_blob] - [REST docs](https://docs.microsoft.com/rest/api/storageservices/understanding-block-blobs--append-blobs--and-page-blobs#about-page-blobs)
The [blob][blob] package contains APIs common to all blob types. This includes APIs for deleting and undeleting a blob, setting metadata, and more.
The [lease][lease] package contains clients for managing leases on blobs and containers. Please see the [reference docs](https://docs.microsoft.com/rest/api/storageservices/lease-blob#remarks) for general information on leases.
The [container][container] package contains APIs specific to containers. This includes APIs setting access policies or properties, and more.
The [service][service] package contains APIs specific to blob service. This includes APIs for manipulating containers, retrieving account information, and more.
The [sas][sas] package contains utilities to aid in the creation and manipulation of Shared Access Signature tokens.
See the package's documentation for more information.
Get started with our [Blob samples][samples]. They contain complete examples of the above snippets and more.
## Contributing
@ -243,19 +250,20 @@ additional questions or comments.
<!-- LINKS -->
[source]: https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/storage/azblob
[docs]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob
[rest_docs]: https://docs.microsoft.com/rest/api/storageservices/blob-service-rest-api
[product_docs]: https://docs.microsoft.com/azure/storage/blobs/storage-blobs-overview
[docs]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob#section_documentation
[rest_docs]: https://learn.microsoft.com/rest/api/storageservices/blob-service-rest-api
[product_docs]: https://learn.microsoft.com/azure/storage/blobs/storage-blobs-overview
[godevdl]: https://go.dev/dl/
[goget]: https://pkg.go.dev/cmd/go#hdr-Add_dependencies_to_current_module_and_install_them
[storage_account_docs]: https://docs.microsoft.com/azure/storage/common/storage-account-overview
[storage_account_create_ps]: https://docs.microsoft.com/azure/storage/common/storage-quickstart-create-account?tabs=azure-powershell
[storage_account_create_cli]: https://docs.microsoft.com/azure/storage/common/storage-quickstart-create-account?tabs=azure-cli
[storage_account_create_portal]: https://docs.microsoft.com/azure/storage/common/storage-quickstart-create-account?tabs=azure-portal
[azure_cli]: https://docs.microsoft.com/cli/azure
[go_samples]: https://github.com/Azure-Samples/azure-sdk-for-go-samples/tree/main
[storage_account_docs]: https://learn.microsoft.com/azure/storage/common/storage-account-overview
[storage_account_create_ps]: https://learn.microsoft.com/azure/storage/common/storage-quickstart-create-account?tabs=azure-powershell
[storage_account_create_cli]: https://learn.microsoft.com/azure/storage/common/storage-quickstart-create-account?tabs=azure-cli
[storage_account_create_portal]: https://learn.microsoft.com/azure/storage/common/storage-quickstart-create-account?tabs=azure-portal
[azure_cli]: https://learn.microsoft.com/cli/azure
[azure_sub]: https://azure.microsoft.com/free/
[azidentity]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity
[storage_ad]: https://docs.microsoft.com/azure/storage/common/storage-auth-aad
[storage_ad]: https://learn.microsoft.com/azure/storage/common/storage-auth-aad
[azcore_response_error]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore#ResponseError
[samples]: https://github.com/Azure/azure-sdk-for-go/blob/main/sdk/storage/azblob/examples_test.go
[append_blob]: https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/storage/azblob/appendblob/client.go

View file

@ -8,6 +8,7 @@ package appendblob
import (
"context"
"errors"
"io"
"os"
"time"
@ -22,9 +23,7 @@ import (
)
// ClientOptions contains the optional parameters when creating a Client.
type ClientOptions struct {
azcore.ClientOptions
}
type ClientOptions base.ClientOptions
// Client represents a client to an Azure Storage append blob;
type Client base.CompositeClient[generated.BlobClient, generated.AppendBlobClient]
@ -34,7 +33,7 @@ type Client base.CompositeClient[generated.BlobClient, generated.AppendBlobClien
// - cred - an Azure AD credential, typically obtained via the azidentity module
// - options - client options; pass nil to accept the default values
func NewClient(blobURL string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) {
authPolicy := runtime.NewBearerTokenPolicy(cred, []string{shared.TokenScope}, nil)
authPolicy := shared.NewStorageChallengePolicy(cred)
conOptions := shared.GetClientOptions(options)
conOptions.PerRetryPolicies = append(conOptions.PerRetryPolicies, authPolicy)
pl := runtime.NewPipeline(exported.ModuleName,
@ -255,14 +254,10 @@ func (ab *Client) SetLegalHold(ctx context.Context, legalHold bool, options *blo
return ab.BlobClient().SetLegalHold(ctx, legalHold, options)
}
// SetTier operation sets the tier on a blob. The operation is allowed on a page
// blob in a premium storage account and on a block blob in a blob storage account (locally
// redundant storage only). A premium page blob's tier determines the allowed size, IOPS, and
// bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation
// does not update the blob's ETag.
// For detailed information about block blob level tiering see https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-storage-tiers.
// SetTier
// Deprecated: SetTier only works for page blob in premium storage account and block blob in blob storage account.
func (ab *Client) SetTier(ctx context.Context, tier blob.AccessTier, o *blob.SetTierOptions) (blob.SetTierResponse, error) {
return ab.BlobClient().SetTier(ctx, tier, o)
return blob.SetTierResponse{}, errors.New("operation will not work on this blob type. SetTier only works for page blob in premium storage account and block blob in blob storage account")
}
// SetExpiry operation sets an expiry time on an existing blob. This operation is only allowed on Hierarchical Namespace enabled accounts.
@ -282,6 +277,12 @@ func (ab *Client) GetProperties(ctx context.Context, o *blob.GetPropertiesOption
return ab.BlobClient().GetProperties(ctx, o)
}
// GetAccountInfo provides account level information
// For more information, see https://learn.microsoft.com/en-us/rest/api/storageservices/get-account-information?tabs=shared-access-signatures.
func (ab *Client) GetAccountInfo(ctx context.Context, o *blob.GetAccountInfoOptions) (blob.GetAccountInfoResponse, error) {
return ab.BlobClient().GetAccountInfo(ctx, o)
}
// SetHTTPHeaders changes a blob's HTTP headers.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-blob-properties.
func (ab *Client) SetHTTPHeaders(ctx context.Context, HTTPHeaders blob.HTTPHeaders, o *blob.SetHTTPHeadersOptions) (blob.SetHTTPHeadersResponse, error) {
@ -326,10 +327,10 @@ func (ab *Client) GetTags(ctx context.Context, o *blob.GetTagsOptions) (blob.Get
return ab.BlobClient().GetTags(ctx, o)
}
// CopyFromURL synchronously copies the data at the source URL to a block blob, with sizes up to 256 MB.
// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/copy-blob-from-url.
// CopyFromURL
// Deprecated: CopyFromURL works only with block blob
func (ab *Client) CopyFromURL(ctx context.Context, copySource string, o *blob.CopyFromURLOptions) (blob.CopyFromURLResponse, error) {
return ab.BlobClient().CopyFromURL(ctx, copySource, o)
return blob.CopyFromURLResponse{}, errors.New("operation will not work on this blob type. CopyFromURL works only with block blob")
}
// Concurrent Download Functions -----------------------------------------------------------------------------------------

View file

@ -100,6 +100,9 @@ func (o *AppendBlockOptions) format() (*generated.AppendBlobClientAppendBlockOpt
// AppendBlockFromURLOptions contains the optional parameters for the Client.AppendBlockFromURL method.
type AppendBlockFromURLOptions struct {
// Only Bearer type is supported. Credentials should be a valid OAuth access token to copy source.
CopySourceAuthorization *string
// SourceContentValidation contains the validation mechanism used on the range of bytes read from the source.
SourceContentValidation blob.SourceContentValidationType
@ -125,7 +128,8 @@ func (o *AppendBlockFromURLOptions) format() (*generated.AppendBlobClientAppendB
}
options := &generated.AppendBlobClientAppendBlockFromURLOptions{
SourceRange: exported.FormatHTTPRange(o.Range),
SourceRange: exported.FormatHTTPRange(o.Range),
CopySourceAuthorization: o.CopySourceAuthorization,
}
if o.SourceContentValidation != nil {

View file

@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "go",
"TagPrefix": "go/storage/azblob",
"Tag": "go/storage/azblob_46e572d43a"
"Tag": "go/storage/azblob_a772b9c866"
}

View file

@ -25,9 +25,7 @@ import (
)
// ClientOptions contains the optional parameters when creating a Client.
type ClientOptions struct {
azcore.ClientOptions
}
type ClientOptions base.ClientOptions
// Client represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob.
type Client base.Client[generated.BlobClient]
@ -37,12 +35,12 @@ type Client base.Client[generated.BlobClient]
// - cred - an Azure AD credential, typically obtained via the azidentity module
// - options - client options; pass nil to accept the default values
func NewClient(blobURL string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) {
authPolicy := runtime.NewBearerTokenPolicy(cred, []string{shared.TokenScope}, nil)
authPolicy := shared.NewStorageChallengePolicy(cred)
conOptions := shared.GetClientOptions(options)
conOptions.PerRetryPolicies = append(conOptions.PerRetryPolicies, authPolicy)
pl := runtime.NewPipeline(exported.ModuleName, exported.ModuleVersion, runtime.PipelineOptions{}, &conOptions.ClientOptions)
return (*Client)(base.NewBlobClient(blobURL, pl, nil)), nil
return (*Client)(base.NewBlobClient(blobURL, pl, &cred)), nil
}
// NewClientWithNoCredential creates an instance of Client with the specified values.
@ -100,6 +98,10 @@ func (b *Client) sharedKey() *SharedKeyCredential {
return base.SharedKey((*base.Client[generated.BlobClient])(b))
}
func (b *Client) credential() any {
return base.Credential((*base.Client[generated.BlobClient])(b))
}
// URL returns the URL endpoint used by the Client object.
func (b *Client) URL() string {
return b.generated().Endpoint()
@ -114,7 +116,7 @@ func (b *Client) WithSnapshot(snapshot string) (*Client, error) {
}
p.Snapshot = snapshot
return (*Client)(base.NewBlobClient(p.String(), b.generated().Pipeline(), b.sharedKey())), nil
return (*Client)(base.NewBlobClient(p.String(), b.generated().Pipeline(), b.credential())), nil
}
// WithVersionID creates a new AppendBlobURL object identical to the source but with the specified version id.
@ -126,7 +128,7 @@ func (b *Client) WithVersionID(versionID string) (*Client, error) {
}
p.VersionID = versionID
return (*Client)(base.NewBlobClient(p.String(), b.generated().Pipeline(), b.sharedKey())), nil
return (*Client)(base.NewBlobClient(p.String(), b.generated().Pipeline(), b.credential())), nil
}
// Delete marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection.
@ -264,6 +266,14 @@ func (b *Client) CopyFromURL(ctx context.Context, copySource string, options *Co
return resp, err
}
// GetAccountInfo provides account level information
// For more information, see https://learn.microsoft.com/en-us/rest/api/storageservices/get-account-information?tabs=shared-access-signatures.
func (b *Client) GetAccountInfo(ctx context.Context, o *GetAccountInfoOptions) (GetAccountInfoResponse, error) {
getAccountInfoOptions := o.format()
resp, err := b.generated().GetAccountInfo(ctx, getAccountInfoOptions)
return resp, err
}
// GetSASURL is a convenience method for generating a SAS token for the currently pointed at blob.
// It can only be used if the credential supplied during creation was a SharedKeyCredential.
func (b *Client) GetSASURL(permissions sas.BlobPermissions, expiry time.Time, o *GetSASURLOptions) (string, error) {
@ -313,12 +323,11 @@ func (b *Client) download(ctx context.Context, writer io.WriterAt, o downloadOpt
count := o.Range.Count
if count == CountToEnd { // If size not specified, calculate it
// If we don't have the length at all, get it
downloadBlobOptions := o.getDownloadBlobOptions(HTTPRange{}, nil)
dr, err := b.DownloadStream(ctx, downloadBlobOptions)
gr, err := b.GetProperties(ctx, o.getBlobPropertiesOptions())
if err != nil {
return 0, err
}
count = *dr.ContentLength - o.Range.Offset
count = *gr.ContentLength - o.Range.Offset
}
if count <= 0 {

View file

@ -565,3 +565,14 @@ func (o *CopyFromURLOptions) format() (*generated.BlobClientCopyFromURLOptions,
leaseAccessConditions, modifiedAccessConditions := exported.FormatBlobAccessConditions(o.BlobAccessConditions)
return options, o.SourceModifiedAccessConditions, modifiedAccessConditions, leaseAccessConditions
}
// ---------------------------------------------------------------------------------------------------------------------
// GetAccountInfoOptions provides set of options for Client.GetAccountInfo
type GetAccountInfoOptions struct {
// placeholder for future options
}
func (o *GetAccountInfoOptions) format() *generated.BlobClientGetAccountInfoOptions {
return nil
}

View file

@ -100,6 +100,9 @@ type SetLegalHoldResponse = generated.BlobClientSetLegalHoldResponse
// CopyFromURLResponse contains the response from method BlobClient.CopyFromURL.
type CopyFromURLResponse = generated.BlobClientCopyFromURLResponse
// GetAccountInfoResponse contains the response from method BlobClient.GetAccountInfo.
type GetAccountInfoResponse = generated.BlobClientGetAccountInfoResponse
// AcquireLeaseResponse contains the response from method BlobClient.AcquireLease.
type AcquireLeaseResponse = generated.BlobClientAcquireLeaseResponse

View file

@ -12,6 +12,7 @@ import (
"encoding/base64"
"errors"
"io"
"math"
"os"
"sync"
"time"
@ -30,9 +31,7 @@ import (
)
// ClientOptions contains the optional parameters when creating a Client.
type ClientOptions struct {
azcore.ClientOptions
}
type ClientOptions base.ClientOptions
// Client defines a set of operations applicable to block blobs.
type Client base.CompositeClient[generated.BlobClient, generated.BlockBlobClient]
@ -42,7 +41,7 @@ type Client base.CompositeClient[generated.BlobClient, generated.BlockBlobClient
// - cred - an Azure AD credential, typically obtained via the azidentity module
// - options - client options; pass nil to accept the default values
func NewClient(blobURL string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) {
authPolicy := runtime.NewBearerTokenPolicy(cred, []string{shared.TokenScope}, nil)
authPolicy := shared.NewStorageChallengePolicy(cred)
conOptions := shared.GetClientOptions(options)
conOptions.PerRetryPolicies = append(conOptions.PerRetryPolicies, authPolicy)
pl := runtime.NewPipeline(exported.ModuleName, exported.ModuleVersion, runtime.PipelineOptions{}, &conOptions.ClientOptions)
@ -165,6 +164,19 @@ func (bb *Client) Upload(ctx context.Context, body io.ReadSeekCloser, options *U
return resp, err
}
// UploadBlobFromURL - The Put Blob from URL operation creates a new Block Blob where the contents of the blob are read from
// a given URL. Partial updates are not supported with Put Blob from URL; the content of an existing blob is overwritten
// with the content of the new blob. To perform partial updates to a block blobs contents using a source URL, use the Put
// Block from URL API in conjunction with Put Block List.
// For more information, see https://learn.microsoft.com/rest/api/storageservices/put-blob-from-url
func (bb *Client) UploadBlobFromURL(ctx context.Context, copySource string, options *UploadBlobFromURLOptions) (UploadBlobFromURLResponse, error) {
opts, httpHeaders, leaseAccessConditions, cpkInfo, cpkSourceInfo, modifiedAccessConditions, sourceModifiedConditions := options.format()
resp, err := bb.generated().PutBlobFromURL(ctx, int64(0), copySource, opts, httpHeaders, leaseAccessConditions, cpkInfo, cpkSourceInfo, modifiedAccessConditions, sourceModifiedConditions)
return resp, err
}
// StageBlock uploads the specified block to the block blob's "staging area" to be later committed by a call to CommitBlockList.
// Note that the http client closes the body stream after the request is sent to the service.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-block.
@ -316,6 +328,12 @@ func (bb *Client) GetProperties(ctx context.Context, o *blob.GetPropertiesOption
return bb.BlobClient().GetProperties(ctx, o)
}
// GetAccountInfo provides account level information
// For more information, see https://learn.microsoft.com/en-us/rest/api/storageservices/get-account-information?tabs=shared-access-signatures.
func (bb *Client) GetAccountInfo(ctx context.Context, o *blob.GetAccountInfoOptions) (blob.GetAccountInfoResponse, error) {
return bb.BlobClient().GetAccountInfo(ctx, o)
}
// SetHTTPHeaders changes a blob's HTTP headers.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-blob-properties.
func (bb *Client) SetHTTPHeaders(ctx context.Context, HTTPHeaders blob.HTTPHeaders, o *blob.SetHTTPHeadersOptions) (blob.SetHTTPHeadersResponse, error) {
@ -370,31 +388,26 @@ func (bb *Client) CopyFromURL(ctx context.Context, copySource string, o *blob.Co
// uploadFromReader uploads a buffer in blocks to a block blob.
func (bb *Client) uploadFromReader(ctx context.Context, reader io.ReaderAt, actualSize int64, o *uploadFromReaderOptions) (uploadFromReaderResponse, error) {
readerSize := actualSize
if o.BlockSize == 0 {
// If bufferSize > (MaxStageBlockBytes * MaxBlocks), then error
if readerSize > MaxStageBlockBytes*MaxBlocks {
if actualSize > MaxStageBlockBytes*MaxBlocks {
return uploadFromReaderResponse{}, errors.New("buffer is too large to upload to a block blob")
}
// If bufferSize <= MaxUploadBlobBytes, then Upload should be used with just 1 I/O request
if readerSize <= MaxUploadBlobBytes {
if actualSize <= MaxUploadBlobBytes {
o.BlockSize = MaxUploadBlobBytes // Default if unspecified
} else {
if remainder := readerSize % MaxBlocks; remainder > 0 {
// ensure readerSize is a multiple of MaxBlocks
readerSize += (MaxBlocks - remainder)
}
o.BlockSize = readerSize / MaxBlocks // buffer / max blocks = block size to use all 50,000 blocks
if o.BlockSize < blob.DefaultDownloadBlockSize { // If the block size is smaller than 4MB, round up to 4MB
o.BlockSize = int64(math.Ceil(float64(actualSize) / MaxBlocks)) // ceil(buffer / max blocks) = block size to use all 50,000 blocks
if o.BlockSize < blob.DefaultDownloadBlockSize { // If the block size is smaller than 4MB, round up to 4MB
o.BlockSize = blob.DefaultDownloadBlockSize
}
// StageBlock will be called with blockSize blocks and a Concurrency of (BufferSize / BlockSize).
}
}
if readerSize <= MaxUploadBlobBytes {
if actualSize <= MaxUploadBlobBytes {
// If the size can fit in 1 Upload call, do it this way
var body io.ReadSeeker = io.NewSectionReader(reader, 0, readerSize)
var body io.ReadSeeker = io.NewSectionReader(reader, 0, actualSize)
if o.Progress != nil {
body = streaming.NewRequestProgress(shared.NopCloser(body), o.Progress)
}
@ -405,7 +418,7 @@ func (bb *Client) uploadFromReader(ctx context.Context, reader io.ReaderAt, actu
return toUploadReaderAtResponseFromUploadResponse(resp), err
}
var numBlocks = uint16(((readerSize - 1) / o.BlockSize) + 1)
var numBlocks = uint16(((actualSize - 1) / o.BlockSize) + 1)
if numBlocks > MaxBlocks {
// prevent any math bugs from attempting to upload too many blocks which will always fail
return uploadFromReaderResponse{}, errors.New("block limit exceeded")
@ -425,7 +438,7 @@ func (bb *Client) uploadFromReader(ctx context.Context, reader io.ReaderAt, actu
err := shared.DoBatchTransfer(ctx, &shared.BatchTransferOptions{
OperationName: "uploadFromReader",
TransferSize: readerSize,
TransferSize: actualSize,
ChunkSize: o.BlockSize,
Concurrency: o.Concurrency,
Operation: func(ctx context.Context, offset int64, chunkSize int64) error {

View file

@ -1,6 +1,6 @@
//go:build go1.18 && (linux || darwin || freebsd || openbsd || netbsd || solaris)
//go:build go1.18 && (linux || darwin || dragonfly || freebsd || openbsd || netbsd || solaris || aix)
// +build go1.18
// +build linux darwin freebsd openbsd netbsd solaris
// +build linux darwin dragonfly freebsd openbsd netbsd solaris aix
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

View file

@ -26,7 +26,9 @@ func newMMB(size int64) (mmb, error) {
if err != nil {
return nil, os.NewSyscallError("CreateFileMapping", err)
}
defer syscall.CloseHandle(hMMF)
defer func() {
_ = syscall.CloseHandle(hMMF)
}()
addr, err := syscall.MapViewOfFile(hMMF, access, 0, 0, uintptr(size))
if err != nil {

View file

@ -70,6 +70,56 @@ func (o *UploadOptions) format() (*generated.BlockBlobClientUploadOptions, *gene
// ---------------------------------------------------------------------------------------------------------------------
// UploadBlobFromURLOptions contains the optional parameters for the Client.UploadBlobFromURL method.
type UploadBlobFromURLOptions struct {
// Optional. Used to set blob tags in various blob operations.
Tags map[string]string
// Only Bearer type is supported. Credentials should be a valid OAuth access token to copy source.
CopySourceAuthorization *string
// Optional, default is true. Indicates if properties from the source blob should be copied.
CopySourceBlobProperties *bool
// Optional. Specifies a user-defined name-value pair associated with the blob.
Metadata map[string]*string
// Optional. Specifies the md5 calculated for the range of bytes that must be read from the copy source.
SourceContentMD5 []byte
// Optional. Indicates the tier to be set on the blob.
Tier *blob.AccessTier
// Additional optional headers
HTTPHeaders *blob.HTTPHeaders
AccessConditions *blob.AccessConditions
CPKInfo *blob.CPKInfo
CPKScopeInfo *blob.CPKScopeInfo
SourceModifiedAccessConditions *blob.SourceModifiedAccessConditions
}
func (o *UploadBlobFromURLOptions) format() (*generated.BlockBlobClientPutBlobFromURLOptions, *generated.BlobHTTPHeaders,
*generated.LeaseAccessConditions, *generated.CPKInfo, *generated.CPKScopeInfo, *generated.ModifiedAccessConditions,
*generated.SourceModifiedAccessConditions) {
if o == nil {
return nil, nil, nil, nil, nil, nil, nil
}
options := generated.BlockBlobClientPutBlobFromURLOptions{
BlobTagsString: shared.SerializeBlobTagsToStrPtr(o.Tags),
CopySourceAuthorization: o.CopySourceAuthorization,
CopySourceBlobProperties: o.CopySourceBlobProperties,
Metadata: o.Metadata,
SourceContentMD5: o.SourceContentMD5,
Tier: o.Tier,
}
leaseAccessConditions, modifiedAccessConditions := exported.FormatBlobAccessConditions(o.AccessConditions)
return &options, o.HTTPHeaders, leaseAccessConditions, o.CPKInfo, o.CPKScopeInfo, modifiedAccessConditions, o.SourceModifiedAccessConditions
}
// ---------------------------------------------------------------------------------------------------------------------
// StageBlockOptions contains the optional parameters for the Client.StageBlock method.
type StageBlockOptions struct {
CPKInfo *blob.CPKInfo

View file

@ -16,6 +16,9 @@ import (
// UploadResponse contains the response from method Client.Upload.
type UploadResponse = generated.BlockBlobClientUploadResponse
// UploadBlobFromURLResponse contains the response from the method Client.UploadBlobFromURL
type UploadBlobFromURLResponse = generated.BlockBlobClientPutBlobFromURLResponse
// StageBlockResponse contains the response from method Client.StageBlock.
type StageBlockResponse = generated.BlockBlobClientStageBlockResponse

View file

@ -26,3 +26,8 @@ stages:
parameters:
ServiceDirectory: 'storage/azblob'
RunLiveTests: true
EnvVars:
AZURE_CLIENT_ID: $(AZBLOB_CLIENT_ID)
AZURE_TENANT_ID: $(AZBLOB_TENANT_ID)
AZURE_CLIENT_SECRET: $(AZBLOB_CLIENT_SECRET)
AZURE_SUBSCRIPTION_ID: $(AZBLOB_SUBSCRIPTION_ID)

View file

@ -13,14 +13,13 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/base"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/shared"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/service"
)
// ClientOptions contains the optional parameters when creating a Client.
type ClientOptions struct {
azcore.ClientOptions
}
type ClientOptions base.ClientOptions
// Client represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob.
type Client struct {

View file

@ -0,0 +1,94 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
package container
import (
"context"
"fmt"
"net/url"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/exported"
)
// BatchBuilder is used for creating the batch operations list. It contains the list of either delete or set tier sub-requests.
// NOTE: All sub-requests in the batch must be of the same type, either delete or set tier.
type BatchBuilder struct {
endpoint string
authPolicy policy.Policy
subRequests []*policy.Request
operationType *exported.BlobBatchOperationType
}
func (bb *BatchBuilder) checkOperationType(operationType exported.BlobBatchOperationType) error {
if bb.operationType == nil {
bb.operationType = &operationType
return nil
}
if *bb.operationType != operationType {
return fmt.Errorf("BlobBatch only supports one operation type per batch and is already being used for %s operations", *bb.operationType)
}
return nil
}
// Delete operation is used to add delete sub-request to the batch builder.
func (bb *BatchBuilder) Delete(blobName string, options *BatchDeleteOptions) error {
err := bb.checkOperationType(exported.BatchDeleteOperationType)
if err != nil {
return err
}
blobName = url.PathEscape(blobName)
blobURL := runtime.JoinPaths(bb.endpoint, blobName)
blobClient, err := blob.NewClientWithNoCredential(blobURL, nil)
if err != nil {
return err
}
deleteOptions, leaseInfo, accessConditions := options.format()
req, err := getGeneratedBlobClient(blobClient).DeleteCreateRequest(context.TODO(), deleteOptions, leaseInfo, accessConditions)
if err != nil {
return err
}
// remove x-ms-version header
exported.UpdateSubRequestHeaders(req)
bb.subRequests = append(bb.subRequests, req)
return nil
}
// SetTier operation is used to add set tier sub-request to the batch builder.
func (bb *BatchBuilder) SetTier(blobName string, accessTier blob.AccessTier, options *BatchSetTierOptions) error {
err := bb.checkOperationType(exported.BatchSetTierOperationType)
if err != nil {
return err
}
blobName = url.PathEscape(blobName)
blobURL := runtime.JoinPaths(bb.endpoint, blobName)
blobClient, err := blob.NewClientWithNoCredential(blobURL, nil)
if err != nil {
return err
}
setTierOptions, leaseInfo, accessConditions := options.format()
req, err := getGeneratedBlobClient(blobClient).SetTierCreateRequest(context.TODO(), accessTier, setTierOptions, leaseInfo, accessConditions)
if err != nil {
return err
}
// remove x-ms-version header
exported.UpdateSubRequestHeaders(req)
bb.subRequests = append(bb.subRequests, req)
return nil
}

View file

@ -7,7 +7,11 @@
package container
import (
"bytes"
"context"
"errors"
"fmt"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror"
"net/http"
"net/url"
@ -28,9 +32,7 @@ import (
)
// ClientOptions contains the optional parameters when creating a Client.
type ClientOptions struct {
azcore.ClientOptions
}
type ClientOptions base.ClientOptions
// Client represents a URL to the Azure Storage container allowing you to manipulate its blobs.
type Client base.Client[generated.ContainerClient]
@ -40,12 +42,12 @@ type Client base.Client[generated.ContainerClient]
// - cred - an Azure AD credential, typically obtained via the azidentity module
// - options - client options; pass nil to accept the default values
func NewClient(containerURL string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) {
authPolicy := runtime.NewBearerTokenPolicy(cred, []string{shared.TokenScope}, nil)
authPolicy := shared.NewStorageChallengePolicy(cred)
conOptions := shared.GetClientOptions(options)
conOptions.PerRetryPolicies = append(conOptions.PerRetryPolicies, authPolicy)
pl := runtime.NewPipeline(exported.ModuleName, exported.ModuleVersion, runtime.PipelineOptions{}, &conOptions.ClientOptions)
return (*Client)(base.NewContainerClient(containerURL, pl, nil)), nil
return (*Client)(base.NewContainerClient(containerURL, pl, &cred)), nil
}
// NewClientWithNoCredential creates an instance of Client with the specified values.
@ -102,6 +104,15 @@ func (c *Client) sharedKey() *SharedKeyCredential {
return base.SharedKey((*base.Client[generated.ContainerClient])(c))
}
func (c *Client) credential() any {
return base.Credential((*base.Client[generated.ContainerClient])(c))
}
// helper method to return the generated.BlobClient which is used for creating the sub-requests
func getGeneratedBlobClient(b *blob.Client) *generated.BlobClient {
return base.InnerClient((*base.Client[generated.BlobClient])(b))
}
// URL returns the URL endpoint used by the Client object.
func (c *Client) URL() string {
return c.generated().Endpoint()
@ -113,7 +124,7 @@ func (c *Client) URL() string {
func (c *Client) NewBlobClient(blobName string) *blob.Client {
blobName = url.PathEscape(blobName)
blobURL := runtime.JoinPaths(c.URL(), blobName)
return (*blob.Client)(base.NewBlobClient(blobURL, c.generated().Pipeline(), c.sharedKey()))
return (*blob.Client)(base.NewBlobClient(blobURL, c.generated().Pipeline(), c.credential()))
}
// NewAppendBlobClient creates a new appendblob.Client object by concatenating blobName to the end of
@ -190,7 +201,7 @@ func (c *Client) Restore(ctx context.Context, deletedContainerVersion string, op
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-container-metadata.
func (c *Client) GetProperties(ctx context.Context, o *GetPropertiesOptions) (GetPropertiesResponse, error) {
// NOTE: GetMetadata actually calls GetProperties internally because GetProperties returns the metadata AND the properties.
// This allows us to not expose a GetProperties method at all simplifying the API.
// This allows us to not expose a GetMetadata method at all simplifying the API.
// The optionals are nil, like they were in track 1.5
opts, leaseAccessConditions := o.format()
@ -226,6 +237,14 @@ func (c *Client) SetAccessPolicy(ctx context.Context, o *SetAccessPolicyOptions)
return resp, err
}
// GetAccountInfo provides account level information
// For more information, see https://learn.microsoft.com/en-us/rest/api/storageservices/get-account-information?tabs=shared-access-signatures.
func (c *Client) GetAccountInfo(ctx context.Context, o *GetAccountInfoOptions) (GetAccountInfoResponse, error) {
getAccountInfoOptions := o.format()
resp, err := c.generated().GetAccountInfo(ctx, getAccountInfoOptions)
return resp, err
}
// NewListBlobsFlatPager returns a pager for blobs starting from the specified Marker. Use an empty
// Marker to start enumeration from the beginning. Blob names are returned in lexicographic order.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/list-blobs.
@ -329,3 +348,67 @@ func (c *Client) GetSASURL(permissions sas.ContainerPermissions, expiry time.Tim
return endpoint, nil
}
// NewBatchBuilder creates an instance of BatchBuilder using the same auth policy as the client.
// BatchBuilder is used to build the batch consisting of either delete or set tier sub-requests.
// All sub-requests in the batch must be of the same type, either delete or set tier.
func (c *Client) NewBatchBuilder() (*BatchBuilder, error) {
var authPolicy policy.Policy
switch cred := c.credential().(type) {
case *azcore.TokenCredential:
authPolicy = shared.NewStorageChallengePolicy(*cred)
case *SharedKeyCredential:
authPolicy = exported.NewSharedKeyCredPolicy(cred)
case nil:
// for authentication using SAS
authPolicy = nil
default:
return nil, fmt.Errorf("unrecognised authentication type %T", cred)
}
return &BatchBuilder{
endpoint: c.URL(),
authPolicy: authPolicy,
}, nil
}
// SubmitBatch operation allows multiple API calls to be embedded into a single HTTP request.
// It builds the request body using the BatchBuilder object passed.
// BatchBuilder contains the list of operations to be submitted. It supports up to 256 sub-requests in a single batch.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/blob-batch.
func (c *Client) SubmitBatch(ctx context.Context, bb *BatchBuilder, options *SubmitBatchOptions) (SubmitBatchResponse, error) {
if bb == nil || len(bb.subRequests) == 0 {
return SubmitBatchResponse{}, errors.New("batch builder is empty")
}
// create the request body
batchReq, batchID, err := exported.CreateBatchRequest(&exported.BlobBatchBuilder{
AuthPolicy: bb.authPolicy,
SubRequests: bb.subRequests,
})
if err != nil {
return SubmitBatchResponse{}, err
}
reader := bytes.NewReader(batchReq)
rsc := streaming.NopCloser(reader)
multipartContentType := "multipart/mixed; boundary=" + batchID
resp, err := c.generated().SubmitBatch(ctx, int64(len(batchReq)), multipartContentType, rsc, options.format())
if err != nil {
return SubmitBatchResponse{}, err
}
batchResponses, err := exported.ParseBlobBatchResponse(resp.Body, resp.ContentType, bb.subRequests)
if err != nil {
return SubmitBatchResponse{}, err
}
return SubmitBatchResponse{
Responses: batchResponses,
ContentType: resp.ContentType,
RequestID: resp.RequestID,
Version: resp.Version,
}, nil
}

View file

@ -7,6 +7,7 @@
package container
import (
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
"reflect"
"time"
@ -329,3 +330,70 @@ func formatTime(c *SignedIdentifier) error {
return nil
}
// ---------------------------------------------------------------------------------------------------------------------
// GetAccountInfoOptions provides set of options for Client.GetAccountInfo
type GetAccountInfoOptions struct {
// placeholder for future options
}
func (o *GetAccountInfoOptions) format() *generated.ContainerClientGetAccountInfoOptions {
return nil
}
// ---------------------------------------------------------------------------------------------------------------------
// BatchDeleteOptions contains the optional parameters for the BatchBuilder.Delete method.
type BatchDeleteOptions struct {
blob.DeleteOptions
VersionID *string
Snapshot *string
}
func (o *BatchDeleteOptions) format() (*generated.BlobClientDeleteOptions, *generated.LeaseAccessConditions, *generated.ModifiedAccessConditions) {
if o == nil {
return nil, nil, nil
}
basics := generated.BlobClientDeleteOptions{
DeleteSnapshots: o.DeleteSnapshots,
DeleteType: o.BlobDeleteType, // None by default
Snapshot: o.Snapshot,
VersionID: o.VersionID,
}
leaseAccessConditions, modifiedAccessConditions := exported.FormatBlobAccessConditions(o.AccessConditions)
return &basics, leaseAccessConditions, modifiedAccessConditions
}
// BatchSetTierOptions contains the optional parameters for the BatchBuilder.SetTier method.
type BatchSetTierOptions struct {
blob.SetTierOptions
VersionID *string
Snapshot *string
}
func (o *BatchSetTierOptions) format() (*generated.BlobClientSetTierOptions, *generated.LeaseAccessConditions, *generated.ModifiedAccessConditions) {
if o == nil {
return nil, nil, nil
}
basics := generated.BlobClientSetTierOptions{
RehydratePriority: o.RehydratePriority,
Snapshot: o.Snapshot,
VersionID: o.VersionID,
}
leaseAccessConditions, modifiedAccessConditions := exported.FormatBlobAccessConditions(o.AccessConditions)
return &basics, leaseAccessConditions, modifiedAccessConditions
}
// SubmitBatchOptions contains the optional parameters for the Client.SubmitBatch method.
type SubmitBatchOptions struct {
// placeholder for future options
}
func (o *SubmitBatchOptions) format() *generated.ContainerClientSubmitBatchOptions {
return nil
}

View file

@ -7,6 +7,7 @@
package container
import (
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/exported"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated"
)
@ -42,3 +43,24 @@ type GetAccessPolicyResponse = generated.ContainerClientGetAccessPolicyResponse
// SetAccessPolicyResponse contains the response from method Client.SetAccessPolicy.
type SetAccessPolicyResponse = generated.ContainerClientSetAccessPolicyResponse
// GetAccountInfoResponse contains the response from method Client.GetAccountInfo.
type GetAccountInfoResponse = generated.ContainerClientGetAccountInfoResponse
// SubmitBatchResponse contains the response from method Client.SubmitBatch.
type SubmitBatchResponse struct {
// Responses contains the responses of the sub-requests in the batch
Responses []*BatchResponseItem
// ContentType contains the information returned from the Content-Type header response.
ContentType *string
// RequestID contains the information returned from the x-ms-request-id header response.
RequestID *string
// Version contains the information returned from the x-ms-version header response.
Version *string
}
// BatchResponseItem contains the response for the individual sub-requests.
type BatchResponseItem = exported.BatchResponseItem

View file

@ -51,7 +51,7 @@ Use the key as the credential parameter to authenticate the client:
cred, err := azblob.NewSharedKeyCredential(accountName, accountKey)
handle(err)
serviceClient, err := azblob.NewServiceClientWithSharedKey(serviceURL, cred, nil)
serviceClient, err := azblob.NewClientWithSharedKeyCredential(serviceURL, cred, nil)
handle(err)
fmt.Println(serviceClient.URL())
@ -59,11 +59,12 @@ Use the key as the credential parameter to authenticate the client:
Using a Connection String
Depending on your use case and authorization method, you may prefer to initialize a client instance with a connection string instead of providing the account URL and credential separately.
To do this, pass the connection string to the service client's `NewServiceClientFromConnectionString` method.
To do this, pass the connection string to the service client's `NewClientFromConnectionString` method.
The connection string can be found in your storage account in the Azure Portal under the "Access Keys" section.
connStr := "DefaultEndpointsProtocol=https;AccountName=<my_account_name>;AccountKey=<my_account_key>;EndpointSuffix=core.windows.net"
serviceClient, err := azblob.NewServiceClientFromConnectionString(connStr, nil)
serviceClient, err := azblob.NewClientFromConnectionString(connStr, nil)
handle(err)
Using a Shared Access Signature (SAS) Token
@ -82,20 +83,20 @@ You can generate a SAS token from the Azure Portal under Shared Access Signature
cred, err := azblob.NewSharedKeyCredential(accountName, accountKey)
handle(err)
serviceClient, err := azblob.NewServiceClientWithSharedKey(serviceURL, cred, nil)
serviceClient, err := azblob.NewClientWithSharedKeyCredential(serviceURL, cred, nil)
handle(err)
fmt.Println(serviceClient.URL())
// Alternatively, you can create SAS on the fly
resources := azblob.AccountSASResourceTypes{Service: true}
permission := azblob.AccountSASPermissions{Read: true}
resources := sas.AccountResourceTypes{Service: true}
permission := sas.AccountPermissions{Read: true}
start := time.Now()
expiry := start.AddDate(0, 0, 1)
serviceURLWithSAS, err := serviceClient.GetSASURL(resources, permission, start, expiry)
serviceURLWithSAS, err := serviceClient.ServiceClient().GetSASURL(resources, permission, expiry, &service.GetSASURLOptions{StartTime: &start})
handle(err)
serviceClientWithSAS, err := azblob.NewServiceClientWithNoCredential(serviceURLWithSAS, nil)
serviceClientWithSAS, err := azblob.NewClientWithNoCredential(serviceURLWithSAS, nil)
handle(err)
fmt.Println(serviceClientWithSAS.URL())
@ -135,13 +136,13 @@ Examples
handle(err)
// The service URL for blob endpoints is usually in the form: http(s)://<account>.blob.core.windows.net/
serviceClient, err := azblob.NewServiceClientWithSharedKey(fmt.Sprintf("https://%s.blob.core.windows.net/", accountName), cred, nil)
serviceClient, err := azblob.NewClientWithSharedKeyCredential(fmt.Sprintf("https://%s.blob.core.windows.net/", accountName), cred, nil)
handle(err)
// ===== 1. Create a container =====
// First, create a container client, and use the Create method to create a new container in your account
containerClient, err := serviceClient.NewContainerClient("testcontainer")
containerClient := serviceClient.ServiceClient().NewContainerClient("testcontainer")
handle(err)
// All APIs have an options' bag struct as a parameter.
@ -154,13 +155,13 @@ Examples
uploadData := "Hello world!"
// Create a new blockBlobClient from the containerClient
blockBlobClient, err := containerClient.NewBlockBlobClient("HelloWorld.txt")
blockBlobClient := containerClient.NewBlockBlobClient("HelloWorld.txt")
handle(err)
// Upload data to the block blob
blockBlobUploadOptions := azblob.BlockBlobUploadOptions{
Metadata: map[string]string{"Foo": "Bar"},
TagsMap: map[string]string{"Year": "2022"},
blockBlobUploadOptions := blockblob.UploadOptions{
Metadata: map[string]*string{"Foo": to.Ptr("Bar")},
Tags: map[string]string{"Year": "2022"},
}
_, err = blockBlobClient.Upload(context.TODO(), streaming.NopCloser(strings.NewReader(uploadData)), &blockBlobUploadOptions)
handle(err)
@ -175,10 +176,9 @@ Examples
downloadData, err := io.ReadAll(reader)
handle(err)
if string(downloadData) != uploadData {
handle(errors.New("Uploaded data should be same as downloaded data"))
handle(errors.New("uploaded data should be same as downloaded data"))
}
if err = reader.Close(); err != nil {
handle(err)
return
@ -189,18 +189,15 @@ Examples
// To iterate over a page use the NextPage(context.Context) to fetch the next page of results.
// PageResponse() can be used to iterate over the results of the specific page.
// Always check the Err() method after paging to see if an error was returned by the pager. A pager will return either an error or the page of results.
pager := containerClient.ListBlobsFlat(nil)
for pager.NextPage(context.TODO()) {
resp := pager.PageResponse()
pager := containerClient.NewListBlobsFlatPager(nil)
for pager.More() {
resp, err := pager.NextPage(context.TODO())
handle(err)
for _, v := range resp.Segment.BlobItems {
fmt.Println(*v.Name)
}
}
if err = pager.Err(); err != nil {
handle(err)
}
// Delete the blob.
_, err = blockBlobClient.Delete(context.TODO(), nil)
handle(err)

View file

@ -7,14 +7,20 @@
package base
import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/exported"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated"
)
// ClientOptions contains the optional parameters when creating a Client.
type ClientOptions struct {
azcore.ClientOptions
}
type Client[T any] struct {
inner *T
sharedKey *exported.SharedKeyCredential
inner *T
credential any
}
func InnerClient[T any](client *Client[T]) *T {
@ -22,31 +28,40 @@ func InnerClient[T any](client *Client[T]) *T {
}
func SharedKey[T any](client *Client[T]) *exported.SharedKeyCredential {
return client.sharedKey
switch cred := client.credential.(type) {
case *exported.SharedKeyCredential:
return cred
default:
return nil
}
}
func Credential[T any](client *Client[T]) any {
return client.credential
}
func NewClient[T any](inner *T) *Client[T] {
return &Client[T]{inner: inner}
}
func NewServiceClient(containerURL string, pipeline runtime.Pipeline, sharedKey *exported.SharedKeyCredential) *Client[generated.ServiceClient] {
func NewServiceClient(containerURL string, pipeline runtime.Pipeline, credential any) *Client[generated.ServiceClient] {
return &Client[generated.ServiceClient]{
inner: generated.NewServiceClient(containerURL, pipeline),
sharedKey: sharedKey,
inner: generated.NewServiceClient(containerURL, pipeline),
credential: credential,
}
}
func NewContainerClient(containerURL string, pipeline runtime.Pipeline, sharedKey *exported.SharedKeyCredential) *Client[generated.ContainerClient] {
func NewContainerClient(containerURL string, pipeline runtime.Pipeline, credential any) *Client[generated.ContainerClient] {
return &Client[generated.ContainerClient]{
inner: generated.NewContainerClient(containerURL, pipeline),
sharedKey: sharedKey,
inner: generated.NewContainerClient(containerURL, pipeline),
credential: credential,
}
}
func NewBlobClient(blobURL string, pipeline runtime.Pipeline, sharedKey *exported.SharedKeyCredential) *Client[generated.BlobClient] {
func NewBlobClient(blobURL string, pipeline runtime.Pipeline, credential any) *Client[generated.BlobClient] {
return &Client[generated.BlobClient]{
inner: generated.NewBlobClient(blobURL, pipeline),
sharedKey: sharedKey,
inner: generated.NewBlobClient(blobURL, pipeline),
credential: credential,
}
}

View file

@ -0,0 +1,279 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
package exported
import (
"bufio"
"bytes"
"errors"
"fmt"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
"github.com/Azure/azure-sdk-for-go/sdk/internal/uuid"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/shared"
"io"
"mime"
"mime/multipart"
"net/http"
"net/textproto"
"strconv"
"strings"
)
const (
batchIdPrefix = "batch_"
httpVersion = "HTTP/1.1"
httpNewline = "\r\n"
)
// createBatchID is used for creating a new batch id which is used as batch boundary in the request body
func createBatchID() (string, error) {
batchID, err := uuid.New()
if err != nil {
return "", err
}
return batchIdPrefix + batchID.String(), nil
}
// buildSubRequest is used for building the sub-request. Example:
// DELETE /container0/blob0 HTTP/1.1
// x-ms-date: Thu, 14 Jun 2018 16:46:54 GMT
// Authorization: SharedKey account:G4jjBXA7LI/RnWKIOQ8i9xH4p76pAQ+4Fs4R1VxasaE=
// Content-Length: 0
func buildSubRequest(req *policy.Request) []byte {
var batchSubRequest strings.Builder
blobPath := req.Raw().URL.Path
if len(req.Raw().URL.RawQuery) > 0 {
blobPath += "?" + req.Raw().URL.RawQuery
}
batchSubRequest.WriteString(fmt.Sprintf("%s %s %s%s", req.Raw().Method, blobPath, httpVersion, httpNewline))
for k, v := range req.Raw().Header {
if strings.EqualFold(k, shared.HeaderXmsVersion) {
continue
}
if len(v) > 0 {
batchSubRequest.WriteString(fmt.Sprintf("%v: %v%v", k, v[0], httpNewline))
}
}
batchSubRequest.WriteString(httpNewline)
return []byte(batchSubRequest.String())
}
// CreateBatchRequest creates a new batch request using the sub-requests present in the BlobBatchBuilder.
//
// Example of a sub-request in the batch request body:
//
// --batch_357de4f7-6d0b-4e02-8cd2-6361411a9525
// Content-Type: application/http
// Content-Transfer-Encoding: binary
// Content-ID: 0
//
// DELETE /container0/blob0 HTTP/1.1
// x-ms-date: Thu, 14 Jun 2018 16:46:54 GMT
// Authorization: SharedKey account:G4jjBXA7LI/RnWKIOQ8i9xH4p76pAQ+4Fs4R1VxasaE=
// Content-Length: 0
func CreateBatchRequest(bb *BlobBatchBuilder) ([]byte, string, error) {
batchID, err := createBatchID()
if err != nil {
return nil, "", err
}
// Create a new multipart buffer
reqBody := &bytes.Buffer{}
writer := multipart.NewWriter(reqBody)
// Set the boundary
err = writer.SetBoundary(batchID)
if err != nil {
return nil, "", err
}
partHeaders := make(textproto.MIMEHeader)
partHeaders["Content-Type"] = []string{"application/http"}
partHeaders["Content-Transfer-Encoding"] = []string{"binary"}
var partWriter io.Writer
for i, req := range bb.SubRequests {
if bb.AuthPolicy != nil {
_, err := bb.AuthPolicy.Do(req)
if err != nil && !strings.EqualFold(err.Error(), "no more policies") {
if log.Should(EventSubmitBatch) {
log.Writef(EventSubmitBatch, "failed to authorize sub-request for %v.\nError: %v", req.Raw().URL.Path, err.Error())
}
return nil, "", err
}
}
partHeaders["Content-ID"] = []string{fmt.Sprintf("%v", i)}
partWriter, err = writer.CreatePart(partHeaders)
if err != nil {
return nil, "", err
}
_, err = partWriter.Write(buildSubRequest(req))
if err != nil {
return nil, "", err
}
}
// Close the multipart writer
err = writer.Close()
if err != nil {
return nil, "", err
}
return reqBody.Bytes(), batchID, nil
}
// UpdateSubRequestHeaders updates the sub-request headers.
// Removes x-ms-version header.
func UpdateSubRequestHeaders(req *policy.Request) {
// remove x-ms-version header from the request header
for k := range req.Raw().Header {
if strings.EqualFold(k, shared.HeaderXmsVersion) {
delete(req.Raw().Header, k)
}
}
}
// BatchResponseItem contains the response for the individual sub-requests.
type BatchResponseItem struct {
ContentID *int
ContainerName *string
BlobName *string
RequestID *string
Version *string
Error error // nil error indicates that the batch sub-request operation is successful
}
func getResponseBoundary(contentType *string) (string, error) {
if contentType == nil {
return "", fmt.Errorf("Content-Type returned in SubmitBatch response is nil")
}
_, params, err := mime.ParseMediaType(*contentType)
if err != nil {
return "", err
}
if val, ok := params["boundary"]; ok {
return val, nil
} else {
return "", fmt.Errorf("batch boundary not present in Content-Type header of the SubmitBatch response.\nContent-Type: %v", *contentType)
}
}
func getContentID(part *multipart.Part) (*int, error) {
contentID := part.Header.Get("Content-ID")
if contentID == "" {
return nil, nil
}
val, err := strconv.Atoi(strings.TrimSpace(contentID))
if err != nil {
return nil, err
}
return &val, nil
}
func getResponseHeader(key string, resp *http.Response) *string {
val := resp.Header.Get(key)
if val == "" {
return nil
}
return &val
}
// ParseBlobBatchResponse is used for parsing the batch response body into individual sub-responses for each item in the batch.
func ParseBlobBatchResponse(respBody io.ReadCloser, contentType *string, subRequests []*policy.Request) ([]*BatchResponseItem, error) {
boundary, err := getResponseBoundary(contentType)
if err != nil {
return nil, err
}
respReader := multipart.NewReader(respBody, boundary)
var responses []*BatchResponseItem
for {
part, err := respReader.NextPart()
if errors.Is(err, io.EOF) {
break
} else if err != nil {
return nil, err
}
batchSubResponse := &BatchResponseItem{}
batchSubResponse.ContentID, err = getContentID(part)
if err != nil {
return nil, err
}
if batchSubResponse.ContentID != nil {
path := strings.Trim(subRequests[*batchSubResponse.ContentID].Raw().URL.Path, "/")
p := strings.Split(path, "/")
batchSubResponse.ContainerName = to.Ptr(p[0])
batchSubResponse.BlobName = to.Ptr(strings.Join(p[1:], "/"))
}
respBytes, err := io.ReadAll(part)
if err != nil {
return nil, err
}
respBytes = append(respBytes, byte('\n'))
buf := bytes.NewBuffer(respBytes)
resp, err := http.ReadResponse(bufio.NewReader(buf), nil)
// sub-response parsing error
if err != nil {
return nil, err
}
batchSubResponse.RequestID = getResponseHeader(shared.HeaderXmsRequestID, resp)
batchSubResponse.Version = getResponseHeader(shared.HeaderXmsVersion, resp)
// sub-response failure
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
if len(responses) == 0 && batchSubResponse.ContentID == nil {
// this case can happen when the parent request fails.
// For example, batch request having more than 256 sub-requests.
return nil, fmt.Errorf("%v", string(respBytes))
}
resp.Request = subRequests[*batchSubResponse.ContentID].Raw()
batchSubResponse.Error = runtime.NewResponseError(resp)
}
responses = append(responses, batchSubResponse)
}
if len(responses) != len(subRequests) {
return nil, fmt.Errorf("expected %v responses, got %v for the batch ID: %v", len(subRequests), len(responses), boundary)
}
return responses, nil
}
// not exported but used for batch request creation
// BlobBatchBuilder is used for creating the blob batch request
type BlobBatchBuilder struct {
AuthPolicy policy.Policy
SubRequests []*policy.Request
}
// BlobBatchOperationType defines the operation of the blob batch sub-requests.
type BlobBatchOperationType string
const (
BatchDeleteOperationType BlobBatchOperationType = "delete"
BatchSetTierOperationType BlobBatchOperationType = "set tier"
)

View file

@ -1,5 +1,8 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Licensed under the MIT License. See License.txt in the project root for license information.
package exported
@ -11,4 +14,7 @@ import (
const (
// EventUpload is used when we compute number of blocks to upload and size of each block.
EventUpload log.Event = "azblob.Upload"
// EventSubmitBatch is used for logging events related to submit blob batch operation.
EventSubmitBatch log.Event = "azblob.SubmitBatch"
)

View file

@ -8,5 +8,5 @@ package exported
const (
ModuleName = "azblob"
ModuleVersion = "v1.0.0"
ModuleVersion = "v1.1.0"
)

View file

@ -30,7 +30,7 @@ directive:
where: $
transform: >-
return $.
replace(/func \(client \*ContainerClient\) NewListBlobFlatSegmentPager\(.+\/\/ listBlobFlatSegmentCreateRequest creates the ListBlobFlatSegment request/s, `// listBlobFlatSegmentCreateRequest creates the ListBlobFlatSegment request`).
replace(/func \(client \*ContainerClient\) NewListBlobFlatSegmentPager\(.+\/\/ listBlobFlatSegmentCreateRequest creates the ListBlobFlatSegment request/s, `//\n// listBlobFlatSegmentCreateRequest creates the ListBlobFlatSegment request`).
replace(/\(client \*ContainerClient\) listBlobFlatSegmentCreateRequest\(/, `(client *ContainerClient) ListBlobFlatSegmentCreateRequest(`).
replace(/\(client \*ContainerClient\) listBlobFlatSegmentHandleResponse\(/, `(client *ContainerClient) ListBlobFlatSegmentHandleResponse(`);
```
@ -43,7 +43,7 @@ directive:
where: $
transform: >-
return $.
replace(/func \(client \*ServiceClient\) NewListContainersSegmentPager\(.+\/\/ listContainersSegmentCreateRequest creates the ListContainersSegment request/s, `// listContainersSegmentCreateRequest creates the ListContainersSegment request`).
replace(/func \(client \*ServiceClient\) NewListContainersSegmentPager\(.+\/\/ listContainersSegmentCreateRequest creates the ListContainersSegment request/s, `//\n// listContainersSegmentCreateRequest creates the ListContainersSegment request`).
replace(/\(client \*ServiceClient\) listContainersSegmentCreateRequest\(/, `(client *ServiceClient) ListContainersSegmentCreateRequest(`).
replace(/\(client \*ServiceClient\) listContainersSegmentHandleResponse\(/, `(client *ServiceClient) ListContainersSegmentHandleResponse(`);
```
@ -384,4 +384,54 @@ directive:
transform: >-
return $.
replace(/xml:"CORS>CORSRule"/g, "xml:\"Cors>CorsRule\"");
```
```
### Fix Content-Type header in submit batch request
``` yaml
directive:
- from:
- zz_container_client.go
- zz_service_client.go
where: $
transform: >-
return $.
replace (/req.SetBody\(body\,\s+\"application\/xml\"\)/g, `req.SetBody(body, multipartContentType)`);
```
### Fix response status code check in submit batch request
``` yaml
directive:
- from: zz_service_client.go
where: $
transform: >-
return $.
replace(/if\s+!runtime\.HasStatusCode\(resp,\s+http\.StatusOK\)\s+\{\s*\n\t\treturn\s+ServiceClientSubmitBatchResponse\{\}\,\s+runtime\.NewResponseError\(resp\)\s*\n\t\}/g,
`if !runtime.HasStatusCode(resp, http.StatusAccepted) {\n\t\treturn ServiceClientSubmitBatchResponse{}, runtime.NewResponseError(resp)\n\t}`);
```
### Convert time to GMT for If-Modified-Since and If-Unmodified-Since request headers
``` yaml
directive:
- from:
- zz_container_client.go
- zz_blob_client.go
- zz_appendblob_client.go
- zz_blockblob_client.go
- zz_pageblob_client.go
where: $
transform: >-
return $.
replace (/req\.Raw\(\)\.Header\[\"If-Modified-Since\"\]\s+=\s+\[\]string\{modifiedAccessConditions\.IfModifiedSince\.Format\(time\.RFC1123\)\}/g,
`req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}`).
replace (/req\.Raw\(\)\.Header\[\"If-Unmodified-Since\"\]\s+=\s+\[\]string\{modifiedAccessConditions\.IfUnmodifiedSince\.Format\(time\.RFC1123\)\}/g,
`req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}`).
replace (/req\.Raw\(\)\.Header\[\"x-ms-source-if-modified-since\"\]\s+=\s+\[\]string\{sourceModifiedAccessConditions\.SourceIfModifiedSince\.Format\(time\.RFC1123\)\}/g,
`req.Raw().Header["x-ms-source-if-modified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfModifiedSince).In(gmt).Format(time.RFC1123)}`).
replace (/req\.Raw\(\)\.Header\[\"x-ms-source-if-unmodified-since\"\]\s+=\s+\[\]string\{sourceModifiedAccessConditions\.SourceIfUnmodifiedSince\.Format\(time\.RFC1123\)\}/g,
`req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)}`).
replace (/req\.Raw\(\)\.Header\[\"x-ms-immutability-policy-until-date\"\]\s+=\s+\[\]string\{options\.ImmutabilityPolicyExpiry\.Format\(time\.RFC1123\)\}/g,
`req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}`);

View file

@ -6,7 +6,15 @@
package generated
import "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
import (
"context"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"time"
)
// used to convert times from UTC to GMT before sending across the wire
var gmt = time.FixedZone("GMT", 0)
func (client *BlobClient) Endpoint() string {
return client.endpoint
@ -15,3 +23,11 @@ func (client *BlobClient) Endpoint() string {
func (client *BlobClient) Pipeline() runtime.Pipeline {
return client.pl
}
func (client *BlobClient) DeleteCreateRequest(ctx context.Context, options *BlobClientDeleteOptions, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions) (*policy.Request, error) {
return client.deleteCreateRequest(ctx, options, leaseAccessConditions, modifiedAccessConditions)
}
func (client *BlobClient) SetTierCreateRequest(ctx context.Context, tier AccessTier, options *BlobClientSetTierOptions, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions) (*policy.Request, error) {
return client.setTierCreateRequest(ctx, tier, options, leaseAccessConditions, modifiedAccessConditions)
}

View file

@ -110,10 +110,10 @@ func (client *AppendBlobClient) appendBlockCreateRequest(ctx context.Context, co
req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -283,10 +283,10 @@ func (client *AppendBlobClient) appendBlockFromURLCreateRequest(ctx context.Cont
req.Raw().Header["x-ms-blob-condition-appendpos"] = []string{strconv.FormatInt(*appendPositionAccessConditions.AppendPosition, 10)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -298,10 +298,10 @@ func (client *AppendBlobClient) appendBlockFromURLCreateRequest(ctx context.Cont
req.Raw().Header["x-ms-if-tags"] = []string{*modifiedAccessConditions.IfTags}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfModifiedSince != nil {
req.Raw().Header["x-ms-source-if-modified-since"] = []string{sourceModifiedAccessConditions.SourceIfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-modified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfUnmodifiedSince != nil {
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{sourceModifiedAccessConditions.SourceIfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfMatch != nil {
req.Raw().Header["x-ms-source-if-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfMatch)}
@ -467,10 +467,10 @@ func (client *AppendBlobClient) createCreateRequest(ctx context.Context, content
req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -489,7 +489,7 @@ func (client *AppendBlobClient) createCreateRequest(ctx context.Context, content
req.Raw().Header["x-ms-tags"] = []string{*options.BlobTagsString}
}
if options != nil && options.ImmutabilityPolicyExpiry != nil {
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{options.ImmutabilityPolicyExpiry.Format(time.RFC1123)}
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}
}
if options != nil && options.ImmutabilityPolicyMode != nil {
req.Raw().Header["x-ms-immutability-policy-mode"] = []string{string(*options.ImmutabilityPolicyMode)}
@ -601,10 +601,10 @@ func (client *AppendBlobClient) sealCreateRequest(ctx context.Context, options *
req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}

View file

@ -152,10 +152,10 @@ func (client *BlobClient) acquireLeaseCreateRequest(ctx context.Context, duratio
req.Raw().Header["x-ms-proposed-lease-id"] = []string{*options.ProposedLeaseID}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -247,10 +247,10 @@ func (client *BlobClient) breakLeaseCreateRequest(ctx context.Context, options *
req.Raw().Header["x-ms-lease-break-period"] = []string{strconv.FormatInt(int64(*options.BreakPeriod), 10)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -350,10 +350,10 @@ func (client *BlobClient) changeLeaseCreateRequest(ctx context.Context, leaseID
req.Raw().Header["x-ms-lease-id"] = []string{leaseID}
req.Raw().Header["x-ms-proposed-lease-id"] = []string{proposedLeaseID}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -458,10 +458,10 @@ func (client *BlobClient) copyFromURLCreateRequest(ctx context.Context, copySour
req.Raw().Header["x-ms-access-tier"] = []string{string(*options.Tier)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfModifiedSince != nil {
req.Raw().Header["x-ms-source-if-modified-since"] = []string{sourceModifiedAccessConditions.SourceIfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-modified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfUnmodifiedSince != nil {
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{sourceModifiedAccessConditions.SourceIfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfMatch != nil {
req.Raw().Header["x-ms-source-if-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfMatch)}
@ -470,10 +470,10 @@ func (client *BlobClient) copyFromURLCreateRequest(ctx context.Context, copySour
req.Raw().Header["x-ms-source-if-none-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfNoneMatch)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -499,7 +499,7 @@ func (client *BlobClient) copyFromURLCreateRequest(ctx context.Context, copySour
req.Raw().Header["x-ms-tags"] = []string{*options.BlobTagsString}
}
if options != nil && options.ImmutabilityPolicyExpiry != nil {
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{options.ImmutabilityPolicyExpiry.Format(time.RFC1123)}
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}
}
if options != nil && options.ImmutabilityPolicyMode != nil {
req.Raw().Header["x-ms-immutability-policy-mode"] = []string{string(*options.ImmutabilityPolicyMode)}
@ -625,10 +625,10 @@ func (client *BlobClient) createSnapshotCreateRequest(ctx context.Context, optio
req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -754,10 +754,10 @@ func (client *BlobClient) deleteCreateRequest(ctx context.Context, options *Blob
req.Raw().Header["x-ms-delete-snapshots"] = []string{string(*options.DeleteSnapshots)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -925,10 +925,10 @@ func (client *BlobClient) downloadCreateRequest(ctx context.Context, options *Bl
req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -1277,10 +1277,10 @@ func (client *BlobClient) getPropertiesCreateRequest(ctx context.Context, option
req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -1670,10 +1670,10 @@ func (client *BlobClient) queryCreateRequest(ctx context.Context, options *BlobC
req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -1883,10 +1883,10 @@ func (client *BlobClient) releaseLeaseCreateRequest(ctx context.Context, leaseID
req.Raw().Header["x-ms-lease-action"] = []string{"release"}
req.Raw().Header["x-ms-lease-id"] = []string{leaseID}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -1974,10 +1974,10 @@ func (client *BlobClient) renewLeaseCreateRequest(ctx context.Context, leaseID s
req.Raw().Header["x-ms-lease-action"] = []string{"renew"}
req.Raw().Header["x-ms-lease-id"] = []string{leaseID}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -2162,10 +2162,10 @@ func (client *BlobClient) setHTTPHeadersCreateRequest(ctx context.Context, optio
req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -2265,10 +2265,10 @@ func (client *BlobClient) setImmutabilityPolicyCreateRequest(ctx context.Context
req.Raw().Header["x-ms-client-request-id"] = []string{*options.RequestID}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if options != nil && options.ImmutabilityPolicyExpiry != nil {
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{options.ImmutabilityPolicyExpiry.Format(time.RFC1123)}
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}
}
if options != nil && options.ImmutabilityPolicyMode != nil {
req.Raw().Header["x-ms-immutability-policy-mode"] = []string{string(*options.ImmutabilityPolicyMode)}
@ -2440,10 +2440,10 @@ func (client *BlobClient) setMetadataCreateRequest(ctx context.Context, options
req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -2719,10 +2719,10 @@ func (client *BlobClient) startCopyFromURLCreateRequest(ctx context.Context, cop
req.Raw().Header["x-ms-rehydrate-priority"] = []string{string(*options.RehydratePriority)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfModifiedSince != nil {
req.Raw().Header["x-ms-source-if-modified-since"] = []string{sourceModifiedAccessConditions.SourceIfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-modified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfUnmodifiedSince != nil {
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{sourceModifiedAccessConditions.SourceIfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfMatch != nil {
req.Raw().Header["x-ms-source-if-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfMatch)}
@ -2734,10 +2734,10 @@ func (client *BlobClient) startCopyFromURLCreateRequest(ctx context.Context, cop
req.Raw().Header["x-ms-source-if-tags"] = []string{*sourceModifiedAccessConditions.SourceIfTags}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -2763,7 +2763,7 @@ func (client *BlobClient) startCopyFromURLCreateRequest(ctx context.Context, cop
req.Raw().Header["x-ms-seal-blob"] = []string{strconv.FormatBool(*options.SealBlob)}
}
if options != nil && options.ImmutabilityPolicyExpiry != nil {
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{options.ImmutabilityPolicyExpiry.Format(time.RFC1123)}
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}
}
if options != nil && options.ImmutabilityPolicyMode != nil {
req.Raw().Header["x-ms-immutability-policy-mode"] = []string{string(*options.ImmutabilityPolicyMode)}

View file

@ -134,10 +134,10 @@ func (client *BlockBlobClient) commitBlockListCreateRequest(ctx context.Context,
req.Raw().Header["x-ms-access-tier"] = []string{string(*options.Tier)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -156,7 +156,7 @@ func (client *BlockBlobClient) commitBlockListCreateRequest(ctx context.Context,
req.Raw().Header["x-ms-tags"] = []string{*options.BlobTagsString}
}
if options != nil && options.ImmutabilityPolicyExpiry != nil {
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{options.ImmutabilityPolicyExpiry.Format(time.RFC1123)}
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}
}
if options != nil && options.ImmutabilityPolicyMode != nil {
req.Raw().Header["x-ms-immutability-policy-mode"] = []string{string(*options.ImmutabilityPolicyMode)}
@ -424,10 +424,10 @@ func (client *BlockBlobClient) putBlobFromURLCreateRequest(ctx context.Context,
req.Raw().Header["x-ms-access-tier"] = []string{string(*options.Tier)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -439,10 +439,10 @@ func (client *BlockBlobClient) putBlobFromURLCreateRequest(ctx context.Context,
req.Raw().Header["x-ms-if-tags"] = []string{*modifiedAccessConditions.IfTags}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfModifiedSince != nil {
req.Raw().Header["x-ms-source-if-modified-since"] = []string{sourceModifiedAccessConditions.SourceIfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-modified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfUnmodifiedSince != nil {
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{sourceModifiedAccessConditions.SourceIfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfMatch != nil {
req.Raw().Header["x-ms-source-if-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfMatch)}
@ -721,10 +721,10 @@ func (client *BlockBlobClient) stageBlockFromURLCreateRequest(ctx context.Contex
req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfModifiedSince != nil {
req.Raw().Header["x-ms-source-if-modified-since"] = []string{sourceModifiedAccessConditions.SourceIfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-modified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfUnmodifiedSince != nil {
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{sourceModifiedAccessConditions.SourceIfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfMatch != nil {
req.Raw().Header["x-ms-source-if-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfMatch)}
@ -882,10 +882,10 @@ func (client *BlockBlobClient) uploadCreateRequest(ctx context.Context, contentL
req.Raw().Header["x-ms-access-tier"] = []string{string(*options.Tier)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -904,7 +904,7 @@ func (client *BlockBlobClient) uploadCreateRequest(ctx context.Context, contentL
req.Raw().Header["x-ms-tags"] = []string{*options.BlobTagsString}
}
if options != nil && options.ImmutabilityPolicyExpiry != nil {
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{options.ImmutabilityPolicyExpiry.Format(time.RFC1123)}
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}
}
if options != nil && options.ImmutabilityPolicyMode != nil {
req.Raw().Header["x-ms-immutability-policy-mode"] = []string{string(*options.ImmutabilityPolicyMode)}

View file

@ -86,10 +86,10 @@ func (client *ContainerClient) acquireLeaseCreateRequest(ctx context.Context, du
req.Raw().Header["x-ms-proposed-lease-id"] = []string{*options.ProposedLeaseID}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
req.Raw().Header["x-ms-version"] = []string{"2020-10-02"}
if options != nil && options.RequestID != nil {
@ -174,10 +174,10 @@ func (client *ContainerClient) breakLeaseCreateRequest(ctx context.Context, opti
req.Raw().Header["x-ms-lease-break-period"] = []string{strconv.FormatInt(int64(*options.BreakPeriod), 10)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
req.Raw().Header["x-ms-version"] = []string{"2020-10-02"}
if options != nil && options.RequestID != nil {
@ -270,10 +270,10 @@ func (client *ContainerClient) changeLeaseCreateRequest(ctx context.Context, lea
req.Raw().Header["x-ms-lease-id"] = []string{leaseID}
req.Raw().Header["x-ms-proposed-lease-id"] = []string{proposedLeaseID}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
req.Raw().Header["x-ms-version"] = []string{"2020-10-02"}
if options != nil && options.RequestID != nil {
@ -447,10 +447,10 @@ func (client *ContainerClient) deleteCreateRequest(ctx context.Context, options
req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
req.Raw().Header["x-ms-version"] = []string{"2020-10-02"}
if options != nil && options.RequestID != nil {
@ -963,10 +963,10 @@ func (client *ContainerClient) releaseLeaseCreateRequest(ctx context.Context, le
req.Raw().Header["x-ms-lease-action"] = []string{"release"}
req.Raw().Header["x-ms-lease-id"] = []string{leaseID}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
req.Raw().Header["x-ms-version"] = []string{"2020-10-02"}
if options != nil && options.RequestID != nil {
@ -1115,10 +1115,10 @@ func (client *ContainerClient) renewLeaseCreateRequest(ctx context.Context, leas
req.Raw().Header["x-ms-lease-action"] = []string{"renew"}
req.Raw().Header["x-ms-lease-id"] = []string{leaseID}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
req.Raw().Header["x-ms-version"] = []string{"2020-10-02"}
if options != nil && options.RequestID != nil {
@ -1277,10 +1277,10 @@ func (client *ContainerClient) setAccessPolicyCreateRequest(ctx context.Context,
req.Raw().Header["x-ms-blob-public-access"] = []string{string(*options.Access)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
req.Raw().Header["x-ms-version"] = []string{"2020-10-02"}
if options != nil && options.RequestID != nil {
@ -1372,7 +1372,7 @@ func (client *ContainerClient) setMetadataCreateRequest(ctx context.Context, opt
}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
req.Raw().Header["x-ms-version"] = []string{"2020-10-02"}
if options != nil && options.RequestID != nil {
@ -1459,7 +1459,7 @@ func (client *ContainerClient) submitBatchCreateRequest(ctx context.Context, con
req.Raw().Header["x-ms-client-request-id"] = []string{*options.RequestID}
}
req.Raw().Header["Accept"] = []string{"application/xml"}
return req, req.SetBody(body, "application/xml")
return req, req.SetBody(body, multipartContentType)
}
// submitBatchHandleResponse handles the SubmitBatch response.

View file

@ -108,10 +108,10 @@ func (client *PageBlobClient) clearPagesCreateRequest(ctx context.Context, conte
req.Raw().Header["x-ms-if-sequence-number-eq"] = []string{strconv.FormatInt(*sequenceNumberAccessConditions.IfSequenceNumberEqualTo, 10)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -225,10 +225,10 @@ func (client *PageBlobClient) copyIncrementalCreateRequest(ctx context.Context,
}
req.Raw().URL.RawQuery = reqQP.Encode()
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -371,10 +371,10 @@ func (client *PageBlobClient) createCreateRequest(ctx context.Context, contentLe
req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -397,7 +397,7 @@ func (client *PageBlobClient) createCreateRequest(ctx context.Context, contentLe
req.Raw().Header["x-ms-tags"] = []string{*options.BlobTagsString}
}
if options != nil && options.ImmutabilityPolicyExpiry != nil {
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{options.ImmutabilityPolicyExpiry.Format(time.RFC1123)}
req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}
}
if options != nil && options.ImmutabilityPolicyMode != nil {
req.Raw().Header["x-ms-immutability-policy-mode"] = []string{string(*options.ImmutabilityPolicyMode)}
@ -528,10 +528,10 @@ func (client *PageBlobClient) GetPageRangesCreateRequest(ctx context.Context, op
req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -662,10 +662,10 @@ func (client *PageBlobClient) GetPageRangesDiffCreateRequest(ctx context.Context
req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -780,10 +780,10 @@ func (client *PageBlobClient) resizeCreateRequest(ctx context.Context, blobConte
req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -883,10 +883,10 @@ func (client *PageBlobClient) updateSequenceNumberCreateRequest(ctx context.Cont
req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -1024,10 +1024,10 @@ func (client *PageBlobClient) uploadPagesCreateRequest(ctx context.Context, cont
req.Raw().Header["x-ms-if-sequence-number-eq"] = []string{strconv.FormatInt(*sequenceNumberAccessConditions.IfSequenceNumberEqualTo, 10)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -1196,10 +1196,10 @@ func (client *PageBlobClient) uploadPagesFromURLCreateRequest(ctx context.Contex
req.Raw().Header["x-ms-if-sequence-number-eq"] = []string{strconv.FormatInt(*sequenceNumberAccessConditions.IfSequenceNumberEqualTo, 10)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
@ -1211,10 +1211,10 @@ func (client *PageBlobClient) uploadPagesFromURLCreateRequest(ctx context.Contex
req.Raw().Header["x-ms-if-tags"] = []string{*modifiedAccessConditions.IfTags}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfModifiedSince != nil {
req.Raw().Header["x-ms-source-if-modified-since"] = []string{sourceModifiedAccessConditions.SourceIfModifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-modified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfModifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfUnmodifiedSince != nil {
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{sourceModifiedAccessConditions.SourceIfUnmodifiedSince.Format(time.RFC1123)}
req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
}
if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfMatch != nil {
req.Raw().Header["x-ms-source-if-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfMatch)}

View file

@ -513,7 +513,7 @@ func (client *ServiceClient) SubmitBatch(ctx context.Context, contentLength int6
if err != nil {
return ServiceClientSubmitBatchResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
if !runtime.HasStatusCode(resp, http.StatusAccepted) {
return ServiceClientSubmitBatchResponse{}, runtime.NewResponseError(resp)
}
return client.submitBatchHandleResponse(resp)
@ -539,7 +539,7 @@ func (client *ServiceClient) submitBatchCreateRequest(ctx context.Context, conte
req.Raw().Header["x-ms-client-request-id"] = []string{*options.RequestID}
}
req.Raw().Header["Accept"] = []string{"application/xml"}
return req, req.SetBody(body, "application/xml")
return req, req.SetBody(body, multipartContentType)
}
// submitBatchHandleResponse handles the SubmitBatch response.

View file

@ -0,0 +1,113 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
package shared
import (
"errors"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"net/http"
"strings"
)
type storageAuthorizer struct {
scopes []string
tenantID string
}
func NewStorageChallengePolicy(cred azcore.TokenCredential) policy.Policy {
s := storageAuthorizer{scopes: []string{TokenScope}}
return runtime.NewBearerTokenPolicy(cred, []string{TokenScope}, &policy.BearerTokenOptions{
AuthorizationHandler: policy.AuthorizationHandler{
OnRequest: s.onRequest,
OnChallenge: s.onChallenge,
},
})
}
func (s *storageAuthorizer) onRequest(req *policy.Request, authNZ func(policy.TokenRequestOptions) error) error {
return authNZ(policy.TokenRequestOptions{Scopes: s.scopes})
}
func (s *storageAuthorizer) onChallenge(req *policy.Request, resp *http.Response, authNZ func(policy.TokenRequestOptions) error) error {
// parse the challenge
err := s.parseChallenge(resp)
if err != nil {
return err
}
// TODO: Set tenantID when policy.TokenRequestOptions supports it. https://github.com/Azure/azure-sdk-for-go/issues/19841
return authNZ(policy.TokenRequestOptions{Scopes: s.scopes})
}
type challengePolicyError struct {
err error
}
func (c *challengePolicyError) Error() string {
return c.err.Error()
}
func (*challengePolicyError) NonRetriable() {
// marker method
}
func (c *challengePolicyError) Unwrap() error {
return c.err
}
// parses Tenant ID from auth challenge
// https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/oauth2/authorize
func parseTenant(url string) string {
if url == "" {
return ""
}
parts := strings.Split(url, "/")
if len(parts) >= 3 {
tenant := parts[3]
tenant = strings.ReplaceAll(tenant, ",", "")
return tenant
} else {
return ""
}
}
func (s *storageAuthorizer) parseChallenge(resp *http.Response) error {
authHeader := resp.Header.Get("WWW-Authenticate")
if authHeader == "" {
return &challengePolicyError{err: errors.New("response has no WWW-Authenticate header for challenge authentication")}
}
// Strip down to auth and resource
// Format is "Bearer authorization_uri=\"<site>\" resource_id=\"<site>\""
authHeader = strings.ReplaceAll(authHeader, "Bearer ", "")
parts := strings.Split(authHeader, " ")
vals := map[string]string{}
for _, part := range parts {
subParts := strings.Split(part, "=")
if len(subParts) == 2 {
stripped := strings.ReplaceAll(subParts[1], "\"", "")
stripped = strings.TrimSuffix(stripped, ",")
vals[subParts[0]] = stripped
}
}
s.tenantID = parseTenant(vals["authorization_uri"])
scope := vals["resource_id"]
if scope == "" {
return &challengePolicyError{err: errors.New("could not find a valid resource in the WWW-Authenticate header")}
}
if !strings.HasSuffix(scope, "/.default") {
scope += "/.default"
}
s.scopes = []string{scope}
return nil
}

View file

@ -38,6 +38,8 @@ const (
HeaderIfNoneMatch = "If-None-Match"
HeaderIfUnmodifiedSince = "If-Unmodified-Since"
HeaderRange = "Range"
HeaderXmsVersion = "x-ms-version"
HeaderXmsRequestID = "x-ms-request-id"
)
const crc64Polynomial uint64 = 0x9A6C9329AC4BC9B5
@ -85,22 +87,6 @@ func ParseConnectionString(connectionString string) (ParsedConnectionString, err
connStrMap[parts[0]] = parts[1]
}
accountName, ok := connStrMap["AccountName"]
if !ok {
return ParsedConnectionString{}, errors.New("connection string missing AccountName")
}
accountKey, ok := connStrMap["AccountKey"]
if !ok {
sharedAccessSignature, ok := connStrMap["SharedAccessSignature"]
if !ok {
return ParsedConnectionString{}, errors.New("connection string missing AccountKey and SharedAccessSignature")
}
return ParsedConnectionString{
ServiceURL: fmt.Sprintf("%v://%v.blob.%v/?%v", defaultScheme, accountName, defaultSuffix, sharedAccessSignature),
}, nil
}
protocol, ok := connStrMap["DefaultEndpointsProtocol"]
if !ok {
protocol = defaultScheme
@ -111,24 +97,45 @@ func ParseConnectionString(connectionString string) (ParsedConnectionString, err
suffix = defaultSuffix
}
if blobEndpoint, ok := connStrMap["BlobEndpoint"]; ok {
blobEndpoint, has_blobEndpoint := connStrMap["BlobEndpoint"]
accountName, has_accountName := connStrMap["AccountName"]
var serviceURL string
if has_blobEndpoint {
serviceURL = blobEndpoint
} else if has_accountName {
serviceURL = fmt.Sprintf("%v://%v.blob.%v", protocol, accountName, suffix)
} else {
return ParsedConnectionString{}, errors.New("connection string needs either AccountName or BlobEndpoint")
}
if !strings.HasSuffix(serviceURL, "/") {
// add a trailing slash to be consistent with the portal
serviceURL += "/"
}
accountKey, has_accountKey := connStrMap["AccountKey"]
sharedAccessSignature, has_sharedAccessSignature := connStrMap["SharedAccessSignature"]
if has_accountName && has_accountKey {
return ParsedConnectionString{
ServiceURL: blobEndpoint,
ServiceURL: serviceURL,
AccountName: accountName,
AccountKey: accountKey,
}, nil
} else if has_sharedAccessSignature {
return ParsedConnectionString{
ServiceURL: fmt.Sprintf("%v?%v", serviceURL, sharedAccessSignature),
}, nil
} else {
return ParsedConnectionString{}, errors.New("connection string needs either AccountKey or SharedAccessSignature")
}
return ParsedConnectionString{
ServiceURL: fmt.Sprintf("%v://%v.blob.%v", protocol, accountName, suffix),
AccountName: accountName,
AccountKey: accountKey,
}, nil
}
// SerializeBlobTags converts tags to generated.BlobTags
func SerializeBlobTags(tagsMap map[string]string) *generated.BlobTags {
if tagsMap == nil {
if len(tagsMap) == 0 {
return nil
}
blobTagSet := make([]*generated.BlobTag, 0)
@ -140,7 +147,7 @@ func SerializeBlobTags(tagsMap map[string]string) *generated.BlobTags {
}
func SerializeBlobTagsToStrPtr(tagsMap map[string]string) *string {
if tagsMap == nil {
if len(tagsMap) == 0 {
return nil
}
tags := make([]string, 0)

View file

@ -3,9 +3,14 @@
package azblob
import "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/exported"
import (
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/exported"
)
const (
// EventUpload is used for logging events related to upload operation.
EventUpload = exported.EventUpload
// EventSubmitBatch is used for logging events related to submit blob batch operation.
EventSubmitBatch = exported.EventSubmitBatch
)

View file

@ -25,9 +25,7 @@ import (
)
// ClientOptions contains the optional parameters when creating a Client.
type ClientOptions struct {
azcore.ClientOptions
}
type ClientOptions base.ClientOptions
// Client represents a client to an Azure Storage page blob;
type Client base.CompositeClient[generated.BlobClient, generated.PageBlobClient]
@ -37,7 +35,7 @@ type Client base.CompositeClient[generated.BlobClient, generated.PageBlobClient]
// - cred - an Azure AD credential, typically obtained via the azidentity module
// - options - client options; pass nil to accept the default values
func NewClient(blobURL string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) {
authPolicy := runtime.NewBearerTokenPolicy(cred, []string{shared.TokenScope}, nil)
authPolicy := shared.NewStorageChallengePolicy(cred)
conOptions := shared.GetClientOptions(options)
conOptions.PerRetryPolicies = append(conOptions.PerRetryPolicies, authPolicy)
pl := runtime.NewPipeline(exported.ModuleName, exported.ModuleVersion, runtime.PipelineOptions{}, &conOptions.ClientOptions)
@ -363,6 +361,12 @@ func (pb *Client) GetProperties(ctx context.Context, o *blob.GetPropertiesOption
return pb.BlobClient().GetProperties(ctx, o)
}
// GetAccountInfo provides account level information
// For more information, see https://learn.microsoft.com/en-us/rest/api/storageservices/get-account-information?tabs=shared-access-signatures.
func (pb *Client) GetAccountInfo(ctx context.Context, o *blob.GetAccountInfoOptions) (blob.GetAccountInfoResponse, error) {
return pb.BlobClient().GetAccountInfo(ctx, o)
}
// SetHTTPHeaders changes a blob's HTTP headers.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-blob-properties.
func (pb *Client) SetHTTPHeaders(ctx context.Context, HTTPHeaders blob.HTTPHeaders, o *blob.SetHTTPHeadersOptions) (blob.SetHTTPHeadersResponse, error) {

View file

@ -29,9 +29,9 @@ type AccountSignatureValues struct {
Protocol Protocol `param:"spr"` // See the SASProtocol* constants
StartTime time.Time `param:"st"` // Not specified if IsZero
ExpiryTime time.Time `param:"se"` // Not specified if IsZero
Permissions string `param:"sp"` // Create by initializing a AccountSASPermissions and then call String()
Permissions string `param:"sp"` // Create by initializing AccountPermissions and then call String()
IPRange IPRange `param:"sip"`
ResourceTypes string `param:"srt"` // Create by initializing AccountSASResourceTypes and then call String()
ResourceTypes string `param:"srt"` // Create by initializing AccountResourceTypes and then call String()
}
// SignWithSharedKey uses an account's shared key credential to sign this signature values to produce
@ -50,6 +50,12 @@ func (v AccountSignatureValues) SignWithSharedKey(sharedKeyCredential *SharedKey
}
v.Permissions = perms.String()
resources, err := parseAccountResourceTypes(v.ResourceTypes)
if err != nil {
return QueryParameters{}, err
}
v.ResourceTypes = resources.String()
startTime, expiryTime, _ := formatTimesForSigning(v.StartTime, v.ExpiryTime, time.Time{})
stringToSign := strings.Join([]string{
@ -90,13 +96,13 @@ func (v AccountSignatureValues) SignWithSharedKey(sharedKeyCredential *SharedKey
}
// AccountPermissions type simplifies creating the permissions string for an Azure Storage Account SAS.
// Initialize an instance of this type and then call Client.GetSASURL with it or use the String method to set AccountSASSignatureValues Permissions field.
// Initialize an instance of this type and then call its String method to set AccountSignatureValues' Permissions field.
type AccountPermissions struct {
Read, Write, Delete, DeletePreviousVersion, PermanentDelete, List, Add, Create, Update, Process, FilterByTags, Tag, SetImmutabilityPolicy bool
}
// String produces the SAS permissions string for an Azure Storage account.
// Call this method to set AccountSASSignatureValues' Permissions field.
// Call this method to set AccountSignatureValues' Permissions field.
func (p *AccountPermissions) String() string {
var buffer bytes.Buffer
if p.Read {
@ -141,7 +147,7 @@ func (p *AccountPermissions) String() string {
return buffer.String()
}
// Parse initializes the AccountSASPermissions' fields from a string.
// Parse initializes the AccountPermissions' fields from a string.
func parseAccountPermissions(s string) (AccountPermissions, error) {
p := AccountPermissions{} // Clear out the flags
for _, r := range s {
@ -180,13 +186,13 @@ func parseAccountPermissions(s string) (AccountPermissions, error) {
}
// AccountResourceTypes type simplifies creating the resource types string for an Azure Storage Account SAS.
// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues' ResourceTypes field.
// Initialize an instance of this type and then call its String method to set AccountSignatureValues' ResourceTypes field.
type AccountResourceTypes struct {
Service, Container, Object bool
}
// String produces the SAS resource types string for an Azure Storage account.
// Call this method to set AccountSASSignatureValues' ResourceTypes field.
// Call this method to set AccountSignatureValues' ResourceTypes field.
func (rt *AccountResourceTypes) String() string {
var buffer bytes.Buffer
if rt.Service {
@ -200,3 +206,21 @@ func (rt *AccountResourceTypes) String() string {
}
return buffer.String()
}
// parseAccountResourceTypes initializes the AccountResourceTypes' fields from a string.
func parseAccountResourceTypes(s string) (AccountResourceTypes, error) {
rt := AccountResourceTypes{}
for _, r := range s {
switch r {
case 's':
rt.Service = true
case 'c':
rt.Container = true
case 'o':
rt.Object = true
default:
return AccountResourceTypes{}, fmt.Errorf("invalid resource type character: '%v'", r)
}
}
return rt, nil
}

View file

@ -8,6 +8,7 @@ package sas
import (
"bytes"
"errors"
"fmt"
"strings"
"time"
@ -24,7 +25,7 @@ type BlobSignatureValues struct {
StartTime time.Time `param:"st"` // Not specified if IsZero
ExpiryTime time.Time `param:"se"` // Not specified if IsZero
SnapshotTime time.Time
Permissions string `param:"sp"` // Create by initializing a ContainerSASPermissions or BlobSASPermissions and then call String()
Permissions string `param:"sp"` // Create by initializing ContainerPermissions or BlobPermissions and then call String()
IPRange IPRange `param:"sip"`
Identifier string `param:"si"`
ContainerName string
@ -50,8 +51,8 @@ func getDirectoryDepth(path string) string {
// SignWithSharedKey uses an account's SharedKeyCredential to sign this signature values to produce the proper SAS query parameters.
func (v BlobSignatureValues) SignWithSharedKey(sharedKeyCredential *SharedKeyCredential) (QueryParameters, error) {
if sharedKeyCredential == nil {
return QueryParameters{}, fmt.Errorf("cannot sign SAS query without Shared Key Credential")
if v.ExpiryTime.IsZero() || v.Permissions == "" {
return QueryParameters{}, errors.New("service SAS is missing at least one of these: ExpiryTime or Permissions")
}
//Make sure the permission characters are in the correct order
@ -141,6 +142,10 @@ func (v BlobSignatureValues) SignWithUserDelegation(userDelegationCredential *Us
return QueryParameters{}, fmt.Errorf("cannot sign SAS query without User Delegation Key")
}
if v.ExpiryTime.IsZero() || v.Permissions == "" {
return QueryParameters{}, errors.New("user delegation SAS is missing at least one of these: ExpiryTime or Permissions")
}
// Parse the resource
resource := "c"
if !v.SnapshotTime.IsZero() {
@ -261,15 +266,15 @@ func getCanonicalName(account string, containerName string, blobName string, dir
}
// ContainerPermissions type simplifies creating the permissions string for an Azure Storage container SAS.
// Initialize an instance of this type and then call Client.GetSASURL with it or use the String method to set BlobSASSignatureValues Permissions field.
// Initialize an instance of this type and then call its String method to set BlobSignatureValues' Permissions field.
// All permissions descriptions can be found here: https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas#permissions-for-a-directory-container-or-blob
type ContainerPermissions struct {
Read, Add, Create, Write, Delete, DeletePreviousVersion, List, FilterByTags, Move, SetImmutabilityPolicy bool
Execute, ModifyOwnership, ModifyPermissions bool // Meant for hierarchical namespace accounts
Read, Add, Create, Write, Delete, DeletePreviousVersion, List, Tag, FilterByTags, Move, SetImmutabilityPolicy bool
Execute, ModifyOwnership, ModifyPermissions bool // Meant for hierarchical namespace accounts
}
// String produces the SAS permissions string for an Azure Storage container.
// Call this method to set BlobSASSignatureValues' Permissions field.
// Call this method to set BlobSignatureValues' Permissions field.
func (p *ContainerPermissions) String() string {
var b bytes.Buffer
if p.Read {
@ -293,6 +298,9 @@ func (p *ContainerPermissions) String() string {
if p.List {
b.WriteRune('l')
}
if p.Tag {
b.WriteRune('t')
}
if p.FilterByTags {
b.WriteRune('f')
}
@ -333,6 +341,8 @@ func parseContainerPermissions(s string) (ContainerPermissions, error) {
p.DeletePreviousVersion = true
case 'l':
p.List = true
case 't':
p.Tag = true
case 'f':
p.FilterByTags = true
case 'm':
@ -353,13 +363,13 @@ func parseContainerPermissions(s string) (ContainerPermissions, error) {
}
// BlobPermissions type simplifies creating the permissions string for an Azure Storage blob SAS.
// Initialize an instance of this type and then call Client.GetSASURL with it or use the String method to set BlobSASSignatureValues Permissions field.
// Initialize an instance of this type and then call its String method to set BlobSignatureValues' Permissions field.
type BlobPermissions struct {
Read, Add, Create, Write, Delete, DeletePreviousVersion, PermanentDelete, List, Tag, Move, Execute, Ownership, Permissions, SetImmutabilityPolicy bool
}
// String produces the SAS permissions string for an Azure Storage blob.
// Call this method to set BlobSignatureValue's Permissions field.
// Call this method to set BlobSignatureValues' Permissions field.
func (p *BlobPermissions) String() string {
var b bytes.Buffer
if p.Read {

View file

@ -0,0 +1,94 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
package service
import (
"context"
"fmt"
"net/url"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/exported"
)
// BatchBuilder is used for creating the batch operations list. It contains the list of either delete or set tier sub-requests.
// NOTE: All sub-requests in the batch must be of the same type, either delete or set tier.
type BatchBuilder struct {
endpoint string
authPolicy policy.Policy
subRequests []*policy.Request
operationType *exported.BlobBatchOperationType
}
func (bb *BatchBuilder) checkOperationType(operationType exported.BlobBatchOperationType) error {
if bb.operationType == nil {
bb.operationType = &operationType
return nil
}
if *bb.operationType != operationType {
return fmt.Errorf("BlobBatch only supports one operation type per batch and is already being used for %s operations", *bb.operationType)
}
return nil
}
// Delete operation is used to add delete sub-request to the batch builder.
func (bb *BatchBuilder) Delete(containerName string, blobName string, options *BatchDeleteOptions) error {
err := bb.checkOperationType(exported.BatchDeleteOperationType)
if err != nil {
return err
}
blobName = url.PathEscape(blobName)
blobURL := runtime.JoinPaths(bb.endpoint, containerName, blobName)
blobClient, err := blob.NewClientWithNoCredential(blobURL, nil)
if err != nil {
return err
}
deleteOptions, leaseInfo, accessConditions := options.format()
req, err := getGeneratedBlobClient(blobClient).DeleteCreateRequest(context.TODO(), deleteOptions, leaseInfo, accessConditions)
if err != nil {
return err
}
// remove x-ms-version header
exported.UpdateSubRequestHeaders(req)
bb.subRequests = append(bb.subRequests, req)
return nil
}
// SetTier operation is used to add set tier sub-request to the batch builder.
func (bb *BatchBuilder) SetTier(containerName string, blobName string, accessTier blob.AccessTier, options *BatchSetTierOptions) error {
err := bb.checkOperationType(exported.BatchSetTierOperationType)
if err != nil {
return err
}
blobName = url.PathEscape(blobName)
blobURL := runtime.JoinPaths(bb.endpoint, containerName, blobName)
blobClient, err := blob.NewClientWithNoCredential(blobURL, nil)
if err != nil {
return err
}
setTierOptions, leaseInfo, accessConditions := options.format()
req, err := getGeneratedBlobClient(blobClient).SetTierCreateRequest(context.TODO(), accessTier, setTierOptions, leaseInfo, accessConditions)
if err != nil {
return err
}
// remove x-ms-version header
exported.UpdateSubRequestHeaders(req)
bb.subRequests = append(bb.subRequests, req)
return nil
}

View file

@ -7,8 +7,13 @@
package service
import (
"bytes"
"context"
"errors"
"fmt"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/base"
"net/http"
"strings"
"time"
@ -18,7 +23,6 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/base"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/exported"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/shared"
@ -26,9 +30,7 @@ import (
)
// ClientOptions contains the optional parameters when creating a Client.
type ClientOptions struct {
azcore.ClientOptions
}
type ClientOptions base.ClientOptions
// Client represents a URL to the Azure Blob Storage service allowing you to manipulate blob containers.
type Client base.Client[generated.ServiceClient]
@ -38,12 +40,12 @@ type Client base.Client[generated.ServiceClient]
// - cred - an Azure AD credential, typically obtained via the azidentity module
// - options - client options; pass nil to accept the default values
func NewClient(serviceURL string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) {
authPolicy := runtime.NewBearerTokenPolicy(cred, []string{shared.TokenScope}, nil)
authPolicy := shared.NewStorageChallengePolicy(cred)
conOptions := shared.GetClientOptions(options)
conOptions.PerRetryPolicies = append(conOptions.PerRetryPolicies, authPolicy)
pl := runtime.NewPipeline(exported.ModuleName, exported.ModuleVersion, runtime.PipelineOptions{}, &conOptions.ClientOptions)
return (*Client)(base.NewServiceClient(serviceURL, pl, nil)), nil
return (*Client)(base.NewServiceClient(serviceURL, pl, &cred)), nil
}
// NewClientWithNoCredential creates an instance of Client with the specified values.
@ -115,6 +117,15 @@ func (s *Client) sharedKey() *SharedKeyCredential {
return base.SharedKey((*base.Client[generated.ServiceClient])(s))
}
func (s *Client) credential() any {
return base.Credential((*base.Client[generated.ServiceClient])(s))
}
// helper method to return the generated.BlobClient which is used for creating the sub-requests
func getGeneratedBlobClient(b *blob.Client) *generated.BlobClient {
return base.InnerClient((*base.Client[generated.BlobClient])(b))
}
// URL returns the URL endpoint used by the Client object.
func (s *Client) URL() string {
return s.generated().Endpoint()
@ -124,7 +135,7 @@ func (s *Client) URL() string {
// this Client's URL. The new container.Client uses the same request policy pipeline as the Client.
func (s *Client) NewContainerClient(containerName string) *container.Client {
containerURL := runtime.JoinPaths(s.generated().Endpoint(), containerName)
return (*container.Client)(base.NewContainerClient(containerURL, s.generated().Pipeline(), s.sharedKey()))
return (*container.Client)(base.NewContainerClient(containerURL, s.generated().Pipeline(), s.credential()))
}
// CreateContainer is a lifecycle method to creates a new container under the specified account.
@ -154,6 +165,7 @@ func (s *Client) RestoreContainer(ctx context.Context, deletedContainerName stri
}
// GetAccountInfo provides account level information
// For more information, see https://learn.microsoft.com/en-us/rest/api/storageservices/get-account-information?tabs=shared-access-signatures.
func (s *Client) GetAccountInfo(ctx context.Context, o *GetAccountInfoOptions) (GetAccountInfoResponse, error) {
getAccountInfoOptions := o.format()
resp, err := s.generated().GetAccountInfo(ctx, getAccountInfoOptions)
@ -280,3 +292,68 @@ func (s *Client) FilterBlobs(ctx context.Context, where string, o *FilterBlobsOp
resp, err := s.generated().FilterBlobs(ctx, where, serviceFilterBlobsOptions)
return resp, err
}
// NewBatchBuilder creates an instance of BatchBuilder using the same auth policy as the client.
// BatchBuilder is used to build the batch consisting of either delete or set tier sub-requests.
// All sub-requests in the batch must be of the same type, either delete or set tier.
// NOTE: Service level Blob Batch operation is supported only when the Client was created using SharedKeyCredential and Account SAS.
func (s *Client) NewBatchBuilder() (*BatchBuilder, error) {
var authPolicy policy.Policy
switch cred := s.credential().(type) {
case *azcore.TokenCredential:
authPolicy = shared.NewStorageChallengePolicy(*cred)
case *SharedKeyCredential:
authPolicy = exported.NewSharedKeyCredPolicy(cred)
case nil:
// for authentication using SAS
authPolicy = nil
default:
return nil, fmt.Errorf("unrecognised authentication type %T", cred)
}
return &BatchBuilder{
endpoint: s.URL(),
authPolicy: authPolicy,
}, nil
}
// SubmitBatch operation allows multiple API calls to be embedded into a single HTTP request.
// It builds the request body using the BatchBuilder object passed.
// BatchBuilder contains the list of operations to be submitted. It supports up to 256 sub-requests in a single batch.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/blob-batch.
func (s *Client) SubmitBatch(ctx context.Context, bb *BatchBuilder, options *SubmitBatchOptions) (SubmitBatchResponse, error) {
if bb == nil || len(bb.subRequests) == 0 {
return SubmitBatchResponse{}, errors.New("batch builder is empty")
}
// create the request body
batchReq, batchID, err := exported.CreateBatchRequest(&exported.BlobBatchBuilder{
AuthPolicy: bb.authPolicy,
SubRequests: bb.subRequests,
})
if err != nil {
return SubmitBatchResponse{}, err
}
reader := bytes.NewReader(batchReq)
rsc := streaming.NopCloser(reader)
multipartContentType := "multipart/mixed; boundary=" + batchID
resp, err := s.generated().SubmitBatch(ctx, int64(len(batchReq)), multipartContentType, rsc, options.format())
if err != nil {
return SubmitBatchResponse{}, err
}
batchResponses, err := exported.ParseBlobBatchResponse(resp.Body, resp.ContentType, bb.subRequests)
if err != nil {
return SubmitBatchResponse{}, err
}
return SubmitBatchResponse{
Responses: batchResponses,
ContentType: resp.ContentType,
RequestID: resp.RequestID,
Version: resp.Version,
}, nil
}

View file

@ -8,6 +8,7 @@ package service
import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/exported"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated"
@ -299,3 +300,59 @@ func (o *FilterBlobsOptions) format() *generated.ServiceClientFilterBlobsOptions
Maxresults: o.MaxResults,
}
}
// ---------------------------------------------------------------------------------------------------------------------
// BatchDeleteOptions contains the optional parameters for the BatchBuilder.Delete method.
type BatchDeleteOptions struct {
blob.DeleteOptions
VersionID *string
Snapshot *string
}
func (o *BatchDeleteOptions) format() (*generated.BlobClientDeleteOptions, *generated.LeaseAccessConditions, *generated.ModifiedAccessConditions) {
if o == nil {
return nil, nil, nil
}
basics := generated.BlobClientDeleteOptions{
DeleteSnapshots: o.DeleteSnapshots,
DeleteType: o.BlobDeleteType, // None by default
Snapshot: o.Snapshot,
VersionID: o.VersionID,
}
leaseAccessConditions, modifiedAccessConditions := exported.FormatBlobAccessConditions(o.AccessConditions)
return &basics, leaseAccessConditions, modifiedAccessConditions
}
// BatchSetTierOptions contains the optional parameters for the BatchBuilder.SetTier method.
type BatchSetTierOptions struct {
blob.SetTierOptions
VersionID *string
Snapshot *string
}
func (o *BatchSetTierOptions) format() (*generated.BlobClientSetTierOptions, *generated.LeaseAccessConditions, *generated.ModifiedAccessConditions) {
if o == nil {
return nil, nil, nil
}
basics := generated.BlobClientSetTierOptions{
RehydratePriority: o.RehydratePriority,
Snapshot: o.Snapshot,
VersionID: o.VersionID,
}
leaseAccessConditions, modifiedAccessConditions := exported.FormatBlobAccessConditions(o.AccessConditions)
return &basics, leaseAccessConditions, modifiedAccessConditions
}
// SubmitBatchOptions contains the optional parameters for the Client.SubmitBatch method.
type SubmitBatchOptions struct {
// placeholder for future options
}
func (o *SubmitBatchOptions) format() *generated.ServiceClientSubmitBatchOptions {
return nil
}

View file

@ -7,6 +7,7 @@
package service
import (
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/exported"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated"
)
@ -42,3 +43,21 @@ type FilterBlobsResponse = generated.ServiceClientFilterBlobsResponse
// GetUserDelegationKeyResponse contains the response from method ServiceClient.GetUserDelegationKey.
type GetUserDelegationKeyResponse = generated.ServiceClientGetUserDelegationKeyResponse
// SubmitBatchResponse contains the response from method Client.SubmitBatch.
type SubmitBatchResponse struct {
// Responses contains the responses of the sub-requests in the batch
Responses []*BatchResponseItem
// ContentType contains the information returned from the Content-Type header response.
ContentType *string
// RequestID contains the information returned from the x-ms-request-id header response.
RequestID *string
// Version contains the information returned from the x-ms-version header response.
Version *string
}
// BatchResponseItem contains the response for the individual sub-requests.
type BatchResponseItem = exported.BatchResponseItem

View file

@ -1,3 +1,291 @@
# Release (2023-07-13)
## General Highlights
* **Feature**: Modify user agent syntax and introduce support for optional app identifier in UA header
* **Dependency Update**: Updated to the latest SDK module versions
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider`: [v1.23.0](service/cognitoidentityprovider/CHANGELOG.md#v1230-2023-07-13)
* **Feature**: API model updated in Amazon Cognito
* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.61.0](service/connect/CHANGELOG.md#v1610-2023-07-13)
* **Feature**: Add support for deleting Queues and Routing Profiles.
* `github.com/aws/aws-sdk-go-v2/service/databasemigrationservice`: [v1.27.0](service/databasemigrationservice/CHANGELOG.md#v1270-2023-07-13)
* **Feature**: Enhanced PostgreSQL target endpoint settings for providing Babelfish support.
* `github.com/aws/aws-sdk-go-v2/service/datasync`: [v1.25.0](service/datasync/CHANGELOG.md#v1250-2023-07-13)
* **Feature**: Added LunCount to the response object of DescribeStorageSystemResourcesResponse, LunCount represents the number of LUNs on a storage system resource.
* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.104.0](service/ec2/CHANGELOG.md#v11040-2023-07-13)
* **Feature**: This release adds support for the C7gn and Hpc7g instances. C7gn instances are powered by AWS Graviton3 processors and the fifth-generation AWS Nitro Cards. Hpc7g instances are powered by AWS Graviton 3E processors and provide up to 200 Gbps network bandwidth.
* `github.com/aws/aws-sdk-go-v2/service/fsx`: [v1.30.0](service/fsx/CHANGELOG.md#v1300-2023-07-13)
* **Feature**: Amazon FSx for NetApp ONTAP now supports SnapLock, an ONTAP feature that enables you to protect your files in a volume by transitioning them to a write once, read many (WORM) state.
* `github.com/aws/aws-sdk-go-v2/service/iam`: [v1.21.1](service/iam/CHANGELOG.md#v1211-2023-07-13)
* **Documentation**: Documentation updates for AWS Identity and Access Management (IAM).
* `github.com/aws/aws-sdk-go-v2/service/mediatailor`: [v1.25.0](service/mediatailor/CHANGELOG.md#v1250-2023-07-13)
* **Feature**: Adds categories to MediaTailor channel assembly alerts
* `github.com/aws/aws-sdk-go-v2/service/personalize`: [v1.25.0](service/personalize/CHANGELOG.md#v1250-2023-07-13)
* **Feature**: This release provides ability to customers to change schema associated with their datasets in Amazon Personalize
* `github.com/aws/aws-sdk-go-v2/service/proton`: [v1.22.0](service/proton/CHANGELOG.md#v1220-2023-07-13)
* **Feature**: This release adds support for deployment history for Proton provisioned resources
* `github.com/aws/aws-sdk-go-v2/service/s3`: [v1.37.0](service/s3/CHANGELOG.md#v1370-2023-07-13)
* **Feature**: S3 Inventory now supports Object Access Control List and Object Owner as available object metadata fields in inventory reports.
* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.92.0](service/sagemaker/CHANGELOG.md#v1920-2023-07-13)
* **Feature**: Amazon SageMaker Canvas adds WorkspeceSettings support for CanvasAppSettings
* `github.com/aws/aws-sdk-go-v2/service/secretsmanager`: [v1.19.11](service/secretsmanager/CHANGELOG.md#v11911-2023-07-13)
* **Documentation**: Documentation updates for Secrets Manager
# Release (2023-07-07)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs`: [v1.22.0](service/cloudwatchlogs/CHANGELOG.md#v1220-2023-07-07)
* **Feature**: Add CMK encryption support for CloudWatch Logs Insights query result data
* `github.com/aws/aws-sdk-go-v2/service/databasemigrationservice`: [v1.26.0](service/databasemigrationservice/CHANGELOG.md#v1260-2023-07-07)
* **Feature**: Releasing DMS Serverless. Adding support for PostgreSQL 15.x as source and target endpoint. Adding support for DocDB Elastic Clusters with sharded collections, PostgreSQL datatype mapping customization and disabling hostname validation of the certificate authority in Kafka endpoint settings
* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.54.0](service/glue/CHANGELOG.md#v1540-2023-07-07)
* **Feature**: This release enables customers to create new Apache Iceberg tables and associated metadata in Amazon S3 by using native AWS Glue CreateTable operation.
* `github.com/aws/aws-sdk-go-v2/service/medialive`: [v1.32.0](service/medialive/CHANGELOG.md#v1320-2023-07-07)
* **Feature**: This release enables the use of Thumbnails in AWS Elemental MediaLive.
* `github.com/aws/aws-sdk-go-v2/service/mediatailor`: [v1.24.0](service/mediatailor/CHANGELOG.md#v1240-2023-07-07)
* **Feature**: The AWS Elemental MediaTailor SDK for Channel Assembly has added support for EXT-X-CUE-OUT and EXT-X-CUE-IN tags to specify ad breaks in HLS outputs, including support for EXT-OATCLS, EXT-X-ASSET, and EXT-X-CUE-OUT-CONT accessory tags.
# Release (2023-07-06)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.103.0](service/ec2/CHANGELOG.md#v11030-2023-07-06)
* **Feature**: Add Nitro Enclaves support on DescribeInstanceTypes
* `github.com/aws/aws-sdk-go-v2/service/location`: [v1.25.0](service/location/CHANGELOG.md#v1250-2023-07-06)
* **Feature**: This release adds support for authenticating with Amazon Location Service's Places & Routes APIs with an API Key. Also, with this release developers can publish tracked device position updates to Amazon EventBridge.
* `github.com/aws/aws-sdk-go-v2/service/outposts`: [v1.28.0](service/outposts/CHANGELOG.md#v1280-2023-07-06)
* **Feature**: Added paginator support to several APIs. Added the ISOLATED enum value to AssetState.
* `github.com/aws/aws-sdk-go-v2/service/quicksight`: [v1.38.0](service/quicksight/CHANGELOG.md#v1380-2023-07-06)
* **Feature**: This release includes below three changes: small multiples axes improvement, field based coloring, removed required trait from Aggregation function for TopBottomFilter.
* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.46.1](service/rds/CHANGELOG.md#v1461-2023-07-06)
* **Documentation**: Updates Amazon RDS documentation for creating DB instances and creating Aurora global clusters.
# Release (2023-07-05)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/comprehendmedical`: [v1.16.3](service/comprehendmedical/CHANGELOG.md#v1163-2023-07-05)
* **Documentation**: Update to Amazon Comprehend Medical documentation.
* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.60.1](service/connect/CHANGELOG.md#v1601-2023-07-05)
* **Documentation**: GetMetricDataV2 API: Channels filters do not count towards overall limitation of 100 filter values.
* `github.com/aws/aws-sdk-go-v2/service/kms`: [v1.23.0](service/kms/CHANGELOG.md#v1230-2023-07-05)
* **Feature**: Added Dry Run Feature to cryptographic and cross-account mutating KMS APIs (14 in all). This feature allows users to test their permissions and parameters before making the actual API call.
* `github.com/aws/aws-sdk-go-v2/service/mgn`: [v1.19.0](service/mgn/CHANGELOG.md#v1190-2023-07-05)
* **Feature**: This release introduces the Global view feature and new Replication state APIs.
* `github.com/aws/aws-sdk-go-v2/service/securityhub`: [v1.33.2](service/securityhub/CHANGELOG.md#v1332-2023-07-05)
* **Documentation**: Documentation updates for AWS Security Hub
# Release (2023-07-03)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/batch`: [v1.24.0](service/batch/CHANGELOG.md#v1240-2023-07-03)
* **Feature**: This feature allows customers to use AWS Batch with Linux with ARM64 CPU Architecture and X86_64 CPU Architecture with Windows OS on Fargate Platform.
* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.91.0](service/sagemaker/CHANGELOG.md#v1910-2023-07-03)
* **Feature**: SageMaker Inference Recommender now accepts new fields SupportedEndpointType and ServerlessConfiguration to support serverless endpoints.
# Release (2023-06-30)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/ecs`: [v1.28.0](service/ecs/CHANGELOG.md#v1280-2023-06-30)
* **Feature**: Added new field "credentialspecs" to the ecs task definition to support gMSA of windows/linux in both domainless and domain-joined mode
* `github.com/aws/aws-sdk-go-v2/service/mediaconvert`: [v1.38.1](service/mediaconvert/CHANGELOG.md#v1381-2023-06-30)
* **Documentation**: This release includes improved color handling of overlays and general updates to user documentation.
* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.90.0](service/sagemaker/CHANGELOG.md#v1900-2023-06-30)
* **Feature**: This release adds support for rolling deployment in SageMaker Inference.
* `github.com/aws/aws-sdk-go-v2/service/transfer`: [v1.31.0](service/transfer/CHANGELOG.md#v1310-2023-06-30)
* **Feature**: Add outbound Basic authentication support to AS2 connectors
* `github.com/aws/aws-sdk-go-v2/service/verifiedpermissions`: [v1.0.4](service/verifiedpermissions/CHANGELOG.md#v104-2023-06-30)
* **Documentation**: This release corrects several broken links in the documentation.
# Release (2023-06-29)
## General Highlights
* **Dependency Update**: Updated to the latest SDK module versions
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/appstream`: [v1.21.0](service/appstream/CHANGELOG.md#v1210-2023-06-29)
* **Feature**: This release introduces app block builder, allowing customers to provision a resource to package applications into an app block
* `github.com/aws/aws-sdk-go-v2/service/chime`: [v1.24.0](service/chime/CHANGELOG.md#v1240-2023-06-29)
* **Feature**: The Amazon Chime SDK APIs in the Chime namespace are no longer supported. Customers should use APIs in the dedicated Amazon Chime SDK namespaces: ChimeSDKIdentity, ChimeSDKMediaPipelines, ChimeSDKMeetings, ChimeSDKMessaging, and ChimeSDKVoice.
* `github.com/aws/aws-sdk-go-v2/service/cleanrooms`: [v1.2.0](service/cleanrooms/CHANGELOG.md#v120-2023-06-29)
* **Feature**: This release adds support for the OR operator in RSQL join match conditions and the ability to control which operators (AND, OR) are allowed in a join match condition.
* `github.com/aws/aws-sdk-go-v2/service/dynamodb`: [v1.20.0](service/dynamodb/CHANGELOG.md#v1200-2023-06-29)
* **Feature**: This release adds ReturnValuesOnConditionCheckFailure parameter to PutItem, UpdateItem, DeleteItem, ExecuteStatement, BatchExecuteStatement and ExecuteTransaction APIs. When set to ALL_OLD, API returns a copy of the item as it was when a conditional write failed
* `github.com/aws/aws-sdk-go-v2/service/gamelift`: [v1.20.0](service/gamelift/CHANGELOG.md#v1200-2023-06-29)
* **Feature**: Amazon GameLift now supports game builds that use the Amazon Linux 2023 (AL2023) operating system.
* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.53.0](service/glue/CHANGELOG.md#v1530-2023-06-29)
* **Feature**: This release adds support for AWS Glue Crawler with Iceberg Tables, allowing Crawlers to discover Iceberg Tables in S3 and register them in Glue Data Catalog for query engines to query against.
* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.89.0](service/sagemaker/CHANGELOG.md#v1890-2023-06-29)
* **Feature**: Adding support for timeseries forecasting in the CreateAutoMLJobV2 API.
# Release (2023-06-28)
## General Highlights
* **Dependency Update**: Updated to the latest SDK module versions
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/internetmonitor`: [v1.3.0](service/internetmonitor/CHANGELOG.md#v130-2023-06-28)
* **Feature**: This release adds a new feature for Amazon CloudWatch Internet Monitor that enables customers to set custom thresholds, for performance and availability drops, for triggering when to create a health event.
* `github.com/aws/aws-sdk-go-v2/service/kinesisanalyticsv2`: [v1.17.0](service/kinesisanalyticsv2/CHANGELOG.md#v1170-2023-06-28)
* **Feature**: Support for new runtime environment in Kinesis Data Analytics Studio: Zeppelin-0.10, Apache Flink-1.15
* `github.com/aws/aws-sdk-go-v2/service/lambda`: [v1.37.0](service/lambda/CHANGELOG.md#v1370-2023-06-28)
* **Feature**: Surface ResourceConflictException in DeleteEventSourceMapping
* `github.com/aws/aws-sdk-go-v2/service/omics`: [v1.5.0](service/omics/CHANGELOG.md#v150-2023-06-28)
* **Feature**: Add Common Workflow Language (CWL) as a supported language for Omics workflows
* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.46.0](service/rds/CHANGELOG.md#v1460-2023-06-28)
* **Feature**: Amazon Relational Database Service (RDS) now supports joining a RDS for SQL Server instance to a self-managed Active Directory.
* `github.com/aws/aws-sdk-go-v2/service/s3`: [v1.36.0](service/s3/CHANGELOG.md#v1360-2023-06-28)
* **Feature**: The S3 LISTObjects, ListObjectsV2 and ListObjectVersions API now supports a new optional header x-amz-optional-object-attributes. If header contains RestoreStatus as the value, then S3 will include Glacier restore status i.e. isRestoreInProgress and RestoreExpiryDate in List response.
* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.88.0](service/sagemaker/CHANGELOG.md#v1880-2023-06-28)
* **Feature**: This release adds support for Model Cards Model Registry integration.
# Release (2023-06-27)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/appfabric`: [v1.0.0](service/appfabric/CHANGELOG.md#v100-2023-06-27)
* **Release**: New AWS service client module
* **Feature**: Initial release of AWS AppFabric for connecting SaaS applications for better productivity and security.
* `github.com/aws/aws-sdk-go-v2/service/appflow`: [v1.32.0](service/appflow/CHANGELOG.md#v1320-2023-06-27)
* **Feature**: This release adds support to bypass SSO with the SAPOData connector when connecting to an SAP instance.
* `github.com/aws/aws-sdk-go-v2/service/emrserverless`: [v1.8.0](service/emrserverless/CHANGELOG.md#v180-2023-06-27)
* **Feature**: This release adds support to update the release label of an EMR Serverless application to upgrade it to a different version of Amazon EMR via UpdateApplication API.
* `github.com/aws/aws-sdk-go-v2/service/ivs`: [v1.23.0](service/ivs/CHANGELOG.md#v1230-2023-06-27)
* **Feature**: IVS customers can now revoke the viewer session associated with an auth token, to prevent and stop playback using that token.
* `github.com/aws/aws-sdk-go-v2/service/kinesisvideo`: [v1.16.0](service/kinesisvideo/CHANGELOG.md#v1160-2023-06-27)
* **Feature**: General Availability (GA) release of Kinesis Video Streams at Edge, enabling customers to provide a configuration for the Kinesis Video Streams EdgeAgent running on an on-premise IoT device. Customers can now locally record from cameras and stream videos to the cloud on a configured schedule.
* `github.com/aws/aws-sdk-go-v2/service/macie2`: [v1.28.0](service/macie2/CHANGELOG.md#v1280-2023-06-27)
* **Feature**: This release adds support for configuring new classification jobs to use the set of managed data identifiers that we recommend for jobs. For the managed data identifier selection type (managedDataIdentifierSelector), specify RECOMMENDED.
* `github.com/aws/aws-sdk-go-v2/service/privatenetworks`: [v1.3.0](service/privatenetworks/CHANGELOG.md#v130-2023-06-27)
* **Feature**: This release allows Private5G customers to choose different commitment plans (60-days, 1-year, 3-years) when placing new orders, enables automatic renewal option for 1-year and 3-years commitments. It also allows customers to update the commitment plan of an existing radio unit.
* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.87.0](service/sagemaker/CHANGELOG.md#v1870-2023-06-27)
* **Feature**: Introducing TTL for online store records in feature groups.
* `github.com/aws/aws-sdk-go-v2/service/sagemakerfeaturestoreruntime`: [v1.15.0](service/sagemakerfeaturestoreruntime/CHANGELOG.md#v1150-2023-06-27)
* **Feature**: Introducing TTL for online store records for feature groups.
* `github.com/aws/aws-sdk-go-v2/service/ssm`: [v1.36.7](service/ssm/CHANGELOG.md#v1367-2023-06-27)
* **Documentation**: Systems Manager doc-only update for June 2023.
* `github.com/aws/aws-sdk-go-v2/service/verifiedpermissions`: [v1.0.3](service/verifiedpermissions/CHANGELOG.md#v103-2023-06-27)
* **Documentation**: This update fixes several broken links to the Cedar documentation.
# Release (2023-06-26)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.60.0](service/connect/CHANGELOG.md#v1600-2023-06-26)
* **Feature**: This release provides a way to search for existing tags within an instance. Before tagging a resource, ensure consistency by searching for pre-existing key:value pairs.
* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.52.0](service/glue/CHANGELOG.md#v1520-2023-06-26)
* **Feature**: Timestamp Starting Position For Kinesis and Kafka Data Sources in a Glue Streaming Job
* `github.com/aws/aws-sdk-go-v2/service/guardduty`: [v1.24.0](service/guardduty/CHANGELOG.md#v1240-2023-06-26)
* **Feature**: Add support for user.extra.sessionName in Kubernetes Audit Logs Findings.
* `github.com/aws/aws-sdk-go-v2/service/iam`: [v1.21.0](service/iam/CHANGELOG.md#v1210-2023-06-26)
* **Feature**: Support for a new API "GetMFADevice" to present MFA device metadata such as device certifications
* `github.com/aws/aws-sdk-go-v2/service/pinpoint`: [v1.20.0](service/pinpoint/CHANGELOG.md#v1200-2023-06-26)
* **Feature**: Added time zone estimation support for journeys
# Release (2023-06-23)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/devopsguru`: [v1.24.0](service/devopsguru/CHANGELOG.md#v1240-2023-06-23)
* **Feature**: This release adds support for encryption via customer managed keys.
* `github.com/aws/aws-sdk-go-v2/service/fsx`: [v1.29.3](service/fsx/CHANGELOG.md#v1293-2023-06-23)
* **Documentation**: Update to Amazon FSx documentation.
* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.45.3](service/rds/CHANGELOG.md#v1453-2023-06-23)
* **Documentation**: Documentation improvements for create, describe, and modify DB clusters and DB instances.
* `github.com/aws/aws-sdk-go-v2/service/verifiedpermissions`: [v1.0.2](service/verifiedpermissions/CHANGELOG.md#v102-2023-06-23)
* **Documentation**: Added improved descriptions and new code samples to SDK documentation.
# Release (2023-06-22)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/chimesdkidentity`: [v1.12.0](service/chimesdkidentity/CHANGELOG.md#v1120-2023-06-22)
* **Feature**: AppInstanceBots can be configured to be invoked or not using the Target or the CHIME.mentions attribute for ChannelMessages
* `github.com/aws/aws-sdk-go-v2/service/chimesdkmessaging`: [v1.16.0](service/chimesdkmessaging/CHANGELOG.md#v1160-2023-06-22)
* **Feature**: ChannelMessages can be made visible to sender and intended recipient rather than all channel members with the target attribute. For example, a user can send messages to a bot and receive messages back in a group channel without other members seeing them.
* `github.com/aws/aws-sdk-go-v2/service/kendra`: [v1.41.0](service/kendra/CHANGELOG.md#v1410-2023-06-22)
* **Feature**: Introducing Amazon Kendra Retrieve API that can be used to retrieve relevant passages or text excerpts given an input query.
* `github.com/aws/aws-sdk-go-v2/service/sfn`: [v1.18.0](service/sfn/CHANGELOG.md#v1180-2023-06-22)
* **Feature**: Adds support for Versions and Aliases. Adds 8 operations: PublishStateMachineVersion, DeleteStateMachineVersion, ListStateMachineVersions, CreateStateMachineAlias, DescribeStateMachineAlias, UpdateStateMachineAlias, DeleteStateMachineAlias, ListStateMachineAliases
# Release (2023-06-21)
## General Highlights
* **Dependency Update**: Updated to the latest SDK module versions
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/dynamodb`: [v1.19.11](service/dynamodb/CHANGELOG.md#v11911-2023-06-21)
* **Documentation**: Documentation updates for DynamoDB
* `github.com/aws/aws-sdk-go-v2/service/emr`: [v1.27.0](service/emr/CHANGELOG.md#v1270-2023-06-21)
* **Feature**: This release introduces a new Amazon EMR EPI called ListSupportedInstanceTypes that returns a list of all instance types supported by a given EMR release.
* `github.com/aws/aws-sdk-go-v2/service/inspector2`: [v1.15.0](service/inspector2/CHANGELOG.md#v1150-2023-06-21)
* **Feature**: This release adds support for Software Bill of Materials (SBOM) export and the general availability of code scanning for AWS Lambda functions.
* `github.com/aws/aws-sdk-go-v2/service/mediaconvert`: [v1.38.0](service/mediaconvert/CHANGELOG.md#v1380-2023-06-21)
* **Feature**: This release introduces the bandwidth reduction filter for the HEVC encoder, increases the limits of outputs per job, and updates support for the Nagra SDK to version 1.14.7.
* `github.com/aws/aws-sdk-go-v2/service/mq`: [v1.15.0](service/mq/CHANGELOG.md#v1150-2023-06-21)
* **Feature**: The Cross Region Disaster Recovery feature allows to replicate a brokers state from one region to another in order to provide customers with multi-region resiliency in the event of a regional outage.
* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.86.0](service/sagemaker/CHANGELOG.md#v1860-2023-06-21)
* **Feature**: This release provides support in SageMaker for output files in training jobs to be uploaded without compression and enable customer to deploy uncompressed model from S3 to real-time inference Endpoints. In addition, ml.trn1n.32xlarge is added to supported instance type list in training job.
* `github.com/aws/aws-sdk-go-v2/service/transfer`: [v1.30.0](service/transfer/CHANGELOG.md#v1300-2023-06-21)
* **Feature**: This release adds a new parameter StructuredLogDestinations to CreateServer, UpdateServer APIs.
# Release (2023-06-20)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/appflow`: [v1.31.0](service/appflow/CHANGELOG.md#v1310-2023-06-20)
* **Feature**: This release adds new API to reset connector metadata cache
* `github.com/aws/aws-sdk-go-v2/service/configservice`: [v1.34.0](service/configservice/CHANGELOG.md#v1340-2023-06-20)
* **Feature**: Updated ResourceType enum with new resource types onboarded by AWS Config in May 2023.
* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.102.0](service/ec2/CHANGELOG.md#v11020-2023-06-20)
* **Feature**: Adds support for targeting Dedicated Host allocations by assetIds in AWS Outposts
* `github.com/aws/aws-sdk-go-v2/service/lambda`: [v1.36.0](service/lambda/CHANGELOG.md#v1360-2023-06-20)
* **Feature**: This release adds RecursiveInvocationException to the Invoke API and InvokeWithResponseStream API.
* `github.com/aws/aws-sdk-go-v2/service/redshift`: [v1.28.0](service/redshift/CHANGELOG.md#v1280-2023-06-20)
* **Feature**: Added support for custom domain names for Redshift Provisioned clusters. This feature enables customers to create a custom domain name and use ACM to generate fully secure connections to it.
# Release (2023-06-19)
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/cloudformation`: [v1.30.0](service/cloudformation/CHANGELOG.md#v1300-2023-06-19)
* **Feature**: Specify desired CloudFormation behavior in the event of ChangeSet execution failure using the CreateChangeSet OnStackFailure parameter
* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.101.0](service/ec2/CHANGELOG.md#v11010-2023-06-19)
* **Feature**: API changes to AWS Verified Access to include data from trust providers in logs
* `github.com/aws/aws-sdk-go-v2/service/ecs`: [v1.27.4](service/ecs/CHANGELOG.md#v1274-2023-06-19)
* **Documentation**: Documentation only update to address various tickets.
* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.51.0](service/glue/CHANGELOG.md#v1510-2023-06-19)
* **Feature**: This release adds support for creating cross region table/database resource links
* `github.com/aws/aws-sdk-go-v2/service/pricing`: [v1.20.0](service/pricing/CHANGELOG.md#v1200-2023-06-19)
* **Feature**: This release updates the PriceListArn regex pattern.
* `github.com/aws/aws-sdk-go-v2/service/route53domains`: [v1.15.0](service/route53domains/CHANGELOG.md#v1150-2023-06-19)
* **Feature**: Update MaxItems upper bound to 1000 for ListPricesRequest
* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.85.0](service/sagemaker/CHANGELOG.md#v1850-2023-06-19)
* **Feature**: Amazon Sagemaker Autopilot releases CreateAutoMLJobV2 and DescribeAutoMLJobV2 for Autopilot customers with ImageClassification, TextClassification and Tabular problem type config support.
# Release (2023-06-16)
## General Highlights
* **Dependency Update**: Updated to the latest SDK module versions
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/applicationdiscoveryservice`: [v1.16.0](service/applicationdiscoveryservice/CHANGELOG.md#v1160-2023-06-16)
* **Feature**: Add Amazon EC2 instance recommendations export
* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.59.0](service/connect/CHANGELOG.md#v1590-2023-06-16)
* **Feature**: Updates the *InstanceStorageConfig APIs to support a new ResourceType: SCREEN_RECORDINGS to enable screen recording and specify the storage configurations for publishing the recordings. Also updates DescribeInstance and ListInstances APIs to include InstanceAccessUrl attribute in the API response.
* `github.com/aws/aws-sdk-go-v2/service/iam`: [v1.20.3](service/iam/CHANGELOG.md#v1203-2023-06-16)
* **Documentation**: Documentation updates for AWS Identity and Access Management (IAM).
* `github.com/aws/aws-sdk-go-v2/service/s3`: [v1.35.0](service/s3/CHANGELOG.md#v1350-2023-06-16)
* **Feature**: This release adds SDK support for request-payer request header and request-charged response header in the "GetBucketAccelerateConfiguration", "ListMultipartUploads", "ListObjects", "ListObjectsV2" and "ListObjectVersions" S3 APIs.
# Release (2023-06-15)
## General Highlights
* **Dependency Update**: Updated to the latest SDK module versions
## Module Highlights
* `github.com/aws/aws-sdk-go-v2/service/auditmanager`: [v1.25.0](service/auditmanager/CHANGELOG.md#v1250-2023-06-15)
* **Feature**: This release introduces 2 Audit Manager features: CSV exports and new manual evidence options. You can now export your evidence finder results in CSV format. In addition, you can now add manual evidence to a control by entering free-form text or uploading a file from your browser.
* `github.com/aws/aws-sdk-go-v2/service/efs`: [v1.20.3](service/efs/CHANGELOG.md#v1203-2023-06-15)
* **Documentation**: Documentation updates for EFS.
* `github.com/aws/aws-sdk-go-v2/service/guardduty`: [v1.23.2](service/guardduty/CHANGELOG.md#v1232-2023-06-15)
* **Documentation**: Updated descriptions for some APIs.
* `github.com/aws/aws-sdk-go-v2/service/location`: [v1.24.0](service/location/CHANGELOG.md#v1240-2023-06-15)
* **Feature**: Amazon Location Service adds categories to places, including filtering on those categories in searches. Also, you can now add metadata properties to your geofences.
# Release (2023-06-13)
## General Highlights

View file

@ -132,6 +132,14 @@ type Config struct {
// `config.LoadDefaultConfig`. You should not populate this structure
// programmatically, or rely on the values here within your applications.
RuntimeEnvironment RuntimeEnvironment
// AppId is an optional application specific identifier that can be set.
// When set it will be appended to the User-Agent header of every request
// in the form of App/{AppId}. This variable is sourced from environment
// variable AWS_SDK_UA_APP_ID or the shared config profile attribute sdk_ua_app_id.
// See https://docs.aws.amazon.com/sdkref/latest/guide/settings-reference.html for
// more information on environment variables and shared config settings.
AppID string
}
// NewConfig returns a new Config pointer that can be chained with builder

View file

@ -3,4 +3,4 @@
package aws
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.18.1"
const goModuleVersion = "1.19.0"

View file

@ -59,6 +59,11 @@ func (k SDKAgentKeyType) string() string {
const execEnvVar = `AWS_EXECUTION_ENV`
var validChars = map[rune]bool{
'!': true, '#': true, '$': true, '%': true, '&': true, '\'': true, '*': true, '+': true,
'-': true, '.': true, '^': true, '_': true, '`': true, '|': true, '~': true,
}
// requestUserAgent is a build middleware that set the User-Agent for the request.
type requestUserAgent struct {
sdkAgent, userAgent *smithyhttp.UserAgentBuilder
@ -178,24 +183,24 @@ func getOrAddRequestUserAgent(stack *middleware.Stack) (*requestUserAgent, error
// AddUserAgentKey adds the component identified by name to the User-Agent string.
func (u *requestUserAgent) AddUserAgentKey(key string) {
u.userAgent.AddKey(key)
u.userAgent.AddKey(strings.Map(rules, key))
}
// AddUserAgentKeyValue adds the key identified by the given name and value to the User-Agent string.
func (u *requestUserAgent) AddUserAgentKeyValue(key, value string) {
u.userAgent.AddKeyValue(key, value)
u.userAgent.AddKeyValue(strings.Map(rules, key), strings.Map(rules, value))
}
// AddUserAgentKey adds the component identified by name to the User-Agent string.
func (u *requestUserAgent) AddSDKAgentKey(keyType SDKAgentKeyType, key string) {
// TODO: should target sdkAgent
u.userAgent.AddKey(keyType.string() + "/" + key)
u.userAgent.AddKey(keyType.string() + "/" + strings.Map(rules, key))
}
// AddUserAgentKeyValue adds the key identified by the given name and value to the User-Agent string.
func (u *requestUserAgent) AddSDKAgentKeyValue(keyType SDKAgentKeyType, key, value string) {
// TODO: should target sdkAgent
u.userAgent.AddKeyValue(keyType.string()+"/"+key, value)
u.userAgent.AddKeyValue(keyType.string(), strings.Map(rules, key)+"#"+strings.Map(rules, value))
}
// ID the name of the middleware.
@ -241,3 +246,16 @@ func updateHTTPHeader(request *smithyhttp.Request, header string, value string)
}
request.Header[header] = append(request.Header[header][:0], current)
}
func rules(r rune) rune {
switch {
case r >= '0' && r <= '9':
return r
case r >= 'A' && r <= 'Z' || r >= 'a' && r <= 'z':
return r
case validChars[r]:
return r
default:
return '-'
}
}

View file

@ -1,3 +1,7 @@
# v1.18.28 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.27 (2023-06-15)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -76,6 +76,9 @@ var defaultAWSConfigResolvers = []awsConfigResolver{
// Sets the resolved bearer authentication token API clients will use for
// httpBearerAuth authentication scheme.
resolveBearerAuthToken,
// Sets the sdk app ID if present in shared config profile
resolveAppID,
}
// A Config represents a generic configuration value or set of values. This type

View file

@ -3,4 +3,4 @@
package config
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.18.27"
const goModuleVersion = "1.18.28"

View file

@ -199,6 +199,9 @@ type LoadOptions struct {
// Specifies the SDK configuration mode for defaults.
DefaultsModeOptions DefaultsModeOptions
// The sdk app ID retrieved from env var or shared config to be added to request user agent header
AppID string
}
func (o LoadOptions) getDefaultsMode(ctx context.Context) (aws.DefaultsMode, bool, error) {
@ -241,6 +244,11 @@ func (o LoadOptions) getRegion(ctx context.Context) (string, bool, error) {
return o.Region, true, nil
}
// getAppID returns AppID from config's LoadOptions
func (o LoadOptions) getAppID(ctx context.Context) (string, bool, error) {
return o.AppID, len(o.AppID) > 0, nil
}
// WithRegion is a helper function to construct functional options
// that sets Region on config's LoadOptions. Setting the region to
// an empty string, will result in the region value being ignored.
@ -253,6 +261,15 @@ func WithRegion(v string) LoadOptionsFunc {
}
}
// WithAppID is a helper function to construct functional options
// that sets AppID on config's LoadOptions.
func WithAppID(ID string) LoadOptionsFunc {
return func(o *LoadOptions) error {
o.AppID = ID
return nil
}
}
// getDefaultRegion returns DefaultRegion from config's LoadOptions
func (o LoadOptions) getDefaultRegion(ctx context.Context) (string, bool, error) {
if len(o.DefaultRegion) == 0 {

View file

@ -122,6 +122,23 @@ func getRegion(ctx context.Context, configs configs) (value string, found bool,
return
}
// appIDProvider provides access to the sdk app ID value
type appIDProvider interface {
getAppID(ctx context.Context) (string, bool, error)
}
func getAppID(ctx context.Context, configs configs) (value string, found bool, err error) {
for _, cfg := range configs {
if p, ok := cfg.(appIDProvider); ok {
value, found, err = p.getAppID(ctx)
if err != nil || found {
break
}
}
}
return
}
// ec2IMDSRegionProvider provides access to the ec2 imds region
// configuration value
type ec2IMDSRegionProvider interface {

View file

@ -106,6 +106,21 @@ func resolveRegion(ctx context.Context, cfg *aws.Config, configs configs) error
return nil
}
// resolveAppID extracts the sdk app ID from the configs slice's SharedConfig or env var
func resolveAppID(ctx context.Context, cfg *aws.Config, configs configs) error {
ID, _, err := getAppID(ctx, configs)
if err != nil {
return err
}
// if app ID is set in env var, it should precedence shared config value
if appID := os.Getenv(`AWS_SDK_UA_APP_ID`); len(appID) > 0 {
ID = appID
}
cfg.AppID = ID
return nil
}
// resolveDefaultRegion extracts the first instance of a default region and sets `aws.Config.Region` to the default
// region if region had not been resolved from other sources.
func resolveDefaultRegion(ctx context.Context, cfg *aws.Config, configs configs) error {

View file

@ -95,6 +95,8 @@ const (
retryModeKey = "retry_mode"
caBundleKey = "ca_bundle"
sdkAppID = "sdk_ua_app_id"
)
// defaultSharedConfigProfile allows for swapping the default profile for testing
@ -267,6 +269,9 @@ type SharedConfig struct {
//
// ca_bundle=$HOME/my_custom_ca_bundle
CustomCABundle string
// aws sdk app ID that can be added to user agent header string
AppID string
}
func (c SharedConfig) getDefaultsMode(ctx context.Context) (value aws.DefaultsMode, ok bool, err error) {
@ -389,6 +394,11 @@ func (c SharedConfig) getCustomCABundle(context.Context) (io.Reader, bool, error
return bytes.NewReader(b), true, nil
}
// getAppID returns the sdk app ID if set in shared config profile
func (c SharedConfig) getAppID(context.Context) (string, bool, error) {
return c.AppID, len(c.AppID) > 0, nil
}
// loadSharedConfigIgnoreNotExist is an alias for loadSharedConfig with the
// addition of ignoring when none of the files exist or when the profile
// is not found in any of the files.
@ -985,6 +995,9 @@ func (c *SharedConfig) setFromIniSection(profile string, section ini.Section) er
updateString(&c.CustomCABundle, section, caBundleKey)
// user agent app ID added to request User-Agent header
updateString(&c.AppID, section, sdkAppID)
// Shared Credentials
creds := aws.Credentials{
AccessKeyID: section.String(accessKeyIDKey),

View file

@ -1,3 +1,7 @@
# v1.13.27 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.13.26 (2023-06-15)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package credentials
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.13.26"
const goModuleVersion = "1.13.27"

View file

@ -1,3 +1,7 @@
# v1.13.5 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.13.4 (2023-06-13)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package imds
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.13.4"
const goModuleVersion = "1.13.5"

View file

@ -1,3 +1,7 @@
# v1.11.72 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.11.71 (2023-06-28)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package manager
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.11.71"
const goModuleVersion = "1.11.72"

View file

@ -1,3 +1,7 @@
# v1.1.35 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.1.34 (2023-06-13)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package configsources
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.1.34"
const goModuleVersion = "1.1.35"

View file

@ -1,3 +1,7 @@
# v2.4.29 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v2.4.28 (2023-06-13)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package endpoints
// goModuleVersion is the tagged release for this module
const goModuleVersion = "2.4.28"
const goModuleVersion = "2.4.29"

View file

@ -1,3 +1,7 @@
# v1.3.36 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.35 (2023-06-13)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package ini
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.3.35"
const goModuleVersion = "1.3.36"

View file

@ -1,3 +1,7 @@
# v1.0.27 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.0.26 (2023-06-13)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package v4a
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.0.26"
const goModuleVersion = "1.0.27"

View file

@ -1,3 +1,7 @@
# v1.1.30 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.1.29 (2023-06-13)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package checksum
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.1.29"
const goModuleVersion = "1.1.30"

View file

@ -1,3 +1,7 @@
# v1.9.29 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.9.28 (2023-06-13)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package presignedurl
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.9.28"
const goModuleVersion = "1.9.29"

View file

@ -1,3 +1,7 @@
# v1.14.4 (2023-07-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.14.3 (2023-06-13)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package s3shared
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.14.3"
const goModuleVersion = "1.14.4"

View file

@ -1,3 +1,8 @@
# v1.37.0 (2023-07-13)
* **Feature**: S3 Inventory now supports Object Access Control List and Object Owner as available object metadata fields in inventory reports.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.36.0 (2023-06-28)
* **Feature**: The S3 LISTObjects, ListObjectsV2 and ListObjectVersions API now supports a new optional header x-amz-optional-object-attributes. If header contains RestoreStatus as the value, then S3 will include Glacier restore status i.e. isRestoreInProgress and RestoreExpiryDate in List response.

View file

@ -77,6 +77,9 @@ type Options struct {
// modify this list for per operation behavior.
APIOptions []func(*middleware.Stack) error
// The optional application specific identifier appended to the User-Agent header.
AppID string
// Configures the events that will be sent to the configured logger.
ClientLogMode aws.ClientLogMode
@ -284,6 +287,7 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client {
APIOptions: cfg.APIOptions,
Logger: cfg.Logger,
ClientLogMode: cfg.ClientLogMode,
AppID: cfg.AppID,
}
resolveAWSRetryerProvider(cfg, &opts)
resolveAWSRetryMaxAttempts(cfg, &opts)
@ -398,8 +402,16 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) {
o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions, NewDefaultEndpointResolver())
}
func addClientUserAgent(stack *middleware.Stack) error {
return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "s3", goModuleVersion)(stack)
func addClientUserAgent(stack *middleware.Stack, options Options) error {
if err := awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "s3", goModuleVersion)(stack); err != nil {
return err
}
if len(options.AppID) > 0 {
return awsmiddleware.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID)(stack)
}
return nil
}
func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error {

View file

@ -138,7 +138,7 @@ func (c *Client) addOperationAbortMultipartUploadMiddlewares(stack *middleware.S
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -307,7 +307,7 @@ func (c *Client) addOperationCompleteMultipartUploadMiddlewares(stack *middlewar
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -39,11 +39,12 @@ import (
// copied object. If the request is an HTTP 1.1 request, the response is chunk
// encoded. If it were not, it would not contain the content-length, and you would
// need to read the entire body. The copy request charge is based on the storage
// class and Region that you specify for the destination object. For pricing
// information, see Amazon S3 pricing (http://aws.amazon.com/s3/pricing/) . Amazon
// S3 transfer acceleration does not support cross-Region copies. If you request a
// cross-Region copy using a transfer acceleration endpoint, you get a 400 Bad
// Request error. For more information, see Transfer Acceleration (https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html)
// class and Region that you specify for the destination object. The request can
// also result in a data retrieval charge for the source if the source storage
// class bills for data retrieval. For pricing information, see Amazon S3 pricing (http://aws.amazon.com/s3/pricing/)
// . Amazon S3 transfer acceleration does not support cross-Region copies. If you
// request a cross-Region copy using a transfer acceleration endpoint, you get a
// 400 Bad Request error. For more information, see Transfer Acceleration (https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html)
// . Metadata When copying an object, you can preserve all metadata (the default)
// or specify new metadata. However, the access control list (ACL) is not preserved
// and is set to private for the user making the request. To override the default
@ -478,7 +479,7 @@ func (c *Client) addOperationCopyObjectMiddlewares(stack *middleware.Stack, opti
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -184,7 +184,7 @@ func (c *Client) addOperationCreateBucketMiddlewares(stack *middleware.Stack, op
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -459,7 +459,7 @@ func (c *Client) addOperationCreateMultipartUploadMiddlewares(stack *middleware.
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -89,7 +89,7 @@ func (c *Client) addOperationDeleteBucketMiddlewares(stack *middleware.Stack, op
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -102,7 +102,7 @@ func (c *Client) addOperationDeleteBucketAnalyticsConfigurationMiddlewares(stack
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -91,7 +91,7 @@ func (c *Client) addOperationDeleteBucketCorsMiddlewares(stack *middleware.Stack
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -99,7 +99,7 @@ func (c *Client) addOperationDeleteBucketEncryptionMiddlewares(stack *middleware
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -103,7 +103,7 @@ func (c *Client) addOperationDeleteBucketIntelligentTieringConfigurationMiddlewa
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -101,7 +101,7 @@ func (c *Client) addOperationDeleteBucketInventoryConfigurationMiddlewares(stack
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -97,7 +97,7 @@ func (c *Client) addOperationDeleteBucketLifecycleMiddlewares(stack *middleware.
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -105,7 +105,7 @@ func (c *Client) addOperationDeleteBucketMetricsConfigurationMiddlewares(stack *
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -91,7 +91,7 @@ func (c *Client) addOperationDeleteBucketOwnershipControlsMiddlewares(stack *mid
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -103,7 +103,7 @@ func (c *Client) addOperationDeleteBucketPolicyMiddlewares(stack *middleware.Sta
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -96,7 +96,7 @@ func (c *Client) addOperationDeleteBucketReplicationMiddlewares(stack *middlewar
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -90,7 +90,7 @@ func (c *Client) addOperationDeleteBucketTaggingMiddlewares(stack *middleware.St
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

View file

@ -98,7 +98,7 @@ func (c *Client) addOperationDeleteBucketWebsiteMiddlewares(stack *middleware.St
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
return err
}
if err = addClientUserAgent(stack); err != nil {
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {

Some files were not shown because too many files have changed in this diff Show more