Skip to content

Commit c554729

Browse files
YionseChenxiJiang333v-xuto
authored
Azure Storage Sample Automation (Azure#39944)
* complete storage automation * fix storage * fix * Create cspell.yaml * skip mypy for specified line * Add type annotations for key_bytes and key_id * Fix container conflicts * Fix type issues in KeyVaultKey initialization * Fix container conflicts * Replace SecretClient with KeyClient in sample * skip container access policy samples * create containers in the samples * Handle existing container creation error * remove keyvault dependency and skip keyvault sample tests --------- Co-authored-by: ChenxiJiang333 <[email protected]> Co-authored-by: ChenxiJiang333 <[email protected]> Co-authored-by: Tong Xu (MSFT) <[email protected]>
1 parent ba90e15 commit c554729

File tree

67 files changed

+536
-462
lines changed

Some content is hidden

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

67 files changed

+536
-462
lines changed

scripts/devops_tasks/test_run_samples.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@
153153
"sample_abstract_summary.py",
154154
"sample_abstract_summary_async.py",
155155
],
156+
"azure-storage-blob": [
157+
"blob_samples_proxy_configuration.py",
158+
"blob_samples_container_access_policy.py",
159+
"blob_samples_container_access_policy_async.py",
160+
"blob_samples_client_side_encryption_keyvault.py"
161+
],
156162
}
157163

158164
def run_check_call_with_timeout(

sdk/storage/azure-storage-blob/samples/blob_samples_authentication.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,29 @@
1616
USAGE:
1717
python blob_samples_authentication.py
1818
Set the environment variables with your own values before running the sample:
19-
1) AZURE_STORAGE_CONNECTION_STRING - the connection string to your storage account
19+
1) STORAGE_CONNECTION_STRING - the connection string to your storage account
2020
2) OAUTH_STORAGE_ACCOUNT_NAME - the oauth storage account name
21-
3) AZURE_STORAGE_ACCOUNT_NAME - the name of the storage account
22-
4) AZURE_STORAGE_ACCESS_KEY - the storage account access key
21+
3) STORAGE_ACCOUNT_NAME - the name of the storage account
22+
4) STORAGE_ACCOUNT_KEY - the storage account access key
2323
"""
2424

2525
import os
2626
import sys
2727

2828
class AuthSamples(object):
2929
url = "https://{}.blob.core.windows.net".format(
30-
os.getenv("AZURE_STORAGE_ACCOUNT_NAME")
30+
os.getenv("STORAGE_ACCOUNT_NAME")
3131
)
3232
oauth_url = "https://{}.blob.core.windows.net".format(
3333
os.getenv("OAUTH_STORAGE_ACCOUNT_NAME")
3434
)
3535

36-
connection_string = os.getenv("AZURE_STORAGE_CONNECTION_STRING")
37-
shared_access_key = os.getenv("AZURE_STORAGE_ACCESS_KEY")
36+
connection_string = os.getenv("STORAGE_CONNECTION_STRING")
37+
shared_access_key = os.getenv("STORAGE_ACCOUNT_KEY")
3838

3939
def auth_connection_string(self):
4040
if self.connection_string is None:
41-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
41+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
4242
"Test: auth_connection_string")
4343
sys.exit(1)
4444
# [START auth_from_connection_string]
@@ -63,7 +63,7 @@ def auth_connection_string(self):
6363

6464
def auth_shared_key(self):
6565
if self.shared_access_key is None:
66-
print("Missing required environment variable: AZURE_STORAGE_ACCESS_KEY." + '\n' +
66+
print("Missing required environment variable: STORAGE_ACCOUNT_KEY." + '\n' +
6767
"Test: auth_shared_key")
6868
sys.exit(1)
6969
# [START create_blob_service_client]
@@ -89,7 +89,7 @@ def auth_blob_url(self):
8989

9090
def auth_shared_access_signature(self):
9191
if self.connection_string is None:
92-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
92+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
9393
"Test: auth_shared_access_signature")
9494
sys.exit(1)
9595
# Instantiate a BlobServiceClient using a connection string

sdk/storage/azure-storage-blob/samples/blob_samples_authentication_async.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
USAGE:
1717
python blob_samples_authentication_async.py
1818
Set the environment variables with your own values before running the sample:
19-
1) AZURE_STORAGE_CONNECTION_STRING - the connection string to your storage account
19+
1) STORAGE_CONNECTION_STRING - the connection string to your storage account
2020
2) OAUTH_STORAGE_ACCOUNT_NAME - the oauth storage account name
21-
3) AZURE_STORAGE_ACCOUNT_NAME - the name of the storage account
22-
4) AZURE_STORAGE_ACCESS_KEY - the storage account access key
21+
3) STORAGE_ACCOUNT_NAME - the name of the storage account
22+
4) STORAGE_ACCOUNT_KEY - the storage account access key
2323
"""
2424

