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
3 changes: 1 addition & 2 deletions SoftLayer/CLI/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,7 @@ def no_going_back(confirmation):
if not confirmation:
confirmation = 'yes'

prompt = ('This action cannot be undone! Type "%s" or press Enter '
'to abort' % confirmation)
prompt = f"This action cannot be undone! Type '{confirmation}' or press Enter to abort"

ans = click.prompt(prompt, default='', show_default=False)
if ans.lower() == str(confirmation):
Expand Down
20 changes: 14 additions & 6 deletions SoftLayer/CLI/hardware/update_firmware.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,23 @@

@click.command(cls=SoftLayer.CLI.command.SLCommand, )
@click.argument('identifier')
@click.option('-i', '--ipmi', is_flag=True, help="Update IPMI firmware")
@click.option('-r', '--raid', is_flag=True, help="Update RAID firmware")
@click.option('-b', '--bios', is_flag=True, help="Update BIOS firmware")
@click.option('-d', '--harddrive', is_flag=True, help="Update Hard Drives firmware")
@click.option('-n', '--network', is_flag=True, help="Update Network Card firmware")
@environment.pass_env
def cli(env, identifier):
"""Update server firmware."""
def cli(env, identifier, ipmi, raid, bios, harddrive, network):
"""Update server firmware. By default will update all available server components."""

mgr = SoftLayer.HardwareManager(env.client)
hw_id = helpers.resolve_id(mgr.resolve_ids, identifier, 'hardware')
if not (env.skip_confirmations or
formatting.confirm('This will power off the server with id %s and '
'update device firmware. Continue?' % hw_id)):
confirm_message = f"This will power off the server with id {hw_id} and update device firmware. Continue?"
if not (env.skip_confirmations or formatting.confirm(confirm_message)):
raise exceptions.CLIAbort('Aborted.')

