-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable account set, list, and logout
- Loading branch information
1 parent
eb65817
commit 9319be1
Showing
10 changed files
with
300 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,99 @@ | ||
from msrest.authentication import BasicTokenAuthentication | ||
|
||
from .main import CONFIG | ||
import collections | ||
|
||
class Profile(object): | ||
|
||
def update(self, subscriptions, access_token): | ||
subscriptions[0]['active'] = True | ||
CONFIG['subscriptions'] = subscriptions | ||
CONFIG['access_token'] = access_token | ||
def __init__(self, storage=CONFIG): | ||
self._storage = storage | ||
|
||
@staticmethod | ||
def normalize_properties(user, subscriptions): | ||
consolidated = [] | ||
for s in subscriptions: | ||
consolidated.append({ | ||
'id': s.id.split('/')[-1], | ||
'name': s.display_name, | ||
'state': s.state, | ||
'user': user, | ||
'active': False | ||
}) | ||
return consolidated | ||
|
||
def set_subscriptions(self, new_subscriptions, access_token): | ||
existing_ones = self.load_subscriptions() | ||
active_one = next((x for x in existing_ones if x['active']), None) | ||
active_subscription_id = active_one['id'] if active_one else None | ||
|
||
#merge with existing ones | ||
dic = collections.OrderedDict((x['id'], x) for x in existing_ones) | ||
dic.update((x['id'], x) for x in new_subscriptions) | ||
subscriptions = list(dic.values()) | ||
|
||
if active_one: | ||
new_active_one = next( | ||
(x for x in new_subscriptions if x['id'] == active_subscription_id), None) | ||
|
||
def get_credentials(self): | ||
subscriptions = CONFIG['subscriptions'] | ||
sub = [x for x in subscriptions if x['active'] == True ] | ||
if not sub and subscriptions: | ||
sub = subscriptions | ||
for s in subscriptions: | ||
s['active'] = False | ||
|
||
if sub: | ||
return (BasicTokenAuthentication({ 'access_token': CONFIG['access_token']}), | ||
sub[0]['id'] ) | ||
if new_active_one: | ||
new_active_one['active'] = True | ||
else: | ||
new_subscriptions[0]['active'] = True | ||
else: | ||
raise ValueError('you need to login to') | ||
new_subscriptions[0]['active'] = True | ||
|
||
#before adal/python is available, persist tokens with other profile info | ||
for s in new_subscriptions: | ||
s['access_token'] = access_token | ||
|
||
self._save_subscriptions(subscriptions) | ||
|
||
def get_login_credentials(self): | ||
subscriptions = self.load_subscriptions() | ||
if not subscriptions: | ||
raise ValueError('Please run login to setup account.') | ||
|
||
active = [x for x in subscriptions if x['active']] | ||
if len(active) != 1: | ||
raise ValueError('Please run "account set" to select active account.') | ||
|
||
return BasicTokenAuthentication( | ||
{'access_token': active[0]['access_token']}), active[0]['id'] | ||
|
||
def set_active_subscription(self, subscription_id_or_name): | ||
subscriptions = self.load_subscriptions() | ||
|
||
subscription_id_or_name = subscription_id_or_name.lower() | ||
result = [x for x in subscriptions | ||
if subscription_id_or_name == x['id'].lower() or | ||
subscription_id_or_name == x['name'].lower()] | ||
|
||
if len(result) != 1: | ||
raise ValueError('The subscription of "{}" does not exist or has more than' | ||
' one match.'.format(subscription_id_or_name)) | ||
|
||
for s in subscriptions: | ||
s['active'] = False | ||
result[0]['active'] = True | ||
|
||
self._save_subscriptions(subscriptions) | ||
|
||
def logout(self, user): | ||
subscriptions = self.load_subscriptions() | ||
result = [x for x in subscriptions if user.lower() == x['user'].lower()] | ||
subscriptions = [x for x in subscriptions if x not in result] | ||
|
||
#reset the active subscription if needed | ||
result = [x for x in subscriptions if x['active']] | ||
if not result and subscriptions: | ||
subscriptions[0]['active'] = True | ||
|
||
self._save_subscriptions(subscriptions) | ||
|
||
def load_subscriptions(self): | ||
return self._storage.get('subscriptions') or [] | ||
|
||
def _save_subscriptions(self, subscriptions): | ||
self._storage['subscriptions'] = subscriptions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from .._profile import Profile | ||
from .._util import TableOutput | ||
from ..commands import command, description, option | ||
|
||
@command('account list') | ||
@description(_('List the imported subscriptions.')) | ||
def list_subscriptions(args, unexpected): | ||
profile = Profile() | ||
subscriptions = profile.load_subscriptions() | ||
|
||
with TableOutput() as to: | ||
for subscription in subscriptions: | ||
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() | ||
|
||
@command('account set') | ||
@description(_('Set the current subscription')) | ||
@option('--subscription-id -n <subscription-id>', _('Subscription Id, unique name also works.')) | ||
def set_active_subscription(args, unexpected): | ||
id = args.get('subscription-id') | ||
if not id: | ||
raise ValueError(_('Please provide subscription id or unique name.')) | ||
|
||
profile = Profile() | ||
profile.set_active_subscription(id) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from .._profile import Profile | ||
from ..commands import command, description, option | ||
|
||
@command('logout') | ||
@description(_('Log out from Azure subscription using Active Directory.')) | ||
@option('--username -u <username>', _('User name used to log out from Azure Active Directory.')) | ||
def logout(args, unexpected): | ||
username = args.get('username') | ||
if not username: | ||
raise ValueError(_('Please provide a valid username to logout.')) | ||
|
||
profile = Profile() | ||
profile.logout(username) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.