2525

@@ -29,18 +29,18 @@
2929

3030
class AuthSamplesAsync(object):
3131
url = "https://{}.blob.core.windows.net".format(
32-
os.getenv("AZURE_STORAGE_ACCOUNT_NAME")
32+
os.getenv("STORAGE_ACCOUNT_NAME")
3333
)
3434
oauth_url = "https://{}.blob.core.windows.net".format(
3535
os.getenv("OAUTH_STORAGE_ACCOUNT_NAME")
3636
)
3737

38-
connection_string = os.getenv("AZURE_STORAGE_CONNECTION_STRING")
39-
shared_access_key = os.getenv("AZURE_STORAGE_ACCESS_KEY")
38+
connection_string = os.getenv("STORAGE_CONNECTION_STRING")
39+
shared_access_key = os.getenv("STORAGE_ACCOUNT_KEY")
4040

4141
async def auth_connection_string_async(self):
4242
if self.connection_string is None:
43-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
43+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
4444
"Test: auth_connection_string_async")
4545
sys.exit(1)
4646
# [START auth_from_connection_string]
@@ -62,7 +62,7 @@ async def auth_connection_string_async(self):
6262

6363
async def auth_shared_key_async(self):
6464
if self.shared_access_key is None:
65-
print("Missing required environment variable: AZURE_STORAGE_ACCESS_KEY." + '\n' +
65+
print("Missing required environment variable: STORAGE_ACCOUNT_KEY." + '\n' +
6666
"Test: auth_shared_key_async")
6767
sys.exit(1)
6868
# [START create_blob_service_client]
@@ -85,7 +85,7 @@ async def auth_blob_url_async(self):
8585

8686
async def auth_shared_access_signature_async(self):
8787
if self.connection_string is None:
88-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
88+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
8989
"Test: auth_shared_access_signature_async")
9090
sys.exit(1)
9191
# Instantiate a BlobServiceClient using a connection string

sdk/storage/azure-storage-blob/samples/blob_samples_batch_delete_blobs.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,19 @@
1010
USAGE:
1111
python blob_samples_batch_delete_blobs.py
1212
Set the environment variables with your own values before running the sample:
13-
1) AZURE_STORAGE_CONNECTION_STRING - the connection string to your storage account
13+
1) STORAGE_CONNECTION_STRING - the connection string to your storage account
1414
"""
1515

16-
SOURCE_FOLDER = "./sample-blobs/"
16+
current_dir = os.path.dirname(os.path.abspath(__file__))
17+
SOURCE_FOLDER = os.path.join(current_dir, "./sample-blobs/")
1718

1819

1920
def batch_delete_blobs_sample(local_path):
2021
# Set the connection string and container name values to initialize the Container Client
21-
connection_string = os.getenv('AZURE_STORAGE_CONNECTION_STRING')
22+
connection_string = os.getenv('STORAGE_CONNECTION_STRING')
2223

2324
if connection_string is None:
24-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
25+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
2526
"Test: batch_delete_blobs_sample")
2627
sys.exit(1)
2728

sdk/storage/azure-storage-blob/samples/blob_samples_client_side_encryption.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
This example contains sample code for the KeyWrapper and KeyResolver classes
1414
needed to use Storage client side encryption, as well as code that illustrates
1515
key usage patterns for client side encryption features. This sample expects that
16-
the `AZURE_STORAGE_CONNECTION_STRING` environment variable is set. It SHOULD NOT
16+
the `STORAGE_CONNECTION_STRING` environment variable is set. It SHOULD NOT
1717
be hardcoded in any code derived from this sample.
1818
1919
USAGE: python blob_samples_client_side_encryption.py
2020
Set the environment variables with your own values before running the sample:
21-
1) AZURE_STORAGE_CONNECTION_STRING - the connection string to your storage account
21+
1) STORAGE_CONNECTION_STRING - the connection string to your storage account
2222
"""
2323

