Skip to content

Commit 7fa51cf

Browse files
Merge pull request softlayer#524 from sudorandom/hardware-cancel
Hardware cancel consolidation
2 parents 332b223 + ab50844 commit 7fa51cf

3 files changed

Lines changed: 37 additions & 70 deletions

File tree

SoftLayer/CLI/server/detail.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def cli(env, identifier, passwords, price):
3535
result = utils.NestedDict(result)
3636

3737
table.add_row(['id', result['id']])
38-
table.add_row(['guid', result['globalIdentifier']] or formatting.blank())
38+
table.add_row(['guid', result['globalIdentifier'] or formatting.blank()])
3939
table.add_row(['hostname', result['hostname']])
4040
table.add_row(['domain', result['domain']])
4141
table.add_row(['fqdn', result['fullyQualifiedDomainName']])

SoftLayer/managers/hardware.py

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -47,51 +47,22 @@ def cancel_hardware(self, hardware_id, reason='unneeded', comment='',
4747
:param string comment: An optional comment to include with the
4848
cancellation.
4949
"""
50-
# Check to see if this is actually a pre-configured server (BMC). They
51-
# require a different cancellation call.
52-
server = self.get_hardware(hardware_id,
53-
mask='id,bareMetalInstanceFlag')
54-
55-
if server.get('bareMetalInstanceFlag'):
56-
return self.cancel_metal(hardware_id, immediate)
5750

51+
# Get cancel reason
5852
reasons = self.get_cancellation_reasons()
59-
cancel_reason = reasons['unneeded']
60-
61-
if reason in reasons:
62-
cancel_reason = reasons[reason]
63-
64-
# Arguments per SLDN:
65-
# attachmentId - Hardware ID
66-
# Reason
67-
# content - Comment about the cancellation
68-
# cancelAssociatedItems
69-
# attachmentType - Only option is HARDWARE
70-
return self.client['Ticket'].createCancelServerTicket(hardware_id,
71-
cancel_reason,
72-
comment,
73-
True,
74-
'HARDWARE')
75-
76-
def cancel_metal(self, hardware_id, immediate=False):
77-
"""Cancels the specified bare metal instance.
78-
79-
:param int id: The ID of the bare metal instance to be cancelled.
80-
:param bool immediate: If true, the bare metal instance will be
81-
cancelled immediately. Otherwise, it will be
82-
scheduled to cancel on the anniversary date.
83-
"""
53+
cancel_reason = reasons.get(reason, reasons['unneeded'])
54+
8455
hw_billing = self.get_hardware(hardware_id,
8556
mask='mask[id, billingItem.id]')
57+
if 'billingItem' not in hw_billing:
58+
raise SoftLayer.SoftLayerError(
59+
"No billing item found for hardware")
8660

8761
billing_id = hw_billing['billingItem']['id']
8862

89-
billing_item = self.client['Billing_Item']
90-
91-
if immediate:
92-
return billing_item.cancelService(id=billing_id)
93-
else:
94-
return billing_item.cancelServiceOnAnniversaryDate(id=billing_id)
63+
return self.client.call('Billing_Item', 'cancelItem',
64+
immediate, False, cancel_reason, comment,
65+
id=billing_id)
9566

9667
def list_hardware(self, tags=None, cpus=None, memory=None, hostname=None,
9768
domain=None, datacenter=None, nic_speed=None,

SoftLayer/tests/managers/hardware_tests.py

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -243,57 +243,53 @@ def test_place_order(self, create_dict):
243243
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder',
244244
args=({'test': 1, 'verify': 1},))
245245

246-
def test_cancel_metal_immediately(self):
247-
248-
result = self.hardware.cancel_metal(6327, immediate=True)
249-
250-
self.assertEqual(result, True)
251-
self.assert_called_with('SoftLayer_Billing_Item', 'cancelService',
252-
identifier=6327)
253-
254-
def test_cancel_metal_on_anniversary(self):
255-
256-
result = self.hardware.cancel_metal(6327, False)
257-
258-
self.assertEqual(result, True)
259-
self.assert_called_with('SoftLayer_Billing_Item',
260-
'cancelServiceOnAnniversaryDate',
261-
identifier=6327)
262-
263246
def test_cancel_hardware_without_reason(self):
264247
mock = self.set_mock('SoftLayer_Hardware_Server', 'getObject')
265-
mock.return_value = {'id': 987, 'bareMetalInstanceFlag': False}
248+
mock.return_value = {'id': 987, 'billingItem': {'id': 1234}}
266249

267250
result = self.hardware.cancel_hardware(987)
268251

269-
self.assertEqual(result,
270-
fixtures.SoftLayer_Ticket.createCancelServerTicket)
252+
self.assertEqual(result, True)
271253
reasons = self.hardware.get_cancellation_reasons()
272-
args = (987, reasons['unneeded'], '', True, 'HARDWARE')
273-
self.assert_called_with('SoftLayer_Ticket', 'createCancelServerTicket',
254+
args = (False, False, reasons['unneeded'], '')
255+
self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem',
256+
identifier=1234,
274257
args=args)
275258

276259
def test_cancel_hardware_with_reason_and_comment(self):
277260
mock = self.set_mock('SoftLayer_Hardware_Server', 'getObject')
278-
mock.return_value = {'id': 987, 'bareMetalInstanceFlag': False}
261+
mock.return_value = {'id': 987, 'billingItem': {'id': 1234}}
279262

280-
result = self.hardware.cancel_hardware(987, 'sales', 'Test Comment')
263+
result = self.hardware.cancel_hardware(6327,
264+
reason='sales',
265+
comment='Test Comment')
281266

282-
self.assertEqual(result,
283-
fixtures.SoftLayer_Ticket.createCancelServerTicket)
267+
self.assertEqual(result, True)
284268
reasons = self.hardware.get_cancellation_reasons()
285-
args = (987, reasons['sales'], 'Test Comment', True, 'HARDWARE')
286-
self.assert_called_with('SoftLayer_Ticket', 'createCancelServerTicket',
269+
args = (False, False, reasons['sales'], 'Test Comment')
270+
self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem',
271+
identifier=1234,
287272
args=args)
288273

289-
def test_cancel_hardware_on_bmc(self):
274+
def test_cancel_hardware(self):
290275

291276
result = self.hardware.cancel_hardware(6327)
292277

293278
self.assertEqual(result, True)
294279
self.assert_called_with('SoftLayer_Billing_Item',
295-
'cancelServiceOnAnniversaryDate',
296-
identifier=6327)
280+
'cancelItem',
281+
identifier=6327,
282+
args=(False, False, 'No longer needed', ''))
283+
284+
def test_cancel_hardware_no_billing_item(self):
285+
mock = self.set_mock('SoftLayer_Hardware_Server', 'getObject')
286+
mock.return_value = {'id': 987}
287+
288+
ex = self.assertRaises(SoftLayer.SoftLayerError,
289+
self.hardware.cancel_hardware,
290+
6327)
291+
self.assertEqual("No billing item found for hardware",
292+
str(ex))
297293

298294
def test_change_port_speed_public(self):
299295
self.hardware.change_port_speed(2, True, 100)

0 commit comments

Comments
 (0)