mgr.update_firmware(hw_id)
# If no options were specified, set them all to enabled.
if not any([ipmi, raid, bios, harddrive, network]):
ipmi = raid = bios = harddrive = network = 1
mgr.update_firmware(hw_id, ipmi, raid, bios, harddrive, network)
env.fout(f"[green]Firmware update for {identifier} started")
36 changes: 19 additions & 17 deletions SoftLayer/managers/hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -723,44 +723,46 @@ def edit(self, hardware_id, userdata=None, hostname=None, domain=None,

return self.hardware.editObject(obj, id=hardware_id)

def update_firmware(self,
hardware_id,
ipmi=True,
raid_controller=True,
bios=True,
hard_drive=True):
def update_firmware(self, hardware_id: int,
ipmi: bool = True,
raid_controller: bool = True,
bios: bool = True,
hard_drive: bool = True,
network: bool = True):
"""Update hardware firmware.

This will cause the server to be unavailable for ~20 minutes.
https://sldn.softlayer.com/reference/services/SoftLayer_Hardware_Server/createFirmwareUpdateTransaction/

:param int hardware_id: The ID of the hardware to have its firmware
updated.
:param int hardware_id: The ID of the hardware to have its firmware updated.
:param bool ipmi: Update the ipmi firmware.
:param bool raid_controller: Update the raid controller firmware.
:param bool bios: Update the bios firmware.
:param bool hard_drive: Update the hard drive firmware.
:param bool network: Update the network card firmware

Example::

# Check the servers active transactions to see progress
result = mgr.update_firmware(hardware_id=1234)
"""

return self.hardware.createFirmwareUpdateTransaction(
bool(ipmi), bool(raid_controller), bool(bios), bool(hard_drive), id=hardware_id)
return self.client.call(
'SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
bool(ipmi), bool(raid_controller), bool(bios), bool(hard_drive), bool(network), id=hardware_id
)

def reflash_firmware(self,
hardware_id,
ipmi=True,
raid_controller=True,
bios=True):
def reflash_firmware(self, hardware_id: int,
ipmi: bool = True,
raid_controller: bool = True,
bios: bool = True,):
"""Reflash hardware firmware.

This will cause the server to be unavailable for ~60 minutes.
The firmware will not be upgraded but rather reflashed to the version installed.
https://sldn.softlayer.com/reference/services/SoftLayer_Hardware_Server/createFirmwareReflashTransaction/

:param int hardware_id: The ID of the hardware to have its firmware
reflashed.
:param int hardware_id: The ID of the hardware to have its firmware reflashed.
:param bool ipmi: Reflash the ipmi firmware.
:param bool raid_controller: Reflash the raid controller firmware.
:param bool bios: Reflash the bios firmware.
Expand Down
20 changes: 0 additions & 20 deletions tests/CLI/modules/hardware/hardware_basic_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,26 +498,6 @@ def test_edit_server_userfile(self):
self.assert_called_with('SoftLayer_Hardware_Server', 'setUserMetadata',
args=(['some data'],), identifier=1000)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_update_firmware(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['server', 'update-firmware', '1000'])

self.assert_no_fail(result)
self.assertEqual(result.output, "")
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
args=((1, 1, 1, 1)), identifier=1000)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_reflash_firmware(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['server', 'reflash-firmware', '1000'])

self.assert_no_fail(result)
self.assertEqual(result.output, 'Successfully device firmware reflashed\n')
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareReflashTransaction',
args=((1, 1, 1)), identifier=1000)

def test_edit(self):
result = self.run_command(['server', 'edit',
'--domain=example.com',
Expand Down
109 changes: 109 additions & 0 deletions tests/CLI/modules/hardware/hardware_firmware_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"""
SoftLayer.tests.CLI.modules.hardware.hardware_firmware_tests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This suite is for the firmware related tests.

:license: MIT, see LICENSE for more details.
"""
from SoftLayer.CLI import exceptions
from SoftLayer import testing
from unittest import mock as mock


class HardwareFirmwareTests(testing.TestCase):

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_update_firmware(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['server', 'update-firmware', '1000'])
self.assert_no_fail(result)
self.assertIn("Firmware update for 1000 started", result.output)
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
args=((1, 1, 1, 1, 1)), identifier=1000)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_update_firmware_just_ipmi(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['server', 'update-firmware', '1000', '-i'])

self.assert_no_fail(result)
self.assertIn("Firmware update for 1000 started", result.output)
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
args=((1, 0, 0, 0, 0)), identifier=1000)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_update_firmware_just_raid(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['server', 'update-firmware', '1000', '-r'])

self.assert_no_fail(result)
self.assertIn("Firmware update for 1000 started", result.output)
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
args=((0, 1, 0, 0, 0)), identifier=1000)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_update_firmware_just_bios(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['server', 'update-firmware', '1000', '-b'])

self.assert_no_fail(result)
self.assertIn("Firmware update for 1000 started", result.output)
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
args=((0, 0, 1, 0, 0)), identifier=1000)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_update_firmware_just_disk(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['server', 'update-firmware', '1000', '-d'])

self.assert_no_fail(result)
self.assertIn("Firmware update for 1000 started", result.output)
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
args=((0, 0, 0, 1, 0)), identifier=1000)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_update_firmware_just_nic(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['server', 'update-firmware', '1000', '-n'])

self.assert_no_fail(result)
self.assertIn("Firmware update for 1000 started", result.output)
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
args=((0, 0, 0, 0, 1)), identifier=1000)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_update_firmware_just_all(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['server', 'update-firmware', '1000', '-i', '-r', '-b', '-d', '-n'])

self.assert_no_fail(result)
self.assertIn("Firmware update for 1000 started", result.output)
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
args=((1, 1, 1, 1, 1)), identifier=1000)

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

result = self.run_command(['server', 'update-firmware', '1000'])
self.assertEqual(result.exit_code, 2)
self.assertIsInstance(result.exception, exceptions.CLIAbort)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_reflash_firmware(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['server', 'reflash-firmware', '1000'])

self.assert_no_fail(result)
self.assertEqual(result.output, 'Successfully device firmware reflashed\n')
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareReflashTransaction',
args=((1, 1, 1)), identifier=1000)

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

result = self.run_command(['server', 'reflash-firmware', '1000'])
self.assertEqual(result.exit_code, 2)
self.assertIsInstance(result.exception, exceptions.CLIAbort)
4 changes: 2 additions & 2 deletions tests/managers/hardware_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,14 +543,14 @@ def test_update_firmware(self):

self.assertEqual(result, True)
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
identifier=100, args=(1, 1, 1, 1))
identifier=100, args=(1, 1, 1, 1, 1))

def test_update_firmware_selective(self):
result = self.hardware.update_firmware(100, ipmi=False, hard_drive=False)

self.assertEqual(result, True)
self.assert_called_with('SoftLayer_Hardware_Server', 'createFirmwareUpdateTransaction',
identifier=100, args=(0, 1, 1, 0))
identifier=100, args=(0, 1, 1, 0, 1))

def test_reflash_firmware(self):
result = self.hardware.reflash_firmware(100)
Expand Down