#7508079 [Go][Blob][2019-12-12] Blob Versioning (#190)

* Generated code for 12-12-2019 spec

* Fix test

* Changes

* Basic Testing and modification in WithVersionId function.

* Added Tags and Versions in BlobListingDetails.

* Added Tests

* Added TestCases

* Commented out tests which require versioning disabled.

* Added Tests

* Testcases 1-on-1 with python SDK

* Moved all tests to same file for ease of accessibility

Co-authored-by: zezha-msft <zezha@microsoft.com>
This commit is contained in:
Mohit Sharma 2020-07-27 09:02:27 +05:30 коммит произвёл mohsha-msft
Родитель 48d6534d8b
Коммит a702648539
26 изменённых файлов: 4970 добавлений и 512 удалений

Просмотреть файл

@ -1,6 +1,7 @@
package azblob
import (
"errors"
"net"
"net/url"
"strings"
@ -8,6 +9,7 @@ import (
const (
snapshot = "snapshot"
versionid = "versionid"
SnapshotTimeFormat = "2006-01-02T15:04:05.0000000Z07:00"
)
@ -23,6 +25,7 @@ type BlobURLParts struct {
Snapshot string // "" if not a snapshot
SAS SASQueryParameters
UnparsedParams string
VersionID string // "" if not versioning enabled
}
// IPEndpointStyleInfo is used for IP endpoint style URL when working with Azure storage emulator.
@ -85,12 +88,19 @@ func NewBlobURLParts(u url.URL) BlobURLParts {
// Convert the query parameters to a case-sensitive map & trim whitespace
paramsMap := u.Query()
up.Snapshot = "" // Assume no snapshot
up.Snapshot = "" // Assume no snapshot
up.VersionID = "" // Assume no versionID
if snapshotStr, ok := caseInsensitiveValues(paramsMap).Get(snapshot); ok {
up.Snapshot = snapshotStr[0]
// If we recognized the query parameter, remove it from the map
delete(paramsMap, snapshot)
}
if versionIDs, ok := caseInsensitiveValues(paramsMap).Get(versionid); ok {
up.VersionID = versionIDs[0]
// If we recognized the query parameter, remove it from the map
delete(paramsMap, versionid)
}
up.SAS = newSASQueryParameters(paramsMap, true)
up.UnparsedParams = paramsMap.Encode()
return up
@ -124,6 +134,11 @@ func (up BlobURLParts) URL() url.URL {
rawQuery := up.UnparsedParams
// Check: Both snapshot and version id cannot be present in the request URL.
if up.Snapshot != "" && up.VersionID != "" {
errors.New("Snapshot and versioning cannot be enabled simultaneously")
}
//If no snapshot is initially provided, fill it in from the SAS query properties to help the user
if up.Snapshot == "" && !up.SAS.snapshotTime.IsZero() {
up.Snapshot = up.SAS.snapshotTime.Format(SnapshotTimeFormat)
@ -136,6 +151,15 @@ func (up BlobURLParts) URL() url.URL {
}
rawQuery += snapshot + "=" + up.Snapshot
}
// Concatenate blob version id query parameter (if it exists)
if up.VersionID != "" {
if len(rawQuery) > 0 {
rawQuery += "&"
}
rawQuery += versionid + "=" + up.VersionID
}
sas := up.SAS.Encode()
if sas != "" {
if len(rawQuery) > 0 {

Просмотреть файл

@ -44,6 +44,14 @@ func (v BlobSASSignatureValues) NewSASQueryParameters(credential StorageAccountC
return SASQueryParameters{}, err
}
v.Permissions = perms.String()
} else if v.Version != null && v.Version != "" {
resource = "bv"
//Make sure the permission characters are in the correct order
perms := &BlobSASPermissions{}
if err := perms.Parse(v.Permissions); err != nil {
return SASQueryParameters{}, err
}
v.Permissions = perms.String()
} else if v.BlobName == "" {
// Make sure the permission characters are in the correct order
perms := &ContainerSASPermissions{}
@ -209,7 +217,7 @@ func (p *ContainerSASPermissions) Parse(s string) error {
// The BlobSASPermissions type simplifies creating the permissions string for an Azure Storage blob SAS.
// Initialize an instance of this type and then call its String method to set BlobSASSignatureValues's Permissions field.
type BlobSASPermissions struct{ Read, Add, Create, Write, Delete bool }
type BlobSASPermissions struct{ Read, Add, Create, Write, Delete, DeletePreviousVersion bool }
// String produces the SAS permissions string for an Azure Storage blob.
// Call this method to set BlobSASSignatureValues's Permissions field.
@ -230,6 +238,9 @@ func (p BlobSASPermissions) String() string {
if p.Delete {
b.WriteRune('d')
}
if p.DeletePreviousVersion {
b.WriteRune('x')
}
return b.String()
}
@ -248,6 +259,8 @@ func (p *BlobSASPermissions) Parse(s string) error {
p.Write = true
case 'd':
p.Delete = true
case 'x':
p.DeletePreviousVersion = true
default:
return fmt.Errorf("Invalid permission: '%v'", r)
}

Просмотреть файл

@ -42,6 +42,14 @@ func (ab AppendBlobURL) WithSnapshot(snapshot string) AppendBlobURL {
return NewAppendBlobURL(p.URL(), ab.blobClient.Pipeline())
}
// WithVersionID creates a new AppendBlobURL object identical to the source but with the specified version id.
// Pass "" to remove the snapshot returning a URL to the base blob.
func (ab AppendBlobURL) WithVersionID(versionId string) AppendBlobURL {
p := NewBlobURLParts(ab.URL())
p.VersionID = versionId
return NewAppendBlobURL(p.URL(), ab.blobClient.Pipeline())
}
func (ab AppendBlobURL) GetAccountInfo(ctx context.Context) (*BlobGetAccountInfoResponse, error) {
return ab.blobClient.GetAccountInfo(ctx)
}
@ -53,8 +61,13 @@ func (ab AppendBlobURL) Create(ctx context.Context, h BlobHTTPHeaders, metadata
return ab.abClient.Create(ctx, 0, nil,
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5,
&h.CacheControl, metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition,
nil, nil, EncryptionAlgorithmNone, // CPK
ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, nil)
nil, nil, EncryptionAlgorithmNone, // CPK-V
nil, // CPK-N
ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch,
nil, // Blob tags
nil,
nil, // Blob tags
)
}
// AppendBlock writes a stream to a new block of data to the end of the existing append blob.
@ -74,7 +87,10 @@ func (ab AppendBlobURL) AppendBlock(ctx context.Context, body io.ReadSeeker, ac
ac.LeaseAccessConditions.pointers(),
ifMaxSizeLessThanOrEqual, ifAppendPositionEqual,
nil, nil, EncryptionAlgorithmNone, // CPK
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
nil, // CPK-N
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// AppendBlockFromURL copies a new block of data from source URL to the end of the existing append blob.
@ -86,9 +102,12 @@ func (ab AppendBlobURL) AppendBlockFromURL(ctx context.Context, sourceURL url.UR
return ab.abClient.AppendBlockFromURL(ctx, sourceURL.String(), 0, httpRange{offset: offset, count: count}.pointers(),
transactionalMD5, nil, nil, nil,
nil, nil, EncryptionAlgorithmNone, // CPK
nil, // CPK-N
destinationAccessConditions.LeaseAccessConditions.pointers(),
ifMaxSizeLessThanOrEqual, ifAppendPositionEqual,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatchETag, sourceIfNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatchETag, sourceIfNoneMatchETag, nil)
}
type AppendBlobAccessConditions struct {

Просмотреть файл

@ -46,6 +46,14 @@ func (b BlobURL) WithSnapshot(snapshot string) BlobURL {
return NewBlobURL(p.URL(), b.blobClient.Pipeline())
}
// WithVersionID creates a new BlobURL object identical to the source but with the specified version id.
// Pass "" to remove the snapshot returning a URL to the base blob.
func (b BlobURL) WithVersionID(versionID string) BlobURL {
p := NewBlobURLParts(b.URL())
p.VersionID = versionID
return NewBlobURL(p.URL(), b.blobClient.Pipeline())
}
// ToAppendBlobURL creates an AppendBlobURL using the source's URL and pipeline.
func (b BlobURL) ToAppendBlobURL() AppendBlobURL {
return NewAppendBlobURL(b.URL(), b.blobClient.Pipeline())
@ -63,6 +71,9 @@ func (b BlobURL) ToPageBlobURL() PageBlobURL {
// DownloadBlob reads a range of bytes from a blob. The response also includes the blob's properties and metadata.
// Passing azblob.CountToEnd (0) for count will download the blob from the offset to the end.
// Note: Snapshot/VersionId are optional parameters which are part of request URL query params.
// These parameters can be explicitly set by calling WithSnapshot(snapshot string)/WithVersionID(versionID string)
// Therefore it not required to pass these here.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob.
func (b BlobURL) Download(ctx context.Context, offset int64, count int64, ac BlobAccessConditions, rangeGetContentMD5 bool) (*DownloadResponse, error) {
var xRangeGetContentMD5 *bool
@ -70,11 +81,13 @@ func (b BlobURL) Download(ctx context.Context, offset int64, count int64, ac Blo
xRangeGetContentMD5 = &rangeGetContentMD5
}
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
dr, err := b.blobClient.Download(ctx, nil, nil,
dr, err := b.blobClient.Download(ctx, nil, nil, nil,
httpRange{offset: offset, count: count}.pointers(),
ac.LeaseAccessConditions.pointers(), xRangeGetContentMD5, nil,
nil, nil, EncryptionAlgorithmNone, // CPK
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
if err != nil {
return nil, err
}
@ -87,12 +100,17 @@ func (b BlobURL) Download(ctx context.Context, offset int64, count int64, ac Blo
}
// DeleteBlob marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection.
// Note that deleting a blob also deletes all its snapshots.
// Note 1: that deleting a blob also deletes all its snapshots.
// Note 2: Snapshot/VersionId are optional parameters which are part of request URL query params.
// These parameters can be explicitly set by calling WithSnapshot(snapshot string)/WithVersionID(versionID string)
// Therefore it not required to pass these here.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-blob.
func (b BlobURL) Delete(ctx context.Context, deleteOptions DeleteSnapshotsOptionType, ac BlobAccessConditions) (*BlobDeleteResponse, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
return b.blobClient.Delete(ctx, nil, nil, ac.LeaseAccessConditions.pointers(), deleteOptions,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
return b.blobClient.Delete(ctx, nil, nil, nil, ac.LeaseAccessConditions.pointers(), deleteOptions,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// Undelete restores the contents and metadata of a soft-deleted blob and any associated soft-deleted snapshots.
@ -101,23 +119,33 @@ func (b BlobURL) Undelete(ctx context.Context) (*BlobUndeleteResponse, error) {
return b.blobClient.Undelete(ctx, nil, nil)
}
// 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.
// 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.
// Note: VersionId is an optional parameter which is part of request URL query params.
// It can be explicitly set by calling WithVersionID(versionID string) function and hence it not required to pass it here.
// For detailed information about block blob level tiering see https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-storage-tiers.
func (b BlobURL) SetTier(ctx context.Context, tier AccessTierType, lac LeaseAccessConditions) (*BlobSetTierResponse, error) {
return b.blobClient.SetTier(ctx, tier, nil, RehydratePriorityNone, nil, lac.pointers())
return b.blobClient.SetTier(ctx, tier, nil,
nil, // Blob versioning
nil, RehydratePriorityNone, nil, lac.pointers())
}
// GetBlobProperties returns the blob's properties.
// Note: Snapshot/VersionId are optional parameters which are part of request URL query params.
// These parameters can be explicitly set by calling WithSnapshot(snapshot string)/WithVersionID(versionID string)
// Therefore it not required to pass these here.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob-properties.
func (b BlobURL) GetProperties(ctx context.Context, ac BlobAccessConditions) (*BlobGetPropertiesResponse, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
return b.blobClient.GetProperties(ctx, nil, nil, ac.LeaseAccessConditions.pointers(),
return b.blobClient.GetProperties(ctx, nil,
nil, // Blob versioning
nil, ac.LeaseAccessConditions.pointers(),
nil, nil, EncryptionAlgorithmNone, // CPK
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// SetBlobHTTPHeaders changes a blob's HTTP headers.
@ -127,6 +155,7 @@ func (b BlobURL) SetHTTPHeaders(ctx context.Context, h BlobHTTPHeaders, ac BlobA
return b.blobClient.SetHTTPHeaders(ctx, nil,
&h.CacheControl, &h.ContentType, h.ContentMD5, &h.ContentEncoding, &h.ContentLanguage,
ac.LeaseAccessConditions.pointers(), ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
&h.ContentDisposition, nil)
}
@ -135,8 +164,11 @@ func (b BlobURL) SetHTTPHeaders(ctx context.Context, h BlobHTTPHeaders, ac BlobA
func (b BlobURL) SetMetadata(ctx context.Context, metadata Metadata, ac BlobAccessConditions) (*BlobSetMetadataResponse, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
return b.blobClient.SetMetadata(ctx, nil, metadata, ac.LeaseAccessConditions.pointers(),
nil, nil, EncryptionAlgorithmNone, // CPK
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
nil, nil, EncryptionAlgorithmNone, // CPK-V
nil, // CPK-N
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// CreateSnapshot creates a read-only snapshot of a blob.
@ -147,8 +179,11 @@ func (b BlobURL) CreateSnapshot(ctx context.Context, metadata Metadata, ac BlobA
// performance hit.
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
return b.blobClient.CreateSnapshot(ctx, nil, metadata,
nil, nil, EncryptionAlgorithmNone, // CPK
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, ac.LeaseAccessConditions.pointers(), nil)
nil, nil, EncryptionAlgorithmNone, // CPK-V
nil, // CPK-N
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
ac.LeaseAccessConditions.pointers(), nil)
}
// AcquireLease acquires a lease on the blob for write and delete operations. The lease duration must be between
@ -157,7 +192,9 @@ func (b BlobURL) CreateSnapshot(ctx context.Context, metadata Metadata, ac BlobA
func (b BlobURL) AcquireLease(ctx context.Context, proposedID string, duration int32, ac ModifiedAccessConditions) (*BlobAcquireLeaseResponse, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
return b.blobClient.AcquireLease(ctx, nil, &duration, &proposedID,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// RenewLease renews the blob's previously-acquired lease.
@ -165,7 +202,9 @@ func (b BlobURL) AcquireLease(ctx context.Context, proposedID string, duration i
func (b BlobURL) RenewLease(ctx context.Context, leaseID string, ac ModifiedAccessConditions) (*BlobRenewLeaseResponse, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
return b.blobClient.RenewLease(ctx, leaseID, nil,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// ReleaseLease releases the blob's previously-acquired lease.
@ -173,7 +212,9 @@ func (b BlobURL) RenewLease(ctx context.Context, leaseID string, ac ModifiedAcce
func (b BlobURL) ReleaseLease(ctx context.Context, leaseID string, ac ModifiedAccessConditions) (*BlobReleaseLeaseResponse, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
return b.blobClient.ReleaseLease(ctx, leaseID, nil,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// BreakLease breaks the blob's previously-acquired lease (if it exists). Pass the LeaseBreakDefault (-1)
@ -182,7 +223,9 @@ func (b BlobURL) ReleaseLease(ctx context.Context, leaseID string, ac ModifiedAc
func (b BlobURL) BreakLease(ctx context.Context, breakPeriodInSeconds int32, ac ModifiedAccessConditions) (*BlobBreakLeaseResponse, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
return b.blobClient.BreakLease(ctx, nil, leasePeriodPointer(breakPeriodInSeconds),
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// ChangeLease changes the blob's lease ID.
@ -190,7 +233,9 @@ func (b BlobURL) BreakLease(ctx context.Context, breakPeriodInSeconds int32, ac
func (b BlobURL) ChangeLease(ctx context.Context, leaseID string, proposedID string, ac ModifiedAccessConditions) (*BlobChangeLeaseResponse, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
return b.blobClient.ChangeLease(ctx, leaseID, proposedID,
nil, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
nil, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// LeaseBreakNaturally tells ContainerURL's or BlobURL's BreakLease method to break the lease using service semantics.
@ -213,9 +258,14 @@ func (b BlobURL) StartCopyFromURL(ctx context.Context, source url.URL, metadata
return b.blobClient.StartCopyFromURL(ctx, source.String(), nil, metadata,
AccessTierNone, RehydratePriorityNone, srcIfModifiedSince, srcIfUnmodifiedSince,
srcIfMatchETag, srcIfNoneMatchETag,
nil, // Blob tags
dstIfModifiedSince, dstIfUnmodifiedSince,
dstIfMatchETag, dstIfNoneMatchETag,
dstLeaseID, nil)
nil, // Blob tags
dstLeaseID,
nil,
nil, // Blob tags
nil)
}
// AbortCopyFromURL stops a pending copy that was previously started and leaves a destination blob with 0 length and metadata.

Просмотреть файл

@ -45,6 +45,14 @@ func (bb BlockBlobURL) WithSnapshot(snapshot string) BlockBlobURL {
return NewBlockBlobURL(p.URL(), bb.blobClient.Pipeline())
}
// WithVersionID creates a new BlockBlobURRL object identical to the source but with the specified version id.
// Pass "" to remove the snapshot returning a URL to the base blob.
func (bb BlockBlobURL) WithVersionID(versionId string) BlockBlobURL {
p := NewBlobURLParts(bb.URL())
p.VersionID = versionId
return NewBlockBlobURL(p.URL(), bb.blobClient.Pipeline())
}
func (bb BlockBlobURL) GetAccountInfo(ctx context.Context) (*BlobGetAccountInfoResponse, error) {
return bb.blobClient.GetAccountInfo(ctx)
}
@ -65,9 +73,13 @@ func (bb BlockBlobURL) Upload(ctx context.Context, body io.ReadSeeker, h BlobHTT
return bb.bbClient.Upload(ctx, body, count, nil, nil,
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5,
&h.CacheControl, metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition,
nil, nil, EncryptionAlgorithmNone, // CPK
nil, nil, EncryptionAlgorithmNone, // CPK-V
nil, // CPK-N
AccessTierNone, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil)
nil, // Blob tags
nil,
nil, // Blob tags
)
}
// StageBlock uploads the specified block to the block blob's "staging area" to be later committed by a call to CommitBlockList.
@ -79,7 +91,8 @@ func (bb BlockBlobURL) StageBlock(ctx context.Context, base64BlockID string, bod
return nil, err
}
return bb.bbClient.StageBlock(ctx, base64BlockID, count, body, transactionalMD5, nil, nil, ac.pointers(),
nil, nil, EncryptionAlgorithmNone, // CPK
nil, nil, EncryptionAlgorithmNone, // CPK-V
nil, // CPK-N
nil)
}
@ -90,6 +103,7 @@ func (bb BlockBlobURL) StageBlockFromURL(ctx context.Context, base64BlockID stri
sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatchETag, sourceIfNoneMatchETag := sourceAccessConditions.pointers()
return bb.bbClient.StageBlockFromURL(ctx, base64BlockID, 0, sourceURL.String(), httpRange{offset: offset, count: count}.pointers(), nil, nil, nil,
nil, nil, EncryptionAlgorithmNone, // CPK
nil, // CPK-N
destinationAccessConditions.pointers(), sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatchETag, sourceIfNoneMatchETag, nil)
}
@ -106,14 +120,21 @@ func (bb BlockBlobURL) CommitBlockList(ctx context.Context, base64BlockIDs []str
&h.CacheControl, &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, nil, nil,
metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition,
nil, nil, EncryptionAlgorithmNone, // CPK
nil, // CPK-N
AccessTierNone,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil,
nil, // Blob tags
)
}
// GetBlockList returns the list of blocks that have been uploaded as part of a block blob using the specified block list filter.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-block-list.
func (bb BlockBlobURL) GetBlockList(ctx context.Context, listType BlockListType, ac LeaseAccessConditions) (*BlockList, error) {
return bb.bbClient.GetBlockList(ctx, listType, nil, nil, ac.pointers(), nil)
return bb.bbClient.GetBlockList(ctx, listType, nil, nil, ac.pointers(),
nil, // Blob tags
nil)
}
// CopyFromURL synchronously copies the data at the source URL to a block blob, with sizes up to 256 MB.
@ -130,5 +151,9 @@ func (bb BlockBlobURL) CopyFromURL(ctx context.Context, source url.URL, metadata
srcIfMatchETag, srcIfNoneMatchETag,
dstIfModifiedSince, dstIfUnmodifiedSince,
dstIfMatchETag, dstIfNoneMatchETag,
dstLeaseID, nil, srcContentMD5)
nil, // Blob tags
dstLeaseID, nil, srcContentMD5,
nil, // Blob tags
nil, // seal Blob
)
}

Просмотреть файл

@ -84,7 +84,9 @@ func (c ContainerURL) NewPageBlobURL(blobName string) PageBlobURL {
// Create creates a new container within a storage account. If a container with the same name already exists, the operation fails.
// For more information, see https://docs.microsoft.com/rest/api/storageservices/create-container.
func (c ContainerURL) Create(ctx context.Context, metadata Metadata, publicAccessType PublicAccessType) (*ContainerCreateResponse, error) {
return c.client.Create(ctx, nil, metadata, publicAccessType, nil)
return c.client.Create(ctx, nil, metadata, publicAccessType, nil,
nil, nil, // container encryption
)
}
// Delete marks the specified container for deletion. The container and any blobs contained within it are later deleted during garbage collection.
@ -273,7 +275,7 @@ func (o *ListBlobsSegmentOptions) pointers() (prefix *string, include []ListBlob
// BlobListingDetails indicates what additional information the service should return with each blob.
type BlobListingDetails struct {
Copy, Metadata, Snapshots, UncommittedBlobs, Deleted bool
Copy, Metadata, Snapshots, UncommittedBlobs, Deleted, Tags, Versions bool
}
// string produces the Include query parameter's value.
@ -295,5 +297,11 @@ func (d *BlobListingDetails) slice() []ListBlobsIncludeItemType {
if d.UncommittedBlobs {
items = append(items, ListBlobsIncludeItemUncommittedblobs)
}
if d.Tags {
items = append(items, ListBlobsIncludeItemTags)
}
if d.Versions {
items = append(items, ListBlobsIncludeItemVersions)
}
return items
}

Просмотреть файл

@ -44,6 +44,14 @@ func (pb PageBlobURL) WithSnapshot(snapshot string) PageBlobURL {
return NewPageBlobURL(p.URL(), pb.blobClient.Pipeline())
}
// WithVersionID creates a new PageBlobURL object identical to the source but with the specified snapshot timestamp.
// Pass "" to remove the snapshot returning a URL to the base blob.
func (pb PageBlobURL) WithVersionID(versionId string) PageBlobURL {
p := NewBlobURLParts(pb.URL())
p.VersionID = versionId
return NewPageBlobURL(p.URL(), pb.blobClient.Pipeline())
}
func (pb PageBlobURL) GetAccountInfo(ctx context.Context) (*BlobGetAccountInfoResponse, error) {
return pb.blobClient.GetAccountInfo(ctx)
}
@ -55,8 +63,13 @@ func (pb PageBlobURL) Create(ctx context.Context, size int64, sequenceNumber int
return pb.pbClient.Create(ctx, 0, size, nil, PremiumPageBlobAccessTierNone,
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, &h.CacheControl,
metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition,
nil, nil, EncryptionAlgorithmNone, // CPK
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, &sequenceNumber, nil)
nil, nil, EncryptionAlgorithmNone, // CPK-V
nil, // CPK-N
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
&sequenceNumber, nil,
nil, // Blob tags
)
}
// UploadPages writes 1 or more pages to the page blob. The start offset and the stream size must be a multiple of 512 bytes.
@ -74,8 +87,11 @@ func (pb PageBlobURL) UploadPages(ctx context.Context, offset int64, body io.Rea
PageRange{Start: offset, End: offset + count - 1}.pointers(),
ac.LeaseAccessConditions.pointers(),
nil, nil, EncryptionAlgorithmNone, // CPK
nil, // CPK-N
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// UploadPagesFromURL copies 1 or more pages from a source URL to the page blob.
@ -89,10 +105,13 @@ func (pb PageBlobURL) UploadPagesFromURL(ctx context.Context, sourceURL url.URL,
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual := destinationAccessConditions.SequenceNumberAccessConditions.pointers()
return pb.pbClient.UploadPagesFromURL(ctx, sourceURL.String(), *PageRange{Start: sourceOffset, End: sourceOffset + count - 1}.pointers(), 0,
*PageRange{Start: destOffset, End: destOffset + count - 1}.pointers(), transactionalMD5, nil, nil,
nil, nil, EncryptionAlgorithmNone, // CPK
nil, nil, EncryptionAlgorithmNone, // CPK-V
nil, // CPK-N
destinationAccessConditions.LeaseAccessConditions.pointers(),
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatchETag, sourceIfNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatchETag, sourceIfNoneMatchETag, nil)
}
// ClearPages frees the specified pages from the page blob.
@ -104,6 +123,7 @@ func (pb PageBlobURL) ClearPages(ctx context.Context, offset int64, count int64,
PageRange{Start: offset, End: offset + count - 1}.pointers(),
ac.LeaseAccessConditions.pointers(),
nil, nil, EncryptionAlgorithmNone, // CPK
nil, // CPK-N
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan,
ifSequenceNumberEqual, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
}
@ -115,7 +135,9 @@ func (pb PageBlobURL) GetPageRanges(ctx context.Context, offset int64, count int
return pb.pbClient.GetPageRanges(ctx, nil, nil,
httpRange{offset: offset, count: count}.pointers(),
ac.LeaseAccessConditions.pointers(),
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
// GetPageRangesDiff gets the collection of page ranges that differ between a specified snapshot and this page blob.
@ -123,9 +145,11 @@ func (pb PageBlobURL) GetPageRanges(ctx context.Context, offset int64, count int
func (pb PageBlobURL) GetPageRangesDiff(ctx context.Context, offset int64, count int64, prevSnapshot string, ac BlobAccessConditions) (*PageList, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
return pb.pbClient.GetPageRangesDiff(ctx, nil, nil, &prevSnapshot,
nil, // Get managed disk diff
httpRange{offset: offset, count: count}.pointers(),
ac.LeaseAccessConditions.pointers(),
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
nil, // Blob tags
nil)
}
@ -135,6 +159,7 @@ func (pb PageBlobURL) Resize(ctx context.Context, size int64, ac BlobAccessCondi
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
return pb.pbClient.Resize(ctx, size, nil, ac.LeaseAccessConditions.pointers(),
nil, nil, EncryptionAlgorithmNone, // CPK
nil, // CPK-N
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
}

Просмотреть файл

@ -116,14 +116,14 @@ type ListContainersSegmentOptions struct {
// TODO: update swagger to generate this type?
}
func (o *ListContainersSegmentOptions) pointers() (prefix *string, include ListContainersIncludeType, maxResults *int32) {
func (o *ListContainersSegmentOptions) pointers() (prefix *string, include []ListContainersIncludeType, maxResults *int32) {
if o.Prefix != "" {
prefix = &o.Prefix
}
if o.MaxResults != 0 {
maxResults = &o.MaxResults
}
include = ListContainersIncludeType(o.Detail.string())
include = []ListContainersIncludeType{ListContainersIncludeType(o.Detail.string())}
return
}
@ -131,15 +131,21 @@ func (o *ListContainersSegmentOptions) pointers() (prefix *string, include ListC
type ListContainersDetail struct {
// Tells the service whether to return metadata for each container.
Metadata bool
// Show containers that have been deleted when the soft-delete feature is enabled.
Deleted bool
}
// string produces the Include query parameter's value.
func (d *ListContainersDetail) string() string {
items := make([]string, 0, 1)
items := make([]string, 0, 2)
// NOTE: Multiple strings MUST be appended in alphabetic order or signing the string for authentication fails!
if d.Metadata {
items = append(items, string(ListContainersIncludeMetadata))
}
if d.Deleted {
items = append(items, string(ListContainersIncludeDeleted))
}
if len(items) > 0 {
return strings.Join(items, ",")
}

Просмотреть файл

@ -76,7 +76,7 @@ func (v AccountSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *Sh
// The AccountSASPermissions type simplifies creating the permissions string for an Azure Storage Account SAS.
// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues's Permissions field.
type AccountSASPermissions struct {
Read, Write, Delete, List, Add, Create, Update, Process bool
Read, Write, Delete, DeletePreviousVersion, List, Add, Create, Update, Process bool
}
// String produces the SAS permissions string for an Azure Storage account.
@ -92,6 +92,9 @@ func (p AccountSASPermissions) String() string {
if p.Delete {
buffer.WriteRune('d')
}
if p.DeletePreviousVersion {
buffer.WriteRune('x')
}
if p.List {
buffer.WriteRune('l')
}
@ -131,6 +134,8 @@ func (p *AccountSASPermissions) Parse(s string) error {
p.Update = true
case 'p':
p.Process = true
case 'x':
p.Process = true
default:
return fmt.Errorf("Invalid permission character: '%v'", r)
}

Просмотреть файл

@ -114,6 +114,8 @@ const (
// ServiceCodeResourceNotFound means the specified resource does not exist (404).
ServiceCodeResourceNotFound ServiceCodeType = "ResourceNotFound"
ServiceCodeNoAuthenticationInformation ServiceCodeType = "NoAuthenticationInformation"
// ServiceCodeServerBusy means the server is currently unable to receive requests. Please retry your request or Ingress/egress is over the account limit or operations per second is over the account limit (503).
ServiceCodeServerBusy ServiceCodeType = "ServerBusy"

Просмотреть файл

@ -0,0 +1,386 @@
package azblob
import (
"context"
"encoding/base64"
"encoding/binary"
"io/ioutil"
"time"
"crypto/md5"
"bytes"
"strings"
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
)
func (s *aztestsSuite) TestGetBlobPropertiesUsingVID(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewAppendBlob(c, containerURL)
blobProp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{})
createResp, err := blobURL.Create(ctx, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: blobProp.ETag()}})
c.Assert(err, chk.IsNil)
c.Assert(createResp.VersionID(), chk.NotNil)
blobProp, _ = blobURL.GetProperties(ctx, BlobAccessConditions{})
c.Assert(createResp.VersionID(), chk.Equals, blobProp.VersionID())
c.Assert(createResp.LastModified(), chk.DeepEquals, blobProp.LastModified())
c.Assert(createResp.ETag(), chk.Equals, blobProp.ETag())
c.Assert(blobProp.IsCurrentVersion(), chk.Equals, "true")
}
func (s *aztestsSuite) TestSetBlobMetadataReturnsVID(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, blobName := createNewBlockBlob(c, containerURL)
metadata := Metadata{"test_key_1": "test_value_1", "test_key_2": "2019"}
resp, err := blobURL.SetMetadata(ctx, metadata, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.VersionID(), chk.NotNil)
listBlobResp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Details: BlobListingDetails{Metadata: true}})
c.Assert(err, chk.IsNil)
c.Assert(listBlobResp.Segment.BlobItems[0].Name, chk.Equals, blobName)
c.Assert(listBlobResp.Segment.BlobItems[0].Metadata, chk.HasLen, 2)
c.Assert(listBlobResp.Segment.BlobItems[0].Metadata, chk.DeepEquals, metadata)
}
func (s *aztestsSuite) TestCreateAndDownloadBlobSpecialCharactersWithVID(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
data := []rune("-._/()$=',~0123456789")
for i := 0; i < len(data); i++ {
blobName := "abc" + string(data[i])
blobURL := containerURL.NewBlockBlobURL(blobName)
resp, err := blobURL.Upload(ctx, strings.NewReader(string(data[i])), BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.VersionID(), chk.NotNil)
dResp, err := blobURL.WithVersionID(resp.VersionID()).Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false)
d1, err := ioutil.ReadAll(dResp.Body(RetryReaderOptions{}))
c.Assert(err, chk.IsNil)
c.Assert(dResp.Version(), chk.Not(chk.Equals), "")
c.Assert(string(d1), chk.DeepEquals, string(data[i]))
versionId := dResp.r.rawResponse.Header.Get("x-ms-version-id")
c.Assert(versionId, chk.NotNil)
c.Assert(versionId, chk.Equals, resp.VersionID())
}
}
func (s *aztestsSuite) TestDeleteSpecificBlobVersion(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := getBlockBlobURL(c, containerURL)
blockBlobUploadResp, err := blobURL.Upload(ctx, bytes.NewReader([]byte("data")), BlobHTTPHeaders{},
basicMetadata, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(blockBlobUploadResp.VersionID(), chk.NotNil)
versionID1 := blockBlobUploadResp.VersionID()
blockBlobUploadResp, err = blobURL.Upload(ctx, bytes.NewReader([]byte("updated_data")), BlobHTTPHeaders{},
basicMetadata, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(blockBlobUploadResp.VersionID(), chk.NotNil)
listBlobsResp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Details: BlobListingDetails{Versions: true}})
c.Assert(err, chk.IsNil)
c.Assert(listBlobsResp.Segment.BlobItems, chk.HasLen, 2)
// Deleting previous version snapshot.
deleteResp, err := blobURL.WithVersionID(versionID1).Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(deleteResp.StatusCode(), chk.Equals, 202)
listBlobsResp, err = containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Details: BlobListingDetails{Versions: true}})
c.Assert(err, chk.IsNil)
c.Assert(listBlobsResp.Segment.BlobItems, chk.NotNil)
if len(listBlobsResp.Segment.BlobItems) != 1 {
c.Fail()
}
}
func (s *aztestsSuite) TestDeleteSpecificBlobVersionWithBlobSAS(c *chk.C) {
bsu := getBSU()
credential, err := getGenericCredential("")
if err != nil {
c.Fatal(err)
}
containerURL, containerName := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, blobName := getBlockBlobURL(c, containerURL)
resp, err := blobURL.Upload(ctx, bytes.NewReader([]byte("data")), BlobHTTPHeaders{},
basicMetadata, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
versionId := resp.VersionID()
c.Assert(versionId, chk.NotNil)
resp, err = blobURL.Upload(ctx, bytes.NewReader([]byte("updated_data")), BlobHTTPHeaders{},
basicMetadata, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.VersionID(), chk.NotNil)
blobParts := NewBlobURLParts(blobURL.URL())
blobParts.VersionID = versionId
blobParts.SAS, err = BlobSASSignatureValues{
Protocol: SASProtocolHTTPS,
ExpiryTime: time.Now().UTC().Add(1 * time.Hour),
ContainerName: containerName,
BlobName: blobName,
Permissions: BlobSASPermissions{Delete: true, DeletePreviousVersion: true}.String(),
}.NewSASQueryParameters(credential)
if err != nil {
c.Fatal(err)
}
sbURL := NewBlockBlobURL(blobParts.URL(), containerURL.client.p)
deleteResp, err := sbURL.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
c.Assert(deleteResp, chk.IsNil)
listBlobResp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Details: BlobListingDetails{Versions: true}})
c.Assert(err, chk.IsNil)
for _, blob := range listBlobResp.Segment.BlobItems {
c.Assert(blob.VersionID, chk.Not(chk.Equals), versionId)
}
}
func (s *aztestsSuite) TestDownloadSpecificBlobVersion(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := getBlockBlobURL(c, containerURL)
blockBlobUploadResp, err := blobURL.Upload(ctx, bytes.NewReader([]byte("data")), BlobHTTPHeaders{},
basicMetadata, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(blockBlobUploadResp, chk.NotNil)
versionId1 := blockBlobUploadResp.VersionID()
blockBlobUploadResp, err = blobURL.Upload(ctx, bytes.NewReader([]byte("updated_data")), BlobHTTPHeaders{},
basicMetadata, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(blockBlobUploadResp, chk.NotNil)
versionId2 := blockBlobUploadResp.VersionID()
c.Assert(blockBlobUploadResp.VersionID(), chk.NotNil)
// Download previous version of snapshot.
blobURL = blobURL.WithVersionID(versionId1)
blockBlobDeleteResp, err := blobURL.Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false)
c.Assert(err, chk.IsNil)
data, err := ioutil.ReadAll(blockBlobDeleteResp.Response().Body)
c.Assert(string(data), chk.Equals, "data")
// Download current version of snapshot.
blobURL = blobURL.WithVersionID(versionId2)
blockBlobDeleteResp, err = blobURL.Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false)
c.Assert(err, chk.IsNil)
data, err = ioutil.ReadAll(blockBlobDeleteResp.Response().Body)
c.Assert(string(data), chk.Equals, "updated_data")
}
func (s *aztestsSuite) TestCreateBlobSnapshotReturnsVID(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer delContainer(c, containerURL)
blobURL := containerURL.NewBlockBlobURL(generateBlobName())
uploadResp, err := blobURL.Upload(ctx, bytes.NewReader([]byte("updated_data")), BlobHTTPHeaders{},
basicMetadata, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(uploadResp.VersionID(), chk.NotNil)
csResp, err := blobURL.CreateSnapshot(ctx, Metadata{}, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(csResp.VersionID(), chk.NotNil)
lbResp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{
Details: BlobListingDetails{Versions: true, Snapshots: true},
})
c.Assert(lbResp, chk.NotNil)
if len(lbResp.Segment.BlobItems) < 2 {
c.Fail()
}
_, err = blobURL.Delete(ctx, DeleteSnapshotsOptionInclude, BlobAccessConditions{})
lbResp, err = containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{
Details: BlobListingDetails{Versions: true, Snapshots: true},
})
c.Assert(lbResp, chk.NotNil)
if len(lbResp.Segment.BlobItems) < 2 {
c.Fail()
}
for _, blob := range lbResp.Segment.BlobItems {
c.Assert(blob.Snapshot, chk.Equals, "")
}
}
func (s *aztestsSuite) TestCopyBlobFromURLWithSASReturnsVID(c *chk.C) {
bsu := getBSU()
credential, err := getGenericCredential("")
if err != nil {
c.Fatal("Invalid credential")
}
container, _ := createNewContainer(c, bsu)
defer delContainer(c, container)
testSize := 4 * 1024 * 1024 // 4MB
r, sourceData := getRandomDataAndReader(testSize)
sourceDataMD5Value := md5.Sum(sourceData)
ctx := context.Background()
srcBlob := container.NewBlockBlobURL(generateBlobName())
destBlob := container.NewBlockBlobURL(generateBlobName())
uploadSrcResp, err := srcBlob.Upload(ctx, r, BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(uploadSrcResp.Response().StatusCode, chk.Equals, 201)
c.Assert(uploadSrcResp.Response().Header.Get("x-ms-version-id"), chk.NotNil)
srcBlobParts := NewBlobURLParts(srcBlob.URL())
srcBlobParts.SAS, err = BlobSASSignatureValues{
Protocol: SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
ContainerName: srcBlobParts.ContainerName,
BlobName: srcBlobParts.BlobName,
Permissions: BlobSASPermissions{Read: true}.String(),
}.NewSASQueryParameters(credential)
if err != nil {
c.Fatal(err)
}
srcBlobURLWithSAS := srcBlobParts.URL()
resp, err := destBlob.CopyFromURL(ctx, srcBlobURLWithSAS, Metadata{"foo": "bar"}, ModifiedAccessConditions{}, BlobAccessConditions{}, sourceDataMD5Value[:])
c.Assert(err, chk.IsNil)
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
c.Assert(resp.CopyID(), chk.Not(chk.Equals), "")
c.Assert(string(resp.CopyStatus()), chk.DeepEquals, "success")
c.Assert(resp.VersionID(), chk.NotNil)
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false)
c.Assert(err, chk.IsNil)
destData, err := ioutil.ReadAll(downloadResp.Body(RetryReaderOptions{}))
c.Assert(err, chk.IsNil)
c.Assert(destData, chk.DeepEquals, sourceData)
c.Assert(downloadResp.Response().Header.Get("x-ms-version-id"), chk.NotNil)
c.Assert(len(downloadResp.NewMetadata()), chk.Equals, 1)
_, badMD5 := getRandomDataAndReader(16)
_, err = destBlob.CopyFromURL(ctx, srcBlobURLWithSAS, Metadata{}, ModifiedAccessConditions{}, BlobAccessConditions{}, badMD5)
c.Assert(err, chk.NotNil)
resp, err = destBlob.CopyFromURL(ctx, srcBlobURLWithSAS, Metadata{}, ModifiedAccessConditions{}, BlobAccessConditions{}, nil)
c.Assert(err, chk.IsNil)
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
c.Assert(resp.XMsContentCrc64(), chk.Not(chk.Equals), "")
c.Assert(resp.Response().Header.Get("x-ms-version"), chk.Equals, ServiceVersion)
c.Assert(resp.Response().Header.Get("x-ms-version-id"), chk.NotNil)
}
func (s *aztestsSuite) TestCreateBlockBlobReturnsVID(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer delContainer(c, containerURL)
testSize := 2 * 1024 * 1024 // 1MB
r, _ := getRandomDataAndReader(testSize)
ctx := context.Background() // Use default Background context
blobURL := containerURL.NewBlockBlobURL(generateBlobName())
// Prepare source blob for copy.
uploadResp, err := blobURL.Upload(ctx, r, BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(uploadResp.Response().StatusCode, chk.Equals, 201)
c.Assert(uploadResp.rawResponse.Header.Get("x-ms-version"), chk.Equals, ServiceVersion)
c.Assert(uploadResp.Response().Header.Get("x-ms-version-id"), chk.NotNil)
csResp, err := blobURL.CreateSnapshot(ctx, Metadata{}, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(csResp.Response().StatusCode, chk.Equals, 201)
c.Assert(csResp.Response().Header.Get("x-ms-version-id"), chk.NotNil)
listBlobResp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true}})
c.Assert(err, chk.IsNil)
c.Assert(listBlobResp.rawResponse.Header.Get("x-ms-request-id"), chk.NotNil)
if len(listBlobResp.Segment.BlobItems) < 2 {
c.Fail()
}
deleteResp, err := blobURL.Delete(ctx, DeleteSnapshotsOptionOnly, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(deleteResp.Response().StatusCode, chk.Equals, 202)
c.Assert(deleteResp.Response().Header.Get("x-ms-version-id"), chk.NotNil)
listBlobResp, err = containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true, Versions: true}})
c.Assert(err, chk.IsNil)
c.Assert(listBlobResp.rawResponse.Header.Get("x-ms-request-id"), chk.NotNil)
if len(listBlobResp.Segment.BlobItems) == 0 {
c.Fail()
}
blobs := listBlobResp.Segment.BlobItems
c.Assert(blobs[0].Snapshot, chk.Equals, "")
}
func (s *aztestsSuite) TestPutBlockListReturnsVID(c *chk.C) {
blockIDIntToBase64 := func(blockID int) string {
binaryBlockID := (&[4]byte{})[:]
binary.LittleEndian.PutUint32(binaryBlockID, uint32(blockID))
return base64.StdEncoding.EncodeToString(binaryBlockID)
}
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer delContainer(c, containerURL)
blobURL := containerURL.NewBlockBlobURL(generateBlobName())
data := []string{"Azure ", "Storage ", "Block ", "Blob."}
base64BlockIDs := make([]string, len(data))
for index, d := range data {
base64BlockIDs[index] = blockIDIntToBase64(index)
resp, err := blobURL.StageBlock(ctx, base64BlockIDs[index], strings.NewReader(d), LeaseAccessConditions{}, nil)
if err != nil {
c.Fail()
}
c.Assert(resp.Response().StatusCode, chk.Equals, 201)
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
}
commitResp, err := blobURL.CommitBlockList(ctx, base64BlockIDs, BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(commitResp.VersionID(), chk.NotNil)
contentResp, err := blobURL.Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false)
c.Assert(err, chk.IsNil)
contentData, err := ioutil.ReadAll(contentResp.Body(RetryReaderOptions{}))
c.Assert(contentData, chk.DeepEquals, []uint8(strings.Join(data, "")))
}
func (s *aztestsSuite) TestSyncCopyBlobReturnsVID(c *chk.C) {
}
func (s *aztestsSuite) TestCreatePageBlobReturnsVID(c *chk.C) {
bsu := getBSU()
container, _ := createNewContainer(c, bsu)
defer delContainer(c, container)
blob, _ := createNewPageBlob(c, container)
putResp, err := blob.UploadPages(context.Background(), 0, getReaderToRandomBytes(1024), PageBlobAccessConditions{}, nil)
c.Assert(err, chk.IsNil)
c.Assert(putResp.Response().StatusCode, chk.Equals, 201)
c.Assert(putResp.LastModified().IsZero(), chk.Equals, false)
c.Assert(putResp.ETag(), chk.Not(chk.Equals), ETagNone)
c.Assert(putResp.Version(), chk.Not(chk.Equals), "")
c.Assert(putResp.rawResponse.Header.Get("x-ms-version-id"), chk.NotNil)
gpResp, err := blob.GetProperties(ctx, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
c.Assert(gpResp, chk.NotNil)
}

Просмотреть файл

@ -622,3 +622,4 @@ func (s *aztestsSuite) TestBlobAppendBlockIfMaxSizeFalse(c *chk.C) {
AppendBlobAccessConditions{AppendPositionAccessConditions: AppendPositionAccessConditions{IfMaxSizeLessThanOrEqual: int64(len(blockBlobDefaultData) - 1)}}, nil)
validateStorageError(c, err, ServiceCodeMaxBlobSizeConditionNotMet)
}

Просмотреть файл

@ -1737,23 +1737,23 @@ func (s *aztestsSuite) TestBlobSetMetadataIfNoneMatchFalse(c *chk.C) {
}
func testBlobsUndeleteImpl(c *chk.C, bsu ServiceURL) error {
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
c.Assert(err, chk.IsNil) // This call will not have errors related to slow update of service properties, so we assert.
_, err = blobURL.Undelete(ctx)
if err != nil { // We want to give the wrapper method a chance to check if it was an error related to the service properties update.
return err
}
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
if err != nil {
return errors.New(string(err.(StorageError).ServiceCode()))
}
c.Assert(resp.BlobType(), chk.Equals, BlobBlockBlob) // We could check any property. This is just to double check it was undeleted.
//containerURL, _ := createNewContainer(c, bsu)
//defer deleteContainer(c, containerURL)
//blobURL, _ := createNewBlockBlob(c, containerURL)
//
//_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
//c.Assert(err, chk.IsNil) // This call will not have errors related to slow update of service properties, so we assert.
//
//_, err = blobURL.Undelete(ctx)
//if err != nil { // We want to give the wrapper method a chance to check if it was an error related to the service properties update.
// return err
//}
//
//resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
//if err != nil {
// return errors.New(string(err.(StorageError).ServiceCode()))
//}
//c.Assert(resp.BlobType(), chk.Equals, BlobBlockBlob) // We could check any property. This is just to double check it was undeleted.
return nil
}
@ -1951,8 +1951,8 @@ func (s *aztestsSuite) TestBlobURLPartsSASQueryTimes(c *chk.C) {
func (s *aztestsSuite) TestDownloadBlockBlobUnexpectedEOF(c *chk.C) {
bsu := getBSU()
cURL, _ := createNewContainer(c, bsu)
defer delContainer(c, cURL)
bURL, _ := createNewBlockBlob(c, cURL) // This uploads for us.
resp, err := bURL.Download(ctx, 0, 0, BlobAccessConditions{}, false)
c.Assert(err, chk.IsNil)
@ -1970,3 +1970,4 @@ func (s *aztestsSuite) TestDownloadBlockBlobUnexpectedEOF(c *chk.C) {
c.Assert(err, chk.IsNil)
c.Assert(buf, chk.DeepEquals, []byte(blockBlobDefaultData))
}

Просмотреть файл

@ -171,7 +171,7 @@ func (s *aztestsSuite) TestCopyBlockBlobFromURL(c *chk.C) {
srcBlobParts := NewBlobURLParts(srcBlob.URL())
srcBlobParts.SAS, err = BlobSASSignatureValues{
Protocol: SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
Protocol: SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
ContainerName: srcBlobParts.ContainerName,
BlobName: srcBlobParts.BlobName,
@ -486,7 +486,7 @@ var blockID string // a single blockID used in tests when only a single ID is ne
func init() {
u := [64]byte{}
binary.BigEndian.PutUint32((u[len(guuid.UUID{}):]), math.MaxUint32)
binary.BigEndian.PutUint32(u[len(guuid.UUID{}):], math.MaxUint32)
blockID = base64.StdEncoding.EncodeToString(u[:])
}
@ -898,3 +898,4 @@ func (s *aztestsSuite) TestBlobPutBlockListModifyBlob(c *chk.C) {
c.Assert(resp.CommittedBlocks[1].Name, chk.Equals, "0011")
c.Assert(resp.UncommittedBlocks, chk.HasLen, 0)
}

Просмотреть файл

@ -156,7 +156,7 @@ func (s *aztestsSuite) TestContainerCreateAccessBlob(c *chk.C) {
// Reference the same container URL but with anonymous credentials
containerURL2 := NewContainerURL(containerURL.URL(), NewPipeline(NewAnonymousCredential(), PipelineOptions{}))
_, err = containerURL2.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
validateStorageError(c, err, ServiceCodeResourceNotFound) // Listing blobs is not publicly accessible
validateStorageError(c, err, ServiceCodeNoAuthenticationInformation) // Listing blobs is not publicly accessible
// Accessing blob specific data should be public
blobURL2 := containerURL2.NewBlockBlobURL(blobPrefix)
@ -180,14 +180,14 @@ func (s *aztestsSuite) TestContainerCreateAccessNone(c *chk.C) {
containerURL2 := NewContainerURL(containerURL.URL(), NewPipeline(NewAnonymousCredential(), PipelineOptions{}))
// Listing blobs is not public
_, err = containerURL2.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
validateStorageError(c, err, ServiceCodeResourceNotFound)
validateStorageError(c, err, ServiceCodeNoAuthenticationInformation)
// Blob data is not public
blobURL2 := containerURL2.NewBlockBlobURL(blobPrefix)
_, err = blobURL2.GetProperties(ctx, BlobAccessConditions{})
c.Assert(err, chk.NotNil)
serr := err.(StorageError)
c.Assert(serr.Response().StatusCode, chk.Equals, 404) // HEAD request does not return a status code
c.Assert(serr.Response().StatusCode, chk.Equals, 401) // HEAD request does not return a status code
}
func validateContainerDeleted(c *chk.C, containerURL ContainerURL) {
@ -424,16 +424,24 @@ func testContainerListBlobsIncludeTypeDeletedImpl(c *chk.C, bsu ServiceURL) erro
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
ListBlobsSegmentOptions{Details: BlobListingDetails{Versions: true, Deleted: true}})
c.Assert(err, chk.IsNil)
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
_, err = blobURL.Delete(ctx, DeleteSnapshotsOptionInclude, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
ListBlobsSegmentOptions{Details: BlobListingDetails{Deleted: true}})
resp, err = containerURL.ListBlobsFlatSegment(ctx, Marker{},
ListBlobsSegmentOptions{Details: BlobListingDetails{Versions: true, Deleted: true}})
c.Assert(err, chk.IsNil)
if len(resp.Segment.BlobItems) != 1 {
return errors.New("DeletedBlobNotFound")
}
c.Assert(resp.Segment.BlobItems[0].Deleted, chk.Equals, true)
// TODO: => Write function to enable/disable versioning from code itself.
// resp.Segment.BlobItems[0].Deleted == true/false if versioning is disabled/enabled.
c.Assert(resp.Segment.BlobItems[0].Deleted, chk.Equals, false)
return nil
}
@ -448,29 +456,29 @@ func testContainerListBlobsIncludeMultipleImpl(c *chk.C, bsu ServiceURL) error {
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, blobName := createBlockBlobWithPrefix(c, containerURL, "z")
blobURL, _ := createBlockBlobWithPrefix(c, containerURL, "z")
_, err := blobURL.CreateSnapshot(ctx, Metadata{}, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
blobURL2, blobName2 := createBlockBlobWithPrefix(c, containerURL, "copy")
blobURL2, _ := createBlockBlobWithPrefix(c, containerURL, "copy")
resp2, err := blobURL2.StartCopyFromURL(ctx, blobURL.URL(), Metadata{}, ModifiedAccessConditions{}, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
waitForCopy(c, blobURL2, resp2)
blobURL3, blobName3 := createBlockBlobWithPrefix(c, containerURL, "deleted")
blobURL3, _ := createBlockBlobWithPrefix(c, containerURL, "deleted")
_, err = blobURL3.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true, Copy: true, Deleted: true}})
ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true, Copy: true, Deleted: true, Versions: true}})
c.Assert(err, chk.IsNil)
if len(resp.Segment.BlobItems) != 5 { // If there are fewer blobs in the container than there should be, it will be because one was permanently deleted.
if len(resp.Segment.BlobItems) != 6 {
// If there are fewer blobs in the container than there should be, it will be because one was permanently deleted.
return errors.New("DeletedBlobNotFound")
}
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName2)
c.Assert(resp.Segment.BlobItems[1].Name, chk.Equals, blobName2) // With soft delete, the overwritten blob will have a backup snapshot
c.Assert(resp.Segment.BlobItems[2].Name, chk.Equals, blobName3)
c.Assert(resp.Segment.BlobItems[3].Name, chk.Equals, blobName)
c.Assert(resp.Segment.BlobItems[3].Snapshot, chk.NotNil)
c.Assert(resp.Segment.BlobItems[4].Name, chk.Equals, blobName)
//c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName2)
//c.Assert(resp.Segment.BlobItems[1].Name, chk.Equals, blobName) // With soft delete, the overwritten blob will have a backup snapshot
//c.Assert(resp.Segment.BlobItems[2].Name, chk.Equals, blobName)
return nil
}
@ -577,19 +585,21 @@ func (s *aztestsSuite) TestContainerGetSetPermissionsMultiplePolicies(c *chk.C)
start := generateCurrentTimeWithModerateResolution()
expiry := start.Add(5 * time.Minute)
expiry2 := start.Add(time.Minute)
readWrite := AccessPolicyPermission{Read: true, Write: true}.String()
readOnly := AccessPolicyPermission{Read: true}.String()
permissions := []SignedIdentifier{
{ID: "0000",
AccessPolicy: AccessPolicy{
Start: start,
Expiry: expiry,
Permission: AccessPolicyPermission{Read: true, Write: true}.String(),
Start: &start,
Expiry: &expiry,
Permission: &readWrite,
},
},
{ID: "0001",
AccessPolicy: AccessPolicy{
Start: start,
Expiry: expiry2,
Permission: AccessPolicyPermission{Read: true}.String(),
Start: &start,
Expiry: &expiry2,
Permission: &readOnly,
},
},
}
@ -639,7 +649,7 @@ func (s *aztestsSuite) TestContainerSetPermissionsPublicAccessNone(c *chk.C) {
resp, _ := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
// If we cannot access a blob's data, we will also not be able to enumerate blobs
validateStorageError(c, err, ServiceCodeResourceNotFound)
validateStorageError(c, err, ServiceCodeNoAuthenticationInformation)
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessNone)
}
@ -683,12 +693,13 @@ func (s *aztestsSuite) TestContainerSetPermissionsACLSinglePolicy(c *chk.C) {
start := time.Now().UTC().Add(-15 * time.Second)
expiry := start.Add(5 * time.Minute).UTC()
listOnly := AccessPolicyPermission{List: true}.String()
permissions := []SignedIdentifier{{
ID: "0000",
AccessPolicy: AccessPolicy{
Start: start,
Expiry: expiry,
Permission: AccessPolicyPermission{List: true}.String(),
Start: &start,
Expiry: &expiry,
Permission: &listOnly,
},
}}
_, err = containerURL.SetAccessPolicy(ctx, PublicAccessNone, permissions, ContainerAccessConditions{})
@ -715,7 +726,7 @@ func (s *aztestsSuite) TestContainerSetPermissionsACLSinglePolicy(c *chk.C) {
anonymousBlobService := NewServiceURL(bsu.URL(), sasPipeline)
anonymousContainer := anonymousBlobService.NewContainerURL(containerName)
_, err = anonymousContainer.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
validateStorageError(c, err, ServiceCodeResourceNotFound)
validateStorageError(c, err, ServiceCodeNoAuthenticationInformation)
}
func (s *aztestsSuite) TestContainerSetPermissionsACLMoreThanFive(c *chk.C) {
@ -727,13 +738,14 @@ func (s *aztestsSuite) TestContainerSetPermissionsACLMoreThanFive(c *chk.C) {
start := time.Now().UTC()
expiry := start.Add(5 * time.Minute).UTC()
permissions := make([]SignedIdentifier, 6, 6)
listOnly := AccessPolicyPermission{Read: true}.String()
for i := 0; i < 6; i++ {
permissions[i] = SignedIdentifier{
ID: "000" + strconv.Itoa(i),
AccessPolicy: AccessPolicy{
Start: start,
Expiry: expiry,
Permission: AccessPolicyPermission{List: true}.String(),
Start: &start,
Expiry: &expiry,
Permission: &listOnly,
},
}
}
@ -750,14 +762,15 @@ func (s *aztestsSuite) TestContainerSetPermissionsDeleteAndModifyACL(c *chk.C) {
start := generateCurrentTimeWithModerateResolution()
expiry := start.Add(5 * time.Minute).UTC()
listOnly := AccessPolicyPermission{Read: true}.String()
permissions := make([]SignedIdentifier, 2, 2)
for i := 0; i < 2; i++ {
permissions[i] = SignedIdentifier{
ID: "000" + strconv.Itoa(i),
AccessPolicy: AccessPolicy{
Start: start,
Expiry: expiry,
Permission: AccessPolicyPermission{List: true}.String(),
Start: &start,
Expiry: &expiry,
Permission: &listOnly,
},
}
}
@ -788,13 +801,14 @@ func (s *aztestsSuite) TestContainerSetPermissionsDeleteAllPolicies(c *chk.C) {
start := time.Now().UTC()
expiry := start.Add(5 * time.Minute).UTC()
permissions := make([]SignedIdentifier, 2, 2)
listOnly := AccessPolicyPermission{Read: true}.String()
for i := 0; i < 2; i++ {
permissions[i] = SignedIdentifier{
ID: "000" + strconv.Itoa(i),
AccessPolicy: AccessPolicy{
Start: start,
Expiry: expiry,
Permission: AccessPolicyPermission{List: true}.String(),
Start: &start,
Expiry: &expiry,
Permission: &listOnly,
},
}
}
@ -820,13 +834,14 @@ func (s *aztestsSuite) TestContainerSetPermissionsInvalidPolicyTimes(c *chk.C) {
expiry := time.Now().UTC()
start := expiry.Add(5 * time.Minute).UTC()
permissions := make([]SignedIdentifier, 2, 2)
listOnly := AccessPolicyPermission{Read: true}.String()
for i := 0; i < 2; i++ {
permissions[i] = SignedIdentifier{
ID: "000" + strconv.Itoa(i),
AccessPolicy: AccessPolicy{
Start: start,
Expiry: expiry,
Permission: AccessPolicyPermission{List: true}.String(),
Start: &start,
Expiry: &expiry,
Permission: &listOnly,
},
}
}
@ -858,13 +873,14 @@ func (s *aztestsSuite) TestContainerSetPermissionsSignedIdentifierTooLong(c *chk
expiry := time.Now().UTC()
start := expiry.Add(5 * time.Minute).UTC()
permissions := make([]SignedIdentifier, 2, 2)
listOnly := AccessPolicyPermission{Read: true}.String()
for i := 0; i < 2; i++ {
permissions[i] = SignedIdentifier{
ID: id,
AccessPolicy: AccessPolicy{
Start: start,
Expiry: expiry,
Permission: AccessPolicyPermission{List: true}.String(),
Start: &start,
Expiry: &expiry,
Permission: &listOnly,
},
}
}

Просмотреть файл

@ -18,6 +18,7 @@ func (s *aztestsSuite) TestGetAccountInfo(c *chk.C) {
// Test on a container
cURL := sa.NewContainerURL(generateContainerName())
defer delContainer(c, cURL)
_, err = cURL.Create(ctx, Metadata{}, PublicAccessNone)
c.Assert(err, chk.IsNil)
cAccInfo, err := cURL.GetAccountInfo(ctx)

Просмотреть файл

@ -47,13 +47,17 @@ func newAppendBlobClient(url url.URL, p pipeline.Pipeline) appendBlobClient {
// see Encryption at Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of the provided
// encryption key. Must be provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is the algorithm
// used to produce the encryption key hash. Currently, the only accepted value is "AES256". Must be provided if the
// x-ms-encryption-key header is provided. ifModifiedSince is specify this header value to operate only on a blob if it
// has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a
// blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on
// blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value.
// requestID is 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.
func (client appendBlobClient) AppendBlock(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, leaseID *string, maxSize *int64, appendPosition *int64, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*AppendBlobAppendBlockResponse, error) {
// x-ms-encryption-key header is provided. encryptionScope is optional. Version 2019-07-07 and later. Specifies the
// name of the encryption scope to use to encrypt the data provided in the request. If not specified, encryption is
// performed with the default account encryption scope. For more information, see Encryption at Rest for Azure Storage
// Services. ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the
// specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been
// modified since the specified date/time. ifMatch is specify an ETag value to operate only on blobs with a matching
// value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. ifTags is specify a
// SQL where clause on blob tags to operate only on blobs with a matching value. requestID is 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.
func (client appendBlobClient) AppendBlock(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, leaseID *string, maxSize *int64, appendPosition *int64, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (*AppendBlobAppendBlockResponse, error) {
if err := validate([]validation{
{targetValue: body,
constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}},
@ -62,7 +66,7 @@ func (client appendBlobClient) AppendBlock(ctx context.Context, body io.ReadSeek
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.appendBlockPreparer(body, contentLength, timeout, transactionalContentMD5, transactionalContentCrc64, leaseID, maxSize, appendPosition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
req, err := client.appendBlockPreparer(body, contentLength, timeout, transactionalContentMD5, transactionalContentCrc64, leaseID, maxSize, appendPosition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID)
if err != nil {
return nil, err
}
@ -74,7 +78,7 @@ func (client appendBlobClient) AppendBlock(ctx context.Context, body io.ReadSeek
}
// appendBlockPreparer prepares the AppendBlock request.
func (client appendBlobClient) appendBlockPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, leaseID *string, maxSize *int64, appendPosition *int64, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client appendBlobClient) appendBlockPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, leaseID *string, maxSize *int64, appendPosition *int64, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, body)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -110,6 +114,9 @@ func (client appendBlobClient) appendBlockPreparer(body io.ReadSeeker, contentLe
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if ifModifiedSince != nil {
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
}
@ -122,6 +129,9 @@ func (client appendBlobClient) appendBlockPreparer(body io.ReadSeeker, contentLe
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
@ -155,31 +165,35 @@ func (client appendBlobClient) appendBlockResponder(resp pipeline.Response) (pip
// information, see Encryption at Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of the
// provided encryption key. Must be provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is the
// algorithm used to produce the encryption key hash. Currently, the only accepted value is "AES256". Must be provided
// if the x-ms-encryption-key header is provided. leaseID is if specified, the operation only succeeds if the
// resource's lease is active and matches this ID. maxSize is optional conditional header. The max length in bytes
// permitted for the append blob. If the Append Block operation would cause the blob to exceed that limit or if the
// blob size is already greater than the value specified in this header, the request will fail with
// MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed). appendPosition is optional
// conditional header, used only for the Append Block operation. A number indicating the byte offset to compare. Append
// Block will succeed only if the append position is equal to this number. If it is not, the request will fail with the
// AppendPositionConditionNotMet error (HTTP status code 412 - Precondition Failed). ifModifiedSince is specify this
// header value to operate only on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is
// specify this header value to operate only on a blob if it has not been modified since the specified date/time.
// ifMatch is specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag
// value to operate only on blobs without a matching value. sourceIfModifiedSince is specify this header value to
// operate only on a blob if it has been modified since the specified date/time. sourceIfUnmodifiedSince is specify
// this header value to operate only on a blob if it has not been modified since the specified date/time. sourceIfMatch
// is specify an ETag value to operate only on blobs with a matching value. sourceIfNoneMatch is specify an ETag value
// to operate only on blobs without a matching value. requestID is 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.
func (client appendBlobClient) AppendBlockFromURL(ctx context.Context, sourceURL string, contentLength int64, sourceRange *string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, transactionalContentMD5 []byte, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, leaseID *string, maxSize *int64, appendPosition *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (*AppendBlobAppendBlockFromURLResponse, error) {
// if the x-ms-encryption-key header is provided. encryptionScope is optional. Version 2019-07-07 and later. Specifies
// the name of the encryption scope to use to encrypt the data provided in the request. If not specified, encryption is
// performed with the default account encryption scope. For more information, see Encryption at Rest for Azure Storage
// Services. leaseID is if specified, the operation only succeeds if the resource's lease is active and matches this
// ID. maxSize is optional conditional header. The max length in bytes permitted for the append blob. If the Append
// Block operation would cause the blob to exceed that limit or if the blob size is already greater than the value
// specified in this header, the request will fail with MaxBlobSizeConditionNotMet error (HTTP status code 412 -
// Precondition Failed). appendPosition is optional conditional header, used only for the Append Block operation. A
// number indicating the byte offset to compare. Append Block will succeed only if the append position is equal to this
// number. If it is not, the request will fail with the AppendPositionConditionNotMet error (HTTP status code 412 -
// Precondition Failed). ifModifiedSince is specify this header value to operate only on a blob if it has been modified
// since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has
// not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on blobs with a
// matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. ifTags is
// specify a SQL where clause on blob tags to operate only on blobs with a matching value. sourceIfModifiedSince is
// specify this header value to operate only on a blob if it has been modified since the specified date/time.
// sourceIfUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified since the
// specified date/time. sourceIfMatch is specify an ETag value to operate only on blobs with a matching value.
// sourceIfNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is 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.
func (client appendBlobClient) AppendBlockFromURL(ctx context.Context, sourceURL string, contentLength int64, sourceRange *string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, transactionalContentMD5 []byte, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, leaseID *string, maxSize *int64, appendPosition *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (*AppendBlobAppendBlockFromURLResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.appendBlockFromURLPreparer(sourceURL, contentLength, sourceRange, sourceContentMD5, sourceContentcrc64, timeout, transactionalContentMD5, encryptionKey, encryptionKeySha256, encryptionAlgorithm, leaseID, maxSize, appendPosition, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatch, sourceIfNoneMatch, requestID)
req, err := client.appendBlockFromURLPreparer(sourceURL, contentLength, sourceRange, sourceContentMD5, sourceContentcrc64, timeout, transactionalContentMD5, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, leaseID, maxSize, appendPosition, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatch, sourceIfNoneMatch, requestID)
if err != nil {
return nil, err
}
@ -191,7 +205,7 @@ func (client appendBlobClient) AppendBlockFromURL(ctx context.Context, sourceURL
}
// appendBlockFromURLPreparer prepares the AppendBlockFromURL request.
func (client appendBlobClient) appendBlockFromURLPreparer(sourceURL string, contentLength int64, sourceRange *string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, transactionalContentMD5 []byte, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, leaseID *string, maxSize *int64, appendPosition *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client appendBlobClient) appendBlockFromURLPreparer(sourceURL string, contentLength int64, sourceRange *string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, transactionalContentMD5 []byte, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, leaseID *string, maxSize *int64, appendPosition *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -225,6 +239,9 @@ func (client appendBlobClient) appendBlockFromURLPreparer(sourceURL string, cont
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if leaseID != nil {
req.Header.Set("x-ms-lease-id", *leaseID)
}
@ -246,6 +263,9 @@ func (client appendBlobClient) appendBlockFromURLPreparer(sourceURL string, cont
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
if sourceIfModifiedSince != nil {
req.Header.Set("x-ms-source-if-modified-since", (*sourceIfModifiedSince).In(gmt).Format(time.RFC1123))
}
@ -300,20 +320,24 @@ func (client appendBlobClient) appendBlockFromURLResponder(resp pipeline.Respons
// Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of the provided encryption key. Must be
// provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is the algorithm used to produce the
// encryption key hash. Currently, the only accepted value is "AES256". Must be provided if the x-ms-encryption-key
// header is provided. ifModifiedSince is specify this header value to operate only on a blob if it has been modified
// since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has
// not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on blobs with a
// matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is
// 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.
func (client appendBlobClient) Create(ctx context.Context, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*AppendBlobCreateResponse, error) {
// header is provided. encryptionScope is optional. Version 2019-07-07 and later. Specifies the name of the encryption
// scope to use to encrypt the data provided in the request. If not specified, encryption is performed with the default
// account encryption scope. For more information, see Encryption at Rest for Azure Storage Services. ifModifiedSince
// is specify this header value to operate only on a blob if it has been modified since the specified date/time.
// ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified since the
// specified date/time. ifMatch is specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is
// specify an ETag value to operate only on blobs without a matching value. ifTags is specify a SQL where clause on
// blob tags to operate only on blobs with a matching value. requestID is 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.
// blobTagsString is optional. Used to set blob tags in various blob operations.
func (client appendBlobClient) Create(ctx context.Context, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string, blobTagsString *string) (*AppendBlobCreateResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.createPreparer(contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
req, err := client.createPreparer(contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID, blobTagsString)
if err != nil {
return nil, err
}
@ -325,7 +349,7 @@ func (client appendBlobClient) Create(ctx context.Context, contentLength int64,
}
// createPreparer prepares the Create request.
func (client appendBlobClient) createPreparer(contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client appendBlobClient) createPreparer(contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string, blobTagsString *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -371,6 +395,9 @@ func (client appendBlobClient) createPreparer(contentLength int64, timeout *int3
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if ifModifiedSince != nil {
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
}
@ -383,10 +410,16 @@ func (client appendBlobClient) createPreparer(contentLength int64, timeout *int3
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
}
if blobTagsString != nil {
req.Header.Set("x-ms-tags", *blobTagsString)
}
req.Header.Set("x-ms-blob-type", "AppendBlob")
return req, nil
}
@ -401,3 +434,84 @@ func (client appendBlobClient) createResponder(resp pipeline.Response) (pipeline
resp.Response().Body.Close()
return &AppendBlobCreateResponse{rawResponse: resp.Response()}, err
}
// Seal the Seal operation seals the Append Blob to make it read-only. Seal is supported only on version 2019-12-12
// version or later.
//
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> requestID is 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. leaseID is if
// specified, the operation only succeeds if the resource's lease is active and matches this ID. ifModifiedSince is
// specify this header value to operate only on a blob if it has been modified since the specified date/time.
// ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified since the
// specified date/time. ifMatch is specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is
// specify an ETag value to operate only on blobs without a matching value. appendPosition is optional conditional
// header, used only for the Append Block operation. A number indicating the byte offset to compare. Append Block will
// succeed only if the append position is equal to this number. If it is not, the request will fail with the
// AppendPositionConditionNotMet error (HTTP status code 412 - Precondition Failed).
func (client appendBlobClient) Seal(ctx context.Context, timeout *int32, requestID *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, appendPosition *int64) (*AppendBlobSealResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.sealPreparer(timeout, requestID, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, appendPosition)
if err != nil {
return nil, err
}
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.sealResponder}, req)
if err != nil {
return nil, err
}
return resp.(*AppendBlobSealResponse), err
}
// sealPreparer prepares the Seal request.
func (client appendBlobClient) sealPreparer(timeout *int32, requestID *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, appendPosition *int64) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
}
params := req.URL.Query()
if timeout != nil {
params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
}
params.Set("comp", "seal")
req.URL.RawQuery = params.Encode()
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
}
if leaseID != nil {
req.Header.Set("x-ms-lease-id", *leaseID)
}
if ifModifiedSince != nil {
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
}
if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
}
if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatch))
}
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if appendPosition != nil {
req.Header.Set("x-ms-blob-condition-appendpos", strconv.FormatInt(*appendPosition, 10))
}
return req, nil
}
// sealResponder handles the response to the Seal request.
func (client appendBlobClient) sealResponder(resp pipeline.Response) (pipeline.Response, error) {
err := validateResponse(resp, http.StatusOK)
if resp == nil {
return nil, err
}
io.Copy(ioutil.Discard, resp.Response().Body)
resp.Response().Body.Close()
return &AppendBlobSealResponse{rawResponse: resp.Response()}, err
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -57,20 +57,25 @@ func newBlockBlobClient(url url.URL, p pipeline.Pipeline) blockBlobClient {
// Services. encryptionKeySha256 is the SHA-256 hash of the provided encryption key. Must be provided if the
// x-ms-encryption-key header is provided. encryptionAlgorithm is the algorithm used to produce the encryption key
// hash. Currently, the only accepted value is "AES256". Must be provided if the x-ms-encryption-key header is
// provided. tier is optional. Indicates the tier to be set on the blob. ifModifiedSince is specify this header value
// to operate only on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this
// header value to operate only on a blob if it has not been modified since the specified date/time. ifMatch is specify
// an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only
// on blobs without a matching value. requestID is 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.
func (client blockBlobClient) CommitBlockList(ctx context.Context, blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, tier AccessTierType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlockBlobCommitBlockListResponse, error) {
// provided. encryptionScope is optional. Version 2019-07-07 and later. Specifies the name of the encryption scope to
// use to encrypt the data provided in the request. If not specified, encryption is performed with the default account
// encryption scope. For more information, see Encryption at Rest for Azure Storage Services. tier is optional.
// Indicates the tier to be set on the blob. ifModifiedSince is specify this header value to operate only on a blob if
// it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only
// on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate
// only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a
// matching value. ifTags is specify a SQL where clause on blob tags to operate only on blobs with a matching value.
// requestID is 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. blobTagsString is optional. Used to set blob tags in various blob
// operations.
func (client blockBlobClient) CommitBlockList(ctx context.Context, blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, tier AccessTierType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string, blobTagsString *string) (*BlockBlobCommitBlockListResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.commitBlockListPreparer(blocks, timeout, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, transactionalContentMD5, transactionalContentCrc64, metadata, leaseID, blobContentDisposition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, tier, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
req, err := client.commitBlockListPreparer(blocks, timeout, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, transactionalContentMD5, transactionalContentCrc64, metadata, leaseID, blobContentDisposition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, tier, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID, blobTagsString)
if err != nil {
return nil, err
}
@ -82,7 +87,7 @@ func (client blockBlobClient) CommitBlockList(ctx context.Context, blocks BlockL
}
// commitBlockListPreparer prepares the CommitBlockList request.
func (client blockBlobClient) commitBlockListPreparer(blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, tier AccessTierType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client blockBlobClient) commitBlockListPreparer(blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, tier AccessTierType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string, blobTagsString *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -134,6 +139,9 @@ func (client blockBlobClient) commitBlockListPreparer(blocks BlockLookupList, ti
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if tier != AccessTierNone {
req.Header.Set("x-ms-access-tier", string(tier))
}
@ -149,10 +157,16 @@ func (client blockBlobClient) commitBlockListPreparer(blocks BlockLookupList, ti
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
}
if blobTagsString != nil {
req.Header.Set("x-ms-tags", *blobTagsString)
}
b, err := xml.Marshal(blocks)
if err != nil {
return req, pipeline.NewError(err, "failed to marshal request body")
@ -186,16 +200,17 @@ func (client blockBlobClient) commitBlockListResponder(resp pipeline.Response) (
// a Snapshot of a Blob.</a> timeout is the timeout parameter is expressed in seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. requestID is 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.
func (client blockBlobClient) GetBlockList(ctx context.Context, listType BlockListType, snapshot *string, timeout *int32, leaseID *string, requestID *string) (*BlockList, error) {
// lease is active and matches this ID. ifTags is specify a SQL where clause on blob tags to operate only on blobs with
// a matching value. requestID is 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.
func (client blockBlobClient) GetBlockList(ctx context.Context, listType BlockListType, snapshot *string, timeout *int32, leaseID *string, ifTags *string, requestID *string) (*BlockList, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.getBlockListPreparer(listType, snapshot, timeout, leaseID, requestID)
req, err := client.getBlockListPreparer(listType, snapshot, timeout, leaseID, ifTags, requestID)
if err != nil {
return nil, err
}
@ -207,7 +222,7 @@ func (client blockBlobClient) GetBlockList(ctx context.Context, listType BlockLi
}
// getBlockListPreparer prepares the GetBlockList request.
func (client blockBlobClient) getBlockListPreparer(listType BlockListType, snapshot *string, timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) {
func (client blockBlobClient) getBlockListPreparer(listType BlockListType, snapshot *string, timeout *int32, leaseID *string, ifTags *string, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("GET", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -225,6 +240,9 @@ func (client blockBlobClient) getBlockListPreparer(listType BlockListType, snaps
if leaseID != nil {
req.Header.Set("x-ms-lease-id", *leaseID)
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
@ -273,9 +291,12 @@ func (client blockBlobClient) getBlockListResponder(resp pipeline.Response) (pip
// more information, see Encryption at Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of the
// provided encryption key. Must be provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is the
// algorithm used to produce the encryption key hash. Currently, the only accepted value is "AES256". Must be provided
// if the x-ms-encryption-key header is provided. requestID is 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.
func (client blockBlobClient) StageBlock(ctx context.Context, blockID string, contentLength int64, body io.ReadSeeker, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, timeout *int32, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, requestID *string) (*BlockBlobStageBlockResponse, error) {
// if the x-ms-encryption-key header is provided. encryptionScope is optional. Version 2019-07-07 and later. Specifies
// the name of the encryption scope to use to encrypt the data provided in the request. If not specified, encryption is
// performed with the default account encryption scope. For more information, see Encryption at Rest for Azure Storage
// Services. requestID is 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.
func (client blockBlobClient) StageBlock(ctx context.Context, blockID string, contentLength int64, body io.ReadSeeker, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, timeout *int32, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, requestID *string) (*BlockBlobStageBlockResponse, error) {
if err := validate([]validation{
{targetValue: body,
constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}},
@ -284,7 +305,7 @@ func (client blockBlobClient) StageBlock(ctx context.Context, blockID string, co
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.stageBlockPreparer(blockID, contentLength, body, transactionalContentMD5, transactionalContentCrc64, timeout, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, requestID)
req, err := client.stageBlockPreparer(blockID, contentLength, body, transactionalContentMD5, transactionalContentCrc64, timeout, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, requestID)
if err != nil {
return nil, err
}
@ -296,7 +317,7 @@ func (client blockBlobClient) StageBlock(ctx context.Context, blockID string, co
}
// stageBlockPreparer prepares the StageBlock request.
func (client blockBlobClient) stageBlockPreparer(blockID string, contentLength int64, body io.ReadSeeker, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, timeout *int32, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, requestID *string) (pipeline.Request, error) {
func (client blockBlobClient) stageBlockPreparer(blockID string, contentLength int64, body io.ReadSeeker, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, timeout *int32, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, body)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -327,6 +348,9 @@ func (client blockBlobClient) stageBlockPreparer(blockID string, contentLength i
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
@ -361,21 +385,24 @@ func (client blockBlobClient) stageBlockResponder(resp pipeline.Response) (pipel
// For more information, see Encryption at Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of
// the provided encryption key. Must be provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is
// the algorithm used to produce the encryption key hash. Currently, the only accepted value is "AES256". Must be
// provided if the x-ms-encryption-key header is provided. leaseID is if specified, the operation only succeeds if the
// resource's lease is active and matches this ID. sourceIfModifiedSince is specify this header value to operate only
// on a blob if it has been modified since the specified date/time. sourceIfUnmodifiedSince is specify this header
// value to operate only on a blob if it has not been modified since the specified date/time. sourceIfMatch is specify
// an ETag value to operate only on blobs with a matching value. sourceIfNoneMatch is specify an ETag value to operate
// only on blobs without a matching value. requestID is 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.
func (client blockBlobClient) StageBlockFromURL(ctx context.Context, blockID string, contentLength int64, sourceURL string, sourceRange *string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, leaseID *string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (*BlockBlobStageBlockFromURLResponse, error) {
// provided if the x-ms-encryption-key header is provided. encryptionScope is optional. Version 2019-07-07 and later.
// Specifies the name of the encryption scope to use to encrypt the data provided in the request. If not specified,
// encryption is performed with the default account encryption scope. For more information, see Encryption at Rest for
// Azure Storage Services. leaseID is if specified, the operation only succeeds if the resource's lease is active and
// matches this ID. sourceIfModifiedSince is specify this header value to operate only on a blob if it has been
// modified since the specified date/time. sourceIfUnmodifiedSince is specify this header value to operate only on a
// blob if it has not been modified since the specified date/time. sourceIfMatch is specify an ETag value to operate
// only on blobs with a matching value. sourceIfNoneMatch is specify an ETag value to operate only on blobs without a
// matching value. requestID is 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.
func (client blockBlobClient) StageBlockFromURL(ctx context.Context, blockID string, contentLength int64, sourceURL string, sourceRange *string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, leaseID *string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (*BlockBlobStageBlockFromURLResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.stageBlockFromURLPreparer(blockID, contentLength, sourceURL, sourceRange, sourceContentMD5, sourceContentcrc64, timeout, encryptionKey, encryptionKeySha256, encryptionAlgorithm, leaseID, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatch, sourceIfNoneMatch, requestID)
req, err := client.stageBlockFromURLPreparer(blockID, contentLength, sourceURL, sourceRange, sourceContentMD5, sourceContentcrc64, timeout, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, leaseID, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatch, sourceIfNoneMatch, requestID)
if err != nil {
return nil, err
}
@ -387,7 +414,7 @@ func (client blockBlobClient) StageBlockFromURL(ctx context.Context, blockID str
}
// stageBlockFromURLPreparer prepares the StageBlockFromURL request.
func (client blockBlobClient) stageBlockFromURLPreparer(blockID string, contentLength int64, sourceURL string, sourceRange *string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, leaseID *string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client blockBlobClient) stageBlockFromURLPreparer(blockID string, contentLength int64, sourceURL string, sourceRange *string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, leaseID *string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -419,6 +446,9 @@ func (client blockBlobClient) stageBlockFromURLPreparer(blockID string, contentL
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if leaseID != nil {
req.Header.Set("x-ms-lease-id", *leaseID)
}
@ -480,14 +510,18 @@ func (client blockBlobClient) stageBlockFromURLResponder(resp pipeline.Response)
// with the root account encryption key. For more information, see Encryption at Rest for Azure Storage Services.
// encryptionKeySha256 is the SHA-256 hash of the provided encryption key. Must be provided if the x-ms-encryption-key
// header is provided. encryptionAlgorithm is the algorithm used to produce the encryption key hash. Currently, the
// only accepted value is "AES256". Must be provided if the x-ms-encryption-key header is provided. tier is optional.
// Indicates the tier to be set on the blob. ifModifiedSince is specify this header value to operate only on a blob if
// it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only
// on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate
// only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a
// matching value. requestID is 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.
func (client blockBlobClient) Upload(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, tier AccessTierType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlockBlobUploadResponse, error) {
// only accepted value is "AES256". Must be provided if the x-ms-encryption-key header is provided. encryptionScope is
// optional. Version 2019-07-07 and later. Specifies the name of the encryption scope to use to encrypt the data
// provided in the request. If not specified, encryption is performed with the default account encryption scope. For
// more information, see Encryption at Rest for Azure Storage Services. tier is optional. Indicates the tier to be set
// on the blob. ifModifiedSince is specify this header value to operate only on a blob if it has been modified since
// the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been
// modified since the specified date/time. ifMatch is specify an ETag value to operate only on blobs with a matching
// value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. ifTags is specify a
// SQL where clause on blob tags to operate only on blobs with a matching value. requestID is 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. blobTagsString is optional. Used to set blob tags in various blob operations.
func (client blockBlobClient) Upload(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, tier AccessTierType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string, blobTagsString *string) (*BlockBlobUploadResponse, error) {
if err := validate([]validation{
{targetValue: body,
constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}},
@ -496,7 +530,7 @@ func (client blockBlobClient) Upload(ctx context.Context, body io.ReadSeeker, co
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.uploadPreparer(body, contentLength, timeout, transactionalContentMD5, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, tier, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
req, err := client.uploadPreparer(body, contentLength, timeout, transactionalContentMD5, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, tier, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID, blobTagsString)
if err != nil {
return nil, err
}
@ -508,7 +542,7 @@ func (client blockBlobClient) Upload(ctx context.Context, body io.ReadSeeker, co
}
// uploadPreparer prepares the Upload request.
func (client blockBlobClient) uploadPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, tier AccessTierType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client blockBlobClient) uploadPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, tier AccessTierType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string, blobTagsString *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, body)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -557,6 +591,9 @@ func (client blockBlobClient) uploadPreparer(body io.ReadSeeker, contentLength i
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if tier != AccessTierNone {
req.Header.Set("x-ms-access-tier", string(tier))
}
@ -572,10 +609,16 @@ func (client blockBlobClient) uploadPreparer(body io.ReadSeeker, contentLength i
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
}
if blobTagsString != nil {
req.Header.Set("x-ms-tags", *blobTagsString)
}
req.Header.Set("x-ms-blob-type", "BlockBlob")
return req, nil
}

Просмотреть файл

@ -10,7 +10,7 @@ import (
const (
// ServiceVersion specifies the version of the operations used in this package.
ServiceVersion = "2019-02-02"
ServiceVersion = "2019-12-12"
)
// managementClient is the base client for Azblob.

Просмотреть файл

@ -259,14 +259,18 @@ func (client containerClient) changeLeaseResponder(resp pipeline.Response) (pipe
// Containers, Blobs, and Metadata for more information. access is specifies whether data in the container may be
// accessed publicly and the level of access requestID is 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.
func (client containerClient) Create(ctx context.Context, timeout *int32, metadata map[string]string, access PublicAccessType, requestID *string) (*ContainerCreateResponse, error) {
// defaultEncryptionScope is optional. Version 2019-07-07 and later. Specifies the default encryption scope to set on
// the container and use for all future writes. preventEncryptionScopeOverride is optional. Version 2019-07-07 and
// newer. If true, prevents any request from specifying a different encryption scope than the scope set on the
// container.
func (client containerClient) Create(ctx context.Context, timeout *int32, metadata map[string]string, access PublicAccessType, requestID *string, defaultEncryptionScope *string, preventEncryptionScopeOverride *bool) (*ContainerCreateResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.createPreparer(timeout, metadata, access, requestID)
req, err := client.createPreparer(timeout, metadata, access, requestID, defaultEncryptionScope, preventEncryptionScopeOverride)
if err != nil {
return nil, err
}
@ -278,7 +282,7 @@ func (client containerClient) Create(ctx context.Context, timeout *int32, metada
}
// createPreparer prepares the Create request.
func (client containerClient) createPreparer(timeout *int32, metadata map[string]string, access PublicAccessType, requestID *string) (pipeline.Request, error) {
func (client containerClient) createPreparer(timeout *int32, metadata map[string]string, access PublicAccessType, requestID *string, defaultEncryptionScope *string, preventEncryptionScopeOverride *bool) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -301,6 +305,12 @@ func (client containerClient) createPreparer(timeout *int32, metadata map[string
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
}
if defaultEncryptionScope != nil {
req.Header.Set("x-ms-default-encryption-scope", *defaultEncryptionScope)
}
if preventEncryptionScopeOverride != nil {
req.Header.Set("x-ms-deny-encryption-scope-override", strconv.FormatBool(*preventEncryptionScopeOverride))
}
return req, nil
}
@ -881,6 +891,70 @@ func (client containerClient) renewLeaseResponder(resp pipeline.Response) (pipel
return &ContainerRenewLeaseResponse{rawResponse: resp.Response()}, err
}
// Restore restores a previously-deleted container.
//
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> requestID is 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.
// deletedContainerName is optional. Version 2019-12-12 and laster. Specifies the name of the deleted container to
// restore. deletedContainerVersion is optional. Version 2019-12-12 and laster. Specifies the version of the deleted
// container to restore.
func (client containerClient) Restore(ctx context.Context, timeout *int32, requestID *string, deletedContainerName *string, deletedContainerVersion *string) (*ContainerRestoreResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.restorePreparer(timeout, requestID, deletedContainerName, deletedContainerVersion)
if err != nil {
return nil, err
}
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.restoreResponder}, req)
if err != nil {
return nil, err
}
return resp.(*ContainerRestoreResponse), err
}
// restorePreparer prepares the Restore request.
func (client containerClient) restorePreparer(timeout *int32, requestID *string, deletedContainerName *string, deletedContainerVersion *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
}
params := req.URL.Query()
if timeout != nil {
params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
}
params.Set("restype", "container")
params.Set("comp", "undelete")
req.URL.RawQuery = params.Encode()
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
}
if deletedContainerName != nil {
req.Header.Set("x-ms-deleted-container-name", *deletedContainerName)
}
if deletedContainerVersion != nil {
req.Header.Set("x-ms-deleted-container-version", *deletedContainerVersion)
}
return req, nil
}
// restoreResponder handles the response to the Restore request.
func (client containerClient) restoreResponder(resp pipeline.Response) (pipeline.Response, error) {
err := validateResponse(resp, http.StatusOK, http.StatusCreated)
if resp == nil {
return nil, err
}
io.Copy(ioutil.Discard, resp.Response().Body)
resp.Response().Body.Close()
return &ContainerRestoreResponse{rawResponse: resp.Response()}, err
}
// SetAccessPolicy sets the permissions for the specified container. The permissions indicate whether blobs in a
// container may be accessed publicly.
//

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -38,23 +38,26 @@ func newPageBlobClient(url url.URL, p pipeline.Pipeline) pageBlobClient {
// Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of the provided encryption key. Must be
// provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is the algorithm used to produce the
// encryption key hash. Currently, the only accepted value is "AES256". Must be provided if the x-ms-encryption-key
// header is provided. ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it
// has a sequence number less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to
// operate only on a blob if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this
// header value to operate only on a blob if it has the specified sequence number. ifModifiedSince is specify this
// header value to operate only on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is
// specify this header value to operate only on a blob if it has not been modified since the specified date/time.
// ifMatch is specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag
// value to operate only on blobs without a matching value. requestID is 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.
func (client pageBlobClient) ClearPages(ctx context.Context, contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobClearPagesResponse, error) {
// header is provided. encryptionScope is optional. Version 2019-07-07 and later. Specifies the name of the encryption
// scope to use to encrypt the data provided in the request. If not specified, encryption is performed with the default
// account encryption scope. For more information, see Encryption at Rest for Azure Storage Services.
// ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it has a sequence number
// less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to operate only on a blob
// if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this header value to operate
// only on a blob if it has the specified sequence number. ifModifiedSince is specify this header value to operate only
// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to
// operate only on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value
// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs
// without a matching value. requestID is 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.
func (client pageBlobClient) ClearPages(ctx context.Context, contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobClearPagesResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.clearPagesPreparer(contentLength, timeout, rangeParameter, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
req, err := client.clearPagesPreparer(contentLength, timeout, rangeParameter, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil {
return nil, err
}
@ -66,7 +69,7 @@ func (client pageBlobClient) ClearPages(ctx context.Context, contentLength int64
}
// clearPagesPreparer prepares the ClearPages request.
func (client pageBlobClient) clearPagesPreparer(contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client pageBlobClient) clearPagesPreparer(contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -93,6 +96,9 @@ func (client pageBlobClient) clearPagesPreparer(contentLength int64, timeout *in
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if ifSequenceNumberLessThanOrEqualTo != nil {
req.Header.Set("x-ms-if-sequence-number-le", strconv.FormatInt(*ifSequenceNumberLessThanOrEqualTo, 10))
}
@ -235,22 +241,26 @@ func (client pageBlobClient) copyIncrementalResponder(resp pipeline.Response) (p
// encryption key. For more information, see Encryption at Rest for Azure Storage Services. encryptionKeySha256 is the
// SHA-256 hash of the provided encryption key. Must be provided if the x-ms-encryption-key header is provided.
// encryptionAlgorithm is the algorithm used to produce the encryption key hash. Currently, the only accepted value is
// "AES256". Must be provided if the x-ms-encryption-key header is provided. ifModifiedSince is specify this header
// value to operate only on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify
// this header value to operate only on a blob if it has not been modified since the specified date/time. ifMatch is
// specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to
// operate only on blobs without a matching value. blobSequenceNumber is set for page blobs only. The sequence number
// is a user-controlled value that you can use to track requests. The value of the sequence number must be between 0
// and 2^63 - 1. requestID is 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.
func (client pageBlobClient) Create(ctx context.Context, contentLength int64, blobContentLength int64, timeout *int32, tier PremiumPageBlobAccessTierType, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (*PageBlobCreateResponse, error) {
// "AES256". Must be provided if the x-ms-encryption-key header is provided. encryptionScope is optional. Version
// 2019-07-07 and later. Specifies the name of the encryption scope to use to encrypt the data provided in the
// request. If not specified, encryption is performed with the default account encryption scope. For more information,
// see Encryption at Rest for Azure Storage Services. ifModifiedSince is specify this header value to operate only on a
// blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to
// operate only on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value
// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs
// without a matching value. ifTags is specify a SQL where clause on blob tags to operate only on blobs with a matching
// value. blobSequenceNumber is set for page blobs only. The sequence number is a user-controlled value that you can
// use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. requestID is 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. blobTagsString is optional. Used to set blob tags in various blob operations.
func (client pageBlobClient) Create(ctx context.Context, contentLength int64, blobContentLength int64, timeout *int32, tier PremiumPageBlobAccessTierType, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, blobSequenceNumber *int64, requestID *string, blobTagsString *string) (*PageBlobCreateResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.createPreparer(contentLength, blobContentLength, timeout, tier, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, blobSequenceNumber, requestID)
req, err := client.createPreparer(contentLength, blobContentLength, timeout, tier, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, blobSequenceNumber, requestID, blobTagsString)
if err != nil {
return nil, err
}
@ -262,7 +272,7 @@ func (client pageBlobClient) Create(ctx context.Context, contentLength int64, bl
}
// createPreparer prepares the Create request.
func (client pageBlobClient) createPreparer(contentLength int64, blobContentLength int64, timeout *int32, tier PremiumPageBlobAccessTierType, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (pipeline.Request, error) {
func (client pageBlobClient) createPreparer(contentLength int64, blobContentLength int64, timeout *int32, tier PremiumPageBlobAccessTierType, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, blobSequenceNumber *int64, requestID *string, blobTagsString *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -311,6 +321,9 @@ func (client pageBlobClient) createPreparer(contentLength int64, blobContentLeng
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if ifModifiedSince != nil {
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
}
@ -323,6 +336,9 @@ func (client pageBlobClient) createPreparer(contentLength int64, blobContentLeng
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
req.Header.Set("x-ms-blob-content-length", strconv.FormatInt(blobContentLength, 10))
if blobSequenceNumber != nil {
req.Header.Set("x-ms-blob-sequence-number", strconv.FormatInt(*blobSequenceNumber, 10))
@ -331,6 +347,9 @@ func (client pageBlobClient) createPreparer(contentLength int64, blobContentLeng
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
}
if blobTagsString != nil {
req.Header.Set("x-ms-tags", *blobTagsString)
}
req.Header.Set("x-ms-blob-type", "PageBlob")
return req, nil
}
@ -359,17 +378,18 @@ func (client pageBlobClient) createResponder(resp pipeline.Response) (pipeline.R
// ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the specified
// date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified
// since the specified date/time. ifMatch is specify an ETag value to operate only on blobs with a matching value.
// ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is 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.
func (client pageBlobClient) GetPageRanges(ctx context.Context, snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageList, error) {
// ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. ifTags is specify a SQL
// where clause on blob tags to operate only on blobs with a matching value. requestID is 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.
func (client pageBlobClient) GetPageRanges(ctx context.Context, snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (*PageList, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.getPageRangesPreparer(snapshot, timeout, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
req, err := client.getPageRangesPreparer(snapshot, timeout, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID)
if err != nil {
return nil, err
}
@ -381,7 +401,7 @@ func (client pageBlobClient) GetPageRanges(ctx context.Context, snapshot *string
}
// getPageRangesPreparer prepares the GetPageRanges request.
func (client pageBlobClient) getPageRangesPreparer(snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client pageBlobClient) getPageRangesPreparer(snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("GET", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -413,6 +433,9 @@ func (client pageBlobClient) getPageRangesPreparer(snapshot *string, timeout *in
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
@ -457,22 +480,25 @@ func (client pageBlobClient) getPageRangesResponder(resp pipeline.Response) (pip
// parameter is a DateTime value that specifies that the response will contain only pages that were changed between
// target blob and previous snapshot. Changed pages include both updated and cleared pages. The target blob may be a
// snapshot, as long as the snapshot specified by prevsnapshot is the older of the two. Note that incremental snapshots
// are currently supported only for blobs created on or after January 1, 2016. rangeParameter is return only the bytes
// of the blob in the specified range. leaseID is if specified, the operation only succeeds if the resource's lease is
// active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it has been
// modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if
// it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on blobs
// with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value.
// requestID is 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.
func (client pageBlobClient) GetPageRangesDiff(ctx context.Context, snapshot *string, timeout *int32, prevsnapshot *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageList, error) {
// are currently supported only for blobs created on or after January 1, 2016. prevSnapshotURL is optional. This header
// is only supported in service versions 2019-04-19 and after and specifies the URL of a previous snapshot of the
// target blob. The response will only contain pages that were changed between the target blob and its previous
// snapshot. rangeParameter is return only the bytes of the blob in the specified range. leaseID is if specified, the
// operation only succeeds if the resource's lease is active and matches this ID. ifModifiedSince is specify this
// header value to operate only on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is
// specify this header value to operate only on a blob if it has not been modified since the specified date/time.
// ifMatch is specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag
// value to operate only on blobs without a matching value. ifTags is specify a SQL where clause on blob tags to
// operate only on blobs with a matching value. requestID is 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.
func (client pageBlobClient) GetPageRangesDiff(ctx context.Context, snapshot *string, timeout *int32, prevsnapshot *string, prevSnapshotURL *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (*PageList, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.getPageRangesDiffPreparer(snapshot, timeout, prevsnapshot, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
req, err := client.getPageRangesDiffPreparer(snapshot, timeout, prevsnapshot, prevSnapshotURL, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID)
if err != nil {
return nil, err
}
@ -484,7 +510,7 @@ func (client pageBlobClient) GetPageRangesDiff(ctx context.Context, snapshot *st
}
// getPageRangesDiffPreparer prepares the GetPageRangesDiff request.
func (client pageBlobClient) getPageRangesDiffPreparer(snapshot *string, timeout *int32, prevsnapshot *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client pageBlobClient) getPageRangesDiffPreparer(snapshot *string, timeout *int32, prevsnapshot *string, prevSnapshotURL *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("GET", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -501,6 +527,9 @@ func (client pageBlobClient) getPageRangesDiffPreparer(snapshot *string, timeout
}
params.Set("comp", "pagelist")
req.URL.RawQuery = params.Encode()
if prevSnapshotURL != nil {
req.Header.Set("x-ms-previous-snapshot-url", *prevSnapshotURL)
}
if rangeParameter != nil {
req.Header.Set("x-ms-range", *rangeParameter)
}
@ -519,6 +548,9 @@ func (client pageBlobClient) getPageRangesDiffPreparer(snapshot *string, timeout
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
@ -563,20 +595,23 @@ func (client pageBlobClient) getPageRangesDiffResponder(resp pipeline.Response)
// more information, see Encryption at Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of the
// provided encryption key. Must be provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is the
// algorithm used to produce the encryption key hash. Currently, the only accepted value is "AES256". Must be provided
// if the x-ms-encryption-key header is provided. ifModifiedSince is specify this header value to operate only on a
// blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to
// operate only on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value
// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs
// without a matching value. requestID is 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.
func (client pageBlobClient) Resize(ctx context.Context, blobContentLength int64, timeout *int32, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobResizeResponse, error) {
// if the x-ms-encryption-key header is provided. encryptionScope is optional. Version 2019-07-07 and later. Specifies
// the name of the encryption scope to use to encrypt the data provided in the request. If not specified, encryption is
// performed with the default account encryption scope. For more information, see Encryption at Rest for Azure Storage
// Services. ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the
// specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been
// modified since the specified date/time. ifMatch is specify an ETag value to operate only on blobs with a matching
// value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is 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.
func (client pageBlobClient) Resize(ctx context.Context, blobContentLength int64, timeout *int32, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobResizeResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.resizePreparer(blobContentLength, timeout, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
req, err := client.resizePreparer(blobContentLength, timeout, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil {
return nil, err
}
@ -588,7 +623,7 @@ func (client pageBlobClient) Resize(ctx context.Context, blobContentLength int64
}
// resizePreparer prepares the Resize request.
func (client pageBlobClient) resizePreparer(blobContentLength int64, timeout *int32, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client pageBlobClient) resizePreparer(blobContentLength int64, timeout *int32, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -611,6 +646,9 @@ func (client pageBlobClient) resizePreparer(blobContentLength int64, timeout *in
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if ifModifiedSince != nil {
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
}
@ -738,16 +776,20 @@ func (client pageBlobClient) updateSequenceNumberResponder(resp pipeline.Respons
// Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of the provided encryption key. Must be
// provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is the algorithm used to produce the
// encryption key hash. Currently, the only accepted value is "AES256". Must be provided if the x-ms-encryption-key
// header is provided. ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it
// has a sequence number less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to
// operate only on a blob if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this
// header value to operate only on a blob if it has the specified sequence number. ifModifiedSince is specify this
// header value to operate only on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is
// specify this header value to operate only on a blob if it has not been modified since the specified date/time.
// ifMatch is specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag
// value to operate only on blobs without a matching value. requestID is 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.
func (client pageBlobClient) UploadPages(ctx context.Context, body io.ReadSeeker, contentLength int64, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobUploadPagesResponse, error) {
// header is provided. encryptionScope is optional. Version 2019-07-07 and later. Specifies the name of the encryption
// scope to use to encrypt the data provided in the request. If not specified, encryption is performed with the default
// account encryption scope. For more information, see Encryption at Rest for Azure Storage Services.
// ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it has a sequence number
// less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to operate only on a blob
// if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this header value to operate
// only on a blob if it has the specified sequence number. ifModifiedSince is specify this header value to operate only
// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to
// operate only on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value
// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs
// without a matching value. ifTags is specify a SQL where clause on blob tags to operate only on blobs with a matching
// value. requestID is 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.
func (client pageBlobClient) UploadPages(ctx context.Context, body io.ReadSeeker, contentLength int64, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (*PageBlobUploadPagesResponse, error) {
if err := validate([]validation{
{targetValue: body,
constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}},
@ -756,7 +798,7 @@ func (client pageBlobClient) UploadPages(ctx context.Context, body io.ReadSeeker
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.uploadPagesPreparer(body, contentLength, transactionalContentMD5, transactionalContentCrc64, timeout, rangeParameter, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
req, err := client.uploadPagesPreparer(body, contentLength, transactionalContentMD5, transactionalContentCrc64, timeout, rangeParameter, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID)
if err != nil {
return nil, err
}
@ -768,7 +810,7 @@ func (client pageBlobClient) UploadPages(ctx context.Context, body io.ReadSeeker
}
// uploadPagesPreparer prepares the UploadPages request.
func (client pageBlobClient) uploadPagesPreparer(body io.ReadSeeker, contentLength int64, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client pageBlobClient) uploadPagesPreparer(body io.ReadSeeker, contentLength int64, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, body)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -801,6 +843,9 @@ func (client pageBlobClient) uploadPagesPreparer(body io.ReadSeeker, contentLeng
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if ifSequenceNumberLessThanOrEqualTo != nil {
req.Header.Set("x-ms-if-sequence-number-le", strconv.FormatInt(*ifSequenceNumberLessThanOrEqualTo, 10))
}
@ -822,6 +867,9 @@ func (client pageBlobClient) uploadPagesPreparer(body io.ReadSeeker, contentLeng
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
@ -857,29 +905,32 @@ func (client pageBlobClient) uploadPagesResponder(resp pipeline.Response) (pipel
// For more information, see Encryption at Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of
// the provided encryption key. Must be provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is
// the algorithm used to produce the encryption key hash. Currently, the only accepted value is "AES256". Must be
// provided if the x-ms-encryption-key header is provided. leaseID is if specified, the operation only succeeds if the
// resource's lease is active and matches this ID. ifSequenceNumberLessThanOrEqualTo is specify this header value to
// operate only on a blob if it has a sequence number less than or equal to the specified. ifSequenceNumberLessThan is
// specify this header value to operate only on a blob if it has a sequence number less than the specified.
// ifSequenceNumberEqualTo is specify this header value to operate only on a blob if it has the specified sequence
// number. ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the
// specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been
// modified since the specified date/time. ifMatch is specify an ETag value to operate only on blobs with a matching
// value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. sourceIfModifiedSince
// is specify this header value to operate only on a blob if it has been modified since the specified date/time.
// sourceIfUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified since the
// specified date/time. sourceIfMatch is specify an ETag value to operate only on blobs with a matching value.
// sourceIfNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is 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.
func (client pageBlobClient) UploadPagesFromURL(ctx context.Context, sourceURL string, sourceRange string, contentLength int64, rangeParameter string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (*PageBlobUploadPagesFromURLResponse, error) {
// provided if the x-ms-encryption-key header is provided. encryptionScope is optional. Version 2019-07-07 and later.
// Specifies the name of the encryption scope to use to encrypt the data provided in the request. If not specified,
// encryption is performed with the default account encryption scope. For more information, see Encryption at Rest for
// Azure Storage Services. leaseID is if specified, the operation only succeeds if the resource's lease is active and
// matches this ID. ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it has
// a sequence number less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to
// operate only on a blob if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this
// header value to operate only on a blob if it has the specified sequence number. ifModifiedSince is specify this
// header value to operate only on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is
// specify this header value to operate only on a blob if it has not been modified since the specified date/time.
// ifMatch is specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag
// value to operate only on blobs without a matching value. ifTags is specify a SQL where clause on blob tags to
// operate only on blobs with a matching value. sourceIfModifiedSince is specify this header value to operate only on a
// blob if it has been modified since the specified date/time. sourceIfUnmodifiedSince is specify this header value to
// operate only on a blob if it has not been modified since the specified date/time. sourceIfMatch is specify an ETag
// value to operate only on blobs with a matching value. sourceIfNoneMatch is specify an ETag value to operate only on
// blobs without a matching value. requestID is 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.
func (client pageBlobClient) UploadPagesFromURL(ctx context.Context, sourceURL string, sourceRange string, contentLength int64, rangeParameter string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (*PageBlobUploadPagesFromURLResponse, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.uploadPagesFromURLPreparer(sourceURL, sourceRange, contentLength, rangeParameter, sourceContentMD5, sourceContentcrc64, timeout, encryptionKey, encryptionKeySha256, encryptionAlgorithm, leaseID, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatch, sourceIfNoneMatch, requestID)
req, err := client.uploadPagesFromURLPreparer(sourceURL, sourceRange, contentLength, rangeParameter, sourceContentMD5, sourceContentcrc64, timeout, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, leaseID, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatch, sourceIfNoneMatch, requestID)
if err != nil {
return nil, err
}
@ -891,7 +942,7 @@ func (client pageBlobClient) UploadPagesFromURL(ctx context.Context, sourceURL s
}
// uploadPagesFromURLPreparer prepares the UploadPagesFromURL request.
func (client pageBlobClient) uploadPagesFromURLPreparer(sourceURL string, sourceRange string, contentLength int64, rangeParameter string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
func (client pageBlobClient) uploadPagesFromURLPreparer(sourceURL string, sourceRange string, contentLength int64, rangeParameter string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -921,6 +972,9 @@ func (client pageBlobClient) uploadPagesFromURLPreparer(sourceURL string, source
if encryptionAlgorithm != EncryptionAlgorithmNone {
req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
}
if encryptionScope != nil {
req.Header.Set("x-ms-encryption-scope", *encryptionScope)
}
if leaseID != nil {
req.Header.Set("x-ms-lease-id", *leaseID)
}
@ -945,6 +999,9 @@ func (client pageBlobClient) uploadPagesFromURLPreparer(sourceURL string, source
if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch))
}
if ifTags != nil {
req.Header.Set("x-ms-if-tags", *ifTags)
}
if sourceIfModifiedSince != nil {
req.Header.Set("x-ms-source-if-modified-since", (*sourceIfModifiedSince).In(gmt).Format(time.RFC1123))
}

Просмотреть файл

@ -25,6 +25,98 @@ func newServiceClient(url url.URL, p pipeline.Pipeline) serviceClient {
return serviceClient{newManagementClient(url, p)}
}
// FilterBlobs the Filter Blobs operation enables callers to list blobs across all containers whose tags match a given
// search expression. Filter blobs searches across all containers within a storage account but can be scoped within
// the expression to a single container.
//
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> requestID is 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. where is filters
// the results to return only to return only blobs whose tags match the specified expression. marker is a string value
// that identifies the portion of the list of containers to be returned with the next listing operation. The operation
// returns the NextMarker value within the response body if the listing operation did not return all containers
// remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter
// in a subsequent call to request the next page of list items. The marker value is opaque to the client. maxresults is
// specifies the maximum number of containers to return. If the request does not specify maxresults, or specifies a
// value greater than 5000, the server will return up to 5000 items. Note that if the listing operation crosses a
// partition boundary, then the service will return a continuation token for retrieving the remainder of the results.
// For this reason, it is possible that the service will return fewer results than specified by maxresults, or than the
// default of 5000.
func (client serviceClient) FilterBlobs(ctx context.Context, timeout *int32, requestID *string, where *string, marker *string, maxresults *int32) (*FilterBlobSegment, error) {
if err := validate([]validation{
{targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}},
{targetValue: maxresults,
constraints: []constraint{{target: "maxresults", name: null, rule: false,
chain: []constraint{{target: "maxresults", name: inclusiveMinimum, rule: 1, chain: nil}}}}}}); err != nil {
return nil, err
}
req, err := client.filterBlobsPreparer(timeout, requestID, where, marker, maxresults)
if err != nil {
return nil, err
}
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.filterBlobsResponder}, req)
if err != nil {
return nil, err
}
return resp.(*FilterBlobSegment), err
}
// filterBlobsPreparer prepares the FilterBlobs request.
func (client serviceClient) filterBlobsPreparer(timeout *int32, requestID *string, where *string, marker *string, maxresults *int32) (pipeline.Request, error) {
req, err := pipeline.NewRequest("GET", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
}
params := req.URL.Query()
if timeout != nil {
params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
}
if where != nil && len(*where) > 0 {
params.Set("where", *where)
}
if marker != nil && len(*marker) > 0 {
params.Set("marker", *marker)
}
if maxresults != nil {
params.Set("maxresults", strconv.FormatInt(int64(*maxresults), 10))
}
params.Set("comp", "blobs")
req.URL.RawQuery = params.Encode()
req.Header.Set("x-ms-version", ServiceVersion)
if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID)
}
return req, nil
}
// filterBlobsResponder handles the response to the FilterBlobs request.
func (client serviceClient) filterBlobsResponder(resp pipeline.Response) (pipeline.Response, error) {
err := validateResponse(resp, http.StatusOK)
if resp == nil {
return nil, err
}
result := &FilterBlobSegment{rawResponse: resp.Response()}
if err != nil {
return result, err
}
defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil {
return result, err
}
if len(b) > 0 {
b = removeBOM(b)
err = xml.Unmarshal(b, result)
if err != nil {
return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body")
}
}
return result, nil
}
// GetAccountInfo returns the sku name and account kind
func (client serviceClient) GetAccountInfo(ctx context.Context) (*ServiceGetAccountInfoResponse, error) {
req, err := client.getAccountInfoPreparer()
@ -300,7 +392,7 @@ func (client serviceClient) getUserDelegationKeyResponder(resp pipeline.Response
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> requestID is 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.
func (client serviceClient) ListContainersSegment(ctx context.Context, prefix *string, marker *string, maxresults *int32, include ListContainersIncludeType, timeout *int32, requestID *string) (*ListContainersSegmentResponse, error) {
func (client serviceClient) ListContainersSegment(ctx context.Context, prefix *string, marker *string, maxresults *int32, include []ListContainersIncludeType, timeout *int32, requestID *string) (*ListContainersSegmentResponse, error) {
if err := validate([]validation{
{targetValue: maxresults,
constraints: []constraint{{target: "maxresults", name: null, rule: false,
@ -322,7 +414,7 @@ func (client serviceClient) ListContainersSegment(ctx context.Context, prefix *s
}
// listContainersSegmentPreparer prepares the ListContainersSegment request.
func (client serviceClient) listContainersSegmentPreparer(prefix *string, marker *string, maxresults *int32, include ListContainersIncludeType, timeout *int32, requestID *string) (pipeline.Request, error) {
func (client serviceClient) listContainersSegmentPreparer(prefix *string, marker *string, maxresults *int32, include []ListContainersIncludeType, timeout *int32, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("GET", client.url, nil)
if err != nil {
return req, pipeline.NewError(err, "failed to create request")
@ -337,8 +429,8 @@ func (client serviceClient) listContainersSegmentPreparer(prefix *string, marker
if maxresults != nil {
params.Set("maxresults", strconv.FormatInt(int64(*maxresults), 10))
}
if include != ListContainersIncludeNone {
params.Set("include", string(include))
if include != nil && len(include) > 0 {
params.Set("include", joinConst(include, ","))
}
if timeout != nil {
params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))

Просмотреть файл

@ -5,7 +5,7 @@ package azblob
// UserAgent returns the UserAgent string to use when sending http.Requests.
func UserAgent() string {
return "Azure-SDK-For-Go/0.0.0 azblob/2019-02-02"
return "Azure-SDK-For-Go/0.0.0 azblob/2019-12-12"
}
// Version returns the semantic version (see http://semver.org) of the client.

Разница между файлами не показана из-за своего большого размера Загрузить разницу