Skip to content

Commit

Permalink
Adding ability to cancel volumes by username softlayer#2146
Browse files Browse the repository at this point in the history
  • Loading branch information
allmightyspiff committed May 2, 2024
1 parent 6ce7991 commit 04377c5
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 52 deletions.
26 changes: 14 additions & 12 deletions SoftLayer/CLI/block/cancel.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@
from SoftLayer.CLI import environment
from SoftLayer.CLI import exceptions
from SoftLayer.CLI import formatting
from SoftLayer.CLI import helpers


@click.command(cls=SoftLayer.CLI.command.SLCommand, )
@click.argument('volume-id')
@click.option('--reason', help="An optional reason for cancellation")
@click.option('--immediate',
is_flag=True,
help="Cancels the block storage volume immediately instead "
"of on the billing anniversary")
@click.option('--immediate', is_flag=True,
help="Cancels the block storage volume immediately instead of on the billing anniversary")
@click.option('--force', default=False, is_flag=True, help="Force cancel block volume without confirmation")
@environment.pass_env
def cli(env, volume_id, reason, immediate, force):
Expand All @@ -24,24 +23,27 @@ def cli(env, volume_id, reason, immediate, force):
Example::
slcli block volume-cancel 12345678 --immediate -f
This command cancels volume with ID 12345678 immediately and without asking for confirmation.
slcli block volume-cancel SL02SEL30111-77
This command cancels volume with username SL02SEL30111-77 and ask for confirmation
"""

block_storage_manager = SoftLayer.BlockStorageManager(env.client)
manager = SoftLayer.BlockStorageManager(env.client)
# Get the actual number for the ID incase the user put in the volume username
block_volume_id = helpers.resolve_id(manager.resolve_ids, volume_id, 'File Storage')


if not force:
if not (env.skip_confirmations or
formatting.confirm(f"This will cancel the block volume: {volume_id} and cannot be undone. Continue?")):
raise exceptions.CLIAbort('Aborted')

cancelled = block_storage_manager.cancel_block_volume(volume_id,
reason, immediate)
cancelled = manager.cancel_block_volume(12341111, reason, immediate)

if cancelled:
if immediate:
click.echo('Block volume with id %s has been marked'
' for immediate cancellation' % volume_id)
click.echo(f'Volume with id {volume_id} has been marked for immediate cancellation')
else:
click.echo('Block volume with id %s has been marked'
' for cancellation' % volume_id)
click.echo(f'Volume with id {volume_id} has been marked for cancellation')
else:
click.echo('Unable to cancel block volume %s' % volume_id)
click.echo(f'Unable to cancel volume {volume_id}')
16 changes: 11 additions & 5 deletions SoftLayer/CLI/file/cancel.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from SoftLayer.CLI import environment
from SoftLayer.CLI import exceptions
from SoftLayer.CLI import formatting
from SoftLayer.CLI import helpers


@click.command(cls=SoftLayer.CLI.command.SLCommand, )
Expand All @@ -22,20 +23,25 @@ def cli(env, volume_id, reason, immediate, force):
EXAMPLE::
slcli file volume-cancel 12345678 --immediate -f
This command cancels volume with ID 12345678 immediately and without asking for confirmation.
slcli file volume-cancel SL02SEL30111-77
This command cancels volume with username SL02SEL30111-77 and ask for confirmation
"""

file_storage_manager = SoftLayer.FileStorageManager(env.client)
manager = SoftLayer.FileStorageManager(env.client)
# Get the actual number for the ID incase the user put in the volume username
file_volume_id = helpers.resolve_id(manager.resolve_ids, volume_id, 'File Storage')

if not force:
if not (env.skip_confirmations or formatting.no_going_back(volume_id)):
raise exceptions.CLIAbort('Aborted.')

cancelled = file_storage_manager.cancel_file_volume(volume_id, reason, immediate)
cancelled = manager.cancel_file_volume(file_volume_id, reason, immediate)

if cancelled:
if immediate:
click.echo(f'File volume with id {volume_id} has been marked for immediate cancellation')
click.echo(f'Volume with id {volume_id} has been marked for immediate cancellation')
else:
click.echo(f'File volume with id {volume_id} has been marked for cancellation')
click.echo(f'Volume with id {volume_id} has been marked for cancellation')
else:
click.echo(f'Unable to cancle file volume {volume_id}')
click.echo(f'Unable to cancel volume {volume_id}')
26 changes: 20 additions & 6 deletions tests/CLI/modules/block_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ def test_volume_cancel(self):
'--really', 'block', 'volume-cancel', '1234'])

self.assert_no_fail(result)
self.assertEqual('Block volume with id 1234 has been marked'
' for cancellation\n', result.output)
self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem',
args=(False, True, None))
self.assertEqual('Volume with id 1234 has been marked for cancellation\n', result.output)
self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem', args=(False, True, None))

