def on_get(self, req, resp, tenant_id, server_id, action_id): client = req.sl_client try: server = client['Virtual_Guest'].getObject( id=server_id, mask='id, accountId, createDate') except SoftLayer.SoftLayerAPIError as e: if e.faultCode == 'SoftLayer_Exception_ObjectNotFound': return error_handling.not_found(resp, 'Instance could not be found') raise actions = client['Event_Log'].getAllObjects( filter={ 'userType': { 'operation': 'SYSTEM' }, 'objectName': { 'operation': 'CCI' }, 'objectId': { 'operation': server_id }, 'traceId': { 'operation': action_id } }) if len(actions) == 0: return error_handling.not_found(resp, 'action could not be found') resp.body = {'instanceAction': format_action(server, actions[0])}
def on_get(self, req, resp, flavor_id, tenant_id=None): try: flavor_id = int(flavor_id) except ValueError: return not_found(resp, "Flavor could not be found") if flavor_id not in FLAVORS: return not_found(resp, "Flavor could not be found") flavor = get_flavor_details(self.app, req, FLAVORS[flavor_id], detail=True) resp.body = {"flavor": flavor}
def on_get(self, req, resp, flavor_id, tenant_id=None): try: flavor_id = int(flavor_id) except ValueError: return error_handling.not_found(resp, 'Flavor could not be found') if flavor_id not in self.flavors: return error_handling.not_found(resp, 'Flavor could not be found') flavor = get_flavor_details(self.app, req, self.flavors[flavor_id], detail=True) resp.body = {'flavor': flavor}
def on_delete(self, req, resp, image_guid=None, tenant_id=None): if not image_guid: return error_handling.not_found(resp, 'Image could not be found') client = req.sl_client results = get_image(client, image_guid) if not results: return error_handling.not_found(resp, 'Image could not be found') client['Virtual_Guest_Block_Device_Template_Group'].deleteObject( id=results['id']) resp.status = 204
def on_delete(self, req, resp, image_guid=None, tenant_id=None): if not image_guid: return error_handling.not_found(resp, 'Image could not be found') client = req.env['sl_client'] results = get_image(client, image_guid) if not results: return error_handling.not_found(resp, 'Image could not be found') client['Virtual_Guest_Block_Device_Template_Group'].deleteObject( id=results['id']) resp.status = 204
def on_delete(self, req, resp, image_guid=None, tenant_id=None): if not image_guid: return not_found(resp, 'Image could not be found') client = req.env['sl_client'] image_obj = SLImages(client) results = image_obj.get_image(image_guid) if not results: return not_found(resp, 'Image could not be found') client['Virtual_Guest_Block_Device_Template_Group'].deleteObject( id=results['id']) resp.status = 204
def on_get(self, req, resp, user_id, **kwargs): if "mask" not in kwargs: items = set(["id", "username", "firstName", "accountId", "email"]) kwargs["mask"] = "mask[%s]" % ",".join(items) client = req.env["sl_client"] try: user = client["User_Customer"].getObject(id=user_id, **kwargs) except SoftLayerAPIError as ex: if ex.faultCode == "SoftLayer_Exception_ObjectNotFound": return not_found(resp, "Invalid User ID specified") raise fieldMap = { # SL-Field : OpenStack-Field "id": "id", "username": "******", "email": "email", "accountId": "tenantId", "firstName": "name", } user_detail = {} for field in fieldMap.keys(): if user.get(field, None): user_detail[fieldMap[field]] = user[field] resp.body = {"user": user_detail}
def on_head(self, req, resp, image_guid, tenant_id=None): client = req.env['sl_client'] image_obj = SLImages(client) results = get_v1_image_details_dict( self.app, req, image_obj.get_image(image_guid)) if not results: return not_found(resp, 'Image could not be found') headers = { 'x-image-meta-id': image_guid, 'x-image-meta-status': results['status'].lower(), 'x-image-meta-owner': 'Need tenant ID here', 'x-image-meta-name': results['name'], 'x-image-meta-container_format': results['container_format'], 'x-image-meta-created_at': results['created'], 'x-image-meta-min_ram': results['minRam'], 'x-image-meta-updated_at': results['updated'], 'location': self.app.get_endpoint_url('image', req, 'v1_image', image_guid=image_guid), 'x-image-meta-deleted': False, 'x-image-meta-protected': results['protected'], 'x-image-meta-min_disk': results['minDisk'], 'x-image-meta-size': results['size'], 'x-image-meta-is_public': results['is_public'], 'x-image-meta-disk_format': results['disk_format'], } resp.set_headers(headers)
def on_head(self, req, resp, image_guid, tenant_id=None): client = req.env['sl_client'] image = get_image(client, image_guid) results = get_v1_image_details_dict(self.app, req, image) if not results: return error_handling.not_found(resp, 'Image could not be found') headers = { 'x-image-meta-id': image_guid, 'x-image-meta-status': results['status'].lower(), 'x-image-meta-owner': results.get('owner'), 'x-image-meta-name': results['name'], 'x-image-meta-container_format': results['container_format'], 'x-image-meta-created_at': results['created'], 'x-image-meta-min_ram': results.get('minRam'), 'x-image-meta-updated_at': results['updated'], 'location': self.app.get_endpoint_url('image', req, 'v1_image', image_guid=image_guid), 'x-image-meta-deleted': False, 'x-image-meta-protected': results['protected'], 'x-image-meta-min_disk': results.get('minDisk'), 'x-image-meta-size': results['size'], 'x-image-meta-is_public': results['is_public'], 'x-image-meta-disk_format': results['disk_format'], } resp.set_headers(headers) resp.content_type = 'text/html; charset=utf-8'
def on_get(self, req, resp, flavor_id, tenant_id=None): for flavor in self.flavors: if str(flavor_id) == flavor['id']: flavor = get_flavor_details(self.app, req, flavor, detail=True) resp.body = {'flavor': flavor} return return error_handling.not_found(resp, 'Flavor could not be found')
def on_get(self, req, resp, tenant_id, server_id): client = req.env['sl_client'] try: server = client['Virtual_Guest'].getObject( id=server_id, mask='id, accountId, createDate') except SoftLayerAPIError as e: if e.faultCode == 'SoftLayer_Exception_ObjectNotFound': return not_found(resp, 'Instance could not be found') raise actions = client['Event_Log'].getAllObjects( filter={ 'userType': { 'operation': 'SYSTEM' }, 'objectName': { 'operation': 'CCI' }, 'objectId': { 'operation': server_id } }) resp.body = { 'instanceActions': [format_action(server, action) for action in actions] }
def on_get(self, req, resp, user_id, **kwargs): if 'mask' not in kwargs: items = set([ 'id', 'username', 'firstName', 'accountId', 'email', ]) kwargs['mask'] = "mask[%s]" % ','.join(items) client = req.env['sl_client'] try: user = client['User_Customer'].getObject(id=user_id, **kwargs) except SoftLayer.SoftLayerAPIError as ex: if ex.faultCode == 'SoftLayer_Exception_ObjectNotFound': return error_handling.not_found(resp, "Invalid User ID specified") raise fieldMap = { # SL-Field : OpenStack-Field 'id': 'id', 'username': '******', 'email': 'email', 'accountId': 'tenantId', 'firstName': 'name' } user_detail = {} for field in fieldMap.keys(): if user.get(field, None): user_detail[fieldMap[field]] = user[field] resp.body = {'user': user_detail}
def on_delete(self, req, resp, tenant_id, keypair_name): # keypair_name client = req.env['sl_client'] mgr = SoftLayer.SshKeyManager(client) keys = mgr.list_keys(label=keypair_name) if len(keys) == 0: return error_handling.not_found(resp, 'KeyPair not Found') mgr.delete_key(keys[0]['id']) resp.status = 202
def on_get(self, req, resp, tenant_id, keypair_name): client = req.env['sl_client'] mgr = SoftLayer.SshKeyManager(client) keys = mgr.list_keys(label=keypair_name) if len(keys) == 0: return error_handling.not_found(resp, 'KeyPair not found') keypair = mgr.get_key(keys[0]['id']) resp.body = {'keypair': format_keypair(keypair)}
def on_delete(self, req, resp, tenant_id, keypair_name): # keypair_name client = req.sl_client mgr = SoftLayer.SshKeyManager(client) keys = mgr.list_keys(label=keypair_name) if len(keys) == 0: return error_handling.not_found(resp, 'KeyPair not Found') mgr.delete_key(keys[0]['id']) resp.status = 202
def on_get(self, req, resp, tenant_id, keypair_name): client = req.sl_client mgr = SoftLayer.SshKeyManager(client) keys = mgr.list_keys(label=keypair_name) if len(keys) == 0: return error_handling.not_found(resp, 'KeyPair not found') keypair = mgr.get_key(keys[0]['id']) resp.body = {'keypair': format_keypair(keypair)}
def on_get(self, req, resp, image_guid, tenant_id=None): client = req.env['sl_client'] image_obj = SLImages(client) results = image_obj.get_image(image_guid) if not results: return not_found(resp, 'Image could not be found') resp.body = { 'image': get_v1_image_details_dict(self.app, req, results)}
def on_get(self, req, resp, image_guid, tenant_id=None): client = req.sl_client results = get_image(client, image_guid) if not results: return error_handling.not_found(resp, 'Image could not be found') details = get_v2_image_details_dict(self.app, req, results, tenant_id) resp.status = 200 resp.body = details
def on_get(self, req, resp, image_guid, tenant_id=None): client = req.env['sl_client'] results = get_image(client, image_guid) if not results: return error_handling.not_found(resp, 'Image could not be found') details = get_v1_image_details_dict(self.app, req, results) resp.status = 200 resp.body = {'image': details}
def on_get(self, req, resp, tenant_id, server_id, action_id): client = req.env['sl_client'] try: server = client['Virtual_Guest'].getObject( id=server_id, mask='id, accountId, createDate') except SoftLayerAPIError as e: if e.faultCode == 'SoftLayer_Exception_ObjectNotFound': return not_found(resp, 'Instance could not be found') raise actions = client['Event_Log'].getAllObjects( filter={ 'userType': {'operation': 'SYSTEM'}, 'objectName': {'operation': 'CCI'}, 'objectId': {'operation': server_id}, 'traceId': {'operation': action_id}}) if len(actions) == 0: return not_found(resp, 'action could not be found') resp.body = {'instanceAction': format_action(server, actions[0])}
def on_head(self, req, resp, image_guid, tenant_id=None): client = req.sl_client image = get_image(client, image_guid) results = get_v1_image_details_dict(self.app, req, image) if not results: return error_handling.not_found(resp, 'Image could not be found') headers = { 'x-image-meta-id': image_guid, 'x-image-meta-status': results['status'].lower(), 'x-image-meta-owner': results.get('owner'), 'x-image-meta-name': results['name'], 'x-image-meta-container_format': results['container_format'], 'x-image-meta-created_at': results['created'], 'x-image-meta-min_ram': results.get('minRam'), 'x-image-meta-updated_at': results['updated'], 'location': self.app.get_endpoint_url('image', req, 'v1_image', image_guid=image_guid), 'x-image-meta-deleted': False, 'x-image-meta-protected': results['protected'], 'x-image-meta-min_disk': results.get('minDisk'), 'x-image-meta-size': results['size'], 'x-image-meta-is_public': results['is_public'], 'x-image-meta-disk_format': results['disk_format'], } resp.set_headers(headers) resp.content_type = 'text/html; charset=utf-8'
def on_get(self, req, resp, tenant_id, instance_id, volume_id): '''Shows details for the specified volume attachment.''' try: instance_id = int(instance_id) except Exception: return error_handling.not_found(resp, "Invalid instance ID specified.") if volume_id and len(volume_id) > OPENSTACK_VOLUME_UUID_LEN: return error_handling.bad_request(resp, message="Malformed request body") # since detail has the same info as the input request params, we can # just return the values back in the response using the request params. # But instead we will do sanity check to ensure the volume_id belongs # to the instance. vg_client = req.sl_client['Virtual_Guest'] try: blkDevices = vg_client.getBlockDevices(mask='id, diskImage.type', id=instance_id) vols = [ x for x in blkDevices if x['diskImage']['type']['keyName'] != 'SWAP' ] for vol in vols: json_response = None vol_disk_id = vol['diskImage']['id'] if str(vol_disk_id) == volume_id: json_response = { "volumeAttachment": { "device": "", "id": vol_disk_id, "serverId": instance_id, "volumeId": vol_disk_id } } break if json_response: resp.body = json_response else: return error_handling.volume_fault(resp, 'Invalid volume id.', code=HTTP.BAD_REQUEST) except Exception as e: return error_handling.volume_fault(resp, e.faultString)
def on_delete(self, req, resp, tenant_id, instance_id, volume_id): """Detach the requested volume from the specified instance.""" try: instance_id = int(instance_id) except Exception: return error_handling.not_found(resp, "Invalid instance ID specified.") if volume_id and len(volume_id) > OPENSTACK_VOLUME_UUID_LEN: return error_handling.bad_request(resp, message="Malformed request body") vdi_client = req.env['sl_client']['Virtual_Disk_Image'] # first let's check if the volume is already attached try: volinfo = vdi_client.getObject(id=volume_id, mask='blockDevices') blkDevices = volinfo['blockDevices'] if len(blkDevices) > 0: guestId_list = [blkDevice['guestId'] for blkDevice in blkDevices] for guest_id in guestId_list: if guest_id == instance_id: try: # detach the volume here vg_client = req.env['sl_client']['Virtual_Guest'] vg_client.detachDiskImage(volume_id, id=instance_id) break except Exception as e: error_handling.volume_fault(resp, e.faultString) else: return error_handling.volume_fault( resp, 'The requested disk image is attached to another ' 'guest and cannot be detached.', code=HTTP.BAD_REQUEST) except Exception as e: return error_handling.volume_fault(resp, e.faultString, code=500) resp.status = HTTP.ACCEPTED
def on_delete(self, req, resp, tenant_id, instance_id, volume_id): """Detach the requested volume from the specified instance.""" try: instance_id = int(instance_id) except Exception: return error_handling.not_found(resp, "Invalid instance ID specified.") if volume_id and len(volume_id) > OPENSTACK_VOLUME_UUID_LEN: return error_handling.bad_request(resp, message="Malformed request body") vdi_client = req.sl_client['Virtual_Disk_Image'] # first let's check if the volume is already attached try: volinfo = vdi_client.getObject(id=volume_id, mask='blockDevices') blkDevices = volinfo['blockDevices'] if len(blkDevices) > 0: guestId_list = [ blkDevice['guestId'] for blkDevice in blkDevices ] for guest_id in guestId_list: if guest_id == instance_id: try: # detach the volume here vg_client = req.sl_client['Virtual_Guest'] vg_client.detachDiskImage(volume_id, id=instance_id) break except Exception as e: error_handling.volume_fault(resp, e.faultString) else: return error_handling.volume_fault( resp, 'The requested disk image is attached to another ' 'guest and cannot be detached.', code=HTTP.BAD_REQUEST) except Exception as e: return error_handling.volume_fault(resp, e.faultString, code=500) resp.status = HTTP.ACCEPTED
def on_get(self, req, resp, tenant_id, server_id, network_label): network_label = network_label.lower() network_mask = None if network_label == 'public': network_mask = 'primaryIpAddress' elif network_label == 'private': network_mask = 'primaryBackendIpAddress' else: return not_found(resp, message='Network does not exist') client = req.env['sl_client'] cci = CCIManager(client) instance = cci.get_instance(server_id, mask='id, ' + network_mask) resp.body = { network_label: [ {'version': 4, 'addr': instance[network_mask]}, ] }
def on_get(self, req, resp, tenant_id, instance_id): '''Lists volume attachments for the instance.''' vg_client = req.sl_client['Virtual_Guest'] try: instance_id = int(instance_id) except Exception: return error_handling.not_found(resp, "Invalid instance ID specified.") try: blkDevices = vg_client.getBlockDevices(mask='id, diskImage.type', id=instance_id) vols = [ format_volume_attachment(vol['diskImage']['id'], instance_id, '') for vol in blkDevices if vol['diskImage']['type']['keyName'] != 'SWAP' ] resp.body = {"volumeAttachments": vols} except Exception as e: error_handling.volume_fault(resp, e.faultString)
def on_get(self, req, resp, tenant_id, server_id, network_label): network_label = network_label.lower() network_mask = None if network_label == 'public': network_mask = 'primaryIpAddress' elif network_label == 'private': network_mask = 'primaryBackendIpAddress' else: return error_handling.not_found(resp, message='Network does not exist') client = req.env['sl_client'] cci = SoftLayer.CCIManager(client) instance = cci.get_instance(server_id, mask='id, ' + network_mask) resp.body = { network_label: [ {'version': 4, 'addr': instance[network_mask]}, ] }
def on_get(self, req, resp, tenant_id, instance_id): '''Lists volume attachments for the instance.''' vg_client = req.env['sl_client']['Virtual_Guest'] try: instance_id = int(instance_id) except Exception: return error_handling.not_found(resp, "Invalid instance ID specified.") try: blkDevices = vg_client.getBlockDevices(mask='id, diskImage.type', id=instance_id) vols = [format_volume_attachment(vol['diskImage']['id'], instance_id, '') for vol in blkDevices if vol['diskImage']['type']['keyName'] != 'SWAP'] resp.body = {"volumeAttachments": vols} except Exception as e: error_handling.volume_fault(resp, e.faultString)
def on_get(self, req, resp, tenant_id, instance_id, volume_id): '''Shows details for the specified volume attachment.''' try: instance_id = int(instance_id) except Exception: return error_handling.not_found(resp, "Invalid instance ID specified.") if volume_id and len(volume_id) > OPENSTACK_VOLUME_UUID_LEN: return error_handling.bad_request(resp, message="Malformed request body") # since detail has the same info as the input request params, we can # just return the values back in the response using the request params. # But instead we will do sanity check to ensure the volume_id belongs # to the instance. vg_client = req.env['sl_client']['Virtual_Guest'] try: blkDevices = vg_client.getBlockDevices(mask='id, diskImage.type', id=instance_id) vols = [x for x in blkDevices if x['diskImage']['type']['keyName'] != 'SWAP'] for vol in vols: json_response = None vol_disk_id = vol['diskImage']['id'] if str(vol_disk_id) == volume_id: json_response = {"volumeAttachment": {"device": "", "id": vol_disk_id, "serverId": instance_id, "volumeId": vol_disk_id}} break if json_response: resp.body = json_response else: error_handling.volume_fault(resp, 'Invalid volume id.', code=HTTP.BAD_REQUEST) except Exception as e: error_handling.volume_fault(resp, e.faultString)
def on_get(self, req, resp, user_id, **kwargs): if 'mask' not in kwargs: items = set([ 'id', 'username', 'firstName', 'accountId', 'email', ]) kwargs['mask'] = "mask[%s]" % ','.join(items) client = req.env['sl_client'] try: user = client['User_Customer'].getObject(id=user_id, **kwargs) except SoftLayer.SoftLayerAPIError as ex: if ex.faultCode == 'SoftLayer_Exception_ObjectNotFound': return error_handling.not_found(resp, "Invalid User ID specified") raise fieldMap = { # SL-Field : OpenStack-Field 'id': 'id', 'username': '******', 'email': 'email', 'accountId': 'tenantId', 'firstName': 'name' } user_detail = {} for field in fieldMap.keys(): if user.get(field, None): user_detail[fieldMap[field]] = user[field] resp.body = { 'user': user_detail }
def on_post(self, req, resp, tenant_id, instance_id): '''Attaches a specified volume to a specified server.''' vs_mgr = SoftLayer.VSManager(req.sl_client) try: instance_id = int(instance_id) except Exception: # If the instance ID is not valid an exception will be sent return error_handling.not_found(resp, "Invalid instance ID specified.") # Get the instance to verify it exists; also using info from # instance to fill out the response object try: instance = vs_mgr.get_instance(instance_id) except Exception as e: # If the instance is not found an exception will be sent return error_handling.volume_fault( resp, 'The requested instance was not found', code=HTTP.NOT_FOUND) if not instance: return error_handling.volume_fault( resp, 'The requested instance was not found', code=HTTP.NOT_FOUND) # Get the volume ID from the request body body = json.loads(req.stream.read().decode()) CREATE_VOLUME_ATTACHMENT_VALIDATOR.validate(body) volume_id = body['volumeAttachment']['volumeId'] # first let's check if the volume is already attached block_mgr = SoftLayer.BlockStorageManager(req.sl_client) blk_devices = [] try: # get the volume info to see if there are any attachments # it also verifies that the volume exists items = {'id', 'allowedVirtualGuests[allowedHost[credential]]'} al_mask = ','.join(items) access_list = block_mgr.get_block_volume_access_list(volume_id, mask=al_mask) blk_devices = access_list['allowedVirtualGuests'] except Exception as e: return error_handling.volume_fault( resp, 'The requested volume was not found', code=HTTP.NOT_FOUND) if len(blk_devices) > 0: return error_handling.volume_fault( resp, 'The requested volume is already attached to ' 'a guest.', code=HTTP.BAD_REQUEST) try: # attach the volume; authorizing the host to the volume block_mgr.authorize_host_to_volume(volume_id, virtual_guest_ids=[instance_id]) volume_att = { 'device': "", 'serverId': instance_id, 'volumeId': volume_id } resp.body = {"volumeAttachment": volume_att} resp.status = HTTP.OK except Exception as e: return error_handling.volume_fault(resp, message=str(e), code=HTTP.BAD_REQUEST)
def on_get(self, req, resp, tenant_id, alias): if alias not in EXTENSIONS: return error_handling.not_found( resp, 'No extension exists with given alias.') resp.body = {'extension': EXTENSIONS[alias]}
def on_post(self, req, resp, tenant_id, instance_id): body = json.loads(req.stream.read().decode()) if len(body) == 0: return error_handling.bad_request(resp, message="Malformed request body") vg_client = req.env['sl_client']['Virtual_Guest'] cci = SoftLayer.CCIManager(req.env['sl_client']) try: instance_id = int(instance_id) except Exception: return error_handling.not_found(resp, "Invalid instance ID specified.") instance = cci.get_instance(instance_id) if 'pause' in body or 'suspend' in body: try: vg_client.pause(id=instance_id) except SoftLayer.SoftLayerAPIError as e: if 'Unable to pause instance' in e.faultString: return error_handling.duplicate(resp, e.faultString) raise resp.status = 202 return elif 'unpause' in body or 'resume' in body: vg_client.resume(id=instance_id) resp.status = 202 return elif 'reboot' in body: if body['reboot'].get('type') == 'SOFT': vg_client.rebootSoft(id=instance_id) elif body['reboot'].get('type') == 'HARD': vg_client.rebootHard(id=instance_id) else: vg_client.rebootDefault(id=instance_id) resp.status = 202 return elif 'os-stop' in body: vg_client.powerOff(id=instance_id) resp.status = 202 return elif 'os-start' in body: vg_client.powerOn(id=instance_id) resp.status = 202 return elif 'createImage' in body: image_name = body['createImage']['name'] disks = [] for disk in filter(lambda x: x['device'] == '0', instance['blockDevices']): disks.append(disk) try: vg_client.createArchiveTransaction( image_name, disks, "Auto-created by OpenStack compatibility layer", id=instance_id, ) # Workaround for not having an image guid until the image is # fully created. TODO(nbeitenmiller): Fix this cci.wait_for_transaction(instance_id, 300) _filter = { 'privateBlockDeviceTemplateGroups': { 'name': {'operation': image_name}, 'createDate': { 'operation': 'orderBy', 'options': [{'name': 'sort', 'value': ['DESC']}], } }} acct = req.env['sl_client']['Account'] matching_image = acct.getPrivateBlockDeviceTemplateGroups( mask='id, globalIdentifier', filter=_filter, limit=1) image_guid = matching_image.get('globalIdentifier') url = self.app.get_endpoint_url('image', req, 'v2_image', image_guid=image_guid) resp.status = 202 resp.set_header('location', url) except SoftLayer.SoftLayerAPIError as e: error_handling.compute_fault(resp, e.faultString) return elif 'os-getConsoleOutput' in body: resp.status = 501 return elif 'resize' in body: flavor_id = int(body['resize'].get('flavorRef')) if flavor_id not in flavors.FLAVORS: return error_handling.bad_request( resp, message="Invalid flavor id in the request body") flavor = flavors.FLAVORS[flavor_id] cci.upgrade(instance_id, cpus=flavor['cpus'], memory=flavor['ram'] / 1024) resp.status = 202 return elif 'confirmResize' in body: resp.status = 204 return return error_handling.bad_request( resp, message="There is no such action: %s" % list(body.keys()), code=400)
def on_post(self, req, resp, tenant_id, instance_id): '''Attaches a specified volume to a specified server.''' body = json.loads(req.stream.read().decode()) if (len(body) == 0 or 'volumeAttachment' not in body or 'volumeId' not in body['volumeAttachment']): return error_handling.bad_request(resp, message="Malformed " "request body") vg_client = req.env['sl_client']['Virtual_Guest'] try: instance_id = int(instance_id) except Exception: return error_handling.not_found(resp, "Invalid instance ID specified.") volume_id = body['volumeAttachment']['volumeId'] if volume_id and len(volume_id) > OPENSTACK_VOLUME_UUID_LEN: return error_handling.bad_request(resp, message="Malformed " "request body") vdi_client = req.env['sl_client']['Virtual_Disk_Image'] volinfo = None # first let's check if the volume is already attached try: volinfo = vdi_client.getObject(id=volume_id, mask='blockDevices') blkDevices = volinfo['blockDevices'] if (len(blkDevices) > 0): guestId_list = [ blkDevice['guestId'] for blkDevice in blkDevices ] for guest_id in guestId_list: if (guest_id == instance_id): return error_handling.volume_fault( resp, 'The requested disk image is already attached to ' 'this guest.', code=HTTP.BAD_REQUEST) else: return error_handling.volume_fault( resp, 'The requested disk image is already attached to ' 'another guest.', code=HTTP.BAD_REQUEST) except Exception as e: return error_handling.volume_fault(resp, e.faultString, code=HTTP.NOT_FOUND) try: # providing different size doesn't seem to have any impact on the # outcome hence using 10 as default size. disk_check = vg_client.checkHostDiskAvailability(10, id=instance_id) except Exception: disk_check = True try: if disk_check: sl_transaction = vg_client.attachDiskImage(volume_id, id=instance_id) resp.body = { "volumeAttachment": { "device": "", "id": sl_transaction['id'], "serverId": instance_id, "volumeId": volume_id } } resp.status = HTTP.ACCEPTED else: return error_handling.volume_fault( resp, 'Action causes migration to a new host. Migration is not ' 'allowed.', code=HTTP.BAD_REQUEST) except Exception as e: error_handling.volume_fault(resp, e.faultString)
def on_post(self, req, resp, tenant_id, instance_id): body = json.loads(req.stream.read().decode()) if len(body) == 0: return bad_request(resp, message="Malformed request body") vg_client = req.env['sl_client']['Virtual_Guest'] cci = CCIManager(req.env['sl_client']) try: instance_id = int(instance_id) except ValueError: return not_found(resp, "Invalid instance ID specified.") instance = cci.get_instance(instance_id) if 'pause' in body or 'suspend' in body: try: vg_client.pause(id=instance_id) except SoftLayerAPIError as e: if 'Unable to pause instance' in e.faultString: return duplicate(resp, e.faultString) raise resp.status = 202 return elif 'unpause' in body or 'resume' in body: vg_client.resume(id=instance_id) resp.status = 202 return elif 'reboot' in body: if body['reboot'].get('type') == 'SOFT': vg_client.rebootSoft(id=instance_id) elif body['reboot'].get('type') == 'HARD': vg_client.rebootHard(id=instance_id) else: vg_client.rebootDefault(id=instance_id) resp.status = 202 return elif 'os-stop' in body: vg_client.powerOff(id=instance_id) resp.status = 202 return elif 'os-start' in body: vg_client.powerOn(id=instance_id) resp.status = 202 return elif 'createImage' in body: image_name = body['createImage']['name'] disks = [] for disk in filter(lambda x: x['device'] == '0', instance['blockDevices']): disks.append(disk) try: vg_client.createArchiveTransaction( image_name, disks, "Auto-created by OpenStack compatibility layer", id=instance_id, ) # Workaround for not having an image guid until the image is # fully created. TODO: Fix this cci.wait_for_transaction(instance_id, 300) _filter = { 'privateBlockDeviceTemplateGroups': { 'name': { 'operation': image_name }, 'createDate': { 'operation': 'orderBy', 'options': [{ 'name': 'sort', 'value': ['DESC'] }], } } } acct = req.env['sl_client']['Account'] matching_image = acct.getPrivateBlockDeviceTemplateGroups( mask='id, globalIdentifier', filter=_filter, limit=1) image_guid = matching_image.get('globalIdentifier') url = self.app.get_endpoint_url('image', req, 'v2_image', image_guid=image_guid) resp.status = 202 resp.set_header('location', url) except SoftLayerAPIError as e: compute_fault(resp, e.faultString) return elif 'os-getConsoleOutput' in body: resp.status = 501 return return bad_request(resp, message="There is no such action: %s" % list(body.keys()), code=400)
def on_get(self, req, resp, tenant_id, alias): if alias not in EXTENSIONS: return not_found(resp, 'No extension exists with given alias.') resp.body = {'extension': EXTENSIONS[alias]}
def on_post(self, req, resp, tenant_id, instance_id): '''Attaches a specified volume to a specified server.''' body = json.loads(req.stream.read().decode()) if any([len(body) == 0, 'volumeAttachment' not in body, 'volumeId' not in body['volumeAttachment']]): return error_handling.bad_request(resp, message="Malformed request body") vg_client = req.env['sl_client']['Virtual_Guest'] try: instance_id = int(instance_id) except Exception: return error_handling.not_found(resp, "Invalid instance ID specified.") volume_id = body['volumeAttachment']['volumeId'] if volume_id and len(volume_id) > OPENSTACK_VOLUME_UUID_LEN: return error_handling.bad_request(resp, message="Malformed request body") vdi_client = req.env['sl_client']['Virtual_Disk_Image'] volinfo = None # first let's check if the volume is already attached try: volinfo = vdi_client.getObject(id=volume_id, mask='blockDevices') blkDevices = volinfo['blockDevices'] if (len(blkDevices) > 0): guestId_list = [blkDevice['guestId'] for blkDevice in blkDevices] for guest_id in guestId_list: if (guest_id == instance_id): return error_handling.volume_fault( resp, 'The requested disk image is already attached to ' 'this guest.', code=HTTP.BAD_REQUEST) else: return error_handling.volume_fault( resp, 'The requested disk image is already attached to ' 'another guest.', code=HTTP.BAD_REQUEST) except Exception as e: return error_handling.volume_fault(resp, e.faultString, code=HTTP.NOT_FOUND) try: # providing different size doesn't seem to have any impact on the # outcome hence using 10 as default size. disk_check = vg_client.checkHostDiskAvailability(10, id=instance_id) except Exception: disk_check = True try: if disk_check: sl_transaction = vg_client.attachDiskImage(volume_id, id=instance_id) resp.body = {"volumeAttachment": {"device": "", "id": sl_transaction['id'], "serverId": instance_id, "volumeId": volume_id}} resp.status = HTTP.ACCEPTED else: return error_handling.volume_fault( resp, 'Action causes migration to a new host. Migration is not ' 'allowed.', code=HTTP.BAD_REQUEST) except Exception as e: error_handling.volume_fault(resp, e.faultString)
def on_post(self, req, resp, tenant_id, instance_id): body = json.loads(req.stream.read().decode()) if len(body) == 0: return bad_request(resp, message="Malformed request body") vg_client = req.env["sl_client"]["Virtual_Guest"] cci = CCIManager(req.env["sl_client"]) try: instance_id = int(instance_id) except ValueError: return not_found(resp, "Invalid instance ID specified.") instance = cci.get_instance(instance_id) if "pause" in body or "suspend" in body: try: vg_client.pause(id=instance_id) except SoftLayerAPIError as e: if "Unable to pause instance" in e.faultString: return duplicate(resp, e.faultString) raise resp.status = 202 return elif "unpause" in body or "resume" in body: vg_client.resume(id=instance_id) resp.status = 202 return elif "reboot" in body: if body["reboot"].get("type") == "SOFT": vg_client.rebootSoft(id=instance_id) elif body["reboot"].get("type") == "HARD": vg_client.rebootHard(id=instance_id) else: vg_client.rebootDefault(id=instance_id) resp.status = 202 return elif "os-stop" in body: vg_client.powerOff(id=instance_id) resp.status = 202 return elif "os-start" in body: vg_client.powerOn(id=instance_id) resp.status = 202 return elif "createImage" in body: image_name = body["createImage"]["name"] disks = [] for disk in filter(lambda x: x["device"] == "0", instance["blockDevices"]): disks.append(disk) try: vg_client.createArchiveTransaction( image_name, disks, "Auto-created by OpenStack compatibility layer", id=instance_id ) # Workaround for not having an image guid until the image is # fully created. TODO: Fix this cci.wait_for_transaction(instance_id, 300) _filter = { "privateBlockDeviceTemplateGroups": { "name": {"operation": image_name}, "createDate": {"operation": "orderBy", "options": [{"name": "sort", "value": ["DESC"]}]}, } } acct = req.env["sl_client"]["Account"] matching_image = acct.getPrivateBlockDeviceTemplateGroups( mask="id, globalIdentifier", filter=_filter, limit=1 ) image_guid = matching_image.get("globalIdentifier") url = self.app.get_endpoint_url("image", req, "v2_image", image_guid=image_guid) resp.status = 202 resp.set_header("location", url) except SoftLayerAPIError as e: compute_fault(resp, e.faultString) return elif "os-getConsoleOutput" in body: resp.status = 501 return return bad_request(resp, message="There is no such action: %s" % list(body.keys()), code=400)