This is an automated email from the ASF dual-hosted git repository.
ephraimanierobi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new fcbf15947f Fix breaking change when Active Directory ID is used as
host in WASB (#32560)
fcbf15947f is described below
commit fcbf15947f2f271d502bc6f4b9e3d0bada072d84
Author: Ephraim Anierobi <[email protected]>
AuthorDate: Wed Jul 12 17:49:43 2023 +0100
Fix breaking change when Active Directory ID is used as host in WASB
(#32560)
* Fix breaking change when Active Directory ID is used as host in WASB
A recent change:
https://github.com/apache/airflow/commit/46ee1c2c8d3d0e5793f42fd10bcd80150caa538b,
to build account url if not provided broke backward compatibility in Wasb
hook by assuming that
host is always provided as a fully qualified url. Previously, we generate
the account url
as the last resort to getting the connection.
This change restores the previous behaviour of generating a URL if the host
was provided with an ID
instead of a URL
* Update tests/providers/microsoft/azure/hooks/test_wasb.py
* rstrip trailing slash in url
---
airflow/providers/microsoft/azure/hooks/wasb.py | 8 ++++-
tests/providers/microsoft/azure/hooks/test_wasb.py | 36 ++++++++++++++++++++++
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/airflow/providers/microsoft/azure/hooks/wasb.py
b/airflow/providers/microsoft/azure/hooks/wasb.py
index 2281e184c2..6c4b76cdc4 100644
--- a/airflow/providers/microsoft/azure/hooks/wasb.py
+++ b/airflow/providers/microsoft/azure/hooks/wasb.py
@@ -210,13 +210,19 @@ class WasbHook(BaseHook):
if sas_token.startswith("https"):
return BlobServiceClient(account_url=sas_token, **extra)
else:
- return
BlobServiceClient(account_url=f"{account_url}/{sas_token}", **extra)
+ if not account_url.startswith("https://"):
+ # TODO: require url in the host field in the next major
version?
+ account_url = f"https://{conn.login}.blob.core.windows.net"
+ return
BlobServiceClient(account_url=f"{account_url.rstrip('/')}/{sas_token}", **extra)
# Fall back to old auth (password) or use managed identity if not
provided.
credential = conn.password
if not credential:
credential = DefaultAzureCredential()
self.log.info("Using DefaultAzureCredential as credential")
+ if not account_url.startswith("https://"):
+ # TODO: require url in the host field in the next major version?
+ account_url = f"https://{conn.login}.blob.core.windows.net/"
return BlobServiceClient(
account_url=account_url,
credential=credential,
diff --git a/tests/providers/microsoft/azure/hooks/test_wasb.py
b/tests/providers/microsoft/azure/hooks/test_wasb.py
index 672d20d3a6..9e9ce9a0d0 100644
--- a/tests/providers/microsoft/azure/hooks/test_wasb.py
+++ b/tests/providers/microsoft/azure/hooks/test_wasb.py
@@ -200,6 +200,42 @@ class TestWasbHook:
assert isinstance(hook.get_conn(), BlobServiceClient)
assert isinstance(hook.get_conn().credential, ClientSecretCredential)
+
@mock.patch("airflow.providers.microsoft.azure.hooks.wasb.BlobServiceClient")
+
@mock.patch("airflow.providers.microsoft.azure.hooks.wasb.DefaultAzureCredential")
+
@mock.patch("airflow.providers.microsoft.azure.hooks.wasb.WasbHook.get_connection")
+ def test_active_directory_ID_used_as_host(self, mock_get_conn,
mock_credential, mock_blob_service_client):
+ hook = WasbHook(wasb_conn_id="testconn")
+ mock_get_conn.return_value = Connection(
+ conn_id="testconn",
+ conn_type=self.connection_type,
+ login="testaccountname",
+ host="testaccountID",
+ )
+ hook.get_conn()
+ assert mock_blob_service_client.call_args == mock.call(
+ account_url="https://testaccountname.blob.core.windows.net/",
+ credential=mock_credential.return_value,
+ )
+
+
@mock.patch("airflow.providers.microsoft.azure.hooks.wasb.BlobServiceClient")
+
@mock.patch("airflow.providers.microsoft.azure.hooks.wasb.WasbHook.get_connection")
+ def test_sas_token_provided_and_active_directory_ID_used_as_host(
+ self, mock_get_conn, mock_blob_service_client
+ ):
+ hook = WasbHook(wasb_conn_id="testconn")
+ mock_get_conn.return_value = Connection(
+ conn_id="testconn",
+ conn_type=self.connection_type,
+ login="testaccountname",
+ host="testaccountID",
+ extra=json.dumps({"sas_token": "SAStoken"}),
+ )
+ hook.get_conn()
+ assert mock_blob_service_client.call_args == mock.call(
+
account_url="https://testaccountname.blob.core.windows.net/SAStoken",
+ sas_token="SAStoken",
+ )
+
@pytest.mark.parametrize(
argnames="conn_id_str",
argvalues=[