def test_volume_set_lun_id_in_range(self):
lun_mock = self.set_mock('SoftLayer_Network_Storage', 'createOrUpdateLunId')
Expand Down Expand Up @@ -984,8 +982,24 @@ def test_cancel_block_volume_force(self, confirm_mock):
confirm_mock.return_value = False
result = self.run_command(['block', 'volume-cancel', '12345678', '--immediate', '--force'])
self.assert_no_fail(result)
self.assertEqual('Block volume with id 12345678 has been marked'
' for immediate cancellation\n', result.output)
self.assertEqual('Volume with id 12345678 has been marked for immediate cancellation\n', result.output)

def test_cancel_block_volume_by_username(self):
result = self.run_command(['block', 'volume-cancel', 'SL123', '--immediate', '--force'])
self.assert_no_fail(result)
test_filter = {
'iscsiNetworkStorage': {
'serviceResource': {
'type': {'type': {'operation': '!~ ISCSI'}}
},
'storageType': {'keyName': {'operation': '*= BLOCK_STORAGE'}},
'username': {'operation': '_= SL123'}
}
}
self.assert_called_with('SoftLayer_Account', 'getIscsiNetworkStorage', filter=test_filter)
self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem', identifier=449)
self.assertEqual('Volume with id SL123 has been marked for immediate cancellation\n', result.output)


@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_cancel_block_volume_no_force(self, confirm_mock):
Expand Down
40 changes: 11 additions & 29 deletions tests/CLI/modules/file_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,26 +66,18 @@ def test_volume_list_order(self):
@mock.patch('SoftLayer.FileStorageManager.list_file_volumes')
def test_volume_list_notes_format_output_json(self, list_mock):
note_mock = 'test ' * 5
list_mock.return_value = [
{'notes': note_mock}
]
list_mock.return_value = [{'notes': note_mock}]

result = self.run_command(['--format', 'json', 'file', 'volume-list', '--columns', 'notes'])

self.assert_no_fail(result)
self.assertEqual(
[{
'notes': note_mock,
}],
json.loads(result.output))
self.assertEqual([{'notes': note_mock,}], json.loads(result.output))

@mock.patch('SoftLayer.FileStorageManager.list_file_volumes')
def test_volume_list_reduced_notes_format_output_table(self, list_mock):
note_mock = 'test ' * 10
expected_reduced_note = 'test ' * 4
list_mock.return_value = [
{'notes': note_mock}
]
list_mock.return_value = [{'notes': note_mock}]
result = self.run_command(['--format', 'table', 'file', 'volume-list', '--columns', 'notes'])

self.assert_no_fail(result)
Expand All @@ -103,12 +95,7 @@ def test_volume_count(self, list_mock):
result = self.run_command(['file', 'volume-count'])

self.assert_no_fail(result)
self.assertEqual(
{
'ams01': 2,
'dal09': 1
},
json.loads(result.output))
self.assertEqual({'ams01': 2, 'dal09': 1}, json.loads(result.output))

def test_snapshot_list(self):
result = self.run_command(['file', 'snapshot-list', '1234'])
Expand All @@ -124,22 +111,17 @@ def test_snapshot_list(self):
json.loads(result.output))

def test_volume_cancel(self):
result = self.run_command([
'--really', 'file', 'volume-cancel', '1234'])
result = self.run_command(['--really', 'file', 'volume-cancel', '1234'])

self.assert_no_fail(result)
self.assertEqual('File volume with id 1234 has been marked'
' for cancellation\n', result.output)
self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem',
args=(False, True, None))
self.assertEqual('Volume with id 1234 has been marked for cancellation\n', result.output)
self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem', args=(False, True, None))

def test_volume_cancel_with_billing_item(self):
result = self.run_command([
'--really', 'file', 'volume-cancel', '1234'])
result = self.run_command(['--really', 'file', 'volume-cancel', '1234'])

self.assert_no_fail(result)
self.assertEqual('File volume with id 1234 has been marked'
' for cancellation\n', result.output)
self.assertEqual('Volume with id 1234 has been marked for cancellation\n', result.output)
self.assert_called_with('SoftLayer_Network_Storage', 'getObject')

def test_volume_cancel_without_billing_item(self):
Expand All @@ -153,8 +135,7 @@ def test_volume_cancel_without_billing_item(self):
"username": "SL01SEV307608_1"
}

result = self.run_command([
'--really', 'file', 'volume-cancel', '1234'])
result = self.run_command(['--really', 'file', 'volume-cancel', '1234'])

self.assertIsInstance(result.exception, SoftLayerError)

Expand Down Expand Up @@ -851,6 +832,7 @@ def test_file_snapshot_cancel_force(self, confirm_mock):
self.assertEqual(2, result.exit_code)
self.assertEqual('Aborted.', result.exception.message)


@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_file_volume_cancel_force(self, confirm_mock):
confirm_mock.return_value = False
Expand Down

0 comments on commit 04377c5

Please sign in to comment.