Skip to content

Commit

Permalink
Deprecate CLI factory in azure-common (#21337)
Browse files Browse the repository at this point in the history
* Deprecate CLI factory in azure-common

* Correct syntax

* ChangeLog

* NotImplementedError

* Deprecate all CLI related methods

* Rewording

* Date change

* Typo thanks @annatisch

* Typo

* Fix tests

* Update CHANGELOG.md

Co-authored-by: Xiang Yan <[email protected]>
  • Loading branch information
lmazuel and xiangyan99 authored Feb 2, 2022
1 parent f363c22 commit 13950c4
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 19 deletions.
5 changes: 4 additions & 1 deletion sdk/core/azure-common/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Release History

## 1.1.28 (Unreleased)
## 1.1.28 (2022-02-03)

- Raise a NotImplementedError if trying to use CLI credentials were CLI version is higher than 2.21.0 #20657 #21313
- Deprecate all methods that needs access to CLI code using azure-cli-core, since this package is no longer importable as public API

## 1.1.27 (2021-03-23)

Expand Down
46 changes: 34 additions & 12 deletions sdk/core/azure-common/azure/common/client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import os
import re
import sys
import warnings
try:
from inspect import getfullargspec as get_arg_spec
except ImportError:
Expand Down Expand Up @@ -50,7 +51,18 @@ def _client_resource(client_class, cloud):
def get_client_from_cli_profile(client_class, **kwargs):
"""Return a SDK client initialized with current CLI credentials, CLI default subscription and CLI default cloud.
This method will fill automatically the following client parameters:
*Disclaimer*: This is NOT the recommended approach to authenticate with CLI login, this method is deprecated.
use https://pypi.org/project/azure-identity/ and AzureCliCredential instead. See example code below:
.. code:: python
from azure.identity import AzureCliCredential
from azure.mgmt.compute import ComputeManagementClient
client = ComputeManagementClient(AzureCliCredential(), subscription_id)
This method is not working for azure-cli-core>=2.21.0 (released in March 2021).
For compatible azure-cli-core (< 2.20.0), This method will automatically fill the following client parameters:
- credentials/credential
- subscription_id
- base_url
Expand All @@ -67,10 +79,20 @@ def get_client_from_cli_profile(client_class, **kwargs):
.. versionadded:: 1.1.6
.. deprecated:: 1.1.28
.. seealso:: https://aka.ms/azsdk/python/identity/migration
:param client_class: A SDK client class
:return: An instantiated client
:raises: ImportError if azure-cli-core package is not available
"""
warnings.warn(
"get_client_from_cli_profile is deprecated, please use azure-identity and AzureCliCredential instead. "+
"See also https://aka.ms/azsdk/python/identity/migration.",
DeprecationWarning
)

cloud = get_cli_active_cloud()
parameters = {}
no_credential_sentinel = object()
Expand Down Expand Up @@ -120,11 +142,7 @@ def _is_autorest_v3(client_class):
def get_client_from_json_dict(client_class, config_dict, **kwargs):
"""Return a SDK client initialized with a JSON auth dict.
The easiest way to obtain this content is to call the following CLI commands:
.. code:: bash
az ad sp create-for-rbac --sdk-auth
*Disclaimer*: This is NOT the recommended approach, see https://aka.ms/azsdk/python/identity/migration for guidance.
This method will fill automatically the following client parameters:
- credentials
Expand Down Expand Up @@ -156,14 +174,18 @@ def get_client_from_json_dict(client_class, config_dict, **kwargs):
.. versionadded:: 1.1.7
.. deprecated:: 1.1.28
.. seealso:: https://aka.ms/azsdk/python/identity/migration
:param client_class: A SDK client class
:param dict config_dict: A config dict.
:return: An instantiated client
"""
if _is_autorest_v3(client_class):
raise ValueError(
"Auth file or JSON dict are deprecated auth approach and are not supported anymore. "
"Please read https://aka.ms/azsdk/python/azidmigration for details"
"See also https://aka.ms/azsdk/python/identity/migration."
)

import adal
Expand Down Expand Up @@ -215,11 +237,7 @@ def get_client_from_json_dict(client_class, config_dict, **kwargs):
def get_client_from_auth_file(client_class, auth_path=None, **kwargs):
"""Return a SDK client initialized with auth file.
The easiest way to obtain this file is to call the following CLI commands:
.. code:: bash
az ad sp create-for-rbac --sdk-auth
*Disclaimer*: This is NOT the recommended approach, see https://aka.ms/azsdk/python/identity/migration for guidance.
You can specific the file path directly, or fill the environment variable AZURE_AUTH_LOCATION.
File must be UTF-8.
Expand Down Expand Up @@ -258,6 +276,10 @@ def get_client_from_auth_file(client_class, auth_path=None, **kwargs):
.. versionadded:: 1.1.7
.. deprecated:: 1.1.28
.. seealso:: https://aka.ms/azsdk/python/identity/migration
:param client_class: A SDK client class
:param str auth_path: Path to the file.
:return: An instantiated client
Expand Down
12 changes: 10 additions & 2 deletions sdk/core/azure-common/azure/common/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
def get_cli_active_cloud():
"""Return a CLI active cloud.
*Disclaimer*: This method is not working for azure-cli-core>=2.21.0 (released in March 2021).
.. versionadded:: 1.1.6
.. deprecated:: 1.1.28
:return: A CLI Cloud
:rtype: azure.cli.core.cloud.Cloud
:raises: ImportError if azure-cli-core package is not available
Expand All @@ -17,6 +21,10 @@ def get_cli_active_cloud():
try:
from azure.cli.core.cloud import get_active_cloud
except ImportError:
raise ImportError("You need to install 'azure-cli-core' to load CLI active Cloud")
raise ImportError(
"The public API of azure-cli-core has been deprecated starting 2.21.0, " +
"and this method no longer can return a cloud instance. " +
"If you want to use this method, you need to install 'azure-cli-core<2.21.0'. " +
"You may corrupt data if you use current CLI and old azure-cli-core."
)
return get_active_cloud()

55 changes: 52 additions & 3 deletions sdk/core/azure-common/azure/common/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import os.path
import time
import warnings
try:
from azure.core.credentials import AccessToken as _AccessToken
except ImportError:
Expand All @@ -15,8 +16,12 @@
def get_cli_profile():
"""Return a CLI profile class.
*Disclaimer*: This method is not working for azure-cli-core>=2.21.0 (released in March 2021).
.. versionadded:: 1.1.6
.. deprecated:: 1.1.28
:return: A CLI Profile
:rtype: azure.cli.core._profile.Profile
:raises: ImportError if azure-cli-core package is not available
Expand All @@ -27,8 +32,12 @@ def get_cli_profile():
from azure.cli.core._session import ACCOUNT
from azure.cli.core._environment import get_config_dir
except ImportError:
raise ImportError("You need to install 'azure-cli-core' to load CLI credentials")

raise ImportError(
"The public API of azure-cli-core has been deprecated starting 2.21.0, " +
"and this method can no longer return a profile. " +
"If you need to load CLI profile using this method, you need to install 'azure-cli-core<2.21.0'. " +
"You may corrupt data if you use current CLI and old azure-cli-core."
)

azure_folder = get_config_dir()
ACCOUNT.load(os.path.join(azure_folder, 'azureProfile.json'))
Expand Down Expand Up @@ -69,6 +78,7 @@ def get_token(self, *scopes, **kwargs): # pylint:disable=unused-argument
resource = scope

credentials = self._get_cred(resource)
# _token_retriever() not accessible after azure-cli-core 2.21.0
_, token, fulltoken = credentials._token_retriever() # pylint:disable=protected-access

return _AccessToken(token, int(fulltoken['expiresIn'] + time.time()))
Expand All @@ -81,19 +91,58 @@ def signed_session(self, session=None):
def get_azure_cli_credentials(resource=None, with_tenant=False):
"""Return Credentials and default SubscriptionID of current loaded profile of the CLI.
Credentials will be the "az login" command:
*Disclaimer*: This method is not working for azure-cli-core>=2.21.0 (released in March 2021).
It is now recommended to authenticate using https://pypi.org/project/azure-identity/ and AzureCliCredential.
See example code below:
.. code:: python
from azure.identity import AzureCliCredential
from azure.mgmt.compute import ComputeManagementClient
client = ComputeManagementClient(AzureCliCredential(), subscription_id)
For compatible azure-cli-core version (< 2.20.0), credentials will be the "az login" command:
https://docs.microsoft.com/cli/azure/authenticate-azure-cli
Default subscription ID is either the only one you have, or you can define it:
https://docs.microsoft.com/cli/azure/manage-azure-subscriptions-azure-cli
.. versionadded:: 1.1.6
.. deprecated:: 1.1.28
.. seealso:: https://aka.ms/azsdk/python/identity/migration
:param str resource: The alternative resource for credentials if not ARM (GraphRBac, etc.)
:param bool with_tenant: If True, return a three-tuple with last as tenant ID
:return: tuple of Credentials and SubscriptionID (and tenant ID if with_tenant)
:rtype: tuple
"""
warnings.warn(
"get_client_from_cli_profile is deprecated, please use azure-identity and AzureCliCredential instead. " +
"https://aka.ms/azsdk/python/identity/migration.",
DeprecationWarning
)

azure_cli_core_check_failed = False
try:
import azure.cli.core
minor_version = int(azure.cli.core.__version__.split(".")[1])
if minor_version >= 21:
azure_cli_core_check_failed = True
except Exception:
azure_cli_core_check_failed = True

if azure_cli_core_check_failed:
raise NotImplementedError(
"The public API of azure-cli-core has been deprecated starting 2.21.0, " +
"and this method can no longer return a valid credential. " +
"If you need to still use this method, you need to install 'azure-cli-core<2.21.0'. " +
"You may corrupt data if you use current CLI and old azure-cli-core. " +
"See also: https://aka.ms/azsdk/python/identity/migration"
)

profile = get_cli_profile()
cred, subscription_id, tenant_id = profile.get_login_credentials(resource=resource)
cred = _CliCredentials(profile, resource)
Expand Down
2 changes: 1 addition & 1 deletion sdk/core/azure-common/tests/test_client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ def __init__(self, credential):

with pytest.raises(ValueError) as excinfo:
get_client_from_auth_file(KeyVaultClientTrack2, temp_auth_file.name)
assert "https://aka.ms/azsdk/python/azidmigration" in str(excinfo.value)
assert "https://aka.ms/azsdk/python/identity/migration" in str(excinfo.value)

os.unlink(temp_auth_file.name)

Expand Down

0 comments on commit 13950c4

Please sign in to comment.