From 2612bd5ff6e2e8b3b468728749e8801d0fed5c4f Mon Sep 17 00:00:00 2001 From: yugangw-msft Date: Wed, 17 Feb 2016 22:28:43 -0800 Subject: [PATCH] working in progress of sign in and run cmdlet using the credentails --- azure-cli.pyproj | 1 + src/azure/cli/_profile.py | 22 ++++++++ src/azure/cli/commands/login.py | 91 ++++++++++++------------------- src/azure/cli/commands/storage.py | 15 ++--- 4 files changed, 64 insertions(+), 65 deletions(-) create mode 100644 src/azure/cli/_profile.py diff --git a/azure-cli.pyproj b/azure-cli.pyproj index de447fd25f9..edcce21d9e6 100644 --- a/azure-cli.pyproj +++ b/azure-cli.pyproj @@ -30,6 +30,7 @@ + Code diff --git a/src/azure/cli/_profile.py b/src/azure/cli/_profile.py new file mode 100644 index 00000000000..50190a5a6c6 --- /dev/null +++ b/src/azure/cli/_profile.py @@ -0,0 +1,22 @@ +from msrest.authentication import BasicTokenAuthentication + +from .main import CONFIG + +class Profile(object): + + def update(self, subscriptions, access_token): + subscriptions[0]['active'] = True + CONFIG['subscriptions'] = subscriptions + CONFIG['access_token'] = access_token + + def get_credentials(self): + subscriptions = CONFIG['subscriptions'] + sub = [x for x in subscriptions if x['active'] == True ] + if not sub and subscriptions: + sub = subscriptions + + if sub: + return (BasicTokenAuthentication({ 'access_token': CONFIG['access_token']}), + sub[0]['id'] ) + else: + raise ValueError('you need to login to') \ No newline at end of file diff --git a/src/azure/cli/commands/login.py b/src/azure/cli/commands/login.py index c3b62a228fb..b84fb4fb846 100644 --- a/src/azure/cli/commands/login.py +++ b/src/azure/cli/commands/login.py @@ -1,71 +1,52 @@ +from azure.mgmt.resource.subscriptions import SubscriptionClient, \ + SubscriptionClientConfiguration +from msrestazure.azure_active_directory import UserPassCredentials + from .._logging import logging -from ..main import CONFIG, SESSION +from .._profile import Profile +from .._util import TableOutput from ..commands import command, description, option -PII_WARNING_TEXT = _( - 'If you choose to continue, Azure command-line interface will cache your ' - 'authentication information. Note that this sensitive information will be stored in ' - 'plain text on the file system of your computer at {}. Ensure that you take suitable ' - 'precautions to protect your computer from unauthorized access in order to minimize the ' - 'risk of that information being disclosed.' - '\nDo you wish to continue: (y/n) ' -) +CLIENT_ID = '04b07795-8ddb-461a-bbee-02f9e1bf7b46' @command('login') -@description('logs you in') -@option('--username -u ', _('user name or service principal ID. If multifactor authentication is required, ' - 'you will be prompted to use the login command without parameters for ' - 'interactive support.')) -@option('--environment -e ', _('Environment to authenticate against, such as AzureChinaCloud; ' - 'must support active directory.')) -@option('--password -p ', _('user password or service principal secret, will prompt if not given.')) -@option('--service-principal', _('If given, log in as a service principal rather than a user.')) -@option('--certificate-file ', _('A PEM encoded certificate private key file.')) -@option('--thumbprint ', _('A hex encoded thumbprint of the certificate.')) -@option('--tenant ', _('Tenant domain or ID to log into.')) -@option('--quiet -q', _('do not prompt for confirmation of PII storage.')) +@description('log in to an Azure subscription using Active Directory Organization Id') +@option('--username -u ', _('organization Id. Microsoft Account is not yet supported.')) +@option('--password -p ', _('user password, will prompt if not given.')) def login(args, unexpected): username = args.get('username') - interactive = bool(username) - - environment_name = args.get('environment') or 'AzureCloud' - environment = CONFIG['environments'].get(environment_name) - if not environment: - raise RuntimeError(_('Unknown environment {0}').format(environment_name)) - - tenant = args.get('tenant') - if args.get('service-principal') and not tenant: - tenant = input(_('Tenant: ')) - - # TODO: PII warning password = args.get('password') - require_password = not args.get('service-principal') or not args.get('certificate-file') - if not interactive and require_password and not password: + if not password: import getpass password = getpass.getpass(_('Password: ')) - if not require_password: - password = { - 'certificateFile': args['certificate-file'], - 'thumbprint': args.thumbprint, - } + credentials = UserPassCredentials(username, password, client_id=CLIENT_ID) + client = SubscriptionClient(SubscriptionClientConfiguration(credentials)) + subscriptions = client.subscriptions.list() - if not interactive: - # TODO: Remove cached token - SESSION.pop(username + '_token', None) - - # TODO: Perform login - token = '' - - SESSION[username + '_token'] = token - - # TODO: Get subscriptions - subscriptions = ['not-a-real-subscription'] if not subscriptions: raise RuntimeError(_("No subscriptions found for this account")) - active_subscription = subscriptions[0] - - logging.info(_('Setting subscription %s as default'), active_subscription) - SESSION['active_subscription'] = active_subscription + #keep useful properties and not json serializable + consolidated = [] + for s in subscriptions: + subscription = {}; + subscription['id'] = s.id.split('/')[-1] + subscription['name'] = s.display_name + subscription['state'] = s.state + subscription['user'] = username + consolidated.append(subscription) + + profile = Profile() + profile.update(consolidated, credentials.token['access_token']) + + #TODO, replace with JSON display + with TableOutput() as to: + for subscription in consolidated: + to.cell('Name', subscription['name']) + to.cell('Active', bool(subscription['active'])) + to.cell('User', subscription['user']) + to.cell('Subscription Id', subscription['id']) + to.cell('State', subscription['state']) + to.end_row() diff --git a/src/azure/cli/commands/storage.py b/src/azure/cli/commands/storage.py index cea5b6b8e8c..cf1bef0617c 100644 --- a/src/azure/cli/commands/storage.py +++ b/src/azure/cli/commands/storage.py @@ -1,7 +1,8 @@ -from ..main import CONFIG, SESSION +from ..main import CONFIG, SESSION from .._logging import logging from .._util import TableOutput from ..commands import command, description, option +from .._profile import Profile @command('storage account list') @description('List storage accounts') @@ -11,17 +12,11 @@ def list_accounts(args, unexpected): from azure.mgmt.storage import StorageManagementClient, StorageManagementClientConfiguration from azure.mgmt.storage.models import StorageAccount from msrestazure.azure_active_directory import UserPassCredentials - - username = '' # TODO: get username somehow - password = '' # TODO: get password somehow - logging.code('''smc = StorageManagementClient(StorageManagementClientConfiguration( - credentials=UserPassCredentials(%r, %r), - subscription_id=%r -)''', username, password, args.subscription) + profile = Profile() + #credentials, subscription_id = profile.get_credentials() smc = StorageManagementClient(StorageManagementClientConfiguration( - credentials=UserPassCredentials(username, password), - subscription_id=args.subscription, + *profile.get_credentials(), )) group = args.get('resource-group')