From 59d933f4777a25a3ac189a4d8722029bf1e2768f Mon Sep 17 00:00:00 2001 From: Jayaraj Tale Date: Wed, 16 Sep 2026 02:30:15 -0400 Subject: [PATCH] Return structured authentication results --- cfa/cloudops/_cloudclient.py | 34 ++++++++++++++++++++++++++++++--- tests/test_cloudclient_more.py | 35 ++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/cfa/cloudops/_cloudclient.py b/cfa/cloudops/_cloudclient.py index 9fea395c..dc633ebf 100644 --- a/cfa/cloudops/_cloudclient.py +++ b/cfa/cloudops/_cloudclient.py @@ -168,23 +168,51 @@ def __init__( self.task_id_ints = False self.task_id_max = 0 - def check_credentials(self): + def check_credentials(self) -> pd.DataFrame: + """Check credentials and return accessible Azure resource information. + + Returns: + pd.DataFrame: A DataFrame containing subscription information and the + configured Batch and Storage account names. + """ logger.debug("Checking credentials by listing subscriptions.") cred = self.cred.default_credential + columns = [ + "subscription_id", + "subscription_name", + "state", + "batch_account", + "storage_account", + ] + try: subscription_client = SubscriptionClient(cred) - # List subscriptions - sub_list = [sub for sub in subscription_client.subscriptions.list()] + sub_list = list(subscription_client.subscriptions.list()) + + rows = [] for subscription in sub_list: logger.info("Found subscription via credential.") logger.info(f"Subscription ID: {subscription.subscription_id}") logger.info(f"Subscription Name: {subscription.display_name}") logger.info(f"State: {subscription.state}") logger.info("-" * 30) + + rows.append( + { + "subscription_id": subscription.subscription_id, + "subscription_name": subscription.display_name, + "state": subscription.state, + "batch_account": self.cred.azure_batch_account, + "storage_account": self.cred.azure_blob_storage_account, + } + ) + logger.debug("Successfully found subscriptions.") + return pd.DataFrame(rows, columns=columns) except Exception as e: logger.exception(f"Error checking credentials: {e}") + return pd.DataFrame(columns=columns) def create_pool( self, diff --git a/tests/test_cloudclient_more.py b/tests/test_cloudclient_more.py index 95148352..1eba7b62 100644 --- a/tests/test_cloudclient_more.py +++ b/tests/test_cloudclient_more.py @@ -41,7 +41,7 @@ def cloud_client_more(monkeypatch): return CloudClient(dotenv_path=None, use_sp=False, use_federated=False) -def test_check_credentials_env_default_sp(cloud_client_more, monkeypatch): +def test_check_credentials_returns_dataframe(cloud_client_more, monkeypatch): seen_creds = [] class FakeSub: @@ -58,11 +58,25 @@ def fake_subscription_client(cred): "cfa.cloudops._cloudclient.SubscriptionClient", fake_subscription_client ) - cloud_client_more.check_credentials() - cloud_client_more.check_credentials() - cloud_client_more.check_credentials() + result = cloud_client_more.check_credentials() - assert seen_creds == ["default-cred", "default-cred", "default-cred"] + assert seen_creds == ["default-cred"] + assert list(result.columns) == [ + "subscription_id", + "subscription_name", + "state", + "batch_account", + "storage_account", + ] + assert result.to_dict(orient="records") == [ + { + "subscription_id": "sub-1", + "subscription_name": "sub-name", + "state": "Enabled", + "batch_account": "acct", + "storage_account": "blobacct", + } + ] def test_check_credentials_handles_exception(cloud_client_more, monkeypatch): @@ -71,7 +85,16 @@ def test_check_credentials_handles_exception(cloud_client_more, monkeypatch): lambda cred: (_ for _ in ()).throw(RuntimeError("boom")), ) - cloud_client_more.check_credentials() + result = cloud_client_more.check_credentials() + + assert result.empty + assert list(result.columns) == [ + "subscription_id", + "subscription_name", + "state", + "batch_account", + "storage_account", + ] def test_delete_job_and_schedule_methods(cloud_client_more):