Skip to content

Commit d0df287

Browse files
azblob: Upgrade to STG 85-86 (#21381)
* Regenerating AzBlob to STG 85/86 (#20724) * Regenerating azblob to stg 85/86 * Updating CopyFromURL * minor change * minor fixes * undo some minor fixes * Updating Go code generator * Fixing calls to pipeline * Adding custom UnmarshalXML for BlobItem and BlobPrefix * Updating constructor method for AppendBlobClient * Updating Client constructors * Undoing minor fixes to blob examples * Fixing authpolicy * Updating azcore version * Fixing client strings * Const for service client * Minor fix * fixing go mod files * Shared constants client name * Addressing comments * [Feature STG 85/86] Cold Tier * [Checksum Work] BlockBlob Client: Transactional/Source Content Validation (#21033) * Adding test for transactional validation in block blob * StageBlockFromURL tests * Deprecating options in CommitBlockList * CopyFromURL test * Updating checksum behavior * Record tests * Updated recording * Updated recording again * Added error for user gen checksums, tests for UploadStream, UploadBuffer, and UploadFile * Added recorded test * Updated CommitBlockList, added tests for CommitBlockList, and added CRC64 test for Upload * Updating UploadStream test * Recorded test * Recorded test * Fixing CommitBlockList errors * Fixing linting issues * Addressing comment + handling CI issues * Removing TransactionalValidation from CommitBlockList + cleaning up tests * Rerecorded tests * Update azcore (#21188) * Updating azcore * Updating changelog.md * Updating go sum file * Update perf go file * Copy Blob from URL/Put Blob from URL copy source tags (#21128) * Regenerating AzBlob to STG 85/86 (#20724) * Regenerating azblob to stg 85/86 * Updating CopyFromURL * minor change * minor fixes * undo some minor fixes * Updating Go code generator * Fixing calls to pipeline * Adding custom UnmarshalXML for BlobItem and BlobPrefix * Updating constructor method for AppendBlobClient * Updating Client constructors * Undoing minor fixes to blob examples * Fixing authpolicy * Updating azcore version * Fixing client strings * Const for service client * Minor fix * fixing go mod files * Shared constants client name * Addressing comments * [Feature STG 85/86] Cold Tier (#21032) * Adding Cold Tier + tests * Recorded tests * Updated CHANGELOG.md * Fixing linting issues * Updating Cold tier test and recording * Addressing commits * Adding CopySourceBlobTags * Fixing enum variable name, adding default test, changelog update * Cleaning up constants * Moving const to constants.go * Small change * Adding PossibleBlobCopySourceTagsValues() Method for CopySourceTags * List System Containers (#21243) * Listing system containers * Updating CHANGELOG.md * Record test * Filter Tags API on Container (#21197) * Adding FilterBlobs to container client * Updating and adding tests * Updating URL Co-authored-by: Sourav Gupta <[email protected]> * Updating comment Co-authored-by: Sourav Gupta <[email protected]> * Updating CHANGELOG.md * Updating test --------- Co-authored-by: Sourav Gupta <[email protected]> * Encryption Scope SAS (#21294) * Adding encryption sas to blob, account, and identity sas * Fixing issues with Blob SAS * Undo some changes * Undo some changes pt 2 * Undo some changes pt 3 * Adding doc comment * Updating variable names in the tests and updated account sas test * Updating tests * Adding back comment * Updating CHANGELOG.md * Update sdk/storage/azblob/sas/query_params.go Co-authored-by: Sourav Gupta <[email protected]> * Update sdk/storage/azblob/CHANGELOG.md Co-authored-by: Sourav Gupta <[email protected]> * Removing SI from Account SAS --------- Co-authored-by: Sourav Gupta <[email protected]> * Test Encryption Scope support for Sync Blob Copy (SyncCopyFromUrl) (#21332) * Test List Blobs Fix for Invalid XML Characters * minor fixes to changelog --------- Co-authored-by: Sourav Gupta <[email protected]>
1 parent 095a389 commit d0df287

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2543
-693
lines changed

sdk/storage/azblob/CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,22 @@
33
## 1.1.1 (Unreleased)
44

55
### Features Added
6+
* Added support for [Cold Tier](https://learn.microsoft.com/azure/storage/blobs/access-tiers-overview?tabs=azure-portal).
7+
* Added `CopySourceTag` option for `UploadBlobFromURLOptions`
8+
* Added [FilterBlobs by Tags](https://learn.microsoft.com/rest/api/storageservices/find-blobs-by-tags-container) API for container client.
9+
* Added `System` option to `ListContainersInclude` to allow listing of system containers (i.e, $web).
10+
* Updated the SAS Version to `2021-12-02` and added `Encryption Scope` to Account SAS, Service SAS, and User Delegation SAS
611

712
### Breaking Changes
813

914
### Bugs Fixed
10-
* Fixed issue where some requests fail with mismatch in string to sign.
15+
* Fixed issue where some requests fail with mismatch in string to sign.
16+
* Fixed service SAS creation where expiry time or permissions can be omitted when stored access policy is used. Fixes [#21229](https://github.com/Azure/azure-sdk-for-go/issues/21229).
1117

1218
* Fixed service SAS creation where expiry time or permissions can be omitted when stored access policy is used. Fixes [#21229](https://github.com/Azure/azure-sdk-for-go/issues/21229).
1319

1420
### Other Changes
21+
* Updating version of azcore to 1.6.0.
1522

1623
## 1.1.0 (2023-07-13)
1724

sdk/storage/azblob/appendblob/client.go

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package appendblob
99
import (
1010
"context"
1111
"errors"
12+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
1213
"io"
1314
"os"
1415
"time"
@@ -35,12 +36,14 @@ type Client base.CompositeClient[generated.BlobClient, generated.AppendBlobClien
3536
func NewClient(blobURL string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) {
3637
authPolicy := shared.NewStorageChallengePolicy(cred)
3738
conOptions := shared.GetClientOptions(options)
38-
conOptions.PerRetryPolicies = append(conOptions.PerRetryPolicies, authPolicy)
39-
pl := runtime.NewPipeline(exported.ModuleName,
40-
exported.ModuleVersion, runtime.PipelineOptions{},
41-
&conOptions.ClientOptions)
39+
plOpts := runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}
4240

43-
return (*Client)(base.NewAppendBlobClient(blobURL, pl, nil)), nil
41+
azClient, err := azcore.NewClient(shared.AppendBlobClient, exported.ModuleVersion, plOpts, &conOptions.ClientOptions)
42+
if err != nil {
43+
return nil, err
44+
}
45+
46+
return (*Client)(base.NewAppendBlobClient(blobURL, azClient, nil)), nil
4447
}
4548

4649
// NewClientWithNoCredential creates an instance of Client with the specified values.
@@ -49,12 +52,13 @@ func NewClient(blobURL string, cred azcore.TokenCredential, options *ClientOptio
4952
// - options - client options; pass nil to accept the default values
5053
func NewClientWithNoCredential(blobURL string, options *ClientOptions) (*Client, error) {
5154
conOptions := shared.GetClientOptions(options)
52-
pl := runtime.NewPipeline(exported.ModuleName,
53-
exported.ModuleVersion,
54-
runtime.PipelineOptions{},
55-
&conOptions.ClientOptions)
5655

57-
return (*Client)(base.NewAppendBlobClient(blobURL, pl, nil)), nil
56+
azClient, err := azcore.NewClient(shared.AppendBlobClient, exported.ModuleVersion, runtime.PipelineOptions{}, &conOptions.ClientOptions)
57+
if err != nil {
58+
return nil, err
59+
}
60+
61+
return (*Client)(base.NewAppendBlobClient(blobURL, azClient, nil)), nil
5862
}
5963

6064
// NewClientWithSharedKeyCredential creates an instance of Client with the specified values.
@@ -64,13 +68,14 @@ func NewClientWithNoCredential(blobURL string, options *ClientOptions) (*Client,
6468
func NewClientWithSharedKeyCredential(blobURL string, cred *blob.SharedKeyCredential, options *ClientOptions) (*Client, error) {
6569
authPolicy := exported.NewSharedKeyCredPolicy(cred)
6670
conOptions := shared.GetClientOptions(options)
67-
conOptions.PerRetryPolicies = append(conOptions.PerRetryPolicies, authPolicy)
68-
pl := runtime.NewPipeline(exported.ModuleName,
69-
exported.ModuleVersion,
70-
runtime.PipelineOptions{},
71-
&conOptions.ClientOptions)
71+
plOpts := runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}
72+
73+
azClient, err := azcore.NewClient(shared.AppendBlobClient, exported.ModuleVersion, plOpts, &conOptions.ClientOptions)
74+
if err != nil {
75+
return nil, err
76+
}
7277

73-
return (*Client)(base.NewAppendBlobClient(blobURL, pl, cred)), nil
78+
return (*Client)(base.NewAppendBlobClient(blobURL, azClient, cred)), nil
7479
}
7580

7681
// NewClientFromConnectionString creates an instance of Client with the specified values.
@@ -130,7 +135,7 @@ func (ab *Client) WithSnapshot(snapshot string) (*Client, error) {
130135
}
131136
p.Snapshot = snapshot
132137

133-
return (*Client)(base.NewAppendBlobClient(p.String(), ab.generated().Pipeline(), ab.sharedKey())), nil
138+
return (*Client)(base.NewAppendBlobClient(p.String(), ab.generated().InternalClient(), ab.sharedKey())), nil
134139
}
135140

136141
// WithVersionID creates a new AppendBlobURL object identical to the source but with the specified version id.
@@ -142,7 +147,7 @@ func (ab *Client) WithVersionID(versionID string) (*Client, error) {
142147
}
143148
p.VersionID = versionID
144149

145-
return (*Client)(base.NewAppendBlobClient(p.String(), ab.generated().Pipeline(), ab.sharedKey())), nil
150+
return (*Client)(base.NewAppendBlobClient(p.String(), ab.generated().InternalClient(), ab.sharedKey())), nil
146151
}
147152

148153
// Create creates a 0-size append blob. Call AppendBlock to append data to an append blob.

sdk/storage/azblob/appendblob/client_test.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"crypto/md5"
1313
"encoding/binary"
1414
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
15+
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/service"
1516
"hash/crc64"
1617
"io"
1718
"math/rand"
@@ -371,6 +372,149 @@ func (s *AppendBlobUnrecordedTestsSuite) TestAppendBlockFromURL() {
371372
_require.Equal(destBuffer, sourceData)
372373
}
373374

375+
func (s *AppendBlobUnrecordedTestsSuite) TestBlobEncryptionScopeSAS() {
376+
_require := require.New(s.T())
377+
testName := s.T().Name()
378+
svcClient, err := testcommon.GetServiceClient(s.T(), testcommon.TestAccountDefault, nil)
379+
_require.NoError(err)
380+
381+
containerName := testcommon.GenerateContainerName(testName)
382+
containerClient := testcommon.CreateNewContainer(context.Background(), _require, containerName, svcClient)
383+
defer testcommon.DeleteContainer(context.Background(), _require, containerClient)
384+
385+
blobClient := containerClient.NewAppendBlobClient(testcommon.GenerateBlobName("appendsrc"))
386+
387+
// Get source abClient URL with SAS for AppendBlockFromURL.
388+
blobParts, _ := blob.ParseURL(blobClient.URL())
389+
390+
encryptionScope, err := testcommon.GetRequiredEnv(testcommon.EncryptionScopeEnvVar)
391+
_require.Nil(err)
392+
credential, err := testcommon.GetGenericSharedKeyCredential(testcommon.TestAccountDefault)
393+
_require.Nil(err)
394+
perms := sas.BlobPermissions{Read: true, Create: true, Write: true, Delete: true}
395+
396+
blobParts.SAS, err = sas.BlobSignatureValues{
397+
Protocol: sas.ProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
398+
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
399+
ContainerName: blobParts.ContainerName,
400+
BlobName: blobParts.BlobName,
401+
Permissions: perms.String(),
402+
EncryptionScope: encryptionScope,
403+
}.SignWithSharedKey(credential)
404+
_require.NoError(err)
405+
406+
blobURLWithSAS := blobParts.String()
407+
408+
// create new client with sas url
409+
blobClient, err = appendblob.NewClientWithNoCredential(blobURLWithSAS, nil)
410+
_require.Nil(err)
411+
412+
createResponse, err := blobClient.Create(context.Background(), nil)
413+
_require.NoError(err)
414+
_require.Equal(*createResponse.EncryptionScope, encryptionScope)
415+
}
416+
417+
func (s *AppendBlobUnrecordedTestsSuite) TestAccountEncryptionScopeSAS() {
418+
_require := require.New(s.T())
419+
testName := s.T().Name()
420+
svcClient, err := testcommon.GetServiceClient(s.T(), testcommon.TestAccountDefault, nil)
421+
_require.NoError(err)
422+
423+
containerName := testcommon.GenerateContainerName(testName)
424+
containerClient := testcommon.CreateNewContainer(context.Background(), _require, containerName, svcClient)
425+
defer testcommon.DeleteContainer(context.Background(), _require, containerClient)
426+
427+
blobName := testcommon.GenerateBlobName("appendsrc")
428+
blobClient := containerClient.NewAppendBlobClient(blobName)
429+
430+
// Get blob URL with SAS for AppendBlockFromURL.
431+
blobParts, _ := blob.ParseURL(blobClient.URL())
432+
433+
encryptionScope, err := testcommon.GetRequiredEnv(testcommon.EncryptionScopeEnvVar)
434+
_require.Nil(err)
435+
436+
credential, err := testcommon.GetGenericSharedKeyCredential(testcommon.TestAccountDefault)
437+
_require.Nil(err)
438+
439+
blobParts.SAS, err = sas.AccountSignatureValues{
440+
Protocol: sas.ProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
441+
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
442+
Permissions: to.Ptr(sas.AccountPermissions{Read: true, Create: true, Write: true, Delete: true}).String(),
443+
ResourceTypes: to.Ptr(sas.AccountResourceTypes{Service: true, Container: true, Object: true}).String(),
444+
EncryptionScope: encryptionScope,
445+
}.SignWithSharedKey(credential)
446+
_require.NoError(err)
447+
448+
blobURLWithSAS := blobParts.String()
449+
blobClient, err = appendblob.NewClientWithNoCredential(blobURLWithSAS, nil)
450+
_require.NoError(err)
451+
452+
createResp, err := blobClient.Create(context.Background(), nil)
453+
_require.NoError(err)
454+
_require.NotNil(createResp)
455+
_require.Equal(*createResp.EncryptionScope, encryptionScope)
456+
}
457+
458+
func (s *AppendBlobUnrecordedTestsSuite) TestGetUserDelegationEncryptionScopeSAS() {
459+
_require := require.New(s.T())
460+
testName := s.T().Name()
461+
accountName, _ := testcommon.GetGenericAccountInfo(testcommon.TestAccountDefault)
462+
_require.Greater(len(accountName), 0)
463+
464+
cred, err := testcommon.GetGenericTokenCredential()
465+
_require.NoError(err)
466+
467+
svcClient, err := service.NewClient("https://"+accountName+".blob.core.windows.net/", cred, nil)
468+
_require.NoError(err)
469+
470+
containerName := testcommon.GenerateContainerName(testName)
471+
cntClientTokenCred := testcommon.CreateNewContainer(context.Background(), _require, containerName, svcClient)
472+
defer testcommon.DeleteContainer(context.Background(), _require, cntClientTokenCred)
473+
474+
blobName := testcommon.GenerateBlobName("appendsrc")
475+
blobClient := cntClientTokenCred.NewAppendBlobClient(blobName)
476+
477+
// Set current and past time and create key
478+
now := time.Now().UTC().Add(-10 * time.Second)
479+
expiry := now.Add(2 * time.Hour)
480+
info := service.KeyInfo{
481+
Start: to.Ptr(now.UTC().Format(sas.TimeFormat)),
482+
Expiry: to.Ptr(expiry.UTC().Format(sas.TimeFormat)),
483+
}
484+
485+
udc, err := svcClient.GetUserDelegationCredential(context.Background(), info, nil)
486+
_require.NoError(err)
487+
488+
// get permissions and details for sas
489+
encryptionScope, err := testcommon.GetRequiredEnv(testcommon.EncryptionScopeEnvVar)
490+
_require.Nil(err)
491+
492+
permissions := sas.BlobPermissions{Read: true, Create: true, Write: true, List: true, Add: true, Delete: true}
493+
494+
blobParts, _ := blob.ParseURL(blobClient.URL())
495+
496+
// Create Blob Signature Values with desired permissions and sign with user delegation credential
497+
blobParts.SAS, err = sas.BlobSignatureValues{
498+
Protocol: sas.ProtocolHTTPS,
499+
StartTime: time.Now().UTC().Add(time.Second * -10),
500+
ExpiryTime: time.Now().UTC().Add(15 * time.Minute),
501+
Permissions: permissions.String(),
502+
ContainerName: containerName,
503+
EncryptionScope: encryptionScope,
504+
}.SignWithUserDelegation(udc)
505+
_require.NoError(err)
506+
507+
blobURLWithSAS := blobParts.String()
508+
blobClient, err = appendblob.NewClientWithNoCredential(blobURLWithSAS, nil)
509+
_require.NoError(err)
510+
511+
createResp, err := blobClient.Create(context.Background(), nil)
512+
_require.NoError(err)
513+
_require.NotNil(createResp)
514+
_require.Equal(*createResp.EncryptionScope, encryptionScope)
515+
516+
}
517+
374518
func (s *AppendBlobUnrecordedTestsSuite) TestAppendBlockFromURLWithMD5() {
375519
_require := require.New(s.T())
376520
testName := s.T().Name()

sdk/storage/azblob/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "go",
44
"TagPrefix": "go/storage/azblob",
5-
"Tag": "go/storage/azblob_0776f1b95b"
5+
"Tag": "go/storage/azblob_7a25fb98e8"
66
}

sdk/storage/azblob/blob/client.go

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package blob
88

99
import (
1010
"context"
11+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
1112
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror"
1213
"io"
1314
"os"
@@ -37,10 +38,13 @@ type Client base.Client[generated.BlobClient]
3738
func NewClient(blobURL string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) {
3839
authPolicy := shared.NewStorageChallengePolicy(cred)
3940
conOptions := shared.GetClientOptions(options)
40-
conOptions.PerRetryPolicies = append(conOptions.PerRetryPolicies, authPolicy)
41-
pl := runtime.NewPipeline(exported.ModuleName, exported.ModuleVersion, runtime.PipelineOptions{}, &conOptions.ClientOptions)
41+
plOpts := runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}
4242

43-
return (*Client)(base.NewBlobClient(blobURL, pl, &cred)), nil
43+
azClient, err := azcore.NewClient(shared.BlobClient, exported.ModuleVersion, plOpts, &conOptions.ClientOptions)
44+
if err != nil {
45+
return nil, err
46+
}
47+
return (*Client)(base.NewBlobClient(blobURL, azClient, &cred)), nil
4448
}
4549

4650
// NewClientWithNoCredential creates an instance of Client with the specified values.
@@ -49,9 +53,12 @@ func NewClient(blobURL string, cred azcore.TokenCredential, options *ClientOptio
4953
// - options - client options; pass nil to accept the default values
5054
func NewClientWithNoCredential(blobURL string, options *ClientOptions) (*Client, error) {
5155
conOptions := shared.GetClientOptions(options)
52-
pl := runtime.NewPipeline(exported.ModuleName, exported.ModuleVersion, runtime.PipelineOptions{}, &conOptions.ClientOptions)
5356

54-
return (*Client)(base.NewBlobClient(blobURL, pl, nil)), nil
57+
azClient, err := azcore.NewClient(shared.BlobClient, exported.ModuleVersion, runtime.PipelineOptions{}, &conOptions.ClientOptions)
58+
if err != nil {
59+
return nil, err
60+
}
61+
return (*Client)(base.NewBlobClient(blobURL, azClient, nil)), nil
5562
}
5663

5764
// NewClientWithSharedKeyCredential creates an instance of Client with the specified values.
@@ -61,10 +68,13 @@ func NewClientWithNoCredential(blobURL string, options *ClientOptions) (*Client,
6168
func NewClientWithSharedKeyCredential(blobURL string, cred *SharedKeyCredential, options *ClientOptions) (*Client, error) {
6269
authPolicy := exported.NewSharedKeyCredPolicy(cred)
6370
conOptions := shared.GetClientOptions(options)
64-
conOptions.PerRetryPolicies = append(conOptions.PerRetryPolicies, authPolicy)
65-
pl := runtime.NewPipeline(exported.ModuleName, exported.ModuleVersion, runtime.PipelineOptions{}, &conOptions.ClientOptions)
71+
plOpts := runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}
6672

67-
return (*Client)(base.NewBlobClient(blobURL, pl, cred)), nil
73+
azClient, err := azcore.NewClient(shared.BlobClient, exported.ModuleVersion, plOpts, &conOptions.ClientOptions)
74+
if err != nil {
75+
return nil, err
76+
}
77+
return (*Client)(base.NewBlobClient(blobURL, azClient, cred)), nil
6878
}
6979

7080
// NewClientFromConnectionString creates an instance of Client with the specified values.
@@ -116,7 +126,7 @@ func (b *Client) WithSnapshot(snapshot string) (*Client, error) {
116126
}
117127
p.Snapshot = snapshot
118128

119-
return (*Client)(base.NewBlobClient(p.String(), b.generated().Pipeline(), b.credential())), nil
129+
return (*Client)(base.NewBlobClient(p.String(), b.generated().InternalClient(), b.credential())), nil
120130
}
121131

122132
// WithVersionID creates a new AppendBlobURL object identical to the source but with the specified version id.
@@ -128,7 +138,7 @@ func (b *Client) WithVersionID(versionID string) (*Client, error) {
128138
}
129139
p.VersionID = versionID
130140

131-
return (*Client)(base.NewBlobClient(p.String(), b.generated().Pipeline(), b.credential())), nil
141+
return (*Client)(base.NewBlobClient(p.String(), b.generated().InternalClient(), b.credential())), nil
132142
}
133143

134144
// Delete marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection.
@@ -261,8 +271,8 @@ func (b *Client) SetLegalHold(ctx context.Context, legalHold bool, options *SetL
261271
// CopyFromURL synchronously copies the data at the source URL to a block blob, with sizes up to 256 MB.
262272
// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/copy-blob-from-url.
263273
func (b *Client) CopyFromURL(ctx context.Context, copySource string, options *CopyFromURLOptions) (CopyFromURLResponse, error) {
264-
copyOptions, smac, mac, lac := options.format()
265-
resp, err := b.generated().CopyFromURL(ctx, copySource, copyOptions, smac, mac, lac)
274+
copyOptions, smac, mac, lac, cpkScopeInfo := options.format()
275+
resp, err := b.generated().CopyFromURL(ctx, copySource, copyOptions, smac, mac, lac, cpkScopeInfo)
266276
return resp, err
267277
}
268278

0 commit comments

Comments
 (0)