Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,32 @@
"file": {"primary": "FILEENDPOINT", "secondary": "FILESECONDARYENDPOINT"},
"dfs": {"primary": "BLOBENDPOINT", "secondary": "BLOBENDPOINT"},
}
_ACCOUNT_NAME_SUFFIXES = (
"-secondary-dualstack",
"-secondary-ipv6",
"-secondary",
"-dualstack",
"-ipv6",
)


def _strip_account_name_suffix(account_name: str) -> str:
"""Strip any well-known storage endpoint suffix from `account_name`.

Azure Storage endpoints may include suffixes such as `-secondary`,
`-dualstack` or `-ipv6` after the real account name. This function
removes those suffixes so callers always get back the base account name.

:param account_name: The raw account name segment extracted from a storage
endpoint hostname (i.e. everything before the first `.blob.core.`).
:type account_name: str
:return: The account name with any recognized suffix removed.
:rtype: str
"""
for suffix in _ACCOUNT_NAME_SUFFIXES:
if account_name.endswith(suffix):
return account_name[: -len(suffix)]
return account_name


class StorageAccountHostsMixin(object):
Expand Down Expand Up @@ -106,7 +132,7 @@ def __init__(
service_name = service.split("-")[0]
account = parsed_url.netloc.split(f".{service_name}.core.")

self.account_name = account[0] if len(account) > 1 else None
self.account_name = _strip_account_name_suffix(account[0]) if len(account) > 1 else None
if (
not self.account_name
and parsed_url.netloc.startswith("localhost")
Expand Down
28 changes: 28 additions & 0 deletions sdk/storage/azure-storage-blob/tests/test_blob_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,34 @@ def test_create_service_with_socket_timeout(self, **kwargs):
assert service._client._client._pipeline._transport.connection_config.timeout == 22
assert default_service._client._client._pipeline._transport.connection_config.timeout in [20, (20, 2000)]

@pytest.mark.parametrize(
"account_url", [
"https://my-account.blob.core.windows.net/",
"https://my-account-secondary.blob.core.windows.net/",
"https://my-account-dualstack.blob.core.windows.net/",
"https://my-account-ipv6.blob.core.windows.net/",
"https://my-account-secondary-dualstack.blob.core.windows.net/",
"https://my-account-secondary-ipv6.blob.core.windows.net/",
]
)
@BlobPreparer()
def test_create_service_ipv6(self, account_url, **kwargs):
storage_account_name = "my-account"
storage_account_key = kwargs.pop("storage_account_key")

for service_type in SERVICES.keys():
service = service_type(
account_url,
credential=storage_account_key.secret,
container_name='foo',
blob_name='bar'
)

assert service is not None
assert service.scheme == "https"
assert service.account_name == storage_account_name
assert service.credential.account_key == storage_account_key.secret

# --Connection String Test Cases --------------------------------------------

@BlobPreparer()
Expand Down
28 changes: 28 additions & 0 deletions sdk/storage/azure-storage-blob/tests/test_blob_client_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,34 @@ def test_create_service_with_socket_timeout(self, **kwargs):
assert service._client._client._pipeline._transport.connection_config.timeout == 22
assert default_service._client._client._pipeline._transport.connection_config.timeout in [20, (20, 2000)]

@pytest.mark.parametrize(
"account_url", [
"https://my-account.blob.core.windows.net/",
"https://my-account-secondary.blob.core.windows.net/",
"https://my-account-dualstack.blob.core.windows.net/",
"https://my-account-ipv6.blob.core.windows.net/",
"https://my-account-secondary-dualstack.blob.core.windows.net/",
"https://my-account-secondary-ipv6.blob.core.windows.net/",
]
)
@BlobPreparer()
def test_create_service_ipv6(self, account_url, **kwargs):
storage_account_name = "my-account"
storage_account_key = kwargs.pop("storage_account_key")

for service_type in SERVICES.keys():
service = service_type(
account_url,
credential=storage_account_key.secret,
container_name='foo',
blob_name='bar'
)

assert service is not None
assert service.scheme == "https"
assert service.account_name == storage_account_name
assert service.credential.account_key == storage_account_key.secret

# --Connection String Test Cases --------------------------------------------
@BlobPreparer()
def test_create_service_with_connection_string_key(self, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,32 @@
"file": {"primary": "FILEENDPOINT", "secondary": "FILESECONDARYENDPOINT"},
"dfs": {"primary": "BLOBENDPOINT", "secondary": "BLOBENDPOINT"},
}
_ACCOUNT_NAME_SUFFIXES = (
"-secondary-dualstack",
"-secondary-ipv6",
"-secondary",
"-dualstack",
"-ipv6",
)


def _strip_account_name_suffix(account_name: str) -> str:
"""Strip any well-known storage endpoint suffix from `account_name`.

Azure Storage endpoints may include suffixes such as `-secondary`,
`-dualstack` or `-ipv6` after the real account name. This function
removes those suffixes so callers always get back the base account name.

:param account_name: The raw account name segment extracted from a storage
endpoint hostname (i.e. everything before the first `.blob.core.`).
:type account_name: str
:return: The account name with any recognized suffix removed.
:rtype: str
"""
for suffix in _ACCOUNT_NAME_SUFFIXES:
if account_name.endswith(suffix):
return account_name[: -len(suffix)]
return account_name


class StorageAccountHostsMixin(object):
Expand Down Expand Up @@ -106,7 +132,7 @@ def __init__(
service_name = service.split("-")[0]
account = parsed_url.netloc.split(f".{service_name}.core.")

self.account_name = account[0] if len(account) > 1 else None
self.account_name = _strip_account_name_suffix(account[0]) if len(account) > 1 else None
if (
not self.account_name
and parsed_url.netloc.startswith("localhost")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,32 @@
"file": {"primary": "FILEENDPOINT", "secondary": "FILESECONDARYENDPOINT"},
"dfs": {"primary": "BLOBENDPOINT", "secondary": "BLOBENDPOINT"},
}
_ACCOUNT_NAME_SUFFIXES = (
"-secondary-dualstack",
"-secondary-ipv6",
"-secondary",
"-dualstack",
"-ipv6",
)


def _strip_account_name_suffix(account_name: str) -> str:
"""Strip any well-known storage endpoint suffix from `account_name`.

Azure Storage endpoints may include suffixes such as `-secondary`,
`-dualstack` or `-ipv6` after the real account name. This function
removes those suffixes so callers always get back the base account name.

:param account_name: The raw account name segment extracted from a storage
endpoint hostname (i.e. everything before the first `.blob.core.`).
:type account_name: str
:return: The account name with any recognized suffix removed.
:rtype: str
"""
for suffix in _ACCOUNT_NAME_SUFFIXES:
if account_name.endswith(suffix):
return account_name[: -len(suffix)]
return account_name


class StorageAccountHostsMixin(object):
Expand Down Expand Up @@ -106,7 +132,7 @@ def __init__(
service_name = service.split("-")[0]
account = parsed_url.netloc.split(f".{service_name}.core.")

self.account_name = account[0] if len(account) > 1 else None
self.account_name = _strip_account_name_suffix(account[0]) if len(account) > 1 else None
if (
not self.account_name
and parsed_url.netloc.startswith("localhost")
Expand Down
29 changes: 29 additions & 0 deletions sdk/storage/azure-storage-file-share/tests/test_file_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,35 @@ def test_create_service_with_socket_timeout(self, **kwargs):
assert service._client._client._pipeline._transport.connection_config.timeout == 22
assert default_service._client._client._pipeline._transport.connection_config.timeout in [20, (20, 2000)]

@pytest.mark.parametrize(
"account_url", [
"https://my-account.file.core.windows.net/",
"https://my-account-secondary.file.core.windows.net/",
"https://my-account-dualstack.file.core.windows.net/",
"https://my-account-ipv6.file.core.windows.net/",
"https://my-account-secondary-dualstack.file.core.windows.net/",
"https://my-account-secondary-ipv6.file.core.windows.net/",
]
)
@FileSharePreparer()
def test_create_service_ipv6(self, account_url, **kwargs):
storage_account_name = "my-account"
storage_account_key = kwargs.pop("storage_account_key")

for service_type in SERVICES.keys():
service = service_type(
account_url,
credential=storage_account_key.secret,
share_name='foo',
directory_path='bar',
file_path='baz'
)

assert service is not None
assert service.scheme == "https"
assert service.account_name == storage_account_name
assert service.credential.account_key == storage_account_key.secret

# --Connection String Test Cases --------------------------------------------

@FileSharePreparer()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,35 @@ async def test_create_service_with_socket_timeout(self, **kwargs):
assert service._client._client._pipeline._transport.connection_config.timeout == 22
assert default_service._client._client._pipeline._transport.connection_config.timeout in [20, (20, 2000)]

@pytest.mark.parametrize(
"account_url", [
"https://my-account.file.core.windows.net/",
"https://my-account-secondary.file.core.windows.net/",
"https://my-account-dualstack.file.core.windows.net/",
"https://my-account-ipv6.file.core.windows.net/",
"https://my-account-secondary-dualstack.file.core.windows.net/",
"https://my-account-secondary-ipv6.file.core.windows.net/",
]
)
@FileSharePreparer()
def test_create_service_ipv6(self, account_url, **kwargs):
storage_account_name = "my-account"
storage_account_key = kwargs.pop("storage_account_key")

for service_type in SERVICES.keys():
service = service_type(
account_url,
credential=storage_account_key.secret,
share_name='foo',
directory_path='bar',
file_path='baz'
)

assert service is not None
assert service.scheme == "https"
assert service.account_name == storage_account_name
assert service.credential.account_key == storage_account_key.secret

# --Connection String Test Cases --------------------------------------------

@FileSharePreparer()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,32 @@
"file": {"primary": "FILEENDPOINT", "secondary": "FILESECONDARYENDPOINT"},
"dfs": {"primary": "BLOBENDPOINT", "secondary": "BLOBENDPOINT"},
}
_ACCOUNT_NAME_SUFFIXES = (
"-secondary-dualstack",
"-secondary-ipv6",
"-secondary",
"-dualstack",
"-ipv6",
)


def _strip_account_name_suffix(account_name: str) -> str:
"""Strip any well-known storage endpoint suffix from `account_name`.

Azure Storage endpoints may include suffixes such as `-secondary`,
`-dualstack` or `-ipv6` after the real account name. This function
removes those suffixes so callers always get back the base account name.

:param account_name: The raw account name segment extracted from a storage
endpoint hostname (i.e. everything before the first `.blob.core.`).
:type account_name: str
:return: The account name with any recognized suffix removed.
:rtype: str
"""
for suffix in _ACCOUNT_NAME_SUFFIXES:
if account_name.endswith(suffix):
return account_name[: -len(suffix)]
return account_name


class StorageAccountHostsMixin(object):
Expand Down Expand Up @@ -106,7 +132,7 @@ def __init__(
service_name = service.split("-")[0]
account = parsed_url.netloc.split(f".{service_name}.core.")

self.account_name = account[0] if len(account) > 1 else None
self.account_name = _strip_account_name_suffix(account[0]) if len(account) > 1 else None
if (
not self.account_name
and parsed_url.netloc.startswith("localhost")
Expand Down
24 changes: 24 additions & 0 deletions sdk/storage/azure-storage-queue/tests/test_queue_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,30 @@ def test_create_service_with_socket_timeout(self, **kwargs):
assert service._client._client._pipeline._transport.connection_config.timeout == 22
assert default_service._client._client._pipeline._transport.connection_config.timeout in [20, (20, 2000)]

@pytest.mark.parametrize(
"account_url",
[
"https://my-account.queue.core.windows.net/",
"https://my-account-secondary.queue.core.windows.net/",
"https://my-account-dualstack.queue.core.windows.net/",
"https://my-account-ipv6.queue.core.windows.net/",
"https://my-account-secondary-dualstack.queue.core.windows.net/",
"https://my-account-secondary-ipv6.queue.core.windows.net/",
],
)
@QueuePreparer()
def test_create_service_ipv6(self, account_url, **kwargs):
storage_account_name = "my-account"
storage_account_key = kwargs.pop("storage_account_key")

for service_type in SERVICES.keys():
service = service_type(account_url, credential=storage_account_key.secret, queue_name="foo")

assert service is not None
assert service.scheme == "https"
assert service.account_name == storage_account_name
assert service.credential.account_key == storage_account_key.secret

# --Connection String Test Cases --------------------------------------------
@QueuePreparer()
def test_create_service_with_connection_string_key(self, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,30 @@ def test_create_service_with_socket_timeout(self, **kwargs):
assert service._client._client._pipeline._transport.connection_config.timeout == 22
assert default_service._client._client._pipeline._transport.connection_config.timeout in [20, (20, 2000)]

@pytest.mark.parametrize(
"account_url",
[
"https://my-account.queue.core.windows.net/",
"https://my-account-secondary.queue.core.windows.net/",
"https://my-account-dualstack.queue.core.windows.net/",
"https://my-account-ipv6.queue.core.windows.net/",
"https://my-account-secondary-dualstack.queue.core.windows.net/",
"https://my-account-secondary-ipv6.queue.core.windows.net/",
],
)
@QueuePreparer()
def test_create_service_ipv6(self, account_url, **kwargs):
storage_account_name = "my-account"
storage_account_key = kwargs.pop("storage_account_key")

for service_type in SERVICES.keys():
service = service_type(account_url, credential=storage_account_key.secret, queue_name="foo")

assert service is not None
assert service.scheme == "https"
assert service.account_name == storage_account_name
assert service.credential.account_key == storage_account_key.secret

# --Connection String Test Cases --------------------------------------------
@QueuePreparer()
def test_create_service_with_connection_string_key(self, **kwargs):
Expand Down
Loading