Skip to content

Commit 2fef3fd

Browse files
committed
Merge pull request softlayer#481 from sudorandom/firmware
Update Firmware CLI/Manager method
2 parents 079d529 + 20ebcc5 commit 2fef3fd

7 files changed

Lines changed: 84 additions & 5 deletions

File tree

SoftLayer/CLI/routes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
('server:reboot', 'SoftLayer.CLI.server.power:reboot'),
150150
('server:reload', 'SoftLayer.CLI.server.reload:cli'),
151151
('server:credentials', 'SoftLayer.CLI.server.credentials:cli'),
152+
('server:update-firmware', 'SoftLayer.CLI.server.update_firmware:cli'),
152153

153154
('snapshot', 'SoftLayer.CLI.snapshot'),
154155
('snapshot:cancel', 'SoftLayer.CLI.snapshot.cancel:cli'),
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""Update firmware."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import SoftLayer
5+
from SoftLayer.CLI import environment
6+
from SoftLayer.CLI import exceptions
7+
from SoftLayer.CLI import formatting
8+
from SoftLayer.CLI import helpers
9+
10+
import click
11+
12+
13+
@click.command()
14+
@click.argument('identifier')
15+
@environment.pass_env
16+
def cli(env, identifier):
17+
"""Update server firmware."""
18+
19+
mgr = SoftLayer.HardwareManager(env.client)
20+
hw_id = helpers.resolve_id(mgr.resolve_ids, identifier, 'hardware')
21+
if env.skip_confirmations or formatting.confirm('This will power off the '
22+
'server with id %s and '
23+
'update device firmware. '
24+
'Continue?' % hw_id):
25+
mgr.update_firmware(hw_id)
26+
else:
27+
raise exceptions.CLIAbort('Aborted.')

SoftLayer/managers/hardware.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,28 @@ def edit(self, hardware_id, userdata=None, hostname=None, domain=None,
746746

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

749+
def update_firmware(self,
750+
hardware_id,
751+
ipmi=True,
752+
raid_controller=True,
753+
bios=True,
754+
hard_drive=True):
755+
"""Update hardware firmware.
756+
757+
This will cause the server to be unavailable for ~20 minutes.
758+
759+
:param int hardware_id: The ID of the hardware to have its firmware
760+
updated.
761+
:param bool ipmi: Update the ipmi firmware.
762+
:param bool raid_controller: Update the raid controller firmware.
763+
:param bool bios: Update the bios firmware.
764+
:param bool hard_drive: Update the hard drive firmware.
765+
"""
766+
767+
return self.hardware.createFirmwareUpdateTransaction(
768+
bool(ipmi), bool(raid_controller), bool(bios), bool(hard_drive),
769+
id=hardware_id)
770+
749771

750772
def get_default_value(package_options, category, hourly=False):
751773
"""Returns the default price ID for the specified category.

SoftLayer/testing/fixtures/SoftLayer_Hardware_Server.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
rebootSoft = True
7474
rebootDefault = True
7575
rebootHard = True
76+
createFirmwareUpdateTransaction = True
7677
setUserMetadata = ['meta']
7778
reloadOperatingSystem = 'OK'
7879
getReverseDomainRecords = [

SoftLayer/tests/CLI/modules/server_tests.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,14 @@ def test_get_default_value_returns_none_for_unknown_category(self):
636636
option_mock = {'categories': {'cat1': []}}
637637
output = create._get_default_value(option_mock, 'nope')
638638
self.assertEqual(None, output)
639+
640+
@mock.patch('SoftLayer.CLI.formatting.confirm')
641+
def test_update_firmware(self, confirm_mock):
642+
confirm_mock.return_value = True
643+
result = self.run_command(['server', 'update-firmware', '1000'])
644+
645+
self.assertEqual(result.exit_code, 0)
646+
self.assertEqual(result.output, "")
647+
self.assert_called_with('SoftLayer_Hardware_Server',
648+
'createFirmwareUpdateTransaction',
649+
args=((1, 1, 1, 1)), identifier=1000)

SoftLayer/tests/managers/hardware_tests.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,10 +473,27 @@ def test_edit(self):
473473
identifier=100)
474474

475475
def test_rescue(self):
476-
# Test rescue environment
477-
restult = self.hardware.rescue(1234)
476+
result = self.hardware.rescue(1234)
478477

479-
self.assertEqual(restult, True)
478+
self.assertEqual(result, True)
480479
self.assert_called_with('SoftLayer_Hardware_Server',
481480
'bootToRescueLayer',
482481
identifier=1234)
482+
483+
def test_update_firmware(self):
484+
result = self.hardware.update_firmware(100)
485+
486+
self.assertEqual(result, True)
487+
self.assert_called_with('SoftLayer_Hardware_Server',
488+
'createFirmwareUpdateTransaction',
489+
identifier=100, args=(1, 1, 1, 1))
490+
491+
def test_update_firmware_selective(self):
492+
result = self.hardware.update_firmware(100,
493+
ipmi=False,
494+
hard_drive=False)
495+
496+
self.assertEqual(result, True)
497+
self.assert_called_with('SoftLayer_Hardware_Server',
498+
'createFirmwareUpdateTransaction',
499+
identifier=100, args=(0, 1, 1, 0))

SoftLayer/transports.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,8 @@ def __call__(self, call):
226226
module_path = 'SoftLayer.testing.fixtures.%s' % call.service
227227
module = importlib.import_module(module_path)
228228
except ImportError:
229-
raise NotImplementedError('%s::%s fixture is not implemented'
230-
% (call.service, call.method))
229+
raise NotImplementedError('%s fixture is not implemented'
230+
% call.service)
231231
try:
232232
return getattr(module, call.method)
233233
except AttributeError:

0 commit comments

Comments
 (0)