Skip to content
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
2 changes: 2 additions & 0 deletions SoftLayer/CLI/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@
('user:detail', 'SoftLayer.CLI.user.detail:cli'),
('user:permissions', 'SoftLayer.CLI.user.permissions:cli'),
('user:edit-permissions', 'SoftLayer.CLI.user.edit_permissions:cli'),
('user:notifications', 'SoftLayer.CLI.user.notifications:cli'),
('user:edit-notifications', 'SoftLayer.CLI.user.edit_notifications:cli'),
('user:edit-details', 'SoftLayer.CLI.user.edit_details:cli'),
('user:create', 'SoftLayer.CLI.user.create:cli'),
('user:delete', 'SoftLayer.CLI.user.delete:cli'),
Expand Down
35 changes: 35 additions & 0 deletions SoftLayer/CLI/user/edit_notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Enable or Disable specific noticication for the current user"""
# :license: MIT, see LICENSE for more details.

import click

import SoftLayer
from SoftLayer.CLI import environment


@click.command()
@click.option('--enable/--disable', default=True,
help="Enable (DEFAULT) or Disable selected notification")
@click.argument('notification', nargs=-1, required=True)
@environment.pass_env
def cli(env, enable, notification):
"""Enable or Disable specific notifications for the active user.

Notification names should be enclosed in quotation marks.
Example::

slcli user edit-notifications --enable 'Order Approved' 'Reload Complete'

"""

mgr = SoftLayer.UserManager(env.client)

if enable:
result = mgr.enable_notifications(notification)
else:
result = mgr.disable_notifications(notification)

if result:
click.secho("Notifications updated successfully: %s" % ", ".join(notification), fg='green')
else:
click.secho("Failed to update notifications: %s" % ", ".join(notification), fg='red')
34 changes: 34 additions & 0 deletions SoftLayer/CLI/user/notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""List user notifications"""
import click

import SoftLayer
from SoftLayer.CLI import environment
from SoftLayer.CLI import formatting


@click.command()
@environment.pass_env
def cli(env):
"""My Notifications."""

mgr = SoftLayer.UserManager(env.client)

all_notifications = mgr.get_all_notifications()

env.fout(notification_table(all_notifications))


def notification_table(all_notifications):
"""Creates a table of available notifications"""

table = formatting.Table(['Id', 'Name', 'Description', 'Enabled'])
table.align['Id'] = 'l'
table.align['Name'] = 'l'
table.align['Description'] = 'l'
table.align['Enabled'] = 'l'
for notification in all_notifications:
table.add_row([notification['id'],
notification['name'],
notification['description'],
notification['enabled']])
return table
22 changes: 22 additions & 0 deletions SoftLayer/fixtures/SoftLayer_Email_Subscription.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
getAllObjects = [
{'description': 'Email about your order.',
'enabled': True,
'id': 1,
'name': 'Order Being Reviewed'
},
{'description': 'Maintenances that will or are likely to cause service '
'outages and disruptions',
'enabled': True,
'id': 8,
'name': 'High Impact'
},
{'description': 'Testing description.',
'enabled': True,
'id': 111,
'name': 'Test notification'
}
]

enable = True

disable = True
64 changes: 64 additions & 0 deletions SoftLayer/managers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def __init__(self, client):
self.user_service = self.client['SoftLayer_User_Customer']
self.override_service = self.client['Network_Service_Vpn_Overrides']
self.account_service = self.client['SoftLayer_Account']
self.subscription_service = self.client['SoftLayer_Email_Subscription']
self.resolvers = [self._get_id_from_username]
self.all_permissions = None

Expand Down Expand Up @@ -85,6 +86,52 @@ def get_all_permissions(self):
self.all_permissions = sorted(permissions, key=itemgetter('keyName'))
return self.all_permissions

def get_all_notifications(self):
"""Calls SoftLayer_Email_Subscription::getAllObjects

Stores the result in self.all_permissions
:returns: A list of dictionaries that contains all valid permissions
"""
return self.subscription_service.getAllObjects(mask='mask[enabled]')

def enable_notifications(self, notifications_names):
"""Enables a list of notifications for the current a user profile.

:param list notifications_names: List of notifications names to enable
:returns: True on success

Example::
enable_notifications(['Order Approved','Reload Complete'])
"""

result = False
notifications = self.gather_notifications(notifications_names)
for notification in notifications:
notification_id = notification.get('id')
result = self.subscription_service.enable(id=notification_id)
if not result:
return False
return result

def disable_notifications(self, notifications_names):
"""Disable a list of notifications for the current a user profile.

:param list notifications_names: List of notifications names to disable
:returns: True on success

Example::
disable_notifications(['Order Approved','Reload Complete'])
"""

result = False
notifications = self.gather_notifications(notifications_names)
for notification in notifications:
notification_id = notification.get('id')
result = self.subscription_service.disable(id=notification_id)
if not result:
return False
return result

def add_permissions(self, user_id, permissions):
"""Enables a list of permissions for a user

Expand Down Expand Up @@ -237,6 +284,23 @@ def format_permission_object(self, permissions):
raise exceptions.SoftLayerError("'%s' is not a valid permission" % permission)
return pretty_permissions

def gather_notifications(self, notifications_names):
"""Gets a list of notifications.