2424
import os
@@ -275,9 +275,9 @@ def alternate_key_algorithms(self):
275275
self.container_client.delete_container()
276276

277277
try:
278-
CONNECTION_STRING = os.environ['AZURE_STORAGE_CONNECTION_STRING']
278+
CONNECTION_STRING = os.environ['STORAGE_CONNECTION_STRING']
279279
except KeyError:
280-
print("AZURE_STORAGE_CONNECTION_STRING must be set.")
280+
print("STORAGE_CONNECTION_STRING must be set.")
281281
sys.exit(1)
282282

283283
# Configure max_single_put_size to make blobs in this sample smaller

sdk/storage/azure-storage-blob/samples/blob_samples_client_side_encryption_keyvault.py

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,30 @@
1414
service for client side encryption, storing and retrieving the key encryption key
1515
(kek) from within Azure KeyVault. This sample requires a service principal be set
1616
configured with access to KeyVault, and that the vault contains a 256-bit base64-
17-
encoded secret named "symmetric-key". Additionally, a number of environment
17+
encoded key named "symmetric-key". Additionally, a number of environment
1818
variables, listed below, must be set. Since these often contain sensitive information,
1919
they SHOULD NOT be replaced with hardcoded values in any code derived from this sample.
2020
2121
USAGE: python blob_samples_client_side_encryption_keyvault.py
2222
Set the environment variables with your own values before running the sample:
2323
1) AZURE_STORAGE_ACCOUNT_URL - the storage account url
24-
2) ACTIVE_DIRECTORY_APPLICATION_ID - Azure Active Directory application ID
25-
3) ACTIVE_DIRECTORY_APPLICATION_SECRET - Azure Active Directory application secret
26-
4) ACTIVE_DIRECTORY_TENANT_ID - Azure Active Directory tenant ID
27-
5) AZURE_KEYVAULT_DNS_NAME: The keyvault account dns name
24+
2) AZURE_KEYVAULT_DNS_NAME: The keyvault account dns name
2825
"""
2926

30-
import base64
3127
import os
3228
import sys
3329
import uuid
3430

3531
from azure.identity import DefaultAzureCredential
3632

3733
from azure.keyvault.keys.crypto import CryptographyClient, KeyWrapAlgorithm
38-
from azure.keyvault.keys import KeyVaultKey, KeyType
39-
from azure.keyvault.secrets import SecretClient
34+
from azure.keyvault.keys import KeyClient
4035

4136
from azure.storage.blob import BlobServiceClient
4237

4338
# Environment variable keys which must be set to run this sample
44-
STORAGE_URL = 'AZURE_STORAGE_ACCOUNT_URL'
45-
KEYVAULT_URL = 'AZURE_KEYVAULT_DNS_NAME'
46-
CLIENT_ID = 'ACTIVE_DIRECTORY_APPLICATION_ID'
47-
CLIENT_SECRET = 'ACTIVE_DIRECTORY_APPLICATION_SECRET'
48-
TENANT_ID = 'ACTIVE_DIRECTORY_TENANT_ID'
39+
STORAGE_URL = 'STORAGE_ACCOUNT_BLOB_URL'
40+
KEYVAULT_URL = 'KEYVAULT_URL'
4941

5042
def get_env_var(key):
5143
try:
@@ -62,19 +54,19 @@ class KeyWrapper:
6254
automatic client-side encyrption and decryption routines. """
6355

6456
def __init__(self, kek, credential):
65-
self.algorithm = KeyWrapAlgorithm.aes_256
57+
self.algorithm = KeyWrapAlgorithm.rsa_oaep_256
6658
self.kek = kek
6759
self.kid = kek.id
6860
self.client = CryptographyClient(kek, credential)
6961

7062
def wrap_key(self, key):
71-
if self.algorithm != KeyWrapAlgorithm.aes_256:
63+
if self.algorithm != KeyWrapAlgorithm.rsa_oaep_256:
7264
raise ValueError('Unknown key wrap algorithm. {}'.format(self.algorithm))
7365
wrapped = self.client.wrap_key(key=key, algorithm=self.algorithm)
7466
return wrapped.encrypted_key
7567

7668
def unwrap_key(self, key, _):
77-
if self.algorithm != KeyWrapAlgorithm.aes_256:
69+
if self.algorithm != KeyWrapAlgorithm.rsa_oaep_256:
7870
raise ValueError('Unknown key wrap algorithm. {}'.format(self.algorithm))
7971
unwrapped = self.client.unwrap_key(encrypted_key=key, algorithm=self.algorithm)
8072
return unwrapped.key
@@ -91,12 +83,10 @@ def get_kid(self):
9183

9284
# Construct a token credential for use by Storage and KeyVault clients.
9385
credential = DefaultAzureCredential()
94-
secret_client = SecretClient(keyvault_url, credential=credential)
86+
key_client = KeyClient(keyvault_url, credential=credential)
9587

96-
# The secret is url-safe base64 encoded bytes, content type 'application/octet-stream'
97-
secret = secret_client.get_secret('symmetric-key')
98-
key_bytes = base64.urlsafe_b64decode(secret.value)
99-
kvk = KeyVaultKey(key_id=secret.id, key_ops=['unwrapKey', 'wrapKey'], k=key_bytes, kty=KeyType.oct)
88+
# The key is url-safe base64 encoded bytes
89+
kvk = key_client.create_rsa_key(name="symmetric-key", size=2048, key_operations=["unwrapKey", "wrapKey"])
10090
kek = KeyWrapper(kvk, credential)
10191

10292
storage_client = BlobServiceClient(storage_url, credential=credential)

sdk/storage/azure-storage-blob/samples/blob_samples_common.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
USAGE:
1515
python blob_samples_common.py
1616
Set the environment variables with your own values before running the sample.
17-
1) AZURE_STORAGE_CONNECTION_STRING - the connection string to your storage account
17+
1) STORAGE_CONNECTION_STRING - the connection string to your storage account
1818
"""
1919

2020
import os
@@ -23,18 +23,19 @@
2323
from azure.core.exceptions import HttpResponseError, ResourceExistsError
2424
from azure.storage.blob import BlobServiceClient
2525

26-
SOURCE_FILE = 'SampleSource.txt'
26+
current_dir = os.path.dirname(os.path.abspath(__file__))
27+
SOURCE_FILE = os.path.join(current_dir, 'SampleSource.txt')
2728

2829

2930
class CommonBlobSamples(object):
3031

31-
connection_string = os.getenv("AZURE_STORAGE_CONNECTION_STRING")
32+
connection_string = os.getenv("STORAGE_CONNECTION_STRING_SOFT")
3233

3334
#--Begin Blob Samples-----------------------------------------------------------------
3435

3536
def blob_snapshots(self):
3637
if self.connection_string is None:
37-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
38+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
3839
"Test: blob_snapshots")
3940
sys.exit(1)
4041

@@ -74,7 +75,7 @@ def blob_snapshots(self):
7475

7576
def soft_delete_and_undelete_blob(self):
7677
if self.connection_string is None:
77-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
78+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
7879
"Test: soft_delete_and_undelete_blob")
7980
sys.exit(1)
8081

@@ -120,7 +121,7 @@ def soft_delete_and_undelete_blob(self):
120121

121122
def delete_multiple_blobs(self):
122123
if self.connection_string is None:
123-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
124+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
124125
"Test: delete_multiple_blobs")
125126
sys.exit(1)
126127
# Instantiate a BlobServiceClient using a connection string
@@ -157,7 +158,7 @@ def delete_multiple_blobs(self):
157158

158159
def acquire_lease_on_blob(self):
159160
if self.connection_string is None:
160-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
161+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
161162
"Test: acquire_lease_on_blob")
162163
sys.exit(1)
163164

@@ -194,7 +195,7 @@ def acquire_lease_on_blob(self):
194195

195196
def start_copy_blob_from_url_and_abort_copy(self):
196197
if self.connection_string is None:
197-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
198+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
198199
"Test: start_copy_blob_from_url_and_abort_copy")
199200
sys.exit(1)
200201
# Instantiate a BlobServiceClient using a connection string

sdk/storage/azure-storage-blob/samples/blob_samples_common_async.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,27 @@
1414
USAGE:
1515
python blob_samples_common_async.py
1616
Set the environment variables with your own values before running the sample.
17-
1) AZURE_STORAGE_CONNECTION_STRING - the connection string to your storage account
17+
1) STORAGE_CONNECTION_STRING - the connection string to your storage account
1818
"""
1919

2020
import os
2121
import sys
2222
import asyncio
2323
from azure.core.exceptions import ResourceExistsError
2424

25-
26-
SOURCE_FILE = './SampleSource.txt'
25+
current_dir = os.path.dirname(os.path.abspath(__file__))
26+
SOURCE_FILE = os.path.join(current_dir, 'SampleSource.txt')
2727

2828

2929
class CommonBlobSamplesAsync(object):
3030

31-
connection_string = os.getenv("AZURE_STORAGE_CONNECTION_STRING")
31+
connection_string = os.getenv("STORAGE_CONNECTION_STRING_SOFT")
3232

3333
#--Begin Blob Samples-----------------------------------------------------------------
3434

3535
async def blob_snapshots_async(self):
3636
if self.connection_string is None:
37-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
37+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
3838
"Test: blob_snapshots_async")
3939
sys.exit(1)
4040
# Instantiate a BlobServiceClient using a connection string
@@ -74,7 +74,7 @@ async def blob_snapshots_async(self):
7474

7575
async def soft_delete_and_undelete_blob_async(self):
7676
if self.connection_string is None:
77-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
77+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
7878
"Test: soft_delete_and_undelete_blob_async")
7979
sys.exit(1)
8080
# Instantiate a BlobServiceClient using a connection string
@@ -120,7 +120,7 @@ async def soft_delete_and_undelete_blob_async(self):
120120

121121
async def delete_multiple_blobs_async(self):
122122
if self.connection_string is None:
123-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
123+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
124124
"Test: delete_multiple_blobs_async")
125125
sys.exit(1)
126126
# Instantiate a BlobServiceClient using a connection string
@@ -158,7 +158,7 @@ async def delete_multiple_blobs_async(self):
158158

159159
async def acquire_lease_on_blob_async(self):
160160
if self.connection_string is None:
161-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
161+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
162162
"Test: acquire_lease_on_blob_async")
163163
sys.exit(1)
164164
# Instantiate a BlobServiceClient using a connection string
@@ -195,7 +195,7 @@ async def acquire_lease_on_blob_async(self):
195195

196196
async def start_copy_blob_from_url_and_abort_copy_async(self):
197197
if self.connection_string is None:
198-
print("Missing required environment variable: AZURE_STORAGE_CONNECTION_STRING." + '\n' +
198+
print("Missing required environment variable: STORAGE_CONNECTION_STRING." + '\n' +
199199
"Test: start_copy_blob_from_url_and_abort_copy_async")
200200
sys.exit(1)
201201
# Instantiate a BlobServiceClient using a connection string

0 commit comments

Comments
 (0)