diff --git a/sdk/storage/azdatalake/common.go b/sdk/storage/azdatalake/common.go new file mode 100644 index 000000000000..32a7862e8256 --- /dev/null +++ b/sdk/storage/azdatalake/common.go @@ -0,0 +1,31 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azdatalake + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" +) + +// ClientOptions contains the optional parameters when creating a Client. +type ClientOptions struct { + azcore.ClientOptions +} + +const SnapshotTimeFormat = "2006-01-02T15:04:05.0000000Z07:00" + +// AccessConditions identifies container-specific access conditions which you optionally set. +type AccessConditions struct { + ModifiedAccessConditions *ModifiedAccessConditions + LeaseAccessConditions *LeaseAccessConditions +} + +// LeaseAccessConditions contains optional parameters to access leased entity. +type LeaseAccessConditions = generated.LeaseAccessConditions + +// ModifiedAccessConditions contains a group of parameters for specifying access conditions. +type ModifiedAccessConditions = generated.ModifiedAccessConditions diff --git a/sdk/storage/azdatalake/directory/client.go b/sdk/storage/azdatalake/directory/client.go new file mode 100644 index 000000000000..f376ad4ec7b8 --- /dev/null +++ b/sdk/storage/azdatalake/directory/client.go @@ -0,0 +1,72 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package directory + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/path" +) + +// Client represents a URL to the Azure Datalake Storage service allowing you to manipulate datalake directories. +type Client struct { + path.Client +} + +// NewClient creates an instance of Client with the specified values. +// - serviceURL - the URL of the storage account e.g. https://<account>.dfs.core.windows.net/ +// - cred - an Azure AD credential, typically obtained via the azidentity module +// - options - client options; pass nil to accept the default values +func NewClient(serviceURL string, cred azcore.TokenCredential, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientWithNoCredential creates an instance of Client with the specified values. +// This is used to anonymously access a storage account or with a shared access signature (SAS) token. +// - serviceURL - the URL of the storage account e.g. https://<account>.dfs.core.windows.net/?<sas token> +// - options - client options; pass nil to accept the default values +func NewClientWithNoCredential(serviceURL string, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientWithSharedKeyCredential creates an instance of Client with the specified values. +// - serviceURL - the URL of the storage account e.g. https://<account>.dfs.core.windows.net/ +// - cred - a SharedKeyCredential created with the matching storage account and access key +// - options - client options; pass nil to accept the default values +func NewClientWithSharedKeyCredential(serviceURL string, cred *SharedKeyCredential, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientFromConnectionString creates an instance of Client with the specified values. +// - connectionString - a connection string for the desired storage account +// - options - client options; pass nil to accept the default values +func NewClientFromConnectionString(connectionString string, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// Create creates a new directory (dfs1). +func (d *Client) Create(ctx context.Context, options *CreateOptions) (CreateResponse, error) { + return CreateResponse{}, nil +} + +// Delete removes the directory (dfs1). +func (d *Client) Delete(ctx context.Context, options *DeleteOptions) (DeleteResponse, error) { + //TODO: pass recursive = true + return DeleteResponse{}, nil +} + +// GetProperties returns the properties of the directory (blob3). #TODO: we may just move this method to path client +func (d *Client) GetProperties(ctx context.Context, options *GetPropertiesOptions) (GetPropertiesResponse, error) { + // TODO: format blob response to path response + return GetPropertiesResponse{}, nil +} + +// Rename renames the directory (dfs1). +func (d *Client) Rename(ctx context.Context, newName string, options *RenameOptions) (RenameResponse, error) { + return RenameResponse{}, nil +} diff --git a/sdk/storage/azdatalake/directory/constants.go b/sdk/storage/azdatalake/directory/constants.go new file mode 100644 index 000000000000..70e675e9f10a --- /dev/null +++ b/sdk/storage/azdatalake/directory/constants.go @@ -0,0 +1,35 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package directory + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/path" +) + +// RenameMode defines the rename mode for RenameDirectory +type RenameMode = path.RenameMode + +const ( + RenameModeLegacy RenameMode = path.RenameModeLegacy + RenameModePosix RenameMode = path.RenameModePosix +) + +// SetAccessControlRecursiveMode defines the set access control recursive mode for SetAccessControlRecursive +type SetAccessControlRecursiveMode = path.SetAccessControlRecursiveMode + +const ( + SetAccessControlRecursiveModeSet SetAccessControlRecursiveMode = path.SetAccessControlRecursiveModeSet + SetAccessControlRecursiveModeModify SetAccessControlRecursiveMode = path.SetAccessControlRecursiveModeModify + SetAccessControlRecursiveModeRemove SetAccessControlRecursiveMode = path.SetAccessControlRecursiveModeRemove +) + +type EncryptionAlgorithmType = path.EncryptionAlgorithmType + +const ( + EncryptionAlgorithmTypeNone EncryptionAlgorithmType = path.EncryptionAlgorithmTypeNone + EncryptionAlgorithmTypeAES256 EncryptionAlgorithmType = path.EncryptionAlgorithmTypeAES256 +) diff --git a/sdk/storage/azdatalake/directory/models.go b/sdk/storage/azdatalake/directory/models.go new file mode 100644 index 000000000000..4be9c742e337 --- /dev/null +++ b/sdk/storage/azdatalake/directory/models.go @@ -0,0 +1,136 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package directory + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/path" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/shared" + "time" +) + +// CreateOptions contains the optional parameters when calling the Create operation. dfs endpoint +type CreateOptions struct { + // AccessConditions contains parameters for accessing the file. + AccessConditions *azdatalake.AccessConditions + // Metadata is a map of name-value pairs to associate with the file storage object. + Metadata map[string]*string + // CPKInfo contains a group of parameters for client provided encryption key. + CPKInfo *CPKInfo + // HTTPHeaders contains the HTTP headers for path operations. + HTTPHeaders *HTTPHeaders + //PathExpiryOptions *ExpiryOptions + // LeaseDuration specifies the duration of the lease. + LeaseDuration *time.Duration + // ProposedLeaseID specifies the proposed lease ID for the file. + ProposedLeaseID *string + // Permissions is the octal representation of the permissions for user, group and mask. + Permissions *string + // Umask is the umask for the file. + Umask *string + // Owner is the owner of the file. + Owner *string + // Group is the owning group of the file. + Group *string + // ACL is the access control list for the file. + ACL *string +} + +func (o *CreateOptions) format() (*generated.LeaseAccessConditions, *generated.ModifiedAccessConditions, *generated.PathHTTPHeaders, error) { + // TODO: add all other required options for the create operation, we don't need sourceModAccCond since this is not rename + leaseAccessConditions, modifiedAccessConditions := shared.FormatPathAccessConditions(o.AccessConditions) + httpHeaders := &generated.PathHTTPHeaders{ + CacheControl: o.HTTPHeaders.CacheControl, + ContentDisposition: o.HTTPHeaders.ContentDisposition, + ContentEncoding: o.HTTPHeaders.ContentEncoding, + ContentLanguage: o.HTTPHeaders.ContentLanguage, + ContentMD5: o.HTTPHeaders.ContentMD5, + ContentType: o.HTTPHeaders.ContentType, + TransactionalContentHash: o.HTTPHeaders.ContentMD5, + } + return leaseAccessConditions, modifiedAccessConditions, httpHeaders, nil +} + +// DeleteOptions contains the optional parameters when calling the Delete operation. dfs endpoint +type DeleteOptions struct { + // AccessConditions specifies parameters for accessing the directory + AccessConditions *azdatalake.AccessConditions +} + +func (o *DeleteOptions) format() (*generated.LeaseAccessConditions, *generated.ModifiedAccessConditions, error) { + leaseAccessConditions, modifiedAccessConditions := shared.FormatPathAccessConditions(o.AccessConditions) + return leaseAccessConditions, modifiedAccessConditions, nil +} + +type RenameOptions struct { + // SourceModifiedAccessConditions specifies parameters for accessing the source directory + SourceModifiedAccessConditions *SourceModifiedAccessConditions + // AccessConditions specifies parameters for accessing the destination directory + AccessConditions *azdatalake.AccessConditions +} + +// GetPropertiesOptions contains the optional parameters for the Client.GetProperties method +type GetPropertiesOptions struct { + AccessConditions *azdatalake.AccessConditions + CPKInfo *CPKInfo +} + +func (o *GetPropertiesOptions) format() *blob.GetPropertiesOptions { + if o == nil { + return nil + } + accessConditions := shared.FormatBlobAccessConditions(o.AccessConditions) + return &blob.GetPropertiesOptions{ + AccessConditions: accessConditions, + CPKInfo: &blob.CPKInfo{ + EncryptionKey: o.CPKInfo.EncryptionKey, + EncryptionAlgorithm: o.CPKInfo.EncryptionAlgorithm, + EncryptionKeySHA256: o.CPKInfo.EncryptionKeySHA256, + }, + } +} + +// ===================================== PATH IMPORTS =========================================== + +// CPKInfo contains a group of parameters for client provided encryption key. +type CPKInfo = path.CPKInfo + +// CPKScopeInfo contains a group of parameters for client provided encryption scope. +type CPKScopeInfo = path.CPKScopeInfo + +// HTTPHeaders contains the HTTP headers for path operations. +type HTTPHeaders = path.HTTPHeaders + +// SourceModifiedAccessConditions identifies the source path access conditions. +type SourceModifiedAccessConditions = path.SourceModifiedAccessConditions + +// SetAccessControlOptions contains the optional parameters when calling the SetAccessControl operation. +type SetAccessControlOptions = path.SetAccessControlOptions + +// GetAccessControlOptions contains the optional parameters when calling the GetAccessControl operation. +type GetAccessControlOptions = path.GetAccessControlOptions + +// SetAccessControlRecursiveOptions contains the optional parameters when calling the SetAccessControlRecursive operation. +type SetAccessControlRecursiveOptions = path.SetAccessControlRecursiveOptions + +// SetMetadataOptions contains the optional parameters when calling the SetMetadata operation. +type SetMetadataOptions = path.SetMetadataOptions + +// SetHTTPHeadersOptions contains the optional parameters when calling the SetHTTPHeaders operation. +type SetHTTPHeadersOptions = path.SetHTTPHeadersOptions + +// RemoveAccessControlRecursiveOptions contains the optional parameters when calling the RemoveAccessControlRecursive operation. +type RemoveAccessControlRecursiveOptions = path.RemoveAccessControlRecursiveOptions + +// UpdateAccessControlRecursiveOptions contains the optional parameters when calling the UpdateAccessControlRecursive operation. +type UpdateAccessControlRecursiveOptions = path.UpdateAccessControlRecursiveOptions + +// SharedKeyCredential contains an account's name and its primary or secondary key. +type SharedKeyCredential = exported.SharedKeyCredential diff --git a/sdk/storage/azdatalake/directory/responses.go b/sdk/storage/azdatalake/directory/responses.go new file mode 100644 index 000000000000..19a975c5a384 --- /dev/null +++ b/sdk/storage/azdatalake/directory/responses.go @@ -0,0 +1,45 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package directory + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/path" +) + +// CreateResponse contains the response fields for the Create operation. +type CreateResponse = generated.PathClientCreateResponse + +// DeleteResponse contains the response fields for the Delete operation. +type DeleteResponse = generated.PathClientDeleteResponse + +// SetAccessControlResponse contains the response fields for the SetAccessControl operation. +type SetAccessControlResponse = path.SetAccessControlResponse + +// SetAccessControlRecursiveResponse contains the response fields for the SetAccessControlRecursive operation. +type SetAccessControlRecursiveResponse = path.SetAccessControlRecursiveResponse + +// UpdateAccessControlRecursiveResponse contains the response fields for the UpdateAccessControlRecursive operation. +type UpdateAccessControlRecursiveResponse = path.SetAccessControlRecursiveResponse + +// RemoveAccessControlRecursiveResponse contains the response fields for the RemoveAccessControlRecursive operation. +type RemoveAccessControlRecursiveResponse = path.SetAccessControlRecursiveResponse + +// GetPropertiesResponse contains the response fields for the GetProperties operation. +type GetPropertiesResponse = path.GetPropertiesResponse + +// SetMetadataResponse contains the response fields for the SetMetadata operation. +type SetMetadataResponse = path.SetMetadataResponse + +// SetHTTPHeadersResponse contains the response fields for the SetHTTPHeaders operation. +type SetHTTPHeadersResponse = path.SetHTTPHeadersResponse + +// RenameResponse contains the response fields for the Rename operation. +type RenameResponse = path.CreateResponse + +// GetAccessControlResponse contains the response fields for the GetAccessControl operation. +type GetAccessControlResponse = path.GetAccessControlResponse diff --git a/sdk/storage/azdatalake/file/client.go b/sdk/storage/azdatalake/file/client.go new file mode 100644 index 000000000000..84e9b64ca4ae --- /dev/null +++ b/sdk/storage/azdatalake/file/client.go @@ -0,0 +1,100 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package file + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/path" +) + +// Client represents a URL to the Azure Datalake Storage service allowing you to manipulate files. +type Client struct { + path.Client +} + +// NewClient creates an instance of Client with the specified values. +// - serviceURL - the URL of the storage account e.g. https://<account>.file.core.windows.net/ +// - cred - an Azure AD credential, typically obtained via the azidentity module +// - options - client options; pass nil to accept the default values +func NewClient(serviceURL string, cred azcore.TokenCredential, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientWithNoCredential creates an instance of Client with the specified values. +// This is used to anonymously access a storage account or with a shared access signature (SAS) token. +// - serviceURL - the URL of the storage account e.g. https://<account>.file.core.windows.net/?<sas token> +// - options - client options; pass nil to accept the default values +func NewClientWithNoCredential(serviceURL string, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientWithSharedKeyCredential creates an instance of Client with the specified values. +// - serviceURL - the URL of the storage account e.g. https://<account>.file.core.windows.net/ +// - cred - a SharedKeyCredential created with the matching storage account and access key +// - options - client options; pass nil to accept the default values +func NewClientWithSharedKeyCredential(serviceURL string, cred *SharedKeyCredential, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientFromConnectionString creates an instance of Client with the specified values. +// - connectionString - a connection string for the desired storage account +// - options - client options; pass nil to accept the default values +func NewClientFromConnectionString(connectionString string, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// Create creates a new file (dfs1). +func (f *Client) Create(ctx context.Context, options *CreateOptions) (CreateResponse, error) { + // TODO: format for options should be able to handle the access conditions parameter correctly + return CreateResponse{}, nil +} + +// Delete deletes a file (dfs1). +func (f *Client) Delete(ctx context.Context, options *DeleteOptions) (DeleteResponse, error) { + // TODO: recursive set to false when calling generated code + return DeleteResponse{}, nil +} + +// GetProperties gets the properties of a file (blob3) +func (f *Client) GetProperties(ctx context.Context, options *GetPropertiesOptions) (GetPropertiesResponse, error) { + // TODO: format blob response to path response + return GetPropertiesResponse{}, nil +} + +// Rename renames a file (dfs1). +func (f *Client) Rename(ctx context.Context, newName string, options *RenameOptions) (RenameResponse, error) { + return RenameResponse{}, nil +} + +// SetExpiry operation sets an expiry time on an existing file. +func (f *Client) SetExpiry(ctx context.Context, expiryType ExpiryType, o *SetExpiryOptions) (SetExpiryResponse, error) { + // TODO: consider using the blob client set expiry + // TODO: call methods in set_expiry.go + return SetExpiryResponse{}, nil +} + +// Upload uploads data to a file. +func (f *Client) Upload(ctx context.Context) { + +} + +// Append appends data to a file. +func (f *Client) Append(ctx context.Context) { + +} + +// Flush flushes previous uploaded data to a file. +func (f *Client) Flush(ctx context.Context) { + +} + +// Download downloads data from a file. +func (f *Client) Download(ctx context.Context) { + +} diff --git a/sdk/storage/azdatalake/file/constants.go b/sdk/storage/azdatalake/file/constants.go new file mode 100644 index 000000000000..5ce02ebff960 --- /dev/null +++ b/sdk/storage/azdatalake/file/constants.go @@ -0,0 +1,42 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package file + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/path" +) + +type ResourceType = path.ResourceType + +// TODO: consider the possibility of not exposing this and just pass it under the hood +const ( + ResourceTypeFile ResourceType = path.ResourceTypeFile + ResourceTypeDirectory ResourceType = path.ResourceTypeDirectory +) + +type RenameMode = path.RenameMode + +// TODO: consider the possibility of not exposing this and just pass it under the hood +const ( + RenameModeLegacy RenameMode = path.RenameModeLegacy + RenameModePosix RenameMode = path.RenameModePosix +) + +type SetAccessControlRecursiveMode = path.SetAccessControlRecursiveMode + +const ( + SetAccessControlRecursiveModeSet SetAccessControlRecursiveMode = path.SetAccessControlRecursiveModeSet + SetAccessControlRecursiveModeModify SetAccessControlRecursiveMode = path.SetAccessControlRecursiveModeModify + SetAccessControlRecursiveModeRemove SetAccessControlRecursiveMode = path.SetAccessControlRecursiveModeRemove +) + +type EncryptionAlgorithmType = path.EncryptionAlgorithmType + +const ( + EncryptionAlgorithmTypeNone EncryptionAlgorithmType = path.EncryptionAlgorithmTypeNone + EncryptionAlgorithmTypeAES256 EncryptionAlgorithmType = path.EncryptionAlgorithmTypeAES256 +) diff --git a/sdk/storage/azdatalake/file/models.go b/sdk/storage/azdatalake/file/models.go new file mode 100644 index 000000000000..f45f6041b50b --- /dev/null +++ b/sdk/storage/azdatalake/file/models.go @@ -0,0 +1,157 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package file + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/path" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/shared" + "time" +) + +// CreateOptions contains the optional parameters when calling the Create operation. dfs endpoint. TODO: Design formatter +type CreateOptions struct { + // AccessConditions contains parameters for accessing the file. + AccessConditions *azdatalake.AccessConditions + // Metadata is a map of name-value pairs to associate with the file storage object. + Metadata map[string]*string + // CPKInfo contains a group of parameters for client provided encryption key. + CPKInfo CPKInfo + // HTTPHeaders contains the HTTP headers for path operations. + HTTPHeaders HTTPHeaders + //PathExpiryOptions *ExpiryOptions + // ExpiresOn specifies the time that the file will expire. + ExpiresOn *time.Time + // LeaseDuration specifies the duration of the lease. + LeaseDuration *time.Duration + // ProposedLeaseID specifies the proposed lease ID for the file. + ProposedLeaseID *string + // Permissions is the octal representation of the permissions for user, group and mask. + Permissions *string + // Umask is the umask for the file. + Umask *string + // Owner is the owner of the file. + Owner *string + // Group is the owning group of the file. + Group *string + // ACL is the access control list for the file. + ACL *string +} + +func (o *CreateOptions) format() (*generated.LeaseAccessConditions, *generated.ModifiedAccessConditions, *generated.PathHTTPHeaders, error) { + // TODO: add all other required options for the create operation, we don't need sourceModAccCond since this is not rename + leaseAccessConditions, modifiedAccessConditions := shared.FormatPathAccessConditions(o.AccessConditions) + httpHeaders := &generated.PathHTTPHeaders{ + CacheControl: o.HTTPHeaders.CacheControl, + ContentDisposition: o.HTTPHeaders.ContentDisposition, + ContentEncoding: o.HTTPHeaders.ContentEncoding, + ContentLanguage: o.HTTPHeaders.ContentLanguage, + ContentMD5: o.HTTPHeaders.ContentMD5, + ContentType: o.HTTPHeaders.ContentType, + TransactionalContentHash: o.HTTPHeaders.ContentMD5, + } + return leaseAccessConditions, modifiedAccessConditions, httpHeaders, nil +} + +// DeleteOptions contains the optional parameters when calling the Delete operation. dfs endpoint +type DeleteOptions struct { + // AccessConditions contains parameters for accessing the file. + AccessConditions *azdatalake.AccessConditions +} + +func (o *DeleteOptions) format() (*generated.LeaseAccessConditions, *generated.ModifiedAccessConditions, error) { + leaseAccessConditions, modifiedAccessConditions := shared.FormatPathAccessConditions(o.AccessConditions) + return leaseAccessConditions, modifiedAccessConditions, nil +} + +// RenameOptions contains the optional parameters when calling the Rename operation. TODO: Design formatter +type RenameOptions struct { + // SourceModifiedAccessConditions identifies the source path access conditions. + SourceModifiedAccessConditions *SourceModifiedAccessConditions + // AccessConditions contains parameters for accessing the file. + AccessConditions *azdatalake.AccessConditions +} + +// GetPropertiesOptions contains the optional parameters for the Client.GetProperties method +type GetPropertiesOptions struct { + AccessConditions *azdatalake.AccessConditions + CPKInfo *CPKInfo +} + +func (o *GetPropertiesOptions) format() *blob.GetPropertiesOptions { + if o == nil { + return nil + } + accessConditions := shared.FormatBlobAccessConditions(o.AccessConditions) + return &blob.GetPropertiesOptions{ + AccessConditions: accessConditions, + CPKInfo: &blob.CPKInfo{ + EncryptionKey: o.CPKInfo.EncryptionKey, + EncryptionAlgorithm: o.CPKInfo.EncryptionAlgorithm, + EncryptionKeySHA256: o.CPKInfo.EncryptionKeySHA256, + }, + } +} + +// ===================================== PATH IMPORTS =========================================== + +// CPKInfo contains a group of parameters for client provided encryption key. +type CPKInfo = path.CPKInfo + +// CPKScopeInfo contains a group of parameters for client provided encryption scope. +type CPKScopeInfo = path.CPKScopeInfo + +// HTTPHeaders contains the HTTP headers for path operations. +type HTTPHeaders = path.HTTPHeaders + +// SourceModifiedAccessConditions identifies the source path access conditions. +type SourceModifiedAccessConditions = path.SourceModifiedAccessConditions + +// SetAccessControlOptions contains the optional parameters when calling the SetAccessControl operation. +type SetAccessControlOptions = path.SetAccessControlOptions + +// GetAccessControlOptions contains the optional parameters when calling the GetAccessControl operation. +type GetAccessControlOptions = path.GetAccessControlOptions + +// SetAccessControlRecursiveOptions contains the optional parameters when calling the SetAccessControlRecursive operation. +type SetAccessControlRecursiveOptions = path.SetAccessControlRecursiveOptions + +// SetMetadataOptions contains the optional parameters when calling the SetMetadata operation. +type SetMetadataOptions = path.SetMetadataOptions + +// SetHTTPHeadersOptions contains the optional parameters when calling the SetHTTPHeaders operation. +type SetHTTPHeadersOptions = path.SetHTTPHeadersOptions + +// RemoveAccessControlRecursiveOptions contains the optional parameters when calling the RemoveAccessControlRecursive operation. +type RemoveAccessControlRecursiveOptions = path.RemoveAccessControlRecursiveOptions + +// UpdateAccessControlRecursiveOptions contains the optional parameters when calling the UpdateAccessControlRecursive operation. +type UpdateAccessControlRecursiveOptions = path.UpdateAccessControlRecursiveOptions + +// ExpiryType defines values for ExpiryType. +type ExpiryType = exported.ExpiryType + +// ExpiryTypeAbsolute defines the absolute time for the expiry. +type ExpiryTypeAbsolute = exported.ExpiryTypeAbsolute + +// ExpiryTypeRelativeToNow defines the duration relative to now for the expiry. +type ExpiryTypeRelativeToNow = exported.ExpiryTypeRelativeToNow + +// ExpiryTypeRelativeToCreation defines the duration relative to creation for the expiry. +type ExpiryTypeRelativeToCreation = exported.ExpiryTypeRelativeToCreation + +// ExpiryTypeNever defines that will be set to never expire. +type ExpiryTypeNever = exported.ExpiryTypeNever + +// SetExpiryOptions contains the optional parameters for the Client.SetExpiry method. +type SetExpiryOptions = exported.SetExpiryOptions + +// SharedKeyCredential contains an account's name and its primary or secondary key. +type SharedKeyCredential = exported.SharedKeyCredential diff --git a/sdk/storage/azdatalake/file/responses.go b/sdk/storage/azdatalake/file/responses.go new file mode 100644 index 000000000000..8543eaf3902a --- /dev/null +++ b/sdk/storage/azdatalake/file/responses.go @@ -0,0 +1,48 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package file + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/path" +) + +// SetExpiryResponse contains the response fields for the SetExpiry operation. +type SetExpiryResponse = generated.PathClientSetExpiryResponse + +// CreateResponse contains the response fields for the Create operation. +type CreateResponse = generated.PathClientCreateResponse + +// DeleteResponse contains the response fields for the Delete operation. +type DeleteResponse = generated.PathClientDeleteResponse + +// SetAccessControlResponse contains the response fields for the SetAccessControl operation. +type SetAccessControlResponse = path.SetAccessControlResponse + +// SetAccessControlRecursiveResponse contains the response fields for the SetAccessControlRecursive operation. +type SetAccessControlRecursiveResponse = path.SetAccessControlRecursiveResponse + +// UpdateAccessControlRecursiveResponse contains the response fields for the UpdateAccessControlRecursive operation. +type UpdateAccessControlRecursiveResponse = path.SetAccessControlRecursiveResponse + +// RemoveAccessControlRecursiveResponse contains the response fields for the RemoveAccessControlRecursive operation. +type RemoveAccessControlRecursiveResponse = path.SetAccessControlRecursiveResponse + +// GetPropertiesResponse contains the response fields for the GetProperties operation. +type GetPropertiesResponse = path.GetPropertiesResponse + +// SetMetadataResponse contains the response fields for the SetMetadata operation. +type SetMetadataResponse = path.SetMetadataResponse + +// SetHTTPHeadersResponse contains the response fields for the SetHTTPHeaders operation. +type SetHTTPHeadersResponse = path.SetHTTPHeadersResponse + +// RenameResponse contains the response fields for the Rename operation. +type RenameResponse = path.CreateResponse + +// GetAccessControlResponse contains the response fields for the GetAccessControl operation. +type GetAccessControlResponse = path.GetAccessControlResponse diff --git a/sdk/storage/azdatalake/filesystem/client.go b/sdk/storage/azdatalake/filesystem/client.go new file mode 100644 index 000000000000..ae2cbdb536d2 --- /dev/null +++ b/sdk/storage/azdatalake/filesystem/client.go @@ -0,0 +1,115 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package filesystem + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/base" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" +) + +// Client represents a URL to the Azure Datalake Storage service allowing you to manipulate filesystems. +type Client base.Client[generated.FileSystemClient] + +// NewClient creates an instance of Client with the specified values. +// - serviceURL - the URL of the storage account e.g. https://<account>.file.core.windows.net/ +// - cred - an Azure AD credential, typically obtained via the azidentity module +// - options - client options; pass nil to accept the default values +func NewClient(serviceURL string, cred azcore.TokenCredential, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientWithNoCredential creates an instance of Client with the specified values. +// This is used to anonymously access a storage account or with a shared access signature (SAS) token. +// - serviceURL - the URL of the storage account e.g. https://<account>.file.core.windows.net/?<sas token> +// - options - client options; pass nil to accept the default values +func NewClientWithNoCredential(serviceURL string, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientWithSharedKeyCredential creates an instance of Client with the specified values. +// - serviceURL - the URL of the storage account e.g. https://<account>.file.core.windows.net/ +// - cred - a SharedKeyCredential created with the matching storage account and access key +// - options - client options; pass nil to accept the default values +func NewClientWithSharedKeyCredential(serviceURL string, cred *SharedKeyCredential, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientFromConnectionString creates an instance of Client with the specified values. +// - connectionString - a connection string for the desired storage account +// - options - client options; pass nil to accept the default values +func NewClientFromConnectionString(connectionString string, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +func (fs *Client) generated() *generated.FileSystemClient { + return base.InnerClient((*base.Client[generated.FileSystemClient])(fs)) +} + +func (fs *Client) sharedKey() *exported.SharedKeyCredential { + return base.SharedKey((*base.Client[generated.FileSystemClient])(fs)) +} + +// URL returns the URL endpoint used by the Client object. +func (fs *Client) URL() string { + return "s.generated().Endpoint()" +} + +// Create creates a new filesystem under the specified account. (blob3). +func (fs *Client) Create(ctx context.Context, options *CreateOptions) (CreateResponse, error) { + return CreateResponse{}, nil +} + +// Delete deletes the specified filesystem and any files or directories it contains. (blob3). +func (fs *Client) Delete(ctx context.Context, options *DeleteOptions) (DeleteResponse, error) { + return DeleteResponse{}, nil +} + +// GetProperties returns all user-defined metadata, standard HTTP properties, and system properties for the filesystem. (blob3). +func (fs *Client) GetProperties(ctx context.Context, options *GetPropertiesOptions) (GetPropertiesResponse, error) { + // TODO: format blob response to fs response + return GetPropertiesResponse{}, nil +} + +// SetMetadata sets one or more user-defined name-value pairs for the specified filesystem. (blob3). +func (fs *Client) SetMetadata(ctx context.Context, options *SetMetadataOptions) (SetMetadataResponse, error) { + return SetMetadataResponse{}, nil +} + +// SetAccessPolicy sets the permissions for the specified filesystem or the files and directories under it. (blob3). +func (fs *Client) SetAccessPolicy(ctx context.Context, options *SetAccessPolicyOptions) (SetAccessPolicyResponse, error) { + return SetAccessPolicyResponse{}, nil +} + +// GetAccessPolicy returns the permissions for the specified filesystem or the files and directories under it. (blob3). +func (fs *Client) GetAccessPolicy(ctx context.Context, options *GetAccessPolicyOptions) (GetAccessPolicyResponse, error) { + return GetAccessPolicyResponse{}, nil +} + +// UndeletePath restores the specified path that was previously deleted. (dfs op/blob2). +func (fs *Client) UndeletePath(ctx context.Context, path string, options *UndeletePathOptions) (UndeletePathResponse, error) { + return UndeletePathResponse{}, nil +} + +// NewListPathsPager operation returns a pager of the shares under the specified account. (dfs1) +// For more information, see https://learn.microsoft.com/en-us/rest/api/storageservices/list-shares +func (fs *Client) NewListPathsPager(recursive bool, options *ListPathsOptions) *runtime.Pager[ListPathsSegmentResponse] { + //TODO: look into possibility of using blob endpoint like list deleted paths is + //TODO: will use ListPathsCreateRequest + return nil +} + +// NewListDeletedPathsPager operation returns a pager of the shares under the specified account. (dfs op/blob2). +// For more information, see https://learn.microsoft.com/en-us/rest/api/storageservices/list-shares +func (fs *Client) NewListDeletedPathsPager(options *ListDeletedPathsOptions) *runtime.Pager[ListDeletedPathsSegmentResponse] { + //TODO: will use ListBlobHierarchySegmentCreateRequest + return nil +} diff --git a/sdk/storage/azdatalake/filesystem/constants.go b/sdk/storage/azdatalake/filesystem/constants.go new file mode 100644 index 000000000000..3e0c373b87a1 --- /dev/null +++ b/sdk/storage/azdatalake/filesystem/constants.go @@ -0,0 +1,17 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package filesystem + +import "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" + +// PublicAccessType defines values for AccessType - private (default) or file or filesystem. +type PublicAccessType = azblob.PublicAccessType + +const ( + File PublicAccessType = azblob.PublicAccessTypeBlob + Filesystem PublicAccessType = azblob.PublicAccessTypeContainer +) diff --git a/sdk/storage/azdatalake/filesystem/models.go b/sdk/storage/azdatalake/filesystem/models.go new file mode 100644 index 000000000000..ebb1946ec388 --- /dev/null +++ b/sdk/storage/azdatalake/filesystem/models.go @@ -0,0 +1,142 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package filesystem + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/shared" +) + +// SetAccessPolicyOptions provides set of configurations for Filesystem.SetAccessPolicy operation. +type SetAccessPolicyOptions struct { + // Specifies whether data in the filesystem may be accessed publicly and the level of access. + // If this header is not included in the request, filesystem data is private to the account owner. + Access *PublicAccessType + AccessConditions *azdatalake.AccessConditions + FilesystemACL []*SignedIdentifier +} + +func (o *SetAccessPolicyOptions) format() *container.SetAccessPolicyOptions { + return &container.SetAccessPolicyOptions{ + Access: o.Access, + AccessConditions: shared.FormatContainerAccessConditions(o.AccessConditions), + ContainerACL: o.FilesystemACL, + } +} + +// CreateOptions contains the optional parameters for the Client.Create method. +type CreateOptions struct { + // Specifies whether data in the filesystem may be accessed publicly and the level of access. + Access *PublicAccessType + + // Optional. Specifies a user-defined name-value pair associated with the filesystem. + Metadata map[string]*string + + // Optional. Specifies the encryption scope settings to set on the filesystem. + CPKScopeInfo *CPKScopeInfo +} + +func (o *CreateOptions) format() *container.CreateOptions { + return &container.CreateOptions{ + Access: o.Access, + Metadata: o.Metadata, + CPKScopeInfo: o.CPKScopeInfo, + } +} + +// DeleteOptions contains the optional parameters for the Client.Delete method. +type DeleteOptions struct { + AccessConditions *azdatalake.AccessConditions +} + +func (o *DeleteOptions) format() *container.DeleteOptions { + return &container.DeleteOptions{ + AccessConditions: shared.FormatContainerAccessConditions(o.AccessConditions), + } +} + +// GetPropertiesOptions contains the optional parameters for the FilesystemClient.GetProperties method. +type GetPropertiesOptions struct { + LeaseAccessConditions *azdatalake.LeaseAccessConditions +} + +func (o *GetPropertiesOptions) format() *container.GetPropertiesOptions { + return &container.GetPropertiesOptions{ + LeaseAccessConditions: &container.LeaseAccessConditions{ + LeaseID: o.LeaseAccessConditions.LeaseID, + }, + } +} + +// SetMetadataOptions contains the optional parameters for the Client.SetMetadata method. +type SetMetadataOptions struct { + Metadata map[string]*string + AccessConditions *azdatalake.AccessConditions +} + +func (o *SetMetadataOptions) format() *container.SetMetadataOptions { + return &container.SetMetadataOptions{ + Metadata: o.Metadata, + LeaseAccessConditions: &container.LeaseAccessConditions{ + LeaseID: o.AccessConditions.LeaseAccessConditions.LeaseID, + }, + ModifiedAccessConditions: &container.ModifiedAccessConditions{ + IfMatch: o.AccessConditions.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.AccessConditions.ModifiedAccessConditions.IfNoneMatch, + IfModifiedSince: o.AccessConditions.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.AccessConditions.ModifiedAccessConditions.IfUnmodifiedSince, + }, + } +} + +// GetAccessPolicyOptions contains the optional parameters for the Client.GetAccessPolicy method. +type GetAccessPolicyOptions struct { + LeaseAccessConditions *azdatalake.LeaseAccessConditions +} + +func (o *GetAccessPolicyOptions) format() *container.GetAccessPolicyOptions { + return &container.GetAccessPolicyOptions{ + LeaseAccessConditions: &container.LeaseAccessConditions{ + LeaseID: o.LeaseAccessConditions.LeaseID, + }, + } +} + +// CPKScopeInfo contains a group of parameters for the FilesystemClient.Create method. +type CPKScopeInfo = container.CPKScopeInfo + +// AccessPolicy - An Access policy. +type AccessPolicy = container.AccessPolicy + +// SignedIdentifier - signed identifier. +type SignedIdentifier = container.SignedIdentifier + +// ListPathsOptions contains the optional parameters for the Filesystem.ListPaths operation. +type ListPathsOptions struct { + Marker *string + MaxResults *int32 + Prefix *string + Upn *bool +} + +// ListDeletedPathsOptions contains the optional parameters for the Filesystem.ListDeletedPaths operation. PLACEHOLDER +type ListDeletedPathsOptions struct { + Marker *string + MaxResults *int32 + Prefix *string + Upn *bool +} + +// UndeletePathOptions contains the optional parameters for the Filesystem.UndeletePath operation. +type UndeletePathOptions struct { + // placeholder +} + +// SharedKeyCredential contains an account's name and its primary or secondary key. +type SharedKeyCredential = exported.SharedKeyCredential diff --git a/sdk/storage/azdatalake/filesystem/responses.go b/sdk/storage/azdatalake/filesystem/responses.go new file mode 100644 index 000000000000..06b9d8b78a86 --- /dev/null +++ b/sdk/storage/azdatalake/filesystem/responses.go @@ -0,0 +1,39 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package filesystem + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" +) + +// CreateResponse contains the response from method FilesystemClient.Create. +type CreateResponse = container.CreateResponse + +// DeleteResponse contains the response from method FilesystemClient.Delete. +type DeleteResponse = container.DeleteResponse + +// SetMetadataResponse contains the response from method FilesystemClient.SetMetadata. +type SetMetadataResponse = container.SetMetadataResponse + +// SetAccessPolicyResponse contains the response from method FilesystemClient.SetAccessPolicy. +type SetAccessPolicyResponse = container.SetAccessPolicyResponse + +// GetAccessPolicyResponse contains the response from method FilesystemClient.GetAccessPolicy. +type GetAccessPolicyResponse = container.GetAccessPolicyResponse + +// GetPropertiesResponse contains the response from method FilesystemClient.GetProperties. +type GetPropertiesResponse = generated.FileSystemClientGetPropertiesResponse + +// ListPathsSegmentResponse contains the response from method FilesystemClient.ListPathsSegment. +type ListPathsSegmentResponse = generated.FileSystemClientListPathsResponse + +// ListDeletedPathsSegmentResponse contains the response from method FilesystemClient.ListPathsSegment. +type ListDeletedPathsSegmentResponse = generated.FileSystemClientListBlobHierarchySegmentResponse + +// UndeletePathResponse contains the response from method FilesystemClient.UndeletePath. +type UndeletePathResponse = generated.PathClientUndeleteResponse diff --git a/sdk/storage/azdatalake/go.mod b/sdk/storage/azdatalake/go.mod index dfd718eb5e06..6fc071bf6038 100644 --- a/sdk/storage/azdatalake/go.mod +++ b/sdk/storage/azdatalake/go.mod @@ -1,11 +1,26 @@ module github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake -go 1.19 +go 1.18 -require github.com/Azure/azure-sdk-for-go/sdk/azcore v1.5.0 +require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.5.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 + github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 + github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 + github.com/stretchr/testify v1.7.1 +) require ( - github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/golang-jwt/jwt v3.2.1+incompatible // indirect + github.com/google/uuid v1.1.1 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 // indirect golang.org/x/net v0.8.0 // indirect + golang.org/x/sys v0.6.0 // indirect golang.org/x/text v0.8.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/sdk/storage/azdatalake/go.sum b/sdk/storage/azdatalake/go.sum index 5b3d1f6c33e0..44c525ae55ed 100644 --- a/sdk/storage/azdatalake/go.sum +++ b/sdk/storage/azdatalake/go.sum @@ -1,12 +1,44 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.5.0 h1:xGLAFFd9D3iLGxYiUGPdITSzsFmU1K8VtfuUHWAoN7M= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.5.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 h1:u/LLAOFgsMv7HmNL4Qufg58y+qElGOt5qv0z1mURkRY= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0/go.mod h1:2e8rMJtl2+2j+HXbTBwnyGpm5Nou7KhvSfxOq8JpTag= +github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 h1:BWe8a+f/t+7KY7zH2mqygeUD0t8hNFXe08p1Pb3/jKE= +github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= +github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI= +github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 h1:Tgea0cVUD0ivh5ADBX4WwuI12DUd2to3nCYe2eayMIw= +golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sdk/storage/azdatalake/internal/base/clients.go b/sdk/storage/azdatalake/internal/base/clients.go new file mode 100644 index 000000000000..40c909a17596 --- /dev/null +++ b/sdk/storage/azdatalake/internal/base/clients.go @@ -0,0 +1,24 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package base + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/exported" +) + +type Client[T any] struct { + inner *T + sharedKey *exported.SharedKeyCredential +} + +func InnerClient[T any](client *Client[T]) *T { + return client.inner +} + +func SharedKey[T any](client *Client[T]) *exported.SharedKeyCredential { + return client.sharedKey +} diff --git a/sdk/storage/azdatalake/internal/exported/access_policy.go b/sdk/storage/azdatalake/internal/exported/access_policy.go new file mode 100644 index 000000000000..14c293cf6569 --- /dev/null +++ b/sdk/storage/azdatalake/internal/exported/access_policy.go @@ -0,0 +1,67 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package exported + +import ( + "bytes" + "fmt" +) + +// AccessPolicyPermission type simplifies creating the permissions string for a container's access policy. +// Initialize an instance of this type and then call its String method to set AccessPolicy's Permission field. +type AccessPolicyPermission struct { + Read, Add, Create, Write, Delete, List bool +} + +// String produces the access policy permission string for an Azure Storage container. +// Call this method to set AccessPolicy's Permission field. +func (p *AccessPolicyPermission) String() string { + var b bytes.Buffer + if p.Read { + b.WriteRune('r') + } + if p.Add { + b.WriteRune('a') + } + if p.Create { + b.WriteRune('c') + } + if p.Write { + b.WriteRune('w') + } + if p.Delete { + b.WriteRune('d') + } + if p.List { + b.WriteRune('l') + } + return b.String() +} + +// Parse initializes the AccessPolicyPermission's fields from a string. +func (p *AccessPolicyPermission) Parse(s string) error { + *p = AccessPolicyPermission{} // Clear the flags + for _, r := range s { + switch r { + case 'r': + p.Read = true + case 'a': + p.Add = true + case 'c': + p.Create = true + case 'w': + p.Write = true + case 'd': + p.Delete = true + case 'l': + p.List = true + default: + return fmt.Errorf("invalid permission: '%v'", r) + } + } + return nil +} diff --git a/sdk/storage/azdatalake/internal/exported/exported.go b/sdk/storage/azdatalake/internal/exported/exported.go new file mode 100644 index 000000000000..9bc1ca47df84 --- /dev/null +++ b/sdk/storage/azdatalake/internal/exported/exported.go @@ -0,0 +1,33 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package exported + +import ( + "fmt" + "strconv" +) + +// HTTPRange defines a range of bytes within an HTTP resource, starting at offset and +// ending at offset+count. A zero-value HTTPRange indicates the entire resource. An HTTPRange +// which has an offset but no zero value count indicates from the offset to the resource's end. +type HTTPRange struct { + Offset int64 + Count int64 +} + +// FormatHTTPRange converts an HTTPRange to its string format. +func FormatHTTPRange(r HTTPRange) *string { + if r.Offset == 0 && r.Count == 0 { + return nil // No specified range + } + endOffset := "" // if count == CountToEnd (0) + if r.Count > 0 { + endOffset = strconv.FormatInt((r.Offset+r.Count)-1, 10) + } + dataRange := fmt.Sprintf("bytes=%v-%s", r.Offset, endOffset) + return &dataRange +} diff --git a/sdk/storage/azdatalake/internal/exported/set_expiry.go b/sdk/storage/azdatalake/internal/exported/set_expiry.go new file mode 100644 index 000000000000..041dd8ba60c0 --- /dev/null +++ b/sdk/storage/azdatalake/internal/exported/set_expiry.go @@ -0,0 +1,71 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package exported + +import ( + "net/http" + "strconv" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" +) + +// ExpiryType defines values for ExpiryType +type ExpiryType interface { + Format(o *SetExpiryOptions) (generated.ExpiryOptions, *generated.PathClientSetExpiryOptions) + notPubliclyImplementable() +} + +// ExpiryTypeAbsolute defines the absolute time for the blob expiry +type ExpiryTypeAbsolute time.Time + +// ExpiryTypeRelativeToNow defines the duration relative to now for the blob expiry +type ExpiryTypeRelativeToNow time.Duration + +// ExpiryTypeRelativeToCreation defines the duration relative to creation for the blob expiry +type ExpiryTypeRelativeToCreation time.Duration + +// ExpiryTypeNever defines that the blob will be set to never expire +type ExpiryTypeNever struct { + // empty struct since NeverExpire expiry type does not require expiry time +} + +// SetExpiryOptions contains the optional parameters for the Client.SetExpiry method. +type SetExpiryOptions struct { + // placeholder for future options +} + +func (e ExpiryTypeAbsolute) Format(o *SetExpiryOptions) (generated.ExpiryOptions, *generated.PathClientSetExpiryOptions) { + return generated.ExpiryOptionsAbsolute, &generated.PathClientSetExpiryOptions{ + ExpiresOn: to.Ptr(time.Time(e).UTC().Format(http.TimeFormat)), + } +} + +func (e ExpiryTypeAbsolute) notPubliclyImplementable() {} + +func (e ExpiryTypeRelativeToNow) Format(o *SetExpiryOptions) (generated.ExpiryOptions, *generated.PathClientSetExpiryOptions) { + return generated.ExpiryOptionsRelativeToNow, &generated.PathClientSetExpiryOptions{ + ExpiresOn: to.Ptr(strconv.FormatInt(time.Duration(e).Milliseconds(), 10)), + } +} + +func (e ExpiryTypeRelativeToNow) notPubliclyImplementable() {} + +func (e ExpiryTypeRelativeToCreation) Format(o *SetExpiryOptions) (generated.ExpiryOptions, *generated.PathClientSetExpiryOptions) { + return generated.ExpiryOptionsRelativeToCreation, &generated.PathClientSetExpiryOptions{ + ExpiresOn: to.Ptr(strconv.FormatInt(time.Duration(e).Milliseconds(), 10)), + } +} + +func (e ExpiryTypeRelativeToCreation) notPubliclyImplementable() {} + +func (e ExpiryTypeNever) Format(o *SetExpiryOptions) (generated.ExpiryOptions, *generated.PathClientSetExpiryOptions) { + return generated.ExpiryOptionsNeverExpire, nil +} + +func (e ExpiryTypeNever) notPubliclyImplementable() {} diff --git a/sdk/storage/azdatalake/internal/exported/shared_key_credential.go b/sdk/storage/azdatalake/internal/exported/shared_key_credential.go new file mode 100644 index 000000000000..01934a0f14de --- /dev/null +++ b/sdk/storage/azdatalake/internal/exported/shared_key_credential.go @@ -0,0 +1,218 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package exported + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "fmt" + "net/http" + "net/url" + "sort" + "strings" + "sync/atomic" + "time" + + azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/shared" +) + +// NewSharedKeyCredential creates an immutable SharedKeyCredential containing the +// storage account's name and either its primary or secondary key. +func NewSharedKeyCredential(accountName string, accountKey string) (*SharedKeyCredential, error) { + c := SharedKeyCredential{accountName: accountName} + if err := c.SetAccountKey(accountKey); err != nil { + return nil, err + } + return &c, nil +} + +// SharedKeyCredential contains an account's name and its primary or secondary key. +type SharedKeyCredential struct { + // Only the NewSharedKeyCredential method should set these; all other methods should treat them as read-only + accountName string + accountKey atomic.Value // []byte +} + +// AccountName returns the Storage account's name. +func (c *SharedKeyCredential) AccountName() string { + return c.accountName +} + +// SetAccountKey replaces the existing account key with the specified account key. +func (c *SharedKeyCredential) SetAccountKey(accountKey string) error { + _bytes, err := base64.StdEncoding.DecodeString(accountKey) + if err != nil { + return fmt.Errorf("decode account key: %w", err) + } + c.accountKey.Store(_bytes) + return nil +} + +// ComputeHMACSHA256 generates a hash signature for an HTTP request or for a SAS. +func (c *SharedKeyCredential) computeHMACSHA256(message string) (string, error) { + h := hmac.New(sha256.New, c.accountKey.Load().([]byte)) + _, err := h.Write([]byte(message)) + return base64.StdEncoding.EncodeToString(h.Sum(nil)), err +} + +func (c *SharedKeyCredential) buildStringToSign(req *http.Request) (string, error) { + // https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services + headers := req.Header + contentLength := getHeader(shared.HeaderContentLength, headers) + if contentLength == "0" { + contentLength = "" + } + + canonicalizedResource, err := c.buildCanonicalizedResource(req.URL) + if err != nil { + return "", err + } + + stringToSign := strings.Join([]string{ + req.Method, + getHeader(shared.HeaderContentEncoding, headers), + getHeader(shared.HeaderContentLanguage, headers), + contentLength, + getHeader(shared.HeaderContentMD5, headers), + getHeader(shared.HeaderContentType, headers), + "", // Empty date because x-ms-date is expected (as per web page above) + getHeader(shared.HeaderIfModifiedSince, headers), + getHeader(shared.HeaderIfMatch, headers), + getHeader(shared.HeaderIfNoneMatch, headers), + getHeader(shared.HeaderIfUnmodifiedSince, headers), + getHeader(shared.HeaderRange, headers), + c.buildCanonicalizedHeader(headers), + canonicalizedResource, + }, "\n") + return stringToSign, nil +} + +func getHeader(key string, headers map[string][]string) string { + if headers == nil { + return "" + } + if v, ok := headers[key]; ok { + if len(v) > 0 { + return v[0] + } + } + + return "" +} + +func (c *SharedKeyCredential) buildCanonicalizedHeader(headers http.Header) string { + cm := map[string][]string{} + for k, v := range headers { + headerName := strings.TrimSpace(strings.ToLower(k)) + if strings.HasPrefix(headerName, "x-ms-") { + cm[headerName] = v // NOTE: the value must not have any whitespace around it. + } + } + if len(cm) == 0 { + return "" + } + + keys := make([]string, 0, len(cm)) + for key := range cm { + keys = append(keys, key) + } + sort.Strings(keys) + ch := bytes.NewBufferString("") + for i, key := range keys { + if i > 0 { + ch.WriteRune('\n') + } + ch.WriteString(key) + ch.WriteRune(':') + ch.WriteString(strings.Join(cm[key], ",")) + } + return ch.String() +} + +func (c *SharedKeyCredential) buildCanonicalizedResource(u *url.URL) (string, error) { + // https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services + cr := bytes.NewBufferString("/") + cr.WriteString(c.accountName) + + if len(u.Path) > 0 { + // Any portion of the CanonicalizedResource string that is derived from + // the resource's URI should be encoded exactly as it is in the URI. + // -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx + cr.WriteString(u.EscapedPath()) + } else { + // a slash is required to indicate the root path + cr.WriteString("/") + } + + // params is a map[string][]string; param name is key; params values is []string + params, err := url.ParseQuery(u.RawQuery) // Returns URL decoded values + if err != nil { + return "", fmt.Errorf("failed to parse query params: %w", err) + } + + if len(params) > 0 { // There is at least 1 query parameter + var paramNames []string // We use this to sort the parameter key names + for paramName := range params { + paramNames = append(paramNames, paramName) // paramNames must be lowercase + } + sort.Strings(paramNames) + + for _, paramName := range paramNames { + paramValues := params[paramName] + sort.Strings(paramValues) + + // Join the sorted key values separated by ',' + // Then prepend "keyName:"; then add this string to the buffer + cr.WriteString("\n" + paramName + ":" + strings.Join(paramValues, ",")) + } + } + return cr.String(), nil +} + +// ComputeHMACSHA256 is a helper for computing the signed string outside of this package. +func ComputeHMACSHA256(cred *SharedKeyCredential, message string) (string, error) { + return cred.computeHMACSHA256(message) +} + +// the following content isn't actually exported but must live +// next to SharedKeyCredential as it uses its unexported methods + +type SharedKeyCredPolicy struct { + cred *SharedKeyCredential +} + +func NewSharedKeyCredPolicy(cred *SharedKeyCredential) *SharedKeyCredPolicy { + return &SharedKeyCredPolicy{cred: cred} +} + +func (s *SharedKeyCredPolicy) Do(req *policy.Request) (*http.Response, error) { + if d := getHeader(shared.HeaderXmsDate, req.Raw().Header); d == "" { + req.Raw().Header.Set(shared.HeaderXmsDate, time.Now().UTC().Format(http.TimeFormat)) + } + stringToSign, err := s.cred.buildStringToSign(req.Raw()) + if err != nil { + return nil, err + } + signature, err := s.cred.computeHMACSHA256(stringToSign) + if err != nil { + return nil, err + } + authHeader := strings.Join([]string{"SharedKey ", s.cred.AccountName(), ":", signature}, "") + req.Raw().Header.Set(shared.HeaderAuthorization, authHeader) + + response, err := req.Next() + if err != nil && response != nil && response.StatusCode == http.StatusForbidden { + // Service failed to authenticate request, log it + log.Write(azlog.EventResponse, "===== HTTP Forbidden status, String-to-Sign:\n"+stringToSign+"\n===============================\n") + } + return response, err +} diff --git a/sdk/storage/azdatalake/internal/exported/version.go b/sdk/storage/azdatalake/internal/exported/version.go new file mode 100644 index 000000000000..b570e4653d73 --- /dev/null +++ b/sdk/storage/azdatalake/internal/exported/version.go @@ -0,0 +1,12 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package exported + +const ( + ModuleName = "azdatalake" + ModuleVersion = "v0.1.0" +) diff --git a/sdk/storage/azdatalake/internal/generated/autorest.md b/sdk/storage/azdatalake/internal/generated/autorest.md index 9a83369f048b..e5184eb7f1df 100644 --- a/sdk/storage/azdatalake/internal/generated/autorest.md +++ b/sdk/storage/azdatalake/internal/generated/autorest.md @@ -7,7 +7,7 @@ go: true clear-output-folder: false version: "^3.0.0" license-header: MICROSOFT_MIT_NO_VERSION -input-file: "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.StorageDataLake/preview/2020-10-02/DataLakeStorage.json" +input-file: "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Azure.Storage.Files.DataLake/preview/2020-10-02/DataLakeStorage.json" credential-scope: "https://storage.azure.com/.default" output-folder: ../generated file-prefix: "zz_" @@ -19,7 +19,7 @@ modelerfour: seal-single-value-enum-by-default: true lenient-model-deduplication: true export-clients: true -use: "@autorest/go@4.0.0-preview.45" +use: "@autorest/go@4.0.0-preview.49" ``` ### Remove Filesystem and PathName from parameter list since they are not needed @@ -78,4 +78,153 @@ directive: replace(/func \(client \*ServiceClient\) NewListFileSystemsPager\(.+\/\/ listFileSystemsCreateRequest creates the ListFileSystems request/s, `//\n// ListFileSystemsCreateRequest creates the ListFileSystems request`). replace(/\(client \*ServiceClient\) listFileSystemsCreateRequest\(/, `(client *FileSystemClient) ListFileSystemsCreateRequest(`). replace(/\(client \*ServiceClient\) listFileSystemsHandleResponse\(/, `(client *FileSystemClient) ListFileSystemsHandleResponse(`); -``` \ No newline at end of file +``` + +### Fix EncryptionAlgorithm + +``` yaml +directive: +- from: swagger-document + where: $.parameters + transform: > + delete $.EncryptionAlgorithm.enum; + $.EncryptionAlgorithm.enum = [ + "None", + "AES256" + ]; +``` + +### Clean up some const type names so they don't stutter + +``` yaml +directive: +- from: swagger-document + where: $.parameters['PathExpiryOptions'] + transform: > + $["x-ms-enum"].name = "ExpiryOptions"; + $["x-ms-client-name"].name = "ExpiryOptions"; + +``` + +### use azcore.ETag + +``` yaml +directive: +- from: zz_models.go + where: $ + transform: >- + return $. + replace(/import "time"/, `import (\n\t"time"\n\t"github.com/Azure/azure-sdk-for-go/sdk/azcore"\n)`). + replace(/Etag\s+\*string/g, `ETag *azcore.ETag`). + replace(/IfMatch\s+\*string/g, `IfMatch *azcore.ETag`). + replace(/IfNoneMatch\s+\*string/g, `IfNoneMatch *azcore.ETag`). + replace(/SourceIfMatch\s+\*string/g, `SourceIfMatch *azcore.ETag`). + replace(/SourceIfNoneMatch\s+\*string/g, `SourceIfNoneMatch *azcore.ETag`); + +- from: zz_response_types.go + where: $ + transform: >- + return $. + replace(/"time"/, `"time"\n\t"github.com/Azure/azure-sdk-for-go/sdk/azcore"`). + replace(/ETag\s+\*string/g, `ETag *azcore.ETag`); + +- from: + - zz_filesystem_client.go + - zz_path_client.go + where: $ + transform: >- + return $. + replace(/"github\.com\/Azure\/azure\-sdk\-for\-go\/sdk\/azcore\/policy"/, `"github.com/Azure/azure-sdk-for-go/sdk/azcore"\n\t"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"`). + replace(/result\.ETag\s+=\s+&val/g, `result.ETag = (*azcore.ETag)(&val)`). + replace(/\*modifiedAccessConditions.IfMatch/g, `string(*modifiedAccessConditions.IfMatch)`). + replace(/\*modifiedAccessConditions.IfNoneMatch/g, `string(*modifiedAccessConditions.IfNoneMatch)`). + replace(/\*sourceModifiedAccessConditions.SourceIfMatch/g, `string(*sourceModifiedAccessConditions.SourceIfMatch)`). + replace(/\*sourceModifiedAccessConditions.SourceIfNoneMatch/g, `string(*sourceModifiedAccessConditions.SourceIfNoneMatch)`); + +``` + +### Fix up x-ms-content-crc64 header response name + +``` yaml +directive: +- from: swagger-document + where: $.x-ms-paths.*.*.responses.*.headers.x-ms-content-crc64 + transform: > + $["x-ms-client-name"] = "ContentCRC64" +``` + +### Updating encoding URL, Golang adds '+' which disrupts encoding with service + +``` yaml +directive: + - from: zz_service_client.go + where: $ + transform: >- + return $. + replace(/req.Raw\(\).URL.RawQuery \= reqQP.Encode\(\)/, `req.Raw().URL.RawQuery = strings.Replace(reqQP.Encode(), "+", "%20", -1)`) +``` + +### Change `Duration` parameter in leases to be required + +``` yaml +directive: +- from: swagger-document + where: $.parameters.LeaseDuration + transform: > + $.required = true; +``` + +### Change CPK acronym to be all caps + +``` yaml +directive: + - from: source-file-go + where: $ + transform: >- + return $. + replace(/Cpk/g, "CPK"); +``` + +### Change CORS acronym to be all caps + +``` yaml +directive: + - from: source-file-go + where: $ + transform: >- + return $. + replace(/Cors/g, "CORS"); +``` + +### Change cors xml to be correct + +``` yaml +directive: + - from: source-file-go + where: $ + transform: >- + return $. + replace(/xml:"CORS>CORSRule"/g, "xml:\"Cors>CorsRule\""); +``` + +### Convert time to GMT for If-Modified-Since and If-Unmodified-Since request headers + +``` yaml +directive: +- from: + - zz_filesystem_client.go + - zz_path.go + where: $ + transform: >- + return $. + replace (/req\.Raw\(\)\.Header\[\"If-Modified-Since\"\]\s+=\s+\[\]string\{modifiedAccessConditions\.IfModifiedSince\.Format\(time\.RFC1123\)\}/g, + `req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}`). + replace (/req\.Raw\(\)\.Header\[\"If-Unmodified-Since\"\]\s+=\s+\[\]string\{modifiedAccessConditions\.IfUnmodifiedSince\.Format\(time\.RFC1123\)\}/g, + `req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}`). + replace (/req\.Raw\(\)\.Header\[\"x-ms-source-if-modified-since\"\]\s+=\s+\[\]string\{sourceModifiedAccessConditions\.SourceIfModifiedSince\.Format\(time\.RFC1123\)\}/g, + `req.Raw().Header["x-ms-source-if-modified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfModifiedSince).In(gmt).Format(time.RFC1123)}`). + replace (/req\.Raw\(\)\.Header\[\"x-ms-source-if-unmodified-since\"\]\s+=\s+\[\]string\{sourceModifiedAccessConditions\.SourceIfUnmodifiedSince\.Format\(time\.RFC1123\)\}/g, + `req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)}`). + replace (/req\.Raw\(\)\.Header\[\"x-ms-immutability-policy-until-date\"\]\s+=\s+\[\]string\{options\.ImmutabilityPolicyExpiry\.Format\(time\.RFC1123\)\}/g, + `req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}`); + diff --git a/sdk/storage/azdatalake/internal/generated/filesystem_client.go b/sdk/storage/azdatalake/internal/generated/filesystem_client.go new file mode 100644 index 000000000000..27c60f60cbcb --- /dev/null +++ b/sdk/storage/azdatalake/internal/generated/filesystem_client.go @@ -0,0 +1,23 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package generated + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "time" +) + +func (client *FileSystemClient) Endpoint() string { + return client.endpoint +} + +func (client *FileSystemClient) Pipeline() runtime.Pipeline { + return client.internal.Pipeline() +} + +// used to convert times from UTC to GMT before sending across the wire +var gmt = time.FixedZone("GMT", 0) diff --git a/sdk/storage/azdatalake/internal/generated/path_client.go b/sdk/storage/azdatalake/internal/generated/path_client.go new file mode 100644 index 000000000000..3de3766c9850 --- /dev/null +++ b/sdk/storage/azdatalake/internal/generated/path_client.go @@ -0,0 +1,17 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package generated + +import "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + +func (client *PathClient) Endpoint() string { + return client.endpoint +} + +func (client *PathClient) Pipeline() runtime.Pipeline { + return client.internal.Pipeline() +} diff --git a/sdk/storage/azdatalake/internal/generated/service_client.go b/sdk/storage/azdatalake/internal/generated/service_client.go new file mode 100644 index 000000000000..22f11c20a9fd --- /dev/null +++ b/sdk/storage/azdatalake/internal/generated/service_client.go @@ -0,0 +1,17 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package generated + +import "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + +func (client *ServiceClient) Endpoint() string { + return client.endpoint +} + +func (client *ServiceClient) Pipeline() runtime.Pipeline { + return client.internal.Pipeline() +} diff --git a/sdk/storage/azdatalake/internal/generated/zz_constants.go b/sdk/storage/azdatalake/internal/generated/zz_constants.go index ce7c1ce6f3b9..bfb6f9ceee76 100644 --- a/sdk/storage/azdatalake/internal/generated/zz_constants.go +++ b/sdk/storage/azdatalake/internal/generated/zz_constants.go @@ -9,6 +9,40 @@ package generated +type EncryptionAlgorithmType string + +const ( + EncryptionAlgorithmTypeAES256 EncryptionAlgorithmType = "AES256" + EncryptionAlgorithmTypeNone EncryptionAlgorithmType = "None" +) + +// PossibleEncryptionAlgorithmTypeValues returns the possible values for the EncryptionAlgorithmType const type. +func PossibleEncryptionAlgorithmTypeValues() []EncryptionAlgorithmType { + return []EncryptionAlgorithmType{ + EncryptionAlgorithmTypeAES256, + EncryptionAlgorithmTypeNone, + } +} + +type ExpiryOptions string + +const ( + ExpiryOptionsAbsolute ExpiryOptions = "Absolute" + ExpiryOptionsNeverExpire ExpiryOptions = "NeverExpire" + ExpiryOptionsRelativeToCreation ExpiryOptions = "RelativeToCreation" + ExpiryOptionsRelativeToNow ExpiryOptions = "RelativeToNow" +) + +// PossibleExpiryOptionsValues returns the possible values for the ExpiryOptions const type. +func PossibleExpiryOptionsValues() []ExpiryOptions { + return []ExpiryOptions{ + ExpiryOptionsAbsolute, + ExpiryOptionsNeverExpire, + ExpiryOptionsRelativeToCreation, + ExpiryOptionsRelativeToNow, + } +} + type ListBlobsIncludeItem string const ( @@ -16,9 +50,9 @@ const ( ListBlobsIncludeItemDeleted ListBlobsIncludeItem = "deleted" ListBlobsIncludeItemMetadata ListBlobsIncludeItem = "metadata" ListBlobsIncludeItemSnapshots ListBlobsIncludeItem = "snapshots" + ListBlobsIncludeItemTags ListBlobsIncludeItem = "tags" ListBlobsIncludeItemUncommittedblobs ListBlobsIncludeItem = "uncommittedblobs" ListBlobsIncludeItemVersions ListBlobsIncludeItem = "versions" - ListBlobsIncludeItemTags ListBlobsIncludeItem = "tags" ) // PossibleListBlobsIncludeItemValues returns the possible values for the ListBlobsIncludeItem const type. @@ -28,9 +62,9 @@ func PossibleListBlobsIncludeItemValues() []ListBlobsIncludeItem { ListBlobsIncludeItemDeleted, ListBlobsIncludeItemMetadata, ListBlobsIncludeItemSnapshots, + ListBlobsIncludeItemTags, ListBlobsIncludeItemUncommittedblobs, ListBlobsIncludeItemVersions, - ListBlobsIncludeItemTags, } } @@ -74,8 +108,8 @@ const ( PathLeaseActionAcquire PathLeaseAction = "acquire" PathLeaseActionBreak PathLeaseAction = "break" PathLeaseActionChange PathLeaseAction = "change" - PathLeaseActionRenew PathLeaseAction = "renew" PathLeaseActionRelease PathLeaseAction = "release" + PathLeaseActionRenew PathLeaseAction = "renew" ) // PossiblePathLeaseActionValues returns the possible values for the PathLeaseAction const type. @@ -84,8 +118,8 @@ func PossiblePathLeaseActionValues() []PathLeaseAction { PathLeaseActionAcquire, PathLeaseActionBreak, PathLeaseActionChange, - PathLeaseActionRenew, PathLeaseActionRelease, + PathLeaseActionRenew, } } @@ -122,17 +156,17 @@ func PossiblePathResourceTypeValues() []PathResourceType { type PathSetAccessControlRecursiveMode string const ( - PathSetAccessControlRecursiveModeSet PathSetAccessControlRecursiveMode = "set" PathSetAccessControlRecursiveModeModify PathSetAccessControlRecursiveMode = "modify" PathSetAccessControlRecursiveModeRemove PathSetAccessControlRecursiveMode = "remove" + PathSetAccessControlRecursiveModeSet PathSetAccessControlRecursiveMode = "set" ) // PossiblePathSetAccessControlRecursiveModeValues returns the possible values for the PathSetAccessControlRecursiveMode const type. func PossiblePathSetAccessControlRecursiveModeValues() []PathSetAccessControlRecursiveMode { return []PathSetAccessControlRecursiveMode{ - PathSetAccessControlRecursiveModeSet, PathSetAccessControlRecursiveModeModify, PathSetAccessControlRecursiveModeRemove, + PathSetAccessControlRecursiveModeSet, } } @@ -141,9 +175,9 @@ type PathUpdateAction string const ( PathUpdateActionAppend PathUpdateAction = "append" PathUpdateActionFlush PathUpdateAction = "flush" - PathUpdateActionSetProperties PathUpdateAction = "setProperties" PathUpdateActionSetAccessControl PathUpdateAction = "setAccessControl" PathUpdateActionSetAccessControlRecursive PathUpdateAction = "setAccessControlRecursive" + PathUpdateActionSetProperties PathUpdateAction = "setProperties" ) // PossiblePathUpdateActionValues returns the possible values for the PathUpdateAction const type. @@ -151,8 +185,8 @@ func PossiblePathUpdateActionValues() []PathUpdateAction { return []PathUpdateAction{ PathUpdateActionAppend, PathUpdateActionFlush, - PathUpdateActionSetProperties, PathUpdateActionSetAccessControl, PathUpdateActionSetAccessControlRecursive, + PathUpdateActionSetProperties, } } diff --git a/sdk/storage/azdatalake/internal/generated/zz_filesystem_client.go b/sdk/storage/azdatalake/internal/generated/zz_filesystem_client.go index 900c08f05fa0..99894e0fc566 100644 --- a/sdk/storage/azdatalake/internal/generated/zz_filesystem_client.go +++ b/sdk/storage/azdatalake/internal/generated/zz_filesystem_client.go @@ -12,6 +12,7 @@ package generated import ( "context" "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" "net/http" @@ -21,21 +22,10 @@ import ( ) // FileSystemClient contains the methods for the FileSystem group. -// Don't use this type directly, use NewFileSystemClient() instead. +// Don't use this type directly, use a constructor function instead. type FileSystemClient struct { + internal *azcore.Client endpoint string - pl runtime.Pipeline -} - -// NewFileSystemClient creates a new instance of FileSystemClient with the specified values. -// - endpoint - The URL of the service account, container, or blob that is the target of the desired operation. -// - pl - the pipeline used for sending requests and handling responses. -func NewFileSystemClient(endpoint string, pl runtime.Pipeline) *FileSystemClient { - client := &FileSystemClient{ - endpoint: endpoint, - pl: pl, - } - return client } // Create - Create a FileSystem rooted at the specified location. If the FileSystem already exists, the operation fails. This @@ -49,7 +39,7 @@ func (client *FileSystemClient) Create(ctx context.Context, options *FileSystemC if err != nil { return FileSystemClientCreateResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return FileSystemClientCreateResponse{}, err } @@ -93,7 +83,7 @@ func (client *FileSystemClient) createHandleResponse(resp *http.Response) (FileS result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) @@ -133,7 +123,7 @@ func (client *FileSystemClient) Delete(ctx context.Context, options *FileSystemC if err != nil { return FileSystemClientDeleteResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return FileSystemClientDeleteResponse{}, err } @@ -160,10 +150,10 @@ func (client *FileSystemClient) deleteCreateRequest(ctx context.Context, options } req.Raw().Header["x-ms-version"] = []string{"2020-10-02"} if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil { - req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)} + req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil { - req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)} + req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)} } req.Raw().Header["Accept"] = []string{"application/json"} return req, nil @@ -199,7 +189,7 @@ func (client *FileSystemClient) GetProperties(ctx context.Context, options *File if err != nil { return FileSystemClientGetPropertiesResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return FileSystemClientGetPropertiesResponse{}, err } @@ -240,7 +230,7 @@ func (client *FileSystemClient) getPropertiesHandleResponse(resp *http.Response) result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) @@ -388,7 +378,7 @@ func (client *FileSystemClient) ListPathsHandleResponse(resp *http.Response) (Fi result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) @@ -427,7 +417,7 @@ func (client *FileSystemClient) SetProperties(ctx context.Context, options *File if err != nil { return FileSystemClientSetPropertiesResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return FileSystemClientSetPropertiesResponse{}, err } @@ -457,10 +447,10 @@ func (client *FileSystemClient) setPropertiesCreateRequest(ctx context.Context, req.Raw().Header["x-ms-properties"] = []string{*options.Properties} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil { - req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)} + req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil { - req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)} + req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)} } req.Raw().Header["Accept"] = []string{"application/json"} return req, nil @@ -477,7 +467,7 @@ func (client *FileSystemClient) setPropertiesHandleResponse(resp *http.Response) result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) diff --git a/sdk/storage/azdatalake/internal/generated/zz_models.go b/sdk/storage/azdatalake/internal/generated/zz_models.go index 1edd40a69a4a..b9c912bcd46b 100644 --- a/sdk/storage/azdatalake/internal/generated/zz_models.go +++ b/sdk/storage/azdatalake/internal/generated/zz_models.go @@ -9,12 +9,15 @@ package generated -import "time" +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "time" +) type ACLFailedEntry struct { - ErrorMessage *string `json:"errorMessage,omitempty"` - Name *string `json:"name,omitempty"` - Type *string `json:"type,omitempty"` + ErrorMessage *string + Name *string + Type *string } type BlobHierarchyListSegment struct { @@ -49,7 +52,7 @@ type BlobPrefix struct { // BlobPropertiesInternal - Properties of a blob type BlobPropertiesInternal struct { // REQUIRED - Etag *string `xml:"Etag"` + ETag *azcore.ETag `xml:"Etag"` // REQUIRED LastModified *time.Time `xml:"Last-Modified"` @@ -87,11 +90,11 @@ type BlobPropertiesInternal struct { TagCount *int32 `xml:"TagCount"` } -// CpkInfo contains a group of parameters for the PathClient.Create method. -type CpkInfo struct { +// CPKInfo contains a group of parameters for the PathClient.Create method. +type CPKInfo struct { // 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.. Specifying any value will set the value to AES256. - EncryptionAlgorithm *string + // if the x-ms-encryption-key header is provided. + EncryptionAlgorithm *EncryptionAlgorithmType // Optional. Specifies the encryption key to use to encrypt the data provided in the request. If not specified, encryption // is performed with the root account encryption key. For more information, see // Encryption at Rest for Azure Storage Services. @@ -101,9 +104,9 @@ type CpkInfo struct { } type FileSystem struct { - ETag *string `json:"eTag,omitempty"` - LastModified *string `json:"lastModified,omitempty"` - Name *string `json:"name,omitempty"` + ETag *string + LastModified *string + Name *string } // FileSystemClientCreateOptions contains the optional parameters for the FileSystemClient.Create method. @@ -218,7 +221,7 @@ type FileSystemClientSetPropertiesOptions struct { } type FileSystemList struct { - Filesystems []*FileSystem `json:"filesystems,omitempty"` + Filesystems []*FileSystem } // LeaseAccessConditions contains a group of parameters for the PathClient.Create method. @@ -247,29 +250,29 @@ type ListBlobsHierarchySegmentResponse struct { // ModifiedAccessConditions contains a group of parameters for the FileSystemClient.SetProperties method. type ModifiedAccessConditions struct { // Specify an ETag value to operate only on blobs with a matching value. - IfMatch *string + IfMatch *azcore.ETag // Specify this header value to operate only on a blob if it has been modified since the specified date/time. IfModifiedSince *time.Time // Specify an ETag value to operate only on blobs without a matching value. - IfNoneMatch *string + IfNoneMatch *azcore.ETag // Specify this header value to operate only on a blob if it has not been modified since the specified date/time. IfUnmodifiedSince *time.Time } type Path struct { - ContentLength *int64 `json:"contentLength,omitempty"` - CreationTime *string `json:"creationTime,omitempty"` - ETag *string `json:"eTag,omitempty"` + ContentLength *int64 + CreationTime *string + ETag *string // The name of the encryption scope under which the blob is encrypted. - EncryptionScope *string `json:"EncryptionScope,omitempty"` - ExpiryTime *string `json:"expiryTime,omitempty"` - Group *string `json:"group,omitempty"` - IsDirectory *bool `json:"isDirectory,omitempty"` - LastModified *string `json:"lastModified,omitempty"` - Name *string `json:"name,omitempty"` - Owner *string `json:"owner,omitempty"` - Permissions *string `json:"permissions,omitempty"` + EncryptionScope *string + ExpiryTime *string + Group *string + IsDirectory *bool + LastModified *string + Name *string + Owner *string + Permissions *string } // PathClientAppendDataOptions contains the optional parameters for the PathClient.AppendData method. @@ -297,14 +300,29 @@ type PathClientAppendDataOptions struct { // PathClientCreateOptions contains the optional parameters for the PathClient.Create method. type PathClientCreateOptions struct { + // Sets POSIX access control rights on files and directories. The value is a comma-separated list of access control entries. + // Each access control entry (ACE) consists of a scope, a type, a user or group + // identifier, and permissions in the format "[scope:][type]:[id]:[permissions]". + ACL *string // Optional. When deleting a directory, the number of paths that are deleted with each invocation is limited. If the number // of paths to be deleted exceeds this limit, a continuation token is returned in // this response header. When a continuation token is returned in the response, it must be specified in a subsequent invocation // of the delete operation to continue deleting the directory. Continuation *string + // The time to set the blob to expiry + ExpiresOn *string + // Required. Indicates mode of the expiry time + ExpiryOptions *PathExpiryOptions + // Optional. The owning group of the blob or directory. + Group *string + // The lease duration is required to acquire a lease, and specifies the duration of the lease in seconds. The lease duration + // must be between 15 and 60 seconds or -1 for infinite lease. + LeaseDuration *int64 // Optional. Valid only when namespace is enabled. This parameter determines the behavior of the rename operation. The value // must be "legacy" or "posix", and the default value will be "posix". Mode *PathRenameMode + // Optional. The owner of the blob or directory. + Owner *string // Optional and only valid if Hierarchical Namespace is enabled for the account. Sets POSIX access permissions for the file // owner, the file owning group, and others. Each class may be granted read, // write, or execute permission. The sticky bit is also supported. Both symbolic (rwxrw-rw-) and 4-digit octal notation (e.g. @@ -317,6 +335,10 @@ type PathClientCreateOptions struct { // header is omitted. To merge new and existing properties, first get all existing properties and the current E-Tag, then // make a conditional request with the E-Tag and include values for all properties. Properties *string + // Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is + // not in the correct format. See Guid Constructor (String) for a list of valid GUID + // string formats. + ProposedLeaseID *string // An optional file or directory to be renamed. The value must have the following format: "/{filesystem}/{path}". If "x-ms-properties" // is specified, the properties will overwrite the existing properties; // otherwise, the existing properties will be preserved. This value must be a URL percent-encoded string. Note that the string @@ -430,9 +452,6 @@ type PathClientLeaseOptions struct { // The lease break period duration is optional to break a lease, and specifies the break period of the lease in seconds. The // lease break duration must be between 0 and 60 seconds. XMSLeaseBreakPeriod *int32 - // The lease duration is required to acquire a lease, and specifies the duration of the lease in seconds. The lease duration - // must be between 15 and 60 seconds or -1 for infinite lease. - XMSLeaseDuration *int32 } // PathClientReadOptions contains the optional parameters for the PathClient.Read method. @@ -622,7 +641,7 @@ type PathHTTPHeaders struct { } type PathList struct { - Paths []*Path `json:"paths,omitempty"` + Paths []*Path } // ServiceClientListFileSystemsOptions contains the optional parameters for the ServiceClient.NewListFileSystemsPager method. @@ -646,34 +665,34 @@ type ServiceClientListFileSystemsOptions struct { } type SetAccessControlRecursiveResponse struct { - DirectoriesSuccessful *int32 `json:"directoriesSuccessful,omitempty"` - FailedEntries []*ACLFailedEntry `json:"failedEntries,omitempty"` - FailureCount *int32 `json:"failureCount,omitempty"` - FilesSuccessful *int32 `json:"filesSuccessful,omitempty"` + DirectoriesSuccessful *int32 + FailedEntries []*ACLFailedEntry + FailureCount *int32 + FilesSuccessful *int32 } // SourceModifiedAccessConditions contains a group of parameters for the PathClient.Create method. type SourceModifiedAccessConditions struct { // Specify an ETag value to operate only on blobs with a matching value. - SourceIfMatch *string + SourceIfMatch *azcore.ETag // Specify this header value to operate only on a blob if it has been modified since the specified date/time. SourceIfModifiedSince *time.Time // Specify an ETag value to operate only on blobs without a matching value. - SourceIfNoneMatch *string + SourceIfNoneMatch *azcore.ETag // Specify this header value to operate only on a blob if it has not been modified since the specified date/time. SourceIfUnmodifiedSince *time.Time } type StorageError struct { // The service error response object. - Error *StorageErrorError `json:"error,omitempty"` + Error *StorageErrorError } // StorageErrorError - The service error response object. type StorageErrorError struct { // The service error code. - Code *string `json:"Code,omitempty"` + Code *string // The service error message. - Message *string `json:"Message,omitempty"` + Message *string } diff --git a/sdk/storage/azdatalake/internal/generated/zz_path_client.go b/sdk/storage/azdatalake/internal/generated/zz_path_client.go index 876f13e3f14d..4f3c3b3ba19f 100644 --- a/sdk/storage/azdatalake/internal/generated/zz_path_client.go +++ b/sdk/storage/azdatalake/internal/generated/zz_path_client.go @@ -12,6 +12,7 @@ package generated import ( "context" "encoding/base64" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" "io" @@ -21,21 +22,11 @@ import ( ) // PathClient contains the methods for the Path group. -// Don't use this type directly, use NewPathClient() instead. +// Don't use this type directly, use a constructor function instead. type PathClient struct { - endpoint string - pl runtime.Pipeline -} - -// NewPathClient creates a new instance of PathClient with the specified values. -// - endpoint - The URL of the service account, container, or blob that is the target of the desired operation. -// - pl - the pipeline used for sending requests and handling responses. -func NewPathClient(endpoint string, pl runtime.Pipeline) *PathClient { - client := &PathClient{ - endpoint: endpoint, - pl: pl, - } - return client + internal *azcore.Client + endpoint string + xmsLeaseDuration int32 } // AppendData - Append data to the file. @@ -46,13 +37,13 @@ func NewPathClient(endpoint string, pl runtime.Pipeline) *PathClient { // - options - PathClientAppendDataOptions contains the optional parameters for the PathClient.AppendData method. // - PathHTTPHeaders - PathHTTPHeaders contains a group of parameters for the PathClient.Create method. // - LeaseAccessConditions - LeaseAccessConditions contains a group of parameters for the PathClient.Create method. -// - CpkInfo - CpkInfo contains a group of parameters for the PathClient.Create method. -func (client *PathClient) AppendData(ctx context.Context, body io.ReadSeekCloser, options *PathClientAppendDataOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CpkInfo) (PathClientAppendDataResponse, error) { +// - CPKInfo - CPKInfo contains a group of parameters for the PathClient.Create method. +func (client *PathClient) AppendData(ctx context.Context, body io.ReadSeekCloser, options *PathClientAppendDataOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CPKInfo) (PathClientAppendDataResponse, error) { req, err := client.appendDataCreateRequest(ctx, body, options, pathHTTPHeaders, leaseAccessConditions, cpkInfo) if err != nil { return PathClientAppendDataResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientAppendDataResponse{}, err } @@ -63,7 +54,7 @@ func (client *PathClient) AppendData(ctx context.Context, body io.ReadSeekCloser } // appendDataCreateRequest creates the AppendData request. -func (client *PathClient) appendDataCreateRequest(ctx context.Context, body io.ReadSeekCloser, options *PathClientAppendDataOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CpkInfo) (*policy.Request, error) { +func (client *PathClient) appendDataCreateRequest(ctx context.Context, body io.ReadSeekCloser, options *PathClientAppendDataOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CPKInfo) (*policy.Request, error) { req, err := runtime.NewRequest(ctx, http.MethodPatch, client.endpoint) if err != nil { return nil, err @@ -100,10 +91,13 @@ func (client *PathClient) appendDataCreateRequest(ctx context.Context, body io.R req.Raw().Header["x-ms-encryption-key-sha256"] = []string{*cpkInfo.EncryptionKeySHA256} } if cpkInfo != nil && cpkInfo.EncryptionAlgorithm != nil { - req.Raw().Header["x-ms-encryption-algorithm"] = []string{"AES256"} + req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)} } req.Raw().Header["Accept"] = []string{"application/json"} - return req, req.SetBody(body, "application/json") + if err := req.SetBody(body, "application/json"); err != nil { + return nil, err + } + return req, nil } // appendDataHandleResponse handles the AppendData response. @@ -126,7 +120,7 @@ func (client *PathClient) appendDataHandleResponse(resp *http.Response) (PathCli result.Version = &val } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Content-MD5"); val != "" { contentMD5, err := base64.StdEncoding.DecodeString(val) @@ -136,11 +130,11 @@ func (client *PathClient) appendDataHandleResponse(resp *http.Response) (PathCli result.ContentMD5 = contentMD5 } if val := resp.Header.Get("x-ms-content-crc64"); val != "" { - xMSContentCRC64, err := base64.StdEncoding.DecodeString(val) + contentCRC64, err := base64.StdEncoding.DecodeString(val) if err != nil { return PathClientAppendDataResponse{}, err } - result.XMSContentCRC64 = xMSContentCRC64 + result.ContentCRC64 = contentCRC64 } if val := resp.Header.Get("x-ms-request-server-encrypted"); val != "" { isServerEncrypted, err := strconv.ParseBool(val) @@ -171,13 +165,13 @@ func (client *PathClient) appendDataHandleResponse(resp *http.Response) (PathCli // method. // - SourceModifiedAccessConditions - SourceModifiedAccessConditions contains a group of parameters for the PathClient.Create // method. -// - CpkInfo - CpkInfo contains a group of parameters for the PathClient.Create method. -func (client *PathClient) Create(ctx context.Context, options *PathClientCreateOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, sourceModifiedAccessConditions *SourceModifiedAccessConditions, cpkInfo *CpkInfo) (PathClientCreateResponse, error) { +// - CPKInfo - CPKInfo contains a group of parameters for the PathClient.Create method. +func (client *PathClient) Create(ctx context.Context, options *PathClientCreateOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, sourceModifiedAccessConditions *SourceModifiedAccessConditions, cpkInfo *CPKInfo) (PathClientCreateResponse, error) { req, err := client.createCreateRequest(ctx, options, pathHTTPHeaders, leaseAccessConditions, modifiedAccessConditions, sourceModifiedAccessConditions, cpkInfo) if err != nil { return PathClientCreateResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientCreateResponse{}, err } @@ -188,7 +182,7 @@ func (client *PathClient) Create(ctx context.Context, options *PathClientCreateO } // createCreateRequest creates the Create request. -func (client *PathClient) createCreateRequest(ctx context.Context, options *PathClientCreateOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, sourceModifiedAccessConditions *SourceModifiedAccessConditions, cpkInfo *CpkInfo) (*policy.Request, error) { +func (client *PathClient) createCreateRequest(ctx context.Context, options *PathClientCreateOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, sourceModifiedAccessConditions *SourceModifiedAccessConditions, cpkInfo *CPKInfo) (*policy.Request, error) { req, err := runtime.NewRequest(ctx, http.MethodPut, client.endpoint) if err != nil { return nil, err @@ -245,10 +239,10 @@ func (client *PathClient) createCreateRequest(ctx context.Context, options *Path req.Raw().Header["x-ms-umask"] = []string{*options.Umask} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil { - req.Raw().Header["If-Match"] = []string{*modifiedAccessConditions.IfMatch} + req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil { - req.Raw().Header["If-None-Match"] = []string{*modifiedAccessConditions.IfNoneMatch} + req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil { req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)} @@ -257,10 +251,10 @@ func (client *PathClient) createCreateRequest(ctx context.Context, options *Path req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)} } if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfMatch != nil { - req.Raw().Header["x-ms-source-if-match"] = []string{*sourceModifiedAccessConditions.SourceIfMatch} + req.Raw().Header["x-ms-source-if-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfMatch)} } if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfNoneMatch != nil { - req.Raw().Header["x-ms-source-if-none-match"] = []string{*sourceModifiedAccessConditions.SourceIfNoneMatch} + req.Raw().Header["x-ms-source-if-none-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfNoneMatch)} } if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfModifiedSince != nil { req.Raw().Header["x-ms-source-if-modified-since"] = []string{sourceModifiedAccessConditions.SourceIfModifiedSince.Format(time.RFC1123)} @@ -275,7 +269,28 @@ func (client *PathClient) createCreateRequest(ctx context.Context, options *Path req.Raw().Header["x-ms-encryption-key-sha256"] = []string{*cpkInfo.EncryptionKeySHA256} } if cpkInfo != nil && cpkInfo.EncryptionAlgorithm != nil { - req.Raw().Header["x-ms-encryption-algorithm"] = []string{"AES256"} + req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)} + } + if options != nil && options.Owner != nil { + req.Raw().Header["x-ms-owner"] = []string{*options.Owner} + } + if options != nil && options.Group != nil { + req.Raw().Header["x-ms-group"] = []string{*options.Group} + } + if options != nil && options.ACL != nil { + req.Raw().Header["x-ms-acl"] = []string{*options.ACL} + } + if options != nil && options.ProposedLeaseID != nil { + req.Raw().Header["x-ms-proposed-lease-id"] = []string{*options.ProposedLeaseID} + } + if options != nil && options.LeaseDuration != nil { + req.Raw().Header["x-ms-lease-duration"] = []string{strconv.FormatInt(*options.LeaseDuration, 10)} + } + if options != nil && options.ExpiryOptions != nil { + req.Raw().Header["x-ms-expiry-option"] = []string{string(*options.ExpiryOptions)} + } + if options != nil && options.ExpiresOn != nil { + req.Raw().Header["x-ms-expiry-time"] = []string{*options.ExpiresOn} } req.Raw().Header["Accept"] = []string{"application/json"} return req, nil @@ -292,7 +307,7 @@ func (client *PathClient) createHandleResponse(resp *http.Response) (PathClientC result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) @@ -345,7 +360,7 @@ func (client *PathClient) Delete(ctx context.Context, options *PathClientDeleteO if err != nil { return PathClientDeleteResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientDeleteResponse{}, err } @@ -380,10 +395,10 @@ func (client *PathClient) deleteCreateRequest(ctx context.Context, options *Path req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil { - req.Raw().Header["If-Match"] = []string{*modifiedAccessConditions.IfMatch} + req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil { - req.Raw().Header["If-None-Match"] = []string{*modifiedAccessConditions.IfNoneMatch} + req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil { req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)} @@ -429,13 +444,13 @@ func (client *PathClient) deleteHandleResponse(resp *http.Response) (PathClientD // - LeaseAccessConditions - LeaseAccessConditions contains a group of parameters for the PathClient.Create method. // - ModifiedAccessConditions - ModifiedAccessConditions contains a group of parameters for the FileSystemClient.SetProperties // method. -// - CpkInfo - CpkInfo contains a group of parameters for the PathClient.Create method. -func (client *PathClient) FlushData(ctx context.Context, options *PathClientFlushDataOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, cpkInfo *CpkInfo) (PathClientFlushDataResponse, error) { +// - CPKInfo - CPKInfo contains a group of parameters for the PathClient.Create method. +func (client *PathClient) FlushData(ctx context.Context, options *PathClientFlushDataOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, cpkInfo *CPKInfo) (PathClientFlushDataResponse, error) { req, err := client.flushDataCreateRequest(ctx, options, pathHTTPHeaders, leaseAccessConditions, modifiedAccessConditions, cpkInfo) if err != nil { return PathClientFlushDataResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientFlushDataResponse{}, err } @@ -446,7 +461,7 @@ func (client *PathClient) FlushData(ctx context.Context, options *PathClientFlus } // flushDataCreateRequest creates the FlushData request. -func (client *PathClient) flushDataCreateRequest(ctx context.Context, options *PathClientFlushDataOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, cpkInfo *CpkInfo) (*policy.Request, error) { +func (client *PathClient) flushDataCreateRequest(ctx context.Context, options *PathClientFlushDataOptions, pathHTTPHeaders *PathHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, cpkInfo *CPKInfo) (*policy.Request, error) { req, err := runtime.NewRequest(ctx, http.MethodPatch, client.endpoint) if err != nil { return nil, err @@ -491,10 +506,10 @@ func (client *PathClient) flushDataCreateRequest(ctx context.Context, options *P req.Raw().Header["x-ms-content-language"] = []string{*pathHTTPHeaders.ContentLanguage} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil { - req.Raw().Header["If-Match"] = []string{*modifiedAccessConditions.IfMatch} + req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil { - req.Raw().Header["If-None-Match"] = []string{*modifiedAccessConditions.IfNoneMatch} + req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil { req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)} @@ -513,7 +528,7 @@ func (client *PathClient) flushDataCreateRequest(ctx context.Context, options *P req.Raw().Header["x-ms-encryption-key-sha256"] = []string{*cpkInfo.EncryptionKeySHA256} } if cpkInfo != nil && cpkInfo.EncryptionAlgorithm != nil { - req.Raw().Header["x-ms-encryption-algorithm"] = []string{"AES256"} + req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)} } req.Raw().Header["Accept"] = []string{"application/json"} return req, nil @@ -530,7 +545,7 @@ func (client *PathClient) flushDataHandleResponse(resp *http.Response) (PathClie result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) @@ -585,7 +600,7 @@ func (client *PathClient) GetProperties(ctx context.Context, options *PathClient if err != nil { return PathClientGetPropertiesResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientGetPropertiesResponse{}, err } @@ -620,10 +635,10 @@ func (client *PathClient) getPropertiesCreateRequest(ctx context.Context, option req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil { - req.Raw().Header["If-Match"] = []string{*modifiedAccessConditions.IfMatch} + req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil { - req.Raw().Header["If-None-Match"] = []string{*modifiedAccessConditions.IfNoneMatch} + req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil { req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)} @@ -677,7 +692,7 @@ func (client *PathClient) getPropertiesHandleResponse(resp *http.Response) (Path result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) @@ -746,7 +761,7 @@ func (client *PathClient) Lease(ctx context.Context, xmsLeaseAction PathLeaseAct if err != nil { return PathClientLeaseResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientLeaseResponse{}, err } @@ -772,9 +787,7 @@ func (client *PathClient) leaseCreateRequest(ctx context.Context, xmsLeaseAction } req.Raw().Header["x-ms-version"] = []string{"2020-10-02"} req.Raw().Header["x-ms-lease-action"] = []string{string(xmsLeaseAction)} - if options != nil && options.XMSLeaseDuration != nil { - req.Raw().Header["x-ms-lease-duration"] = []string{strconv.FormatInt(int64(*options.XMSLeaseDuration), 10)} - } + req.Raw().Header["x-ms-lease-duration"] = []string{strconv.FormatInt(int64(client.xmsLeaseDuration), 10)} if options != nil && options.XMSLeaseBreakPeriod != nil { req.Raw().Header["x-ms-lease-break-period"] = []string{strconv.FormatInt(int64(*options.XMSLeaseBreakPeriod), 10)} } @@ -785,10 +798,10 @@ func (client *PathClient) leaseCreateRequest(ctx context.Context, xmsLeaseAction req.Raw().Header["x-ms-proposed-lease-id"] = []string{*options.ProposedLeaseID} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil { - req.Raw().Header["If-Match"] = []string{*modifiedAccessConditions.IfMatch} + req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil { - req.Raw().Header["If-None-Match"] = []string{*modifiedAccessConditions.IfNoneMatch} + req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil { req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)} @@ -811,7 +824,7 @@ func (client *PathClient) leaseHandleResponse(resp *http.Response) (PathClientLe result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) @@ -845,13 +858,13 @@ func (client *PathClient) leaseHandleResponse(resp *http.Response) (PathClientLe // - LeaseAccessConditions - LeaseAccessConditions contains a group of parameters for the PathClient.Create method. // - ModifiedAccessConditions - ModifiedAccessConditions contains a group of parameters for the FileSystemClient.SetProperties // method. -// - CpkInfo - CpkInfo contains a group of parameters for the PathClient.Create method. -func (client *PathClient) Read(ctx context.Context, options *PathClientReadOptions, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, cpkInfo *CpkInfo) (PathClientReadResponse, error) { +// - CPKInfo - CPKInfo contains a group of parameters for the PathClient.Create method. +func (client *PathClient) Read(ctx context.Context, options *PathClientReadOptions, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, cpkInfo *CPKInfo) (PathClientReadResponse, error) { req, err := client.readCreateRequest(ctx, options, leaseAccessConditions, modifiedAccessConditions, cpkInfo) if err != nil { return PathClientReadResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientReadResponse{}, err } @@ -862,7 +875,7 @@ func (client *PathClient) Read(ctx context.Context, options *PathClientReadOptio } // readCreateRequest creates the Read request. -func (client *PathClient) readCreateRequest(ctx context.Context, options *PathClientReadOptions, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, cpkInfo *CpkInfo) (*policy.Request, error) { +func (client *PathClient) readCreateRequest(ctx context.Context, options *PathClientReadOptions, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions, cpkInfo *CPKInfo) (*policy.Request, error) { req, err := runtime.NewRequest(ctx, http.MethodGet, client.endpoint) if err != nil { return nil, err @@ -887,10 +900,10 @@ func (client *PathClient) readCreateRequest(ctx context.Context, options *PathCl req.Raw().Header["x-ms-range-get-content-md5"] = []string{strconv.FormatBool(*options.XMSRangeGetContentMD5)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil { - req.Raw().Header["If-Match"] = []string{*modifiedAccessConditions.IfMatch} + req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil { - req.Raw().Header["If-None-Match"] = []string{*modifiedAccessConditions.IfNoneMatch} + req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil { req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)} @@ -905,7 +918,7 @@ func (client *PathClient) readCreateRequest(ctx context.Context, options *PathCl req.Raw().Header["x-ms-encryption-key-sha256"] = []string{*cpkInfo.EncryptionKeySHA256} } if cpkInfo != nil && cpkInfo.EncryptionAlgorithm != nil { - req.Raw().Header["x-ms-encryption-algorithm"] = []string{"AES256"} + req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)} } req.Raw().Header["Accept"] = []string{"application/json"} return req, nil @@ -953,7 +966,7 @@ func (client *PathClient) readHandleResponse(resp *http.Response) (PathClientRea result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) @@ -1012,7 +1025,7 @@ func (client *PathClient) SetAccessControl(ctx context.Context, options *PathCli if err != nil { return PathClientSetAccessControlResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientSetAccessControlResponse{}, err } @@ -1050,10 +1063,10 @@ func (client *PathClient) setAccessControlCreateRequest(ctx context.Context, opt req.Raw().Header["x-ms-acl"] = []string{*options.ACL} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil { - req.Raw().Header["If-Match"] = []string{*modifiedAccessConditions.IfMatch} + req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil { - req.Raw().Header["If-None-Match"] = []string{*modifiedAccessConditions.IfNoneMatch} + req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil { req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)} @@ -1080,7 +1093,7 @@ func (client *PathClient) setAccessControlHandleResponse(resp *http.Response) (P result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) @@ -1115,7 +1128,7 @@ func (client *PathClient) SetAccessControlRecursive(ctx context.Context, mode Pa if err != nil { return PathClientSetAccessControlRecursiveResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientSetAccessControlRecursiveResponse{}, err } @@ -1192,12 +1205,12 @@ func (client *PathClient) setAccessControlRecursiveHandleResponse(resp *http.Res // Generated from API version 2020-10-02 // - expiryOptions - Required. Indicates mode of the expiry time // - options - PathClientSetExpiryOptions contains the optional parameters for the PathClient.SetExpiry method. -func (client *PathClient) SetExpiry(ctx context.Context, expiryOptions PathExpiryOptions, options *PathClientSetExpiryOptions) (PathClientSetExpiryResponse, error) { +func (client *PathClient) SetExpiry(ctx context.Context, expiryOptions ExpiryOptions, options *PathClientSetExpiryOptions) (PathClientSetExpiryResponse, error) { req, err := client.setExpiryCreateRequest(ctx, expiryOptions, options) if err != nil { return PathClientSetExpiryResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientSetExpiryResponse{}, err } @@ -1208,7 +1221,7 @@ func (client *PathClient) SetExpiry(ctx context.Context, expiryOptions PathExpir } // setExpiryCreateRequest creates the SetExpiry request. -func (client *PathClient) setExpiryCreateRequest(ctx context.Context, expiryOptions PathExpiryOptions, options *PathClientSetExpiryOptions) (*policy.Request, error) { +func (client *PathClient) setExpiryCreateRequest(ctx context.Context, expiryOptions ExpiryOptions, options *PathClientSetExpiryOptions) (*policy.Request, error) { req, err := runtime.NewRequest(ctx, http.MethodPut, client.endpoint) if err != nil { return nil, err @@ -1235,7 +1248,7 @@ func (client *PathClient) setExpiryCreateRequest(ctx context.Context, expiryOpti func (client *PathClient) setExpiryHandleResponse(resp *http.Response) (PathClientSetExpiryResponse, error) { result := PathClientSetExpiryResponse{} if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) @@ -1273,7 +1286,7 @@ func (client *PathClient) Undelete(ctx context.Context, options *PathClientUndel if err != nil { return PathClientUndeleteResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientUndeleteResponse{}, err } @@ -1360,7 +1373,7 @@ func (client *PathClient) Update(ctx context.Context, action PathUpdateAction, m if err != nil { return PathClientUpdateResponse{}, err } - resp, err := client.pl.Do(req) + resp, err := client.internal.Pipeline().Do(req) if err != nil { return PathClientUpdateResponse{}, err } @@ -1445,10 +1458,10 @@ func (client *PathClient) updateCreateRequest(ctx context.Context, action PathUp req.Raw().Header["x-ms-acl"] = []string{*options.ACL} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil { - req.Raw().Header["If-Match"] = []string{*modifiedAccessConditions.IfMatch} + req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil { - req.Raw().Header["If-None-Match"] = []string{*modifiedAccessConditions.IfNoneMatch} + req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)} } if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil { req.Raw().Header["If-Modified-Since"] = []string{modifiedAccessConditions.IfModifiedSince.Format(time.RFC1123)} @@ -1457,7 +1470,10 @@ func (client *PathClient) updateCreateRequest(ctx context.Context, action PathUp req.Raw().Header["If-Unmodified-Since"] = []string{modifiedAccessConditions.IfUnmodifiedSince.Format(time.RFC1123)} } req.Raw().Header["Accept"] = []string{"application/json"} - return req, req.SetBody(body, "application/octet-stream") + if err := req.SetBody(body, "application/octet-stream"); err != nil { + return nil, err + } + return req, nil } // updateHandleResponse handles the Update response. @@ -1471,7 +1487,7 @@ func (client *PathClient) updateHandleResponse(resp *http.Response) (PathClientU result.Date = &date } if val := resp.Header.Get("ETag"); val != "" { - result.ETag = &val + result.ETag = (*azcore.ETag)(&val) } if val := resp.Header.Get("Last-Modified"); val != "" { lastModified, err := time.Parse(time.RFC1123, val) diff --git a/sdk/storage/azdatalake/internal/generated/zz_response_types.go b/sdk/storage/azdatalake/internal/generated/zz_response_types.go index e95f5035e654..0c55d6312788 100644 --- a/sdk/storage/azdatalake/internal/generated/zz_response_types.go +++ b/sdk/storage/azdatalake/internal/generated/zz_response_types.go @@ -10,6 +10,7 @@ package generated import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "io" "time" ) @@ -23,7 +24,7 @@ type FileSystemClientCreateResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // LastModified contains the information returned from the Last-Modified header response. LastModified *time.Time @@ -53,7 +54,7 @@ type FileSystemClientGetPropertiesResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // LastModified contains the information returned from the Last-Modified header response. LastModified *time.Time @@ -100,7 +101,7 @@ type FileSystemClientListPathsResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // LastModified contains the information returned from the Last-Modified header response. LastModified *time.Time @@ -118,7 +119,7 @@ type FileSystemClientSetPropertiesResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // LastModified contains the information returned from the Last-Modified header response. LastModified *time.Time @@ -135,6 +136,9 @@ type PathClientAppendDataResponse struct { // ClientRequestID contains the information returned from the x-ms-client-request-id header response. ClientRequestID *string + // ContentCRC64 contains the information returned from the x-ms-content-crc64 header response. + ContentCRC64 []byte + // ContentMD5 contains the information returned from the Content-MD5 header response. ContentMD5 []byte @@ -142,7 +146,7 @@ type PathClientAppendDataResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // EncryptionKeySHA256 contains the information returned from the x-ms-encryption-key-sha256 header response. EncryptionKeySHA256 *string @@ -155,9 +159,6 @@ type PathClientAppendDataResponse struct { // Version contains the information returned from the x-ms-version header response. Version *string - - // XMSContentCRC64 contains the information returned from the x-ms-content-crc64 header response. - XMSContentCRC64 []byte } // PathClientCreateResponse contains the response from method PathClient.Create. @@ -172,7 +173,7 @@ type PathClientCreateResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // EncryptionKeySHA256 contains the information returned from the x-ms-encryption-key-sha256 header response. EncryptionKeySHA256 *string @@ -220,7 +221,7 @@ type PathClientFlushDataResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // EncryptionKeySHA256 contains the information returned from the x-ms-encryption-key-sha256 header response. EncryptionKeySHA256 *string @@ -274,7 +275,7 @@ type PathClientGetPropertiesResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // Group contains the information returned from the x-ms-group header response. Group *string @@ -316,7 +317,7 @@ type PathClientLeaseResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // LastModified contains the information returned from the Last-Modified header response. LastModified *time.Time @@ -370,7 +371,7 @@ type PathClientReadResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // EncryptionKeySHA256 contains the information returned from the x-ms-encryption-key-sha256 header response. EncryptionKeySHA256 *string @@ -434,7 +435,7 @@ type PathClientSetAccessControlResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // LastModified contains the information returned from the Last-Modified header response. LastModified *time.Time @@ -455,7 +456,7 @@ type PathClientSetExpiryResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // LastModified contains the information returned from the Last-Modified header response. LastModified *time.Time @@ -519,7 +520,7 @@ type PathClientUpdateResponse struct { Date *time.Time // ETag contains the information returned from the ETag header response. - ETag *string + ETag *azcore.ETag // LastModified contains the information returned from the Last-Modified header response. LastModified *time.Time diff --git a/sdk/storage/azdatalake/internal/generated/zz_service_client.go b/sdk/storage/azdatalake/internal/generated/zz_service_client.go index 40654cbdefbe..f4322dd4f3fd 100644 --- a/sdk/storage/azdatalake/internal/generated/zz_service_client.go +++ b/sdk/storage/azdatalake/internal/generated/zz_service_client.go @@ -11,29 +11,20 @@ package generated import ( "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" "net/http" "strconv" + "strings" "time" ) // ServiceClient contains the methods for the Service group. -// Don't use this type directly, use NewServiceClient() instead. +// Don't use this type directly, use a constructor function instead. type ServiceClient struct { + internal *azcore.Client endpoint string - pl runtime.Pipeline -} - -// NewServiceClient creates a new instance of ServiceClient with the specified values. -// - endpoint - The URL of the service account, container, or blob that is the target of the desired operation. -// - pl - the pipeline used for sending requests and handling responses. -func NewServiceClient(endpoint string, pl runtime.Pipeline) *ServiceClient { - client := &ServiceClient{ - endpoint: endpoint, - pl: pl, - } - return client } // NewListFileSystemsPager - List filesystems and their properties in given account. @@ -62,7 +53,7 @@ func (client *FileSystemClient) ListFileSystemsCreateRequest(ctx context.Context if options != nil && options.Timeout != nil { reqQP.Set("timeout", strconv.FormatInt(int64(*options.Timeout), 10)) } - req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().URL.RawQuery = strings.Replace(reqQP.Encode(), "+", "%20", -1) if options != nil && options.RequestID != nil { req.Raw().Header["x-ms-client-request-id"] = []string{*options.RequestID} } diff --git a/sdk/storage/azdatalake/internal/path/client.go b/sdk/storage/azdatalake/internal/path/client.go new file mode 100644 index 000000000000..bfeab81bcbcc --- /dev/null +++ b/sdk/storage/azdatalake/internal/path/client.go @@ -0,0 +1,71 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package path + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/base" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" +) + +// Client represents a URL to the Azure Datalake Storage service allowing you to manipulate paths. +type Client base.Client[generated.PathClient] + +func (p *Client) generated() *generated.PathClient { + return base.InnerClient((*base.Client[generated.PathClient])(p)) +} + +func (p *Client) sharedKey() *exported.SharedKeyCredential { + return base.SharedKey((*base.Client[generated.PathClient])(p)) +} + +// URL returns the URL endpoint used by the Client object. +func (p *Client) URL() string { + return "s.generated().Endpoint()" +} + +// SetAccessControl sets the owner, owning group, and permissions for a file or directory (dfs1). +func (p *Client) SetAccessControl(ctx context.Context, options *SetAccessControlOptions) (SetAccessControlResponse, error) { + return SetAccessControlResponse{}, nil +} + +// SetAccessControlRecursive sets the owner, owning group, and permissions for a file or directory (dfs1). +func (p *Client) SetAccessControlRecursive(ctx context.Context, options *SetAccessControlRecursiveOptions) (SetAccessControlRecursiveResponse, error) { + // TODO explicitly pass SetAccessControlRecursiveMode + return SetAccessControlRecursiveResponse{}, nil +} + +// UpdateAccessControlRecursive updates the owner, owning group, and permissions for a file or directory (dfs1). +func (p *Client) UpdateAccessControlRecursive(ctx context.Context, options *UpdateAccessControlRecursiveOptions) (UpdateAccessControlRecursiveResponse, error) { + // TODO explicitly pass SetAccessControlRecursiveMode + return SetAccessControlRecursiveResponse{}, nil +} + +// GetAccessControl gets the owner, owning group, and permissions for a file or directory (dfs1). +func (p *Client) GetAccessControl(ctx context.Context, options *GetAccessControlOptions) (GetAccessControlResponse, error) { + return GetAccessControlResponse{}, nil +} + +// RemoveAccessControlRecursive removes the owner, owning group, and permissions for a file or directory (dfs1). +func (p *Client) RemoveAccessControlRecursive(ctx context.Context, options *RemoveAccessControlRecursiveOptions) (RemoveAccessControlRecursiveResponse, error) { + // TODO explicitly pass SetAccessControlRecursiveMode + return SetAccessControlRecursiveResponse{}, nil +} + +// SetMetadata sets the metadata for a file or directory (blob3). +func (p *Client) SetMetadata(ctx context.Context, options *SetMetadataOptions) (SetMetadataResponse, error) { + // TODO: call directly into blob + return SetMetadataResponse{}, nil +} + +// SetHTTPHeaders sets the HTTP headers for a file or directory (blob3). +func (p *Client) SetHTTPHeaders(ctx context.Context, httpHeaders HTTPHeaders, options *SetHTTPHeadersOptions) (SetHTTPHeadersResponse, error) { + // TODO: call formatBlobHTTPHeaders() since we want to add the blob prefix to our options before calling into blob + // TODO: call into blob + return SetHTTPHeadersResponse{}, nil +} diff --git a/sdk/storage/azdatalake/internal/path/constants.go b/sdk/storage/azdatalake/internal/path/constants.go new file mode 100644 index 000000000000..d2d11defca1c --- /dev/null +++ b/sdk/storage/azdatalake/internal/path/constants.go @@ -0,0 +1,43 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package path + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" +) + +type ResourceType = generated.PathResourceType + +// TODO: consider the possibility of not exposing this and just pass it under the hood +const ( + ResourceTypeFile ResourceType = generated.PathResourceTypeFile + ResourceTypeDirectory ResourceType = generated.PathResourceTypeDirectory +) + +type RenameMode = generated.PathRenameMode + +// TODO: consider the possibility of not exposing this and just pass it under the hood +const ( + RenameModeLegacy RenameMode = generated.PathRenameModeLegacy + RenameModePosix RenameMode = generated.PathRenameModePosix +) + +type SetAccessControlRecursiveMode = generated.PathSetAccessControlRecursiveMode + +const ( + SetAccessControlRecursiveModeSet SetAccessControlRecursiveMode = generated.PathSetAccessControlRecursiveModeSet + SetAccessControlRecursiveModeModify SetAccessControlRecursiveMode = generated.PathSetAccessControlRecursiveModeModify + SetAccessControlRecursiveModeRemove SetAccessControlRecursiveMode = generated.PathSetAccessControlRecursiveModeRemove +) + +type EncryptionAlgorithmType = blob.EncryptionAlgorithmType + +const ( + EncryptionAlgorithmTypeNone EncryptionAlgorithmType = blob.EncryptionAlgorithmTypeNone + EncryptionAlgorithmTypeAES256 EncryptionAlgorithmType = blob.EncryptionAlgorithmTypeAES256 +) diff --git a/sdk/storage/azdatalake/internal/path/models.go b/sdk/storage/azdatalake/internal/path/models.go new file mode 100644 index 000000000000..75cca62c85c8 --- /dev/null +++ b/sdk/storage/azdatalake/internal/path/models.go @@ -0,0 +1,227 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package path + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/shared" +) + +// SetAccessControlOptions contains the optional parameters when calling the SetAccessControl operation. dfs endpoint +type SetAccessControlOptions struct { + // Owner is the owner of the path. + Owner *string + // Group is the owning group of the path. + Group *string + // ACL is the access control list for the path. + ACL *string + // Permissions is the octal representation of the permissions for user, group and mask. + Permissions *string + // AccessConditions contains parameters for accessing the path. + AccessConditions *azdatalake.AccessConditions +} + +func (o *SetAccessControlOptions) format() (*generated.PathClientSetAccessControlOptions, *generated.LeaseAccessConditions, *generated.ModifiedAccessConditions, error) { + if o == nil { + return nil, nil, nil, nil + } + // call path formatter since we're hitting dfs in this operation + leaseAccessConditions, modifiedAccessConditions := shared.FormatPathAccessConditions(o.AccessConditions) + return &generated.PathClientSetAccessControlOptions{ + Owner: o.Owner, + Group: o.Group, + ACL: o.ACL, + Permissions: o.Permissions, + }, leaseAccessConditions, modifiedAccessConditions, nil +} + +// GetAccessControlOptions contains the optional parameters when calling the GetAccessControl operation. +type GetAccessControlOptions struct { + // UPN is the user principal name. + UPN *bool + // AccessConditions contains parameters for accessing the path. + AccessConditions *azdatalake.AccessConditions +} + +func (o *GetAccessControlOptions) format() (*generated.PathClientGetPropertiesOptions, *generated.LeaseAccessConditions, *generated.ModifiedAccessConditions, error) { + action := generated.PathGetPropertiesActionGetAccessControl + if o == nil { + return &generated.PathClientGetPropertiesOptions{ + Action: &action, + }, nil, nil, nil + } + // call path formatter since we're hitting dfs in this operation + leaseAccessConditions, modifiedAccessConditions := shared.FormatPathAccessConditions(o.AccessConditions) + return &generated.PathClientGetPropertiesOptions{ + Upn: o.UPN, + Action: &action, + }, leaseAccessConditions, modifiedAccessConditions, nil +} + +// SetAccessControlRecursiveOptions contains the optional parameters when calling the SetAccessControlRecursive operation. TODO: Design formatter +type SetAccessControlRecursiveOptions struct { + // ACL is the access control list for the path. + ACL *string + // BatchSize is the number of paths to set access control recursively in a single call. + BatchSize *int32 + // MaxBatches is the maximum number of batches to perform the operation on. + MaxBatches *int32 + // ContinueOnFailure indicates whether to continue on failure when the operation encounters an error. + ContinueOnFailure *bool + // Marker is the continuation token to use when continuing the operation. + Marker *string +} + +func (o *SetAccessControlRecursiveOptions) format() (*generated.PathClientSetAccessControlRecursiveOptions, error) { + // TODO: design formatter + return nil, nil +} + +// UpdateAccessControlRecursiveOptions contains the optional parameters when calling the UpdateAccessControlRecursive operation. TODO: Design formatter +type UpdateAccessControlRecursiveOptions struct { + // ACL is the access control list for the path. + ACL *string + // BatchSize is the number of paths to set access control recursively in a single call. + BatchSize *int32 + // MaxBatches is the maximum number of batches to perform the operation on. + MaxBatches *int32 + // ContinueOnFailure indicates whether to continue on failure when the operation encounters an error. + ContinueOnFailure *bool + // Marker is the continuation token to use when continuing the operation. + Marker *string +} + +func (o *UpdateAccessControlRecursiveOptions) format() (*generated.PathClientSetAccessControlRecursiveOptions, error) { + // TODO: design formatter - similar to SetAccessControlRecursiveOptions + return nil, nil +} + +// RemoveAccessControlRecursiveOptions contains the optional parameters when calling the RemoveAccessControlRecursive operation. TODO: Design formatter +type RemoveAccessControlRecursiveOptions struct { + // ACL is the access control list for the path. + ACL *string + // BatchSize is the number of paths to set access control recursively in a single call. + BatchSize *int32 + // MaxBatches is the maximum number of batches to perform the operation on. + MaxBatches *int32 + // ContinueOnFailure indicates whether to continue on failure when the operation encounters an error. + ContinueOnFailure *bool + // Marker is the continuation token to use when continuing the operation. + Marker *string +} + +func (o *RemoveAccessControlRecursiveOptions) format() (*generated.PathClientSetAccessControlRecursiveOptions, error) { + // TODO: design formatter - similar to SetAccessControlRecursiveOptions + return nil, nil +} + +// SetHTTPHeadersOptions contains the optional parameters for the Client.SetHTTPHeaders method. +type SetHTTPHeadersOptions struct { + AccessConditions *azdatalake.AccessConditions +} + +func (o *SetHTTPHeadersOptions) format() *blob.SetHTTPHeadersOptions { + if o == nil { + return nil + } + accessConditions := shared.FormatBlobAccessConditions(o.AccessConditions) + return &blob.SetHTTPHeadersOptions{ + AccessConditions: accessConditions, + } +} + +// HTTPHeaders contains the HTTP headers for path operations. +type HTTPHeaders struct { + // Optional. Sets the path's cache control. If specified, this property is stored with the path and returned with a read request. + CacheControl *string + // Optional. Sets the path's Content-Disposition header. + ContentDisposition *string + // Optional. Sets the path's content encoding. If specified, this property is stored with the blobpath and returned with a read + // request. + ContentEncoding *string + // Optional. Set the path's content language. If specified, this property is stored with the path and returned with a read + // request. + ContentLanguage *string + // Specify the transactional md5 for the body, to be validated by the service. + ContentMD5 []byte + // Optional. Sets the path's content type. If specified, this property is stored with the path and returned with a read request. + ContentType *string +} + +func (o *HTTPHeaders) formatBlobHTTPHeaders() (*blob.HTTPHeaders, error) { + if o == nil { + return nil, nil + } + opts := blob.HTTPHeaders{ + BlobCacheControl: o.CacheControl, + BlobContentDisposition: o.ContentDisposition, + BlobContentEncoding: o.ContentEncoding, + BlobContentLanguage: o.ContentLanguage, + BlobContentMD5: o.ContentMD5, + BlobContentType: o.ContentType, + } + return &opts, nil +} + +func (o *HTTPHeaders) formatPathHTTPHeaders() (*generated.PathHTTPHeaders, error) { + // TODO: will be used for file related ops, like append + if o == nil { + return nil, nil + } + opts := generated.PathHTTPHeaders{ + CacheControl: o.CacheControl, + ContentDisposition: o.ContentDisposition, + ContentEncoding: o.ContentEncoding, + ContentLanguage: o.ContentLanguage, + ContentMD5: o.ContentMD5, + ContentType: o.ContentType, + TransactionalContentHash: o.ContentMD5, + } + return &opts, nil +} + +// SetMetadataOptions provides set of configurations for Set Metadata on path operation +type SetMetadataOptions struct { + AccessConditions *azdatalake.AccessConditions + CPKInfo *CPKInfo + CPKScopeInfo *CPKScopeInfo +} + +func (o *SetMetadataOptions) format() *blob.SetMetadataOptions { + if o == nil { + return nil + } + accessConditions := shared.FormatBlobAccessConditions(o.AccessConditions) + return &blob.SetMetadataOptions{ + AccessConditions: accessConditions, + CPKInfo: &blob.CPKInfo{ + EncryptionKey: o.CPKInfo.EncryptionKey, + EncryptionAlgorithm: o.CPKInfo.EncryptionAlgorithm, + EncryptionKeySHA256: o.CPKInfo.EncryptionKeySHA256, + }, + CPKScopeInfo: &blob.CPKScopeInfo{ + EncryptionScope: o.CPKScopeInfo.EncryptionScope, + }, + } +} + +// CPKInfo contains a group of parameters for the PathClient.Download method. +type CPKInfo struct { + EncryptionAlgorithm *EncryptionAlgorithmType + EncryptionKey *string + EncryptionKeySHA256 *string +} + +// CPKScopeInfo contains a group of parameters for the PathClient.SetMetadata method. +type CPKScopeInfo struct { + EncryptionScope *string +} + +// SourceModifiedAccessConditions identifies the source path access conditions. +type SourceModifiedAccessConditions = generated.SourceModifiedAccessConditions diff --git a/sdk/storage/azdatalake/internal/path/responses.go b/sdk/storage/azdatalake/internal/path/responses.go new file mode 100644 index 000000000000..e61078ead210 --- /dev/null +++ b/sdk/storage/azdatalake/internal/path/responses.go @@ -0,0 +1,42 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package path + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" +) + +// CreateResponse contains the response fields for the Create operation. +type CreateResponse = generated.PathClientCreateResponse + +// DeleteResponse contains the response fields for the Delete operation. +type DeleteResponse = generated.PathClientDeleteResponse + +// SetAccessControlResponse contains the response fields for the SetAccessControl operation. +type SetAccessControlResponse = generated.PathClientSetAccessControlResponse + +// SetAccessControlRecursiveResponse contains the response fields for the SetAccessControlRecursive operation. +type SetAccessControlRecursiveResponse = generated.PathClientSetAccessControlRecursiveResponse + +// UpdateAccessControlRecursiveResponse contains the response fields for the UpdateAccessControlRecursive operation. +type UpdateAccessControlRecursiveResponse = generated.PathClientSetAccessControlRecursiveResponse + +// RemoveAccessControlRecursiveResponse contains the response fields for the RemoveAccessControlRecursive operation. +type RemoveAccessControlRecursiveResponse = generated.PathClientSetAccessControlRecursiveResponse + +// GetAccessControlResponse contains the response fields for the GetAccessControl operation. +type GetAccessControlResponse = generated.PathClientGetPropertiesResponse + +// GetPropertiesResponse contains the response fields for the GetProperties operation. +type GetPropertiesResponse = generated.PathClientGetPropertiesResponse + +// SetMetadataResponse contains the response fields for the SetMetadata operation. +type SetMetadataResponse = blob.SetMetadataResponse + +// SetHTTPHeadersResponse contains the response fields for the SetHTTPHeaders operation. +type SetHTTPHeadersResponse = blob.SetHTTPHeadersResponse diff --git a/sdk/storage/azdatalake/internal/shared/access_conditions.go b/sdk/storage/azdatalake/internal/shared/access_conditions.go new file mode 100644 index 000000000000..a51de4518f6b --- /dev/null +++ b/sdk/storage/azdatalake/internal/shared/access_conditions.go @@ -0,0 +1,56 @@ +package shared + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" +) + +// FormatContainerAccessConditions formats FilesystemAccessConditions into container's LeaseAccessConditions and ModifiedAccessConditions. +func FormatContainerAccessConditions(b *azdatalake.AccessConditions) *container.AccessConditions { + if b == nil { + return nil + } + return &container.AccessConditions{ + LeaseAccessConditions: &container.LeaseAccessConditions{ + LeaseID: b.LeaseAccessConditions.LeaseID, + }, + ModifiedAccessConditions: &container.ModifiedAccessConditions{ + IfMatch: b.ModifiedAccessConditions.IfMatch, + IfNoneMatch: b.ModifiedAccessConditions.IfNoneMatch, + IfModifiedSince: b.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: b.ModifiedAccessConditions.IfUnmodifiedSince, + }, + } +} + +// FormatPathAccessConditions formats PathAccessConditions into path's LeaseAccessConditions and ModifiedAccessConditions. +func FormatPathAccessConditions(p *azdatalake.AccessConditions) (*generated.LeaseAccessConditions, *generated.ModifiedAccessConditions) { + if p == nil { + return nil, nil + } + return &generated.LeaseAccessConditions{ + LeaseID: p.LeaseAccessConditions.LeaseID, + }, &generated.ModifiedAccessConditions{ + IfMatch: p.ModifiedAccessConditions.IfMatch, + IfNoneMatch: p.ModifiedAccessConditions.IfNoneMatch, + IfModifiedSince: p.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: p.ModifiedAccessConditions.IfUnmodifiedSince, + } +} + +// FormatBlobAccessConditions formats PathAccessConditions into blob's LeaseAccessConditions and ModifiedAccessConditions. +func FormatBlobAccessConditions(p *azdatalake.AccessConditions) *blob.AccessConditions { + if p == nil { + return nil + } + return &blob.AccessConditions{LeaseAccessConditions: &blob.LeaseAccessConditions{ + LeaseID: p.LeaseAccessConditions.LeaseID, + }, ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfMatch: p.ModifiedAccessConditions.IfMatch, + IfNoneMatch: p.ModifiedAccessConditions.IfNoneMatch, + IfModifiedSince: p.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: p.ModifiedAccessConditions.IfUnmodifiedSince, + }} +} diff --git a/sdk/storage/azdatalake/internal/shared/bytes_writer.go b/sdk/storage/azdatalake/internal/shared/bytes_writer.go new file mode 100644 index 000000000000..8d4d35bdeffd --- /dev/null +++ b/sdk/storage/azdatalake/internal/shared/bytes_writer.go @@ -0,0 +1,30 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package shared + +import ( + "errors" +) + +type bytesWriter []byte + +func NewBytesWriter(b []byte) bytesWriter { + return b +} + +func (c bytesWriter) WriteAt(b []byte, off int64) (int, error) { + if off >= int64(len(c)) || off < 0 { + return 0, errors.New("offset value is out of range") + } + + n := copy(c[int(off):], b) + if n < len(b) { + return n, errors.New("not enough space for all bytes") + } + + return n, nil +} diff --git a/sdk/storage/azdatalake/internal/shared/challenge_policy.go b/sdk/storage/azdatalake/internal/shared/challenge_policy.go new file mode 100644 index 000000000000..e7c8e9213d80 --- /dev/null +++ b/sdk/storage/azdatalake/internal/shared/challenge_policy.go @@ -0,0 +1,113 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package shared + +import ( + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "strings" +) + +type storageAuthorizer struct { + scopes []string + tenantID string +} + +func NewStorageChallengePolicy(cred azcore.TokenCredential) policy.Policy { + s := storageAuthorizer{scopes: []string{TokenScope}} + return runtime.NewBearerTokenPolicy(cred, []string{TokenScope}, &policy.BearerTokenOptions{ + AuthorizationHandler: policy.AuthorizationHandler{ + OnRequest: s.onRequest, + OnChallenge: s.onChallenge, + }, + }) +} + +func (s *storageAuthorizer) onRequest(req *policy.Request, authNZ func(policy.TokenRequestOptions) error) error { + return authNZ(policy.TokenRequestOptions{Scopes: s.scopes}) +} + +func (s *storageAuthorizer) onChallenge(req *policy.Request, resp *http.Response, authNZ func(policy.TokenRequestOptions) error) error { + // parse the challenge + err := s.parseChallenge(resp) + if err != nil { + return err + } + // TODO: Set tenantID when policy.TokenRequestOptions supports it. https://github.com/Azure/azure-sdk-for-go/issues/19841 + return authNZ(policy.TokenRequestOptions{Scopes: s.scopes}) +} + +type challengePolicyError struct { + err error +} + +func (c *challengePolicyError) Error() string { + return c.err.Error() +} + +func (*challengePolicyError) NonRetriable() { + // marker method +} + +func (c *challengePolicyError) Unwrap() error { + return c.err +} + +// parses Tenant ID from auth challenge +// https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/oauth2/authorize +func parseTenant(url string) string { + if url == "" { + return "" + } + parts := strings.Split(url, "/") + if len(parts) >= 3 { + tenant := parts[3] + tenant = strings.ReplaceAll(tenant, ",", "") + return tenant + } else { + return "" + } +} + +func (s *storageAuthorizer) parseChallenge(resp *http.Response) error { + authHeader := resp.Header.Get("WWW-Authenticate") + if authHeader == "" { + return &challengePolicyError{err: errors.New("response has no WWW-Authenticate header for challenge authentication")} + } + + // Strip down to auth and resource + // Format is "Bearer authorization_uri=\"<site>\" resource_id=\"<site>\"" + authHeader = strings.ReplaceAll(authHeader, "Bearer ", "") + + parts := strings.Split(authHeader, " ") + + vals := map[string]string{} + for _, part := range parts { + subParts := strings.Split(part, "=") + if len(subParts) == 2 { + stripped := strings.ReplaceAll(subParts[1], "\"", "") + stripped = strings.TrimSuffix(stripped, ",") + vals[subParts[0]] = stripped + } + } + + s.tenantID = parseTenant(vals["authorization_uri"]) + + scope := vals["resource_id"] + if scope == "" { + return &challengePolicyError{err: errors.New("could not find a valid resource in the WWW-Authenticate header")} + } + + if !strings.HasSuffix(scope, "/.default") { + scope += "/.default" + } + s.scopes = []string{scope} + return nil +} diff --git a/sdk/storage/azdatalake/internal/shared/section_writer.go b/sdk/storage/azdatalake/internal/shared/section_writer.go new file mode 100644 index 000000000000..c8528a2e3ed2 --- /dev/null +++ b/sdk/storage/azdatalake/internal/shared/section_writer.go @@ -0,0 +1,53 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package shared + +import ( + "errors" + "io" +) + +type SectionWriter struct { + Count int64 + Offset int64 + Position int64 + WriterAt io.WriterAt +} + +func NewSectionWriter(c io.WriterAt, off int64, count int64) *SectionWriter { + return &SectionWriter{ + Count: count, + Offset: off, + WriterAt: c, + } +} + +func (c *SectionWriter) Write(p []byte) (int, error) { + remaining := c.Count - c.Position + + if remaining <= 0 { + return 0, errors.New("end of section reached") + } + + slice := p + + if int64(len(slice)) > remaining { + slice = slice[:remaining] + } + + n, err := c.WriterAt.WriteAt(slice, c.Offset+c.Position) + c.Position += int64(n) + if err != nil { + return n, err + } + + if len(p) > n { + return n, errors.New("not enough space for all bytes") + } + + return n, nil +} diff --git a/sdk/storage/azdatalake/internal/shared/shared.go b/sdk/storage/azdatalake/internal/shared/shared.go new file mode 100644 index 000000000000..d94f84deb8a6 --- /dev/null +++ b/sdk/storage/azdatalake/internal/shared/shared.go @@ -0,0 +1,236 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package shared + +import ( + "errors" + "fmt" + "hash/crc64" + "io" + "net" + "net/url" + "strconv" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" +) + +const ( + TokenScope = "https://storage.azure.com/.default" +) + +const ( + HeaderAuthorization = "Authorization" + HeaderXmsDate = "x-ms-date" + HeaderContentLength = "Content-Length" + HeaderContentEncoding = "Content-Encoding" + HeaderContentLanguage = "Content-Language" + HeaderContentType = "Content-Type" + HeaderContentMD5 = "Content-MD5" + HeaderIfModifiedSince = "If-Modified-Since" + HeaderIfMatch = "If-Match" + HeaderIfNoneMatch = "If-None-Match" + HeaderIfUnmodifiedSince = "If-Unmodified-Since" + HeaderRange = "Range" + HeaderXmsVersion = "x-ms-version" + HeaderXmsRequestID = "x-ms-request-id" +) + +const crc64Polynomial uint64 = 0x9A6C9329AC4BC9B5 + +var CRC64Table = crc64.MakeTable(crc64Polynomial) + +// CopyOptions returns a zero-value T if opts is nil. +// If opts is not nil, a copy is made and its address returned. +func CopyOptions[T any](opts *T) *T { + if opts == nil { + return new(T) + } + cp := *opts + return &cp +} + +var errConnectionString = errors.New("connection string is either blank or malformed. The expected connection string " + + "should contain key value pairs separated by semicolons. For example 'DefaultEndpointsProtocol=https;AccountName=<accountName>;" + + "AccountKey=<accountKey>;EndpointSuffix=core.windows.net'") + +type ParsedConnectionString struct { + ServiceURL string + AccountName string + AccountKey string +} + +func ParseConnectionString(connectionString string) (ParsedConnectionString, error) { + const ( + defaultScheme = "https" + defaultSuffix = "core.windows.net" + ) + + connStrMap := make(map[string]string) + connectionString = strings.TrimRight(connectionString, ";") + + splitString := strings.Split(connectionString, ";") + if len(splitString) == 0 { + return ParsedConnectionString{}, errConnectionString + } + for _, stringPart := range splitString { + parts := strings.SplitN(stringPart, "=", 2) + if len(parts) != 2 { + return ParsedConnectionString{}, errConnectionString + } + connStrMap[parts[0]] = parts[1] + } + + protocol, ok := connStrMap["DefaultEndpointsProtocol"] + if !ok { + protocol = defaultScheme + } + + suffix, ok := connStrMap["EndpointSuffix"] + if !ok { + suffix = defaultSuffix + } + + blobEndpoint, has_blobEndpoint := connStrMap["BlobEndpoint"] + accountName, has_accountName := connStrMap["AccountName"] + + var serviceURL string + if has_blobEndpoint { + serviceURL = blobEndpoint + } else if has_accountName { + serviceURL = fmt.Sprintf("%v://%v.blob.%v", protocol, accountName, suffix) + } else { + return ParsedConnectionString{}, errors.New("connection string needs either AccountName or BlobEndpoint") + } + + if !strings.HasSuffix(serviceURL, "/") { + // add a trailing slash to be consistent with the portal + serviceURL += "/" + } + + accountKey, has_accountKey := connStrMap["AccountKey"] + sharedAccessSignature, has_sharedAccessSignature := connStrMap["SharedAccessSignature"] + + if has_accountName && has_accountKey { + return ParsedConnectionString{ + ServiceURL: serviceURL, + AccountName: accountName, + AccountKey: accountKey, + }, nil + } else if has_sharedAccessSignature { + return ParsedConnectionString{ + ServiceURL: fmt.Sprintf("%v?%v", serviceURL, sharedAccessSignature), + }, nil + } else { + return ParsedConnectionString{}, errors.New("connection string needs either AccountKey or SharedAccessSignature") + } + +} + +func SerializeBlobTagsToStrPtr(tagsMap map[string]string) *string { + if len(tagsMap) == 0 { + return nil + } + tags := make([]string, 0) + for key, val := range tagsMap { + tags = append(tags, url.QueryEscape(key)+"="+url.QueryEscape(val)) + } + blobTagsString := strings.Join(tags, "&") + return &blobTagsString +} + +func ValidateSeekableStreamAt0AndGetCount(body io.ReadSeeker) (int64, error) { + if body == nil { // nil body's are "logically" seekable to 0 and are 0 bytes long + return 0, nil + } + + err := validateSeekableStreamAt0(body) + if err != nil { + return 0, err + } + + count, err := body.Seek(0, io.SeekEnd) + if err != nil { + return 0, errors.New("body stream must be seekable") + } + + _, err = body.Seek(0, io.SeekStart) + if err != nil { + return 0, err + } + return count, nil +} + +// return an error if body is not a valid seekable stream at 0 +func validateSeekableStreamAt0(body io.ReadSeeker) error { + if body == nil { // nil body's are "logically" seekable to 0 + return nil + } + if pos, err := body.Seek(0, io.SeekCurrent); pos != 0 || err != nil { + // Help detect programmer error + if err != nil { + return errors.New("body stream must be seekable") + } + return errors.New("body stream must be set to position 0") + } + return nil +} + +func RangeToString(offset, count int64) string { + return "bytes=" + strconv.FormatInt(offset, 10) + "-" + strconv.FormatInt(offset+count-1, 10) +} + +type nopCloser struct { + io.ReadSeeker +} + +func (n nopCloser) Close() error { + return nil +} + +// NopCloser returns a ReadSeekCloser with a no-op close method wrapping the provided io.ReadSeeker. +func NopCloser(rs io.ReadSeeker) io.ReadSeekCloser { + return nopCloser{rs} +} + +func GenerateLeaseID(leaseID *string) (*string, error) { + if leaseID == nil { + generatedUuid, err := uuid.New() + if err != nil { + return nil, err + } + leaseID = to.Ptr(generatedUuid.String()) + } + return leaseID, nil +} + +func GetClientOptions[T any](o *T) *T { + if o == nil { + return new(T) + } + return o +} + +// IsIPEndpointStyle checkes if URL's host is IP, in this case the storage account endpoint will be composed as: +// http(s)://IP(:port)/storageaccount/container/... +// As url's Host property, host could be both host or host:port +func IsIPEndpointStyle(host string) bool { + if host == "" { + return false + } + if h, _, err := net.SplitHostPort(host); err == nil { + host = h + } + // For IPv6, there could be case where SplitHostPort fails for cannot finding port. + // In this case, eliminate the '[' and ']' in the URL. + // For details about IPv6 URL, please refer to https://tools.ietf.org/html/rfc2732 + if host[0] == '[' && host[len(host)-1] == ']' { + host = host[1 : len(host)-1] + } + return net.ParseIP(host) != nil +} diff --git a/sdk/storage/azdatalake/lease/constants.go b/sdk/storage/azdatalake/lease/constants.go new file mode 100644 index 000000000000..04df4d58e7b1 --- /dev/null +++ b/sdk/storage/azdatalake/lease/constants.go @@ -0,0 +1,51 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package lease + +import "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/lease" + +// StatusType defines values for StatusType +type StatusType = lease.StatusType + +const ( + StatusTypeLocked StatusType = lease.StatusTypeLocked + StatusTypeUnlocked StatusType = lease.StatusTypeUnlocked +) + +// PossibleStatusTypeValues returns the possible values for the StatusType const type. +func PossibleStatusTypeValues() []StatusType { + return lease.PossibleStatusTypeValues() +} + +// DurationType defines values for DurationType +type DurationType = lease.DurationType + +const ( + DurationTypeInfinite DurationType = lease.DurationTypeInfinite + DurationTypeFixed DurationType = lease.DurationTypeFixed +) + +// PossibleDurationTypeValues returns the possible values for the DurationType const type. +func PossibleDurationTypeValues() []DurationType { + return lease.PossibleDurationTypeValues() +} + +// StateType defines values for StateType +type StateType = lease.StateType + +const ( + StateTypeAvailable StateType = lease.StateTypeAvailable + StateTypeLeased StateType = lease.StateTypeLeased + StateTypeExpired StateType = lease.StateTypeExpired + StateTypeBreaking StateType = lease.StateTypeBreaking + StateTypeBroken StateType = lease.StateTypeBroken +) + +// PossibleStateTypeValues returns the possible values for the StateType const type. +func PossibleStateTypeValues() []StateType { + return lease.PossibleStateTypeValues() +} diff --git a/sdk/storage/azdatalake/lease/filesystem_client.go b/sdk/storage/azdatalake/lease/filesystem_client.go new file mode 100644 index 000000000000..e2c5100a859e --- /dev/null +++ b/sdk/storage/azdatalake/lease/filesystem_client.go @@ -0,0 +1,81 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package lease + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/lease" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/filesystem" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/base" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" +) + +// FilesystemClient provides lease functionality for the underlying filesystem client. +type FilesystemClient struct { + filesystemClient *filesystem.Client + leaseID *string + containerClient *lease.ContainerClient +} + +// FilesystemClientOptions contains the optional values when creating a FilesystemClient. +type FilesystemClientOptions struct { + // LeaseID contains a caller-provided lease ID. + LeaseID *string +} + +func (c *FilesystemClient) generated() *generated.FileSystemClient { + return base.InnerClient((*base.Client[generated.FileSystemClient])(c.filesystemClient)) +} + +// NewFilesystemClient creates a filesystem lease client for the provided filesystem client. +// - client - an instance of a filesystem client +// - options - client options; pass nil to accept the default values +func NewFilesystemClient(client *filesystem.Client, options *FilesystemClientOptions) (*FilesystemClient, error) { + // TODO: set up container lease client + return nil, nil +} + +// LeaseID returns leaseID of the client. +func (c *FilesystemClient) LeaseID() *string { + return c.leaseID +} + +// AcquireLease acquires a lease on the filesystem for write and delete operations. +// The lease Duration must be between 15 and 60 seconds, or infinite (-1). +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (c *FilesystemClient) AcquireLease(ctx context.Context, duration int32, o *FilesystemAcquireOptions) (FilesystemAcquireResponse, error) { + opts := o.format() + return c.containerClient.AcquireLease(ctx, duration, opts) +} + +// BreakLease breaks the filesystem's previously-acquired lease (if it exists). Pass the LeaseBreakDefault (-1) +// constant to break a fixed-Duration lease when it expires or an infinite lease immediately. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (c *FilesystemClient) BreakLease(ctx context.Context, o *FilesystemBreakOptions) (FilesystemBreakResponse, error) { + opts := o.format() + return c.containerClient.BreakLease(ctx, opts) +} + +// ChangeLease changes the filesystem's lease ID. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (c *FilesystemClient) ChangeLease(ctx context.Context, proposedLeaseID string, o *FilesystemChangeOptions) (FilesystemChangeResponse, error) { + opts := o.format() + return c.containerClient.ChangeLease(ctx, proposedLeaseID, opts) +} + +// RenewLease renews the filesystem's previously-acquired lease. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (c *FilesystemClient) RenewLease(ctx context.Context, o *FilesystemRenewOptions) (FilesystemRenewResponse, error) { + opts := o.format() + return c.containerClient.RenewLease(ctx, opts) +} + +// ReleaseLease releases the filesystem's previously-acquired lease. +func (c *FilesystemClient) ReleaseLease(ctx context.Context, o *FilesystemReleaseOptions) (FilesystemReleaseResponse, error) { + opts := o.format() + return c.containerClient.ReleaseLease(ctx, opts) +} diff --git a/sdk/storage/azdatalake/lease/models.go b/sdk/storage/azdatalake/lease/models.go new file mode 100644 index 000000000000..4d94dafc5ec0 --- /dev/null +++ b/sdk/storage/azdatalake/lease/models.go @@ -0,0 +1,173 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package lease + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/lease" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake" +) + +// FilesystemAcquireOptions contains the optional parameters for the LeaseClient.AcquireLease method. +type FilesystemAcquireOptions struct { + ModifiedAccessConditions *azdatalake.ModifiedAccessConditions +} + +func (o *FilesystemAcquireOptions) format() *lease.ContainerAcquireOptions { + return &lease.ContainerAcquireOptions{ + ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfModifiedSince: o.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.ModifiedAccessConditions.IfUnmodifiedSince, + IfMatch: o.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.ModifiedAccessConditions.IfNoneMatch, + }, + } +} + +// FilesystemBreakOptions contains the optional parameters for the LeaseClient.BreakLease method. +type FilesystemBreakOptions struct { + BreakPeriod *int32 + ModifiedAccessConditions *azdatalake.ModifiedAccessConditions +} + +func (o *FilesystemBreakOptions) format() *lease.ContainerBreakOptions { + return &lease.ContainerBreakOptions{ + BreakPeriod: o.BreakPeriod, + ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfModifiedSince: o.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.ModifiedAccessConditions.IfUnmodifiedSince, + IfMatch: o.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.ModifiedAccessConditions.IfNoneMatch, + }, + } +} + +// FilesystemChangeOptions contains the optional parameters for the LeaseClient.ChangeLease method. +type FilesystemChangeOptions struct { + ModifiedAccessConditions *azdatalake.ModifiedAccessConditions +} + +func (o *FilesystemChangeOptions) format() *lease.ContainerChangeOptions { + return &lease.ContainerChangeOptions{ + ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfModifiedSince: o.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.ModifiedAccessConditions.IfUnmodifiedSince, + IfMatch: o.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.ModifiedAccessConditions.IfNoneMatch, + }, + } +} + +type FilesystemReleaseOptions struct { + ModifiedAccessConditions *azdatalake.ModifiedAccessConditions +} + +func (o *FilesystemReleaseOptions) format() *lease.ContainerReleaseOptions { + return &lease.ContainerReleaseOptions{ + ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfModifiedSince: o.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.ModifiedAccessConditions.IfUnmodifiedSince, + IfMatch: o.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.ModifiedAccessConditions.IfNoneMatch, + }, + } +} + +type FilesystemRenewOptions struct { + ModifiedAccessConditions *azdatalake.ModifiedAccessConditions +} + +func (o *FilesystemRenewOptions) format() *lease.ContainerRenewOptions { + return &lease.ContainerRenewOptions{ + ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfModifiedSince: o.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.ModifiedAccessConditions.IfUnmodifiedSince, + IfMatch: o.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.ModifiedAccessConditions.IfNoneMatch, + }, + } +} + +// PathAcquireOptions contains the optional parameters for the LeaseClient.AcquireLease method. +type PathAcquireOptions struct { + ModifiedAccessConditions *azdatalake.ModifiedAccessConditions +} + +func (o *PathAcquireOptions) format() *lease.BlobAcquireOptions { + return &lease.BlobAcquireOptions{ + ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfModifiedSince: o.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.ModifiedAccessConditions.IfUnmodifiedSince, + IfMatch: o.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.ModifiedAccessConditions.IfNoneMatch, + }, + } +} + +// PathBreakOptions contains the optional parameters for the LeaseClient.BreakLease method. +type PathBreakOptions struct { + BreakPeriod *int32 + ModifiedAccessConditions *azdatalake.ModifiedAccessConditions +} + +func (o *PathBreakOptions) format() *lease.BlobBreakOptions { + return &lease.BlobBreakOptions{ + BreakPeriod: o.BreakPeriod, + ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfModifiedSince: o.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.ModifiedAccessConditions.IfUnmodifiedSince, + IfMatch: o.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.ModifiedAccessConditions.IfNoneMatch, + }, + } +} + +// PathChangeOptions contains the optional parameters for the LeaseClient.ChangeLease method. +type PathChangeOptions struct { + ModifiedAccessConditions *azdatalake.ModifiedAccessConditions +} + +func (o *PathChangeOptions) format() *lease.BlobChangeOptions { + return &lease.BlobChangeOptions{ + ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfModifiedSince: o.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.ModifiedAccessConditions.IfUnmodifiedSince, + IfMatch: o.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.ModifiedAccessConditions.IfNoneMatch, + }, + } +} + +type PathReleaseOptions struct { + ModifiedAccessConditions *azdatalake.ModifiedAccessConditions +} + +func (o *PathReleaseOptions) format() *lease.BlobReleaseOptions { + return &lease.BlobReleaseOptions{ + ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfModifiedSince: o.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.ModifiedAccessConditions.IfUnmodifiedSince, + IfMatch: o.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.ModifiedAccessConditions.IfNoneMatch, + }, + } +} + +type PathRenewOptions struct { + ModifiedAccessConditions *azdatalake.ModifiedAccessConditions +} + +func (o *PathRenewOptions) format() *lease.BlobRenewOptions { + return &lease.BlobRenewOptions{ + ModifiedAccessConditions: &blob.ModifiedAccessConditions{ + IfModifiedSince: o.ModifiedAccessConditions.IfModifiedSince, + IfUnmodifiedSince: o.ModifiedAccessConditions.IfUnmodifiedSince, + IfMatch: o.ModifiedAccessConditions.IfMatch, + IfNoneMatch: o.ModifiedAccessConditions.IfNoneMatch, + }, + } +} diff --git a/sdk/storage/azdatalake/lease/path_client.go b/sdk/storage/azdatalake/lease/path_client.go new file mode 100644 index 000000000000..57b06f5c20a2 --- /dev/null +++ b/sdk/storage/azdatalake/lease/path_client.go @@ -0,0 +1,82 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package lease + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/lease" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/directory" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/file" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/base" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/path" +) + +// PathClient provides lease functionality for the underlying path client. +type PathClient struct { + blobClient *lease.BlobClient + pathClient *path.Client + leaseID *string +} + +// PathClientOptions contains the optional values when creating a PathClient. +type PathClientOptions struct { + // LeaseID contains a caller-provided lease ID. + LeaseID *string +} + +// NewPathClient creates a path lease client for the provided path client. +// - client - an instance of a path client +// - options - client options; pass nil to accept the default values +func NewPathClient[T directory.Client | file.Client](client *T, options *PathClientOptions) (*PathClient, error) { + // TODO: set up blob lease client + return nil, nil +} + +func (c *PathClient) generated() *generated.PathClient { + return base.InnerClient((*base.Client[generated.PathClient])(c.pathClient)) +} + +// LeaseID returns leaseID of the client. +func (c *PathClient) LeaseID() *string { + return c.leaseID +} + +// AcquireLease acquires a lease on the path for write and delete operations. +// The lease Duration must be between 15 and 60 seconds, or infinite (-1). +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (c *PathClient) AcquireLease(ctx context.Context, duration int32, o *PathAcquireOptions) (PathAcquireResponse, error) { + opts := o.format() + return c.blobClient.AcquireLease(ctx, duration, opts) +} + +// BreakLease breaks the path's previously-acquired lease. +func (c *PathClient) BreakLease(ctx context.Context, o *PathBreakOptions) (PathBreakResponse, error) { + opts := o.format() + return c.blobClient.BreakLease(ctx, opts) +} + +// ChangeLease changes the path's lease ID. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (c *PathClient) ChangeLease(ctx context.Context, proposedID string, o *PathChangeOptions) (PathChangeResponse, error) { + opts := o.format() + return c.blobClient.ChangeLease(ctx, proposedID, opts) +} + +// RenewLease renews the path's previously-acquired lease. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (c *PathClient) RenewLease(ctx context.Context, o *PathRenewOptions) (PathRenewResponse, error) { + opts := o.format() + return c.blobClient.RenewLease(ctx, opts) +} + +// ReleaseLease releases the path's previously-acquired lease. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (c *PathClient) ReleaseLease(ctx context.Context, o *PathReleaseOptions) (PathReleaseResponse, error) { + opts := o.format() + return c.blobClient.ReleaseLease(ctx, opts) +} diff --git a/sdk/storage/azdatalake/lease/responses.go b/sdk/storage/azdatalake/lease/responses.go new file mode 100644 index 000000000000..1ff60df3b227 --- /dev/null +++ b/sdk/storage/azdatalake/lease/responses.go @@ -0,0 +1,39 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package lease + +import "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/lease" + +// FilesystemAcquireResponse contains the response from method FilesystemClient.AcquireLease. +type FilesystemAcquireResponse = lease.ContainerAcquireResponse + +// FilesystemBreakResponse contains the response from method FilesystemClient.BreakLease. +type FilesystemBreakResponse = lease.ContainerBreakResponse + +// FilesystemChangeResponse contains the response from method FilesystemClient.ChangeLease. +type FilesystemChangeResponse = lease.ContainerChangeResponse + +// FilesystemReleaseResponse contains the response from method FilesystemClient.ReleaseLease. +type FilesystemReleaseResponse = lease.ContainerReleaseResponse + +// FilesystemRenewResponse contains the response from method FilesystemClient.RenewLease. +type FilesystemRenewResponse = lease.ContainerRenewResponse + +// PathAcquireResponse contains the response from method PathClient.AcquireLease. +type PathAcquireResponse = lease.BlobAcquireResponse + +// PathBreakResponse contains the response from method PathClient.BreakLease. +type PathBreakResponse = lease.BlobBreakResponse + +// PathChangeResponse contains the response from method PathClient.ChangeLease. +type PathChangeResponse = lease.BlobChangeResponse + +// PathReleaseResponse contains the response from method PathClient.ReleaseLease. +type PathReleaseResponse = lease.BlobReleaseResponse + +// PathRenewResponse contains the response from method PathClient.RenewLease. +type PathRenewResponse = lease.BlobRenewResponse diff --git a/sdk/storage/azdatalake/service/client.go b/sdk/storage/azdatalake/service/client.go new file mode 100644 index 000000000000..5d887ffddd9d --- /dev/null +++ b/sdk/storage/azdatalake/service/client.go @@ -0,0 +1,113 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package service + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/filesystem" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/base" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated" +) + +// Client represents a URL to the Azure Datalake Storage service. +type Client base.Client[generated.ServiceClient] + +// NewClient creates an instance of Client with the specified values. +// - serviceURL - the URL of the storage account e.g. https://<account>.file.core.windows.net/ +// - cred - an Azure AD credential, typically obtained via the azidentity module +// - options - client options; pass nil to accept the default values +func NewClient(serviceURL string, cred azcore.TokenCredential, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientWithNoCredential creates an instance of Client with the specified values. +// This is used to anonymously access a storage account or with a shared access signature (SAS) token. +// - serviceURL - the URL of the storage account e.g. https://<account>.file.core.windows.net/?<sas token> +// - options - client options; pass nil to accept the default values +func NewClientWithNoCredential(serviceURL string, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientWithSharedKeyCredential creates an instance of Client with the specified values. +// - serviceURL - the URL of the storage account e.g. https://<account>.file.core.windows.net/ +// - cred - a SharedKeyCredential created with the matching storage account and access key +// - options - client options; pass nil to accept the default values +func NewClientWithSharedKeyCredential(serviceURL string, cred *SharedKeyCredential, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewClientFromConnectionString creates an instance of Client with the specified values. +// - connectionString - a connection string for the desired storage account +// - options - client options; pass nil to accept the default values +func NewClientFromConnectionString(connectionString string, options *azdatalake.ClientOptions) (*Client, error) { + return nil, nil +} + +// NewFilesystemClient creates a new share.Client object by concatenating shareName to the end of this Client's URL. +// The new share.Client uses the same request policy pipeline as the Client. +func (s *Client) NewFilesystemClient(filesystemName string) *filesystem.Client { + return nil +} + +// NewDirectoryClient creates a new share.Client object by concatenating shareName to the end of this Client's URL. +// The new share.Client uses the same request policy pipeline as the Client. +func (s *Client) NewDirectoryClient(directoryName string) *filesystem.Client { + return nil +} + +// NewFileClient creates a new share.Client object by concatenating shareName to the end of this Client's URL. +// The new share.Client uses the same request policy pipeline as the Client. +func (s *Client) NewFileClient(fileName string) *filesystem.Client { + return nil +} + +func (s *Client) generated() *generated.ServiceClient { + return base.InnerClient((*base.Client[generated.ServiceClient])(s)) +} + +func (s *Client) sharedKey() *exported.SharedKeyCredential { + return base.SharedKey((*base.Client[generated.ServiceClient])(s)) +} + +// URL returns the URL endpoint used by the Client object. +func (s *Client) URL() string { + return "s.generated().Endpoint()" +} + +// CreateFilesystem creates a new filesystem under the specified account. (blob3) +func (s *Client) CreateFilesystem(ctx context.Context, filesystem string, options *CreateFilesystemOptions) (CreateFilesystemResponse, error) { + filesystemClient := s.NewFilesystemClient(filesystem) + resp, err := filesystemClient.Create(ctx, options) + return resp, err +} + +// DeleteFilesystem deletes the specified filesystem. (blob3) +func (s *Client) DeleteFilesystem(ctx context.Context, filesystem string, options *DeleteFilesystemOptions) (DeleteFilesystemResponse, error) { + filesystemClient := s.NewFilesystemClient(filesystem) + resp, err := filesystemClient.Delete(ctx, options) + return resp, err +} + +// SetServiceProperties sets properties for a storage account's File service endpoint. (blob3) +func (s *Client) SetServiceProperties(ctx context.Context, options *SetPropertiesOptions) (SetPropertiesResponse, error) { + return SetPropertiesResponse{}, nil +} + +// GetProperties gets properties for a storage account's File service endpoint. (blob3) +func (s *Client) GetProperties(ctx context.Context, options *GetPropertiesOptions) (GetPropertiesResponse, error) { + return GetPropertiesResponse{}, nil +} + +// NewListFilesystemsPager operation returns a pager of the shares under the specified account. (blob3) +// For more information, see https://learn.microsoft.com/en-us/rest/api/storageservices/list-shares +func (s *Client) NewListFilesystemsPager(options *ListFilesystemsOptions) *runtime.Pager[ListFilesystemsResponse] { + return nil +} diff --git a/sdk/storage/azdatalake/service/models.go b/sdk/storage/azdatalake/service/models.go new file mode 100644 index 000000000000..bca2a179f73a --- /dev/null +++ b/sdk/storage/azdatalake/service/models.go @@ -0,0 +1,98 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package service + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/service" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/filesystem" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/exported" +) + +type CreateFilesystemOptions = filesystem.CreateOptions + +type DeleteFilesystemOptions = filesystem.DeleteOptions + +// CORSRule - CORS is an HTTP feature that enables a web application running under one domain to access resources in another +// domain. Web browsers implement a security restriction known as same-origin policy that +// prevents a web page from calling APIs in a different domain; CORS provides a secure way to allow one domain (the origin +// domain) to call APIs in another domain. +type CORSRule = service.CORSRule + +// RetentionPolicy - the retention policy which determines how long the associated data should persist. +type RetentionPolicy = service.RetentionPolicy + +// Metrics - a summary of request statistics grouped by API in hour or minute aggregates +type Metrics = service.Metrics + +// Logging - Azure Analytics Logging settings. +type Logging = service.Logging + +// StaticWebsite - The properties that enable an account to host a static website. +type StaticWebsite = service.StaticWebsite + +// GetPropertiesOptions contains the optional parameters for the Client.GetProperties method. +type GetPropertiesOptions struct { + // placeholder for future options +} + +func (o *GetPropertiesOptions) format() *service.GetPropertiesOptions { + return nil +} + +// SetPropertiesOptions provides set of options for Client.SetProperties +type SetPropertiesOptions struct { + // The set of CORS rules. + CORS []*CORSRule + + // The default version to use for requests to the Datalake service if an incoming request's version is not specified. Possible + // values include version 2008-10-27 and all more recent versions. + DefaultServiceVersion *string + + // the retention policy which determines how long the associated data should persist. + DeleteRetentionPolicy *RetentionPolicy + + // a summary of request statistics grouped by API in hour or minute aggregates + // If version is not set - we default to "1.0" + HourMetrics *Metrics + + // Azure Analytics Logging settings. + // If version is not set - we default to "1.0" + Logging *Logging + + // a summary of request statistics grouped by API in hour or minute aggregates + // If version is not set - we default to "1.0" + MinuteMetrics *Metrics + + // The properties that enable an account to host a static website. + StaticWebsite *StaticWebsite +} + +func (o *SetPropertiesOptions) format() *service.SetPropertiesOptions { + return nil +} + +// ListFilesystemsInclude indicates what additional information the service should return with each filesystem. +type ListFilesystemsInclude struct { + // Tells the service whether to return metadata for each filesystem. + Metadata bool + + // Tells the service whether to return soft-deleted filesystems. + Deleted bool +} + +// ListFilesystemsOptions contains the optional parameters for the Client.List method. +type ListFilesystemsOptions struct { + Include ListFilesystemsInclude + Marker *string + MaxResults *int32 + Prefix *string +} + +// TODO: Design formatter to convert to blob + +// SharedKeyCredential contains an account's name and its primary or secondary key. +type SharedKeyCredential = exported.SharedKeyCredential diff --git a/sdk/storage/azdatalake/service/responses.go b/sdk/storage/azdatalake/service/responses.go new file mode 100644 index 000000000000..e9393cbdbee3 --- /dev/null +++ b/sdk/storage/azdatalake/service/responses.go @@ -0,0 +1,30 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package service + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/service" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/filesystem" +) + +// CreateFilesystemResponse contains the response fields for the CreateFilesystem operation. +type CreateFilesystemResponse = filesystem.CreateResponse + +// DeleteFilesystemResponse contains the response fields for the DeleteFilesystem operation. +type DeleteFilesystemResponse = filesystem.DeleteResponse + +// SetPropertiesResponse contains the response fields for the SetProperties operation. +type SetPropertiesResponse = service.SetPropertiesResponse + +// GetPropertiesResponse contains the response fields for the GetProperties operation. +type GetPropertiesResponse = service.GetPropertiesResponse + +// ListFilesystemsResponse contains the response fields for the ListFilesystems operation. +type ListFilesystemsResponse = service.ListContainersResponse