99import socket
1010import time
1111
12+
1213import SoftLayer
1314from SoftLayer .decoration import retry
1415from SoftLayer .managers import ordering
@@ -56,8 +57,7 @@ def __init__(self, client, ordering_manager=None):
5657 else :
5758 self .ordering_manager = ordering_manager
5859
59- def cancel_hardware (self , hardware_id , reason = 'unneeded' , comment = '' ,
60- immediate = False ):
60+ def cancel_hardware (self , hardware_id , reason = 'unneeded' , comment = '' , immediate = False ):
6161 """Cancels the specified dedicated server.
6262
6363 Example::
@@ -66,27 +66,46 @@ def cancel_hardware(self, hardware_id, reason='unneeded', comment='',
6666 result = mgr.cancel_hardware(hardware_id=1234)
6767
6868 :param int hardware_id: The ID of the hardware to be cancelled.
69- :param string reason: The reason code for the cancellation. This should
70- come from :func:`get_cancellation_reasons`.
71- :param string comment: An optional comment to include with the
72- cancellation.
69+ :param string reason: The reason code for the cancellation. This should come from
70+ :func:`get_cancellation_reasons`.
71+ :param string comment: An optional comment to include with the cancellation.
72+ :param bool immediate: If set to True, will automatically update the cancelation ticket to request
73+ the resource be reclaimed asap. This request still has to be reviewed by a human
74+ :returns: True on success or an exception
7375 """
7476
7577 # Get cancel reason
7678 reasons = self .get_cancellation_reasons ()
7779 cancel_reason = reasons .get (reason , reasons ['unneeded' ])
80+ ticket_mgr = SoftLayer .TicketManager (self .client )
81+ mask = 'mask[id, hourlyBillingFlag, billingItem[id], openCancellationTicket[id]]'
82+ hw_billing = self .get_hardware (hardware_id , mask = mask )
7883
79- hw_billing = self .get_hardware (hardware_id ,
80- mask = 'mask[id, billingItem.id]' )
8184 if 'billingItem' not in hw_billing :
82- raise SoftLayer .SoftLayerError (
83- "No billing item found for hardware" )
85+ raise SoftLayer .SoftLayerError ("Ticket #%s already exists for this server" %
86+ hw_billing [ 'openCancellationTicket' ][ 'id' ] )
8487
8588 billing_id = hw_billing ['billingItem' ]['id' ]
8689
87- return self .client .call ('Billing_Item' , 'cancelItem' ,
88- immediate , False , cancel_reason , comment ,
89- id = billing_id )
90+ if immediate and not hw_billing ['hourlyBillingFlag' ]:
91+ LOGGER .warning ("Immediate cancelation of montly servers is not guaranteed. " +
92+ "Please check the cancelation ticket for updates." )
93+
94+ result = self .client .call ('Billing_Item' , 'cancelItem' ,
95+ False , False , cancel_reason , comment , id = billing_id )
96+ hw_billing = self .get_hardware (hardware_id , mask = mask )
97+ ticket_number = hw_billing ['openCancellationTicket' ]['id' ]
98+ cancel_message = "Please reclaim this server ASAP, it is no longer needed. Thankyou."
99+ ticket_mgr .update_ticket (ticket_number , cancel_message )
100+ LOGGER .info ("Cancelation ticket #%s has been updated requesting immediate reclaim" , ticket_number )
101+ else :
102+ result = self .client .call ('Billing_Item' , 'cancelItem' ,
103+ immediate , False , cancel_reason , comment , id = billing_id )
104+ hw_billing = self .get_hardware (hardware_id , mask = mask )
105+ ticket_number = hw_billing ['openCancellationTicket' ]['id' ]
106+ LOGGER .info ("Cancelation ticket #%s has been created" , ticket_number )
107+
108+ return result
90109
91110 @retry (logger = LOGGER )
92111 def list_hardware (self , tags = None , cpus = None , memory = None , hostname = None ,
@@ -359,7 +378,7 @@ def get_create_options(self):
359378
360379 # Sizes
361380 sizes = []
362- for preset in package ['activePresets' ]:
381+ for preset in package ['activePresets' ] + package [ 'accountRestrictedActivePresets' ] :
363382 sizes .append ({
364383 'name' : preset ['description' ],
365384 'key' : preset ['keyName' ]
@@ -418,6 +437,7 @@ def _get_package(self):
418437 prices
419438 ],
420439 activePresets,
440+ accountRestrictedActivePresets,
421441 regions[location[location[priceGroups]]]
422442 '''
423443
@@ -774,7 +794,7 @@ def _get_location(package, location):
774794
775795def _get_preset_id (package , size ):
776796 """Get the preset id given the keyName of the preset."""
777- for preset in package ['activePresets' ]:
797+ for preset in package ['activePresets' ] + package [ 'accountRestrictedActivePresets' ] :
778798 if preset ['keyName' ] == size or preset ['id' ] == size :
779799 return preset ['id' ]
780800
0 commit comments