:param list notifications_names: A list of notifications names.
:returns: list of notifications.
"""
notifications = []
available_notifications = self.get_all_notifications()
for notification in notifications_names:
result = next((item for item in available_notifications
if item.get('name') == notification), None)
if result:
notifications.append(result)
else:
raise exceptions.SoftLayerError("{} is not a valid notification name".format(notification))
return notifications

def create_user(self, user_object, password):
"""Blindly sends user_object to SoftLayer_User_Customer::createObject

Expand Down
8 changes: 8 additions & 0 deletions docs/cli/users.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@ Version 5.6.0 introduces the ability to interact with user accounts from the cli
:prog: user detail
:show-nested:

.. click:: SoftLayer.CLI.user.notifications:cli
:prog: user notifications
:show-nested:

.. click:: SoftLayer.CLI.user.permissions:cli
:prog: user permissions
:show-nested:

.. click:: SoftLayer.CLI.user.edit_notifications:cli
:prog: user edit-notifications
:show-nested:

.. click:: SoftLayer.CLI.user.edit_permissions:cli
:prog: user edit-permissions
:show-nested:
Expand Down
32 changes: 32 additions & 0 deletions tests/CLI/modules/user_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,35 @@ def test_vpn_subnet_remove(self, click):
result = self.run_command(['user', 'vpn-subnet', '12345', '--remove', '1234'])
click.secho.assert_called_with('12345 updated successfully', fg='green')
self.assert_no_fail(result)

"""User notification tests"""

def test_notificacions_list(self):
result = self.run_command(['user', 'notifications'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Email_Subscription', 'getAllObjects', mask='mask[enabled]')

"""User edit-notification tests"""

def test_edit_notification_on(self):
result = self.run_command(['user', 'edit-notifications', '--enable', 'Test notification'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Email_Subscription', 'enable', identifier=111)

def test_edit_notification_on_bad(self):
result = self.run_command(['user', 'edit-notifications', '--enable', 'Test not exist'])
self.assertEqual(result.exit_code, 1)

def test_edit_notifications_off(self):
result = self.run_command(['user', 'edit-notifications', '--disable', 'Test notification'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Email_Subscription', 'disable', identifier=111)

@mock.patch('SoftLayer.CLI.user.edit_notifications.click')
def test_edit_notification_off_failure(self, click):
notification = self.set_mock('SoftLayer_Email_Subscription', 'disable')
notification.return_value = False
result = self.run_command(['user', 'edit-notifications', '--disable', 'Test notification'])
click.secho.assert_called_with('Failed to update notifications: Test notification', fg='red')
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Email_Subscription', 'disable', identifier=111)
48 changes: 48 additions & 0 deletions tests/managers/user_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

"""
import datetime

import mock

import SoftLayer
from SoftLayer import exceptions
from SoftLayer import testing
Expand Down Expand Up @@ -246,3 +248,49 @@ def test_vpn_subnet_remove(self):
self.manager.vpn_subnet_remove(user_id, [subnet_id])
self.assert_called_with('SoftLayer_Network_Service_Vpn_Overrides', 'deleteObjects', args=expected_args)
self.assert_called_with('SoftLayer_User_Customer', 'updateVpnUser', identifier=user_id)

def test_get_all_notifications(self):
self.manager.get_all_notifications()
self.assert_called_with('SoftLayer_Email_Subscription', 'getAllObjects')

def test_enable_notifications(self):
self.manager.enable_notifications(['Test notification'])
self.assert_called_with('SoftLayer_Email_Subscription', 'enable', identifier=111)

def test_disable_notifications(self):
self.manager.disable_notifications(['Test notification'])
self.assert_called_with('SoftLayer_Email_Subscription', 'disable', identifier=111)

def test_enable_notifications_fail(self):
notification = self.set_mock('SoftLayer_Email_Subscription', 'enable')
notification.return_value = False
result = self.manager.enable_notifications(['Test notification'])
self.assert_called_with('SoftLayer_Email_Subscription', 'enable', identifier=111)
self.assertFalse(result)

def test_disable_notifications_fail(self):
notification = self.set_mock('SoftLayer_Email_Subscription', 'disable')
notification.return_value = False
result = self.manager.disable_notifications(['Test notification'])
self.assert_called_with('SoftLayer_Email_Subscription', 'disable', identifier=111)
self.assertFalse(result)

def test_gather_notifications(self):
expected_result = [
{'description': 'Testing description.',
'enabled': True,
'id': 111,
'name': 'Test notification'
}
]
result = self.manager.gather_notifications(['Test notification'])
self.assert_called_with('SoftLayer_Email_Subscription',
'getAllObjects',
mask='mask[enabled]')
self.assertEqual(result, expected_result)

def test_gather_notifications_fail(self):
ex = self.assertRaises(SoftLayer.SoftLayerError,
self.manager.gather_notifications,
['Test not exit'])
self.assertEqual("Test not exit is not a valid notification name", str(ex))