Skip to content

Commit 0301417

Browse files
[Storage] Add argument to perf tests to use client-side encryption (#24978)
1 parent b6e1f51 commit 0301417

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

sdk/storage/azure-storage-blob/tests/perfstress_tests/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ The options are available for all Blob perf tests:
5454
- `--max-put-size` Maximum size of data uploading in single HTTP PUT. Default is 64\*1024\*1024.
5555
- `--max-block-size` Maximum size of data in a block within a blob. Defaults to 4\*1024\*1024.
5656
- `--buffer-threshold` Minimum block size to prevent full block buffering. Defaults to 4\*1024\*1024+1.
57+
- `--client-encryption` The version of client-side encryption to use. Leave out for no encryption.
5758

5859
#### List Blobs command line options
5960
This option is only available to the List Blobs test (T1 and T2).

sdk/storage/azure-storage-blob/tests/perfstress_tests/_test_base.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
# Licensed under the MIT License. See License.txt in the project root for license information.
44
# --------------------------------------------------------------------------------------------
55

6-
import os
76
import uuid
87

98
from azure_devtools.perfstress_tests import PerfStressTest
10-
11-
from azure.core.exceptions import ResourceNotFoundError
129
from azure.storage.blob import BlobServiceClient as SyncBlobServiceClient
1310
from azure.storage.blob.aio import BlobServiceClient as AsyncBlobServiceClient
1411

12+
from .key_wrapper import KeyWrapper
13+
1514

1615
class _ServiceTest(PerfStressTest):
1716
service_client = None
@@ -25,13 +24,18 @@ def __init__(self, arguments):
2524
self._client_kwargs['max_single_put_size'] = self.args.max_put_size
2625
self._client_kwargs['max_block_size'] = self.args.max_block_size
2726
self._client_kwargs['min_large_block_upload_threshold'] = self.args.buffer_threshold
27+
if self.args.client_encryption:
28+
self.key_encryption_key = KeyWrapper()
29+
self._client_kwargs['require_encryption'] = True
30+
self._client_kwargs['key_encryption_key'] = self.key_encryption_key
31+
self._client_kwargs['encryption_version'] = self.args.client_encryption
2832
# self._client_kwargs['api_version'] = '2019-02-02' # Used only for comparison with T1 legacy tests
2933

3034
if not _ServiceTest.service_client or self.args.no_client_share:
3135
_ServiceTest.service_client = SyncBlobServiceClient.from_connection_string(conn_str=connection_string, **self._client_kwargs)
3236
_ServiceTest.async_service_client = AsyncBlobServiceClient.from_connection_string(conn_str=connection_string, **self._client_kwargs)
3337
self.service_client = _ServiceTest.service_client
34-
self.async_service_client =_ServiceTest.async_service_client
38+
self.async_service_client = _ServiceTest.async_service_client
3539

3640
async def close(self):
3741
await self.async_service_client.close()
@@ -43,6 +47,7 @@ def add_arguments(parser):
4347
parser.add_argument('--max-put-size', nargs='?', type=int, help='Maximum size of data uploading in single HTTP PUT. Defaults to 64*1024*1024', default=64*1024*1024)
4448
parser.add_argument('--max-block-size', nargs='?', type=int, help='Maximum size of data in a block within a blob. Defaults to 4*1024*1024', default=4*1024*1024)
4549
parser.add_argument('--buffer-threshold', nargs='?', type=int, help='Minimum block size to prevent full block buffering. Defaults to 4*1024*1024+1', default=4*1024*1024+1)
50+
parser.add_argument('--client-encryption', nargs='?', type=str, help='The version of client-side encryption to use. Leave out for no encryption.', default=None)
4651
parser.add_argument('--max-concurrency', nargs='?', type=int, help='Maximum number of concurrent threads used for data transfer. Defaults to 1', default=1)
4752
parser.add_argument('-s', '--size', nargs='?', type=int, help='Size of data to transfer. Default is 10240.', default=10240)
4853
parser.add_argument('--no-client-share', action='store_true', help='Create one ServiceClient per test instance. Default is to share a single ServiceClient.', default=False)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# --------------------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for license information.
4+
# --------------------------------------------------------------------------------------------
5+
6+
import os
7+
8+
from cryptography.hazmat.backends import default_backend
9+
from cryptography.hazmat.primitives.keywrap import aes_key_wrap, aes_key_unwrap
10+
11+
12+
class KeyWrapper:
13+
def __init__(self, kid='local:key1'):
14+
self.kek = os.urandom(32)
15+
self.backend = default_backend()
16+
self.kid = kid
17+
18+
def wrap_key(self, key, algorithm='A256KW'):
19+
if algorithm == 'A256KW':
20+
return aes_key_wrap(self.kek, key, self.backend)
21+
22+
raise ValueError("Unknown key wrap algorithm.")
23+
24+
def unwrap_key(self, key, algorithm):
25+
if algorithm == 'A256KW':
26+
return aes_key_unwrap(self.kek, key, self.backend)
27+
28+
raise ValueError("Unknown key wrap algorithm.")
29+
30+
def get_key_wrap_algorithm(self):
31+
return 'A256KW'
32+
33+
def get_kid(self):
34+
return self.kid

0 commit comments

Comments
 (0)