Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Profile] BREAKING CHANGE: az account show: Drop --sdk-auth #21219

Merged
merged 2 commits into from
Feb 17, 2022
Merged
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
33 changes: 7 additions & 26 deletions src/azure-cli-core/azure/cli/core/_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,38 +643,19 @@ def refresh_accounts(self):
def get_sp_auth_info(self, subscription_id=None, name=None, password=None, cert_file=None):
"""Generate a JSON for --sdk-auth argument when used in:
- az ad sp create-for-rbac --sdk-auth
- az account show --sdk-auth
"""
from collections import OrderedDict
account = self.get_subscription(subscription_id)

# is the credential created through command like 'create-for-rbac'?
result = OrderedDict()
if name and (password or cert_file):
result['clientId'] = name
if password:
result['clientSecret'] = password
else:
result['clientCertificate'] = cert_file
result['subscriptionId'] = subscription_id or account[_SUBSCRIPTION_ID]
else: # has logged in through cli
user_type = account[_USER_ENTITY].get(_USER_TYPE)
if user_type == _SERVICE_PRINCIPAL:
client_id = account[_USER_ENTITY][_USER_NAME]
result['clientId'] = client_id
identity = _create_identity_instance(self.cli_ctx, self._authority, tenant_id=account[_TENANT_ID])
sp_entry = identity.get_service_principal_entry(client_id)

from .auth.msal_authentication import _CLIENT_SECRET, _CERTIFICATE
secret = sp_entry.get(_CLIENT_SECRET)
if secret:
result['clientSecret'] = secret
else:
# we can output 'clientCertificateThumbprint' if asked
result['clientCertificate'] = sp_entry.get(_CERTIFICATE)
result['subscriptionId'] = account[_SUBSCRIPTION_ID]
else:
raise CLIError('SDK Auth file is only applicable when authenticated using a service principal')

result['clientId'] = name
if password:
result['clientSecret'] = password
else:
result['clientCertificate'] = cert_file
result['subscriptionId'] = subscription_id or account[_SUBSCRIPTION_ID]

result[_TENANT_ID] = account[_TENANT_ID]
endpoint_mappings = OrderedDict() # use OrderedDict to control the output sequence
Expand Down
4 changes: 0 additions & 4 deletions src/azure-cli-core/azure/cli/core/auth/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,6 @@ def get_service_principal_credential(self, client_id):
sp_auth = ServicePrincipalAuth(entry)
return ServicePrincipalCredential(sp_auth, **self._msal_app_kwargs)

def get_service_principal_entry(self, client_id):
"""This method is only used by --sdk-auth. DO NOT use it elsewhere."""
return self._service_principal_store.load_entry(client_id, self.tenant_id)

def get_managed_identity_credential(self, client_id=None):
raise NotImplementedError

Expand Down
47 changes: 0 additions & 47 deletions src/azure-cli-core/azure/cli/core/tests/test_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -1387,53 +1387,6 @@ def test_login_common_tenant_mfa_warning(self, get_user_credential_mock, create_

# With pytest, use -o log_cli=True to manually check the log

# Tests for get_sp_auth_info
def test_get_auth_info_fail_on_user_account(self):
cli = DummyCli()
storage_mock = {'subscriptions': None}
profile = Profile(cli_ctx=cli, storage=storage_mock)

consolidated = profile._normalize_properties(self.user1,
[self.subscription1],
False)
profile._set_subscriptions(consolidated)

# testing dump of existing logged in account
self.assertRaises(CLIError, profile.get_sp_auth_info)

@mock.patch('azure.cli.core.auth.identity.Identity.get_service_principal_entry', autospec=True)
@mock.patch('azure.cli.core._profile.SubscriptionFinder._create_subscription_client', autospec=True)
@mock.patch('azure.cli.core.auth.identity.Identity.get_service_principal_credential', autospec=True)
@mock.patch('azure.cli.core.auth.identity.Identity.login_with_service_principal', autospec=True)
def test_get_auth_info_for_logged_in_service_principal(self, login_with_service_principal_mock,
get_service_principal_credential_mock,
create_subscription_client_mock,
get_service_principal_entry_mock):
cli = DummyCli()
mock_subscription_client = mock.MagicMock()
mock_subscription_client.tenants.list.return_value = [TenantStub(self.tenant_id)]
mock_subscription_client.subscriptions.list.return_value = [deepcopy(self.subscription1_raw)]
create_subscription_client_mock.return_value = mock_subscription_client

storage_mock = {'subscriptions': []}
profile = Profile(cli_ctx=cli, storage=storage_mock)
profile._management_resource_uri = 'https://management.core.windows.net/'
profile.login(False, '1234', 'my-secret', True, self.tenant_id, use_device_code=False,
allow_no_subscriptions=False)
# action
get_service_principal_entry_mock.return_value = {
"tenant": self.tenant_id,
"client_id": '1234',
"client_secret": 'my-secret'
}
extended_info = profile.get_sp_auth_info()
# assert
self.assertEqual(self.id1.split('/')[-1], extended_info['subscriptionId'])
self.assertEqual('1234', extended_info['clientId'])
self.assertEqual('my-secret', extended_info['clientSecret'])
self.assertEqual('https://login.microsoftonline.com', extended_info['activeDirectoryEndpointUrl'])
self.assertEqual('https://management.azure.com/', extended_info['resourceManagerEndpointUrl'])

def test_get_auth_info_for_newly_created_service_principal(self):
cli = DummyCli()
storage_mock = {'subscriptions': []}
Expand Down
5 changes: 0 additions & 5 deletions src/azure-cli/azure/cli/command_modules/profile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,6 @@ def load_arguments(self, command):
c.argument('refresh', help="retrieve up-to-date subscriptions from server", action='store_true')
c.ignore('_subscription') # hide the global subscription parameter

with self.argument_context('account show') as c:
c.argument('show_auth_for_sdk', options_list=['--sdk-auth'], action='store_true',
deprecate_info=c.deprecate(target='--sdk-auth'),
help='Output result to a file compatible with Azure SDK auth. Only applicable when authenticating with a Service Principal.')

with self.argument_context('account get-access-token') as c:
c.argument('resource_type', get_enum_type(cloud_resource_types), options_list=['--resource-type'], arg_group='', help='Type of well-known resource.')
c.argument('resource', options_list=['--resource'], help='Azure resource endpoints in AAD v1.0.')
Expand Down
12 changes: 1 addition & 11 deletions src/azure-cli/azure/cli/command_modules/profile/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,8 @@ def list_subscriptions(cmd, all=False, refresh=False): # pylint: disable=redefi
return subscriptions


# pylint: disable=inconsistent-return-statements
def show_subscription(cmd, subscription=None, show_auth_for_sdk=None):
import json
def show_subscription(cmd, subscription=None):
profile = Profile(cli_ctx=cmd.cli_ctx)

if show_auth_for_sdk:
from azure.cli.command_modules.role.custom import CREDENTIAL_WARNING
logger.warning(CREDENTIAL_WARNING)
# sdk-auth file should be in json format all the time, hence the print
print(json.dumps(profile.get_sp_auth_info(subscription), indent=2))
return

return profile.get_subscription(subscription)


Expand Down