Skip to content

Commit

Permalink
Adreed/presentation (#14564)
Browse files Browse the repository at this point in the history
* Added Blob/Container Lease Client

* Reduce surface area UDK touches + better UX

* Refactored

* Added License Text

* Added test cases

* Regenerate SDK and (mostly) fix tests

* Remove pathrenamemode from lease client

* Add SAS generation to specialized blob clients

* Add examples for SAS generation

* Extra changes

Co-authored-by: Mohit Sharma <65536214+mohsha-msft@users.noreply.github.com>
  • Loading branch information
adreed-msft and mohsha-msft committed Apr 21, 2021
1 parent 72e587b commit 500d7bb
Show file tree
Hide file tree
Showing 58 changed files with 4,443 additions and 4,103 deletions.
3 changes: 3 additions & 0 deletions sdk/storage/azblob/.gitignore
@@ -1,3 +1,6 @@
## Ignore generated bin files
BigFile*.bin

## ignore .DS_Store on macOS
*.DS_Store

Expand Down
9 changes: 7 additions & 2 deletions sdk/storage/azblob/go.mod
Expand Up @@ -3,10 +3,15 @@ module github.com/Azure/azure-sdk-for-go/sdk/storage/azblob
go 1.13

require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.13.4
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.6.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.3
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.8.0
github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0
github.com/Azure/azure-sdk-for-go/sdk/to v0.1.3
github.com/google/uuid v1.1.1
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 // indirect
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c // indirect
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 // indirect
golang.org/x/text v0.3.6 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
)
22 changes: 22 additions & 0 deletions sdk/storage/azblob/go.sum
@@ -1,8 +1,15 @@
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.13.1/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.13.4 h1:7MfvHEWKfjZSKQNWERlXpHwCRoceEuQef/fB8CWmnQA=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.13.4/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.0/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 h1:jBp1eg+iY1S6SEjISakVfHmvDxfj8bg1Mw9JFwpCKag=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.3 h1:WgQHTcErc4NV3nuMc+OiR16DtpVy7230CjOpjD+FA84=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.3/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.6.0 h1:ksvSe0GxLR0H4narxWihjuz2a90JsmrUELJM9qulh+0=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.6.0/go.mod h1:BfjVb0eeNKsOveaOBnAgUv6nSq5hwScOz7mCm9lqUx8=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.8.0 h1:wb00szFWtKeIef2Q5X8gdd0mYp8oSHmJOYUh/QXD8sw=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.8.0/go.mod h1:acANgl9stsT5xflESXKjZx4rhZJSr0TGgTDYY0xJPIE=
github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0 h1:HG1ggl8L3ZkV/Ydanf7lKr5kkhhPGCpWdnr1J6v7cO4=
github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0/go.mod h1:k4KbFSunV/+0hOHL1vyFaPsiYQ1Vmvy1TBpmtvCDLZM=
github.com/Azure/azure-sdk-for-go/sdk/to v0.1.3 h1:5p7WsYlB8FqcpXdi0rOpppjV8xN3yonEZr1ArSetzZo=
Expand All @@ -16,21 +23,36 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI=
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c h1:KHUzaHIpjWVlVVNh65G3hhuj3KB1HnjY6Cq5cTvRQT8=
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 h1:rF3Ohx8DRyl8h2zw9qojyLHLhrJpEMgyPOImREEryf0=
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
22 changes: 11 additions & 11 deletions sdk/storage/azblob/highlevel.go
Expand Up @@ -49,7 +49,7 @@ type HighLevelUploadToBlockBlobOption struct {
Progress azcore.ProgressReceiver

// BlobHTTPHeaders indicates the HTTP headers to be associated with the blob.
BlobHTTPHeaders *BlobHttpHeaders
BlobHTTPHeaders *BlobHTTPHeaders

// Metadata indicates the metadata to be associated with the blob when PutBlockList is called.
Metadata *map[string]string
Expand All @@ -71,9 +71,9 @@ type HighLevelUploadToBlockBlobOption struct {
// Parallelism indicates the maximum number of blocks to upload in parallel (0=default)
Parallelism uint16

TransactionalContentCrc64 *[]byte
TransactionalContentCRC64 *[]byte
// Specify the transactional md5 for the body, to be validated by the service.
TransactionalContentMd5 *[]byte
TransactionalContentMD5 *[]byte
}

func (o HighLevelUploadToBlockBlobOption) getStageBlockOptions() *StageBlockOptions {
Expand All @@ -82,10 +82,10 @@ func (o HighLevelUploadToBlockBlobOption) getStageBlockOptions() *StageBlockOpti
CpkScopeInfo: o.CpkScopeInfo,
LeaseAccessConditions: o.LeaseAccessCondition,
//BlockBlobStageBlockOptions: &BlockBlobStageBlockOptions{
// RequestId: nil,
// RequestID: nil,
// Timeout: nil,
// TransactionalContentMd5: nil,
// TransactionalContentCrc64: nil,
// TransactionalContentMD5: nil,
// TransactionalContentCRC64: nil,
//},
}
}
Expand All @@ -95,8 +95,8 @@ func (o HighLevelUploadToBlockBlobOption) getUploadBlockBlobOptions() *UploadBlo
BlobTagsMap: o.BlobTagsMap,
Metadata: o.Metadata,
Tier: o.BlobAccessTier,
//TransactionalContentMd5:
BlobHttpHeaders: o.BlobHTTPHeaders,
//TransactionalContentMD5:
BlobHTTPHeaders: o.BlobHTTPHeaders,
LeaseAccessConditions: o.LeaseAccessCondition,
ModifiedAccessConditions: o.ModifiedAccessCondition,
CpkInfo: o.CpkInfo,
Expand Down Expand Up @@ -248,15 +248,15 @@ func (o *HighLevelDownloadFromBlobOptions) getBlobPropertiesOptions() *GetBlobPr
}
}

func (o *HighLevelDownloadFromBlobOptions) getDownloadBlobOptions(offSet, count int64, rangeGetContentMd5 *bool) *DownloadBlobOptions {
func (o *HighLevelDownloadFromBlobOptions) getDownloadBlobOptions(offSet, count int64, rangeGetContentMD5 *bool) *DownloadBlobOptions {
return &DownloadBlobOptions{
LeaseAccessConditions: o.LeaseAccessConditions,
ModifiedAccessConditions: o.ModifiedAccessConditions,
CpkInfo: o.CpkInfo,
CpkScopeInfo: o.CpkScopeInfo,
Offset: &offSet,
Count: &count,
RangeGetContentMd5: rangeGetContentMd5,
RangeGetContentMD5: rangeGetContentMD5,
}
}

Expand Down Expand Up @@ -587,7 +587,7 @@ type UploadStreamToBlockBlobOptions struct {
BufferSize int
// MaxBuffers defines the number of simultaneous uploads will be performed to upload the file.
MaxBuffers int
BlobHTTPHeaders *BlobHttpHeaders
BlobHTTPHeaders *BlobHTTPHeaders
Metadata *map[string]string
AccessConditions *BlobAccessConditions
BlobAccessTier *AccessTier
Expand Down
5 changes: 0 additions & 5 deletions sdk/storage/azblob/shared_policy_shared_key_credential.go
Expand Up @@ -37,11 +37,6 @@ type SharedKeyCredential struct {
accountKey atomic.Value // []byte
}

// noop function to satisfy StorageAccountCredential interface
func (c *SharedKeyCredential) GetUDKParams() *UserDelegationKey {
return nil
}

// AccountName returns the Storage account's name.
func (c *SharedKeyCredential) AccountName() string {
return c.accountName
Expand Down
1 change: 0 additions & 1 deletion sdk/storage/azblob/shared_storage_account_credential.go
Expand Up @@ -7,5 +7,4 @@ package azblob
type StorageAccountCredential interface {
AccountName() string
ComputeHMACSHA256(message string) (base64String string)
GetUDKParams() *UserDelegationKey
}
4 changes: 2 additions & 2 deletions sdk/storage/azblob/shared_user_delegation_credential.go
Expand Up @@ -36,6 +36,6 @@ func (f UserDelegationCredential) ComputeHMACSHA256(message string) (base64Strin
}

// Private method to return important parameters for NewSASQueryParameters
func (f UserDelegationCredential) GetUDKParams() *UserDelegationKey {
return &f.accountKey
func (f UserDelegationCredential) GetUDKParams() UserDelegationKey {
return f.accountKey
}
40 changes: 33 additions & 7 deletions sdk/storage/azblob/zc_appendBlobClient.go
Expand Up @@ -6,7 +6,7 @@ package azblob
import (
"context"
"io"
"net/url"
"time"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
)
Expand Down Expand Up @@ -38,7 +38,8 @@ func (ab AppendBlobClient) URL() string {
func (ab AppendBlobClient) WithSnapshot(snapshot string) AppendBlobClient {
p := NewBlobURLParts(ab.URL())
p.Snapshot = snapshot
con := newConnectionWithPipeline(p.URL(), ab.client.con.p)
con := &connection{u: p.URL(), p: ab.client.con.p}

return AppendBlobClient{
client: &appendBlobClient{con: con},
BlobClient: BlobClient{client: &blobClient{con: con}},
Expand All @@ -50,7 +51,8 @@ func (ab AppendBlobClient) WithSnapshot(snapshot string) AppendBlobClient {
func (ab AppendBlobClient) WithVersionID(versionID string) AppendBlobClient {
p := NewBlobURLParts(ab.URL())
p.VersionID = versionID
con := newConnectionWithPipeline(p.URL(), ab.client.con.p)
con := &connection{u: p.URL(), p: ab.client.con.p}

return AppendBlobClient{
client: &appendBlobClient{con: con},
BlobClient: BlobClient{client: &blobClient{con: con}},
Expand Down Expand Up @@ -85,12 +87,36 @@ func (ab AppendBlobClient) AppendBlock(ctx context.Context, body io.ReadSeeker,

// AppendBlockFromURL copies a new block of data from source URL to the end of the existing append blob.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/append-block-from-url.
func (ab AppendBlobClient) AppendBlockFromURL(ctx context.Context, source string, contentLength int64, options *AppendBlockURLOptions) (AppendBlobAppendBlockFromURLResponse, error) {
func (ab AppendBlobClient) AppendBlockFromURL(ctx context.Context, source string, options *AppendBlockURLOptions) (AppendBlobAppendBlockFromURLResponse, error) {
appendOptions, aac, cpkinfo, cpkscope, mac, lac, smac := options.pointers()

uri, _ := url.Parse(source)

resp, err := ab.client.AppendBlockFromURL(ctx, *uri, contentLength, appendOptions, cpkinfo, cpkscope, lac, aac, mac, smac)
// content length should be 0 on * from URL. always. It's a 400 if it isn't.
resp, err := ab.client.AppendBlockFromURL(ctx, source, 0, appendOptions, cpkinfo, cpkscope, lac, aac, mac, smac)

return resp, handleError(err)
}

// GetBlobSASToken is a convenience method for generating a SAS token for the currently pointed at blob.
// It can only be used if the supplied azcore.Credential during creation was a SharedKeyCredential.
// This validity can be checked with CanGetBlobSASToken().
func (ab AppendBlobClient) GetBlobSASToken(permissions BlobSASPermissions, validityTime time.Duration) (SASQueryParameters, error) {
urlParts := NewBlobURLParts(ab.URL())

t, err := time.Parse(SnapshotTimeFormat, urlParts.Snapshot)

if err != nil {
t = time.Time{}
}

return BlobSASSignatureValues{
ContainerName: urlParts.ContainerName,
BlobName: urlParts.BlobName,
SnapshotTime: t,
Version: SASVersion,

Permissions: permissions.String(),

StartTime: time.Now().UTC(),
ExpiryTime: time.Now().UTC().Add(validityTime),
}.NewSASQueryParameters(ab.cred)
}
30 changes: 15 additions & 15 deletions sdk/storage/azblob/zc_appendBlobRequestOptions.go
Expand Up @@ -6,7 +6,7 @@ package azblob
type CreateAppendBlobOptions struct {
BlobAccessConditions

BlobHttpHeaders *BlobHttpHeaders
BlobHTTPHeaders *BlobHTTPHeaders

CpkInfo *CpkInfo

Expand All @@ -20,30 +20,30 @@ type CreateAppendBlobOptions struct {
// See Naming and Referencing Containers, Blobs, and Metadata for more information.
Metadata *map[string]string
// Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled.
RequestId *string
RequestID *string

Timeout *int32
}

func (o *CreateAppendBlobOptions) pointers() (*AppendBlobCreateOptions, *BlobHttpHeaders, *LeaseAccessConditions, *CpkInfo, *CpkScopeInfo, *ModifiedAccessConditions) {
func (o *CreateAppendBlobOptions) pointers() (*AppendBlobCreateOptions, *BlobHTTPHeaders, *LeaseAccessConditions, *CpkInfo, *CpkScopeInfo, *ModifiedAccessConditions) {
if o == nil {
return nil, nil, nil, nil, nil, nil
}

options := AppendBlobCreateOptions{
BlobTagsString: serializeBlobTagsToStrPtr(o.BlobTagsMap),
Metadata: o.Metadata,
RequestId: o.RequestId,
RequestID: o.RequestID,
Timeout: o.Timeout,
}
return &options, o.BlobHttpHeaders, o.LeaseAccessConditions, o.CpkInfo, o.CpkScopeInfo, o.ModifiedAccessConditions
return &options, o.BlobHTTPHeaders, o.LeaseAccessConditions, o.CpkInfo, o.CpkScopeInfo, o.ModifiedAccessConditions
}

type AppendBlockOptions struct {
// Specify the transactional crc64 for the body, to be validated by the service.
TransactionalContentCrc64 *[]byte
TransactionalContentCRC64 *[]byte
// Specify the transactional md5 for the body, to be validated by the service.
TransactionalContentMd5 *[]byte
TransactionalContentMD5 *[]byte

AppendPositionAccessConditions *AppendPositionAccessConditions
CpkInfo *CpkInfo
Expand All @@ -57,20 +57,20 @@ func (o *AppendBlockOptions) pointers() (*AppendBlobAppendBlockOptions, *AppendP
}

options := &AppendBlobAppendBlockOptions{
TransactionalContentCrc64: o.TransactionalContentCrc64,
TransactionalContentMd5: o.TransactionalContentMd5,
TransactionalContentCRC64: o.TransactionalContentCRC64,
TransactionalContentMD5: o.TransactionalContentMD5,
}

return options, o.AppendPositionAccessConditions, o.CpkInfo, o.CpkScopeInfo, o.ModifiedAccessConditions, o.LeaseAccessConditions
}

type AppendBlockURLOptions struct {
// Specify the md5 calculated for the range of bytes that must be read from the copy source.
SourceContentMd5 *[]byte
SourceContentMD5 *[]byte
// Specify the crc64 calculated for the range of bytes that must be read from the copy source.
SourceContentCrc64 *[]byte
SourceContentCRC64 *[]byte
// Specify the transactional md5 for the body, to be validated by the service.
TransactionalContentMd5 *[]byte
TransactionalContentMD5 *[]byte

AppendPositionAccessConditions *AppendPositionAccessConditions
CpkInfo *CpkInfo
Expand All @@ -89,9 +89,9 @@ func (o *AppendBlockURLOptions) pointers() (*AppendBlobAppendBlockFromURLOptions

options := &AppendBlobAppendBlockFromURLOptions{
SourceRange: getSourceRange(o.Offset, o.Count),
SourceContentMd5: o.SourceContentMd5,
SourceContentcrc64: o.SourceContentCrc64,
TransactionalContentMd5: o.TransactionalContentMd5,
SourceContentMD5: o.SourceContentMD5,
SourceContentcrc64: o.SourceContentCRC64,
TransactionalContentMD5: o.TransactionalContentMD5,
}

return options, o.AppendPositionAccessConditions, o.CpkInfo, o.CpkScopeInfo, o.ModifiedAccessConditions, o.LeaseAccessConditions, o.SourceModifiedAccessConditions
Expand Down

0 comments on commit 500d7bb

Please sign in to comment.