def cancel_file_volume(self, volume_id, reason='No longer needed', immediate=False): """Cancels the given file storage volume. :param integer volume_id: The volume ID :param string reason: The reason for cancellation :param boolean immediate: Cancel immediately or on anniversary date """ file_volume = self.get_file_volume_details( volume_id, mask='mask[id,billingItem[id,hourlyFlag]]') if 'billingItem' not in file_volume: raise exceptions.SoftLayerError('The volume has already been canceled') billing_item_id = file_volume['billingItem']['id'] if utils.lookup(file_volume, 'billingItem', 'hourlyFlag'): immediate = True return self.client['Billing_Item'].cancelItem( immediate, True, reason, id=billing_item_id)
def get_locations_list(self, image_id, location_names): """Converts a list of location names to a list of locations. :param int image_id: The ID of the image. :param list location_names: A list of location names strings. :returns: A list of locations associated with the given location names in the image. """ locations = self.get_storage_locations(image_id) locations_ids = [] matching_location = {} output_error = "Location {} does not exist for available locations for image {}" for location_name in location_names: for location in locations: if location_name == location.get('name'): matching_location = location break if matching_location.get('id') is None: raise exceptions.SoftLayerError( output_error.format(location_name, image_id)) locations_ids.append(matching_location) return locations_ids
def wait_for_sg_request(self, group_id, request_id, limit=60, delay=5): """Wait for a Security Group API request to complete. Security Group API requests may trigger firewall updates that complete ansynchronously. Firewall update completion is signalled via an Audit Log event. This method polls Security Group audit logs until the specified request is complete (either successfully or unsuccessfully). :param int group_id: The security group ID with the pending API request :param int request_id: The request ID of the API request we want to verify completion for. Security Group APIs that may complete asynchronously contain this value in the requestId field of their return value. :param int limit: The maximum amount of time to wait for completion. :param int delay: The number of seconds to sleep before polling checks. Defaults to 5. Example:: # Will return once firewall updates for Security Group API request 'abc123' are complete for security group 123456. net_mgr.wait_for_sg_request(123456, 'abc123') """ # Audit log event name for successfully API completion success_event_name = 'Network Component(s) Updated With Security Group' # Audit log event name for unsuccessful API completion failure_event_name = 'Security Group Update on Network Components Failed' LOGGER.info('wait %s seconds for request %s completion on Security Group %s', limit, request_id, group_id) wait_until = time.time() + limit for sg_id in itertools.repeat(group_id): LOGGER.info('check event logs for completion') try: # get all event logs for the specified security group logs = self.client.call("Event_Log", 'getAllObjects', filter={'objectId': {'operation': sg_id}}) # # look for a log for the indicated request, there will be # only 1 SG log per request_id. # completion_log = None for one_log in logs: if 'metaData' not in one_log: LOGGER.info('no metaData') continue metadata = json.loads(one_log['metaData']) if 'requestId' not in metadata: LOGGER.info('no requestId') continue if metadata['requestId'] == request_id: LOGGER.info('req Id match') event_name = one_log['eventName'] if event_name == success_event_name or event_name == failure_event_name: completion_log = one_log break else: # LOGGER.info('req Id doesnt match') pass # # check if it's a successful or failure completion log # if completion_log is not None: if completion_log['eventName'] == success_event_name: # return True if firewall updates for the Security Group request # completed successfully. LOGGER.info('request %s complete successfully', request_id) return True elif completion_log['eventName'] == failure_event_name: LOGGER.info('request %s complete with failure', request_id) raise exceptions.SoftLayerError("Security Group %s request %s did not " "complete within the specified timeout" " (%s seconds)" % (sg_id, request_id, limit)) else: LOGGER.warning('unexpected log event: %s', completion_log['eventName']) raise exceptions.SoftLayerError("Security Group internal error, rcvd %s " % completion_log['eventName']) # # no completion log yet, delay and try again # LOGGER.info("%s not complete.", str(request_id)) except exceptions.SoftLayerAPIError: # if the call is excepting unexpectedly, scale back how # frequently we call it. delay = (delay * 2) + random.randint(0, 9) LOGGER.exception() now = time.time() if now > wait_until: LOGGER.info("Security Group %s request %s did not complete" " within the specified timeout %s", sg_id, request_id, limit) raise exceptions.SoftLayerError("Security Group %s request %s did not complete" " within the specified timeout %s" % (sg_id, request_id, limit)) LOGGER.info('Auto retry in %s seconds', str(min(delay, wait_until - now))) time.sleep(min(delay, wait_until - now))