def __init__(self, action, vm, credentials=None, atomic_context=None, action_fields=None, for_user=None): if not isinstance(vm, models.VirtualMachine): vm = util.get_vm(vm, credentials, for_update=True, non_deleted=True, non_suspended=not credentials.is_admin) self.vm = vm user_id = for_user if user_id is None: user_id = vm.userid if action == "BUILD": raise AssertionError("decorator does not support action 'BUILD'") validate_server_action(vm, action) vm.action = action commission_name = "client: api, resource: %s" % vm serial = quotas.handle_resource_commission( vm, action=action, action_fields=action_fields, commission_name=commission_name, for_user=user_id) if serial is not None: quotas.set_serial(atomic_context, serial)
def add(request, net, args): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # buildInProgress (409), # badMediaType(415), # itemNotFound (404), # overLimit (413) if net.state != 'ACTIVE': raise faults.BuildInProgress('Network not active yet') server_id = args.get('serverRef', None) if not server_id: raise faults.BadRequest('Malformed Request.') vm = get_vm(server_id, request.user_uniq, non_suspended=True) address = None if net.dhcp: # Get a free IP from the address pool. try: address = get_network_free_address(net) except EmptyPool: raise faults.OverLimit('Network is full') log.info("Connecting VM %s to Network %s(%s)", vm, net, address) backend.connect_to_network(vm, net, address) return HttpResponse(status=202)
def create_port(credentials, network_id, machine_id=None, address=None, name="", security_groups=None, device_owner=None): user_id = credentials.userid vm = None if machine_id is not None: vm = util.get_vm(machine_id, credentials, for_update=True, non_deleted=True, non_suspended=True) if vm.nics.count() == settings.GANETI_MAX_NICS_PER_INSTANCE: raise faults.BadRequest("Maximum ports per server limit reached") network = util.get_network(network_id, credentials, non_deleted=True, for_update=True) ipaddress = None if network.public: # Creating a port to a public network is only allowed if the user has # already a floating IP address in this network which is specified # as the fixed IP address of the port if address is None: msg = ("'fixed_ips' attribute must contain a floating IP address" " in order to connect to a public network.") raise faults.BadRequest(msg) ipaddress = util.get_floating_ip_by_address(credentials, address, for_update=True) port = _create_port(user_id, network, machine=vm, use_ipaddress=ipaddress, name=name, security_groups=security_groups, device_owner=device_owner) log.info("User %s created port %s, network: %s, machine: %s, ip: %s", user_id, port.id, network, vm, ipaddress) return port
def resize(server_id, flavor_id, credentials=None, atomic_context=None): vm = util.get_vm(server_id, credentials, for_update=True, non_deleted=True, non_suspended=True) flavor = util.get_flavor(flavor_id, credentials, include_deleted=False, for_project=vm.project) action_fields = {"beparams": {"vcpus": flavor.cpu, "maxmem": flavor.ram}} with commands.ServerCommand( "RESIZE", server_id, credentials, atomic_context, action_fields=action_fields) as vm: old_flavor = vm.flavor # User requested the same flavor if old_flavor.id == flavor.id: raise faults.BadRequest("Server '%s' flavor is already '%s'." % (vm, flavor)) # Check that resize can be performed if old_flavor.disk != flavor.disk: raise faults.BadRequest("Cannot change instance's disk size.") if old_flavor.volume_type_id != flavor.volume_type_id: raise faults.BadRequest("Cannot change instance's volume type.") log.info("Resizing VM from flavor '%s' to '%s", old_flavor, flavor) job_id = backend.resize_instance( vm, vcpus=flavor.cpu, memory=flavor.ram) vm.record_job(job_id) return vm
def remove(request, net, args): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # badMediaType(415), # itemNotFound (404), # overLimit (413) try: # attachment string: nic-<vm-id>-<nic-index> server_id = args.get('attachment', None).split('-')[1] nic_index = args.get('attachment', None).split('-')[2] except AttributeError: raise faults.BadRequest("Malformed Request") except IndexError: raise faults.BadRequest('Malformed Network Interface Id') if not server_id or not nic_index: raise faults.BadRequest('Malformed Request.') vm = get_vm(server_id, request.user_uniq, non_suspended=True) nic = get_nic_from_index(vm, nic_index) log.info("Removing NIC %s from VM %s", str(nic.index), vm) if nic.dirty: raise faults.BuildInProgress('Machine is busy.') else: vm.nics.all().update(dirty=True) backend.disconnect_from_network(vm, nic) return HttpResponse(status=202)
def demux_server_action(request, server_id): req = utils.get_json_body(request) log.debug('server_action %s %s', server_id, req) if not isinstance(req, dict) and len(req) != 1: raise faults.BadRequest("Malformed request") # Do not allow any action on deleted or suspended VMs vm = util.get_vm(server_id, request.user_uniq, for_update=True, non_deleted=True, non_suspended=True) try: action = req.keys()[0] except IndexError: raise faults.BadRequest("Malformed Request.") if not isinstance(action, basestring): raise faults.BadRequest("Malformed Request. Invalid action.") if key_to_action(action) not in [x[0] for x in VirtualMachine.ACTIONS]: if action not in ARBITRARY_ACTIONS: raise faults.BadRequest("Action %s not supported" % action) action_args = utils.get_attribute(req, action, required=True, attr_type=dict) return server_actions[action](request, vm, action_args)
def update_server_name(request, server_id): # Normal Response Code: 204 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # badMediaType(415), # itemNotFound (404), # buildInProgress (409), # overLimit (413) req = utils.get_json_body(request) log.debug("User: %s, VM: %s, Action: rename, Request: %s", request.user_uniq, server_id, req) req = utils.get_attribute(req, "server", attr_type=dict, required=True) name = utils.get_attribute(req, "name", attr_type=basestring, required=True) vm = util.get_vm(server_id, request.user_uniq, request.user_projects, for_update=True, non_suspended=True, non_deleted=True) servers.rename(vm, new_name=name) log.info("User %s renamed server %s", request.user_uniq, vm.id) return HttpResponse(status=204)
def update_metadata(request, server_id): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_request_dict(request) log.info('update_server_metadata %s %s', server_id, req) vm = util.get_vm(server_id, request.user_uniq, non_suspended=True) metadata = utils.get_attribute(req, "metadata", required=True, attr_type=dict) for key, val in metadata.items(): if not isinstance(key, (basestring, int)) or\ not isinstance(val, (basestring, int)): raise faults.BadRequest("Malformed Request. Invalid metadata.") meta, created = vm.metadata.get_or_create(meta_key=key) meta.meta_value = val meta.save() vm.save() vm_meta = dict((m.meta_key, m.meta_value) for m in vm.metadata.all()) return util.render_metadata(request, vm_meta, status=201)
def remove(request, net, args): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # badMediaType(415), # itemNotFound (404), # overLimit (413) attachment = args.get("attachment") if attachment is None: raise faults.BadRequest("Missing 'attachment' attribute.") try: nic_id = int(attachment) except (ValueError, TypeError): raise faults.BadRequest("Invalid 'attachment' attribute.") nic = util.get_nic(nic_id=nic_id) server_id = nic.machine_id vm = util.get_vm(server_id, request.user_uniq, request.user_projects, non_suspended=True, for_update=True, non_deleted=True) servers.disconnect(vm, nic) log.info("User %s disconnected VM %s to network %s, port: %s", request.user_uniq, vm.id, network.id, nic.id) return HttpResponse(status=202)
def remove(request, net, args): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # badMediaType(415), # itemNotFound (404), # overLimit (413) attachment = args.get("attachment") if attachment is None: raise faults.BadRequest("Missing 'attachment' attribute.") try: nic_id = int(attachment) except (ValueError, TypeError): raise faults.BadRequest("Invalid 'attachment' attribute.") nic = util.get_nic(nic_id=nic_id) server_id = nic.machine_id vm = util.get_vm(server_id, request.user_uniq, non_suspended=True, for_update=True, non_deleted=True) servers.disconnect(vm, nic) return HttpResponse(status=202)
def server_stats(request, server_id): # Normal Response Codes: 200 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # itemNotFound (404), # overLimit (413) log.debug('server_stats %s', server_id) vm = util.get_vm(server_id, request.user_uniq) secret = util.stats_encrypt(vm.backend_vm_id) stats = { 'serverRef': vm.id, 'refresh': settings.STATS_REFRESH_PERIOD, 'cpuBar': settings.CPU_BAR_GRAPH_URL % secret, 'cpuTimeSeries': settings.CPU_TIMESERIES_GRAPH_URL % secret, 'netBar': settings.NET_BAR_GRAPH_URL % secret, 'netTimeSeries': settings.NET_TIMESERIES_GRAPH_URL % secret } if request.serialization == 'xml': data = render_to_string('server_stats.xml', stats) else: data = json.dumps({'stats': stats}) return HttpResponse(data, status=200)
def server_action(request, server_id): req = utils.get_request_dict(request) log.debug('server_action %s %s', server_id, req) if len(req) != 1: raise faults.BadRequest("Malformed request") # Do not allow any action on deleted or suspended VMs vm = util.get_vm(server_id, request.user_uniq, for_update=True, non_deleted=True, non_suspended=True) try: key = req.keys()[0] if key not in ARBITRARY_ACTIONS: start_action(vm, key_to_action(key)) val = req[key] assert isinstance(val, dict) return server_actions[key](request, vm, val) except KeyError: raise faults.BadRequest("Unknown action") except AssertionError: raise faults.BadRequest("Invalid argument")
def demux_server_action(request, server_id): req = utils.get_json_body(request) if not isinstance(req, dict) and len(req) != 1: raise faults.BadRequest("Malformed request") # Do not allow any action on deleted or suspended VMs vm = util.get_vm(server_id, request.user_uniq, request.user_projects, for_update=True, non_deleted=True, non_suspended=True) try: action = req.keys()[0] except IndexError: raise faults.BadRequest("Malformed Request.") log.debug("User: %s, VM: %s, Action: %s Request: %s", request.user_uniq, server_id, action, req) if not isinstance(action, basestring): raise faults.BadRequest("Malformed Request. Invalid action.") if key_to_action(action) not in [x[0] for x in VirtualMachine.ACTIONS]: if action not in ARBITRARY_ACTIONS: raise faults.BadRequest("Action %s not supported" % action) action_args = utils.get_attribute(req, action, required=True, attr_type=dict) return server_actions[action](request, vm, action_args)
def update_server_name(request, server_id): # Normal Response Code: 204 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # badMediaType(415), # itemNotFound (404), # buildInProgress (409), # overLimit (413) req = utils.get_request_dict(request) log.info('update_server_name %s %s', server_id, req) try: name = req['server']['name'] except (TypeError, KeyError): raise faults.BadRequest("Malformed request") vm = util.get_vm(server_id, request.user_uniq, for_update=True, non_suspended=True) vm.name = name vm.save() return HttpResponse(status=204)
def update_metadata(request, server_id): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_request_dict(request) log.info('update_server_metadata %s %s', server_id, req) vm = util.get_vm(server_id, request.user_uniq, non_suspended=True) try: metadata = req['metadata'] assert isinstance(metadata, dict) except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") for key, val in metadata.items(): meta, created = vm.metadata.get_or_create(meta_key=key) meta.meta_value = val meta.save() vm.save() vm_meta = dict((m.meta_key, m.meta_value) for m in vm.metadata.all()) return util.render_metadata(request, vm_meta, status=201)
def create_metadata_item(request, server_id, key): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # itemNotFound (404), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_request_dict(request) log.info('create_server_metadata_item %s %s %s', server_id, key, req) vm = util.get_vm(server_id, request.user_uniq, non_suspended=True) try: metadict = req['meta'] assert isinstance(metadict, dict) assert len(metadict) == 1 assert key in metadict except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") meta, created = VirtualMachineMetadata.objects.get_or_create( meta_key=key, vm=vm) meta.meta_value = metadict[key] meta.save() vm.save() d = {meta.meta_key: meta.meta_value} return util.render_meta(request, d, status=201)
def server_stats(request, server_id): # Normal Response Codes: 200 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # itemNotFound (404), # overLimit (413) log.debug('server_stats %s', server_id) vm = util.get_vm(server_id, request.user_uniq) #secret = util.encrypt(vm.backend_vm_id) secret = vm.backend_vm_id # XXX disable backend id encryption stats = { 'serverRef': vm.id, 'refresh': settings.STATS_REFRESH_PERIOD, 'cpuBar': settings.CPU_BAR_GRAPH_URL % secret, 'cpuTimeSeries': settings.CPU_TIMESERIES_GRAPH_URL % secret, 'netBar': settings.NET_BAR_GRAPH_URL % secret, 'netTimeSeries': settings.NET_TIMESERIES_GRAPH_URL % secret} if request.serialization == 'xml': data = render_to_string('server_stats.xml', stats) else: data = json.dumps({'stats': stats}) return HttpResponse(data, status=200)
def resize(server_id, flavor_id, credentials=None, atomic_context=None): vm = util.get_vm(server_id, credentials, for_update=True, non_deleted=True, non_suspended=True) flavor = util.get_flavor(flavor_id, credentials, include_deleted=False, for_project=vm.project) action_fields = {"beparams": {"vcpus": flavor.cpu, "maxmem": flavor.ram}} with commands.ServerCommand("RESIZE", server_id, credentials, atomic_context, action_fields=action_fields) as vm: old_flavor = vm.flavor # User requested the same flavor if old_flavor.id == flavor.id: raise faults.BadRequest("Server '%s' flavor is already '%s'." % (vm, flavor)) # Check that resize can be performed if old_flavor.disk != flavor.disk: raise faults.BadRequest("Cannot change instance's disk size.") if old_flavor.volume_type_id != flavor.volume_type_id: raise faults.BadRequest("Cannot change instance's volume type.") log.info("Resizing VM from flavor '%s' to '%s", old_flavor, flavor) job_id = backend.resize_instance(vm, vcpus=flavor.cpu, memory=flavor.ram) vm.record_job(job_id) return vm
def update_server_name(request, server_id): # Normal Response Code: 204 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # badMediaType(415), # itemNotFound (404), # buildInProgress (409), # overLimit (413) req = utils.get_json_body(request) log.info('update_server_name %s %s', server_id, req) req = utils.get_attribute(req, "server", attr_type=dict, required=True) name = utils.get_attribute(req, "name", attr_type=basestring, required=True) vm = util.get_vm(server_id, request.user_uniq, for_update=True, non_suspended=True, non_deleted=True) servers.rename(vm, new_name=name) return HttpResponse(status=204)
def get_server_diagnostics(request, server_id): """ Virtual machine diagnostics api view. """ log.debug('server_diagnostics %s', server_id) vm = util.get_vm(server_id, request.user_uniq) diagnostics = diagnostics_to_dict(vm.diagnostics.all()) return render_diagnostics(request, diagnostics)
def detach_volume(server_id, volume_id, credentials): user_id = credentials.userid vm = util.get_vm(server_id, credentials, for_update=True, non_deleted=True) volume = get_volume(credentials, volume_id, for_update=True, non_deleted=True, exception=faults.BadRequest) server_attachments.detach_volume(vm, volume) log.info("User %s detached volume %s to VM %s", user_id, volume.id, vm.id)
def detach_volume(request, server_id, volume_id): log.debug("detach_volume server_id %s volume_id", server_id, volume_id) user_id = request.user_uniq vm = util.get_vm(server_id, user_id, for_update=True, non_deleted=True) volume = get_volume(user_id, volume_id, for_update=True, non_deleted=True, exception=faults.BadRequest) vm = server_attachments.detach_volume(vm, volume) # TODO: Check volume state, send job to detach volume return HttpResponse(status=202)
def get_volumes(request, server_id): vm = util.get_vm(server_id, request.credentials, for_update=False) # TODO: Filter attachments!! volumes = vm.volumes.filter(deleted=False).order_by("id") attachments = [volume_to_attachment(v) for v in volumes] data = json.dumps({'volumeAttachments': attachments}) return HttpResponse(data, status=200)
def get_volume_info(request, server_id, volume_id): log.debug("get_volume_info server_id %s volume_id", server_id, volume_id) user_id = request.user_uniq vm = util.get_vm(server_id, user_id, for_update=False) volume = get_volume(user_id, volume_id, for_update=False, non_deleted=True, exception=faults.BadRequest) servers._check_attachment(vm, volume) attachment = volume_to_attachment(volume) data = json.dumps({'volumeAttachment': attachment}) return HttpResponse(data, status=200)
def attach_volume(server_id, volume_id, credentials, atomic_context=None): user_id = credentials.userid vm = util.get_vm(server_id, credentials, for_update=True, non_deleted=True) volume = get_volume(credentials, volume_id, for_update=True, non_deleted=True, exception=faults.BadRequest) server_attachments.attach_volume(vm, volume, atomic_context) log.info("User %s attached volume %s to VM %s", user_id, volume.id, vm.id) return volume
def get_volumes(request, server_id): vm = util.get_vm(server_id, request.user_uniq, request.user_projects, for_update=False) # TODO: Filter attachments!! volumes = vm.volumes.filter(deleted=False).order_by("id") attachments = [volume_to_attachment(v) for v in volumes] data = json.dumps({'volumeAttachments': attachments}) return HttpResponse(data, status=200)
def delete_server_password(request, server_id): # Normal Response Code: 204 # Error Response Codes: computeFault (400, 500), # unauthorized (401), # itemNotFound (404), # badRequest (400), vm = util.get_vm(server_id, request.credentials) VM_PASSWORD_CACHE.delete(str(vm.pk)) return HttpResponse(status=204)
def update_metadata(request, server_id): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_json_body(request) credentials = request.credentials userid = credentials.userid log.debug("User: %s, VM: %s, Action: update_metadata, Request: %s", userid, server_id, req) vm = util.get_vm(server_id, credentials, non_suspended=True, non_deleted=True) metadata = utils.get_attribute(req, "metadata", required=True, attr_type=dict) if len(metadata) + len(vm.metadata.all()) - \ len(vm.metadata.all().filter(meta_key__in=metadata.keys())) > \ settings.CYCLADES_VM_MAX_METADATA: raise faults.BadRequest("Virtual Machines cannot have more than %s " "metadata items" % settings.CYCLADES_VM_MAX_METADATA) for key, val in metadata.items(): if len(key) > VirtualMachineMetadata.KEY_LENGTH: raise faults.BadRequest("Malformed Request. Metadata key is too" " long") if len(val) > VirtualMachineMetadata.VALUE_LENGTH: raise faults.BadRequest("Malformed Request. Metadata value is too" " long") if not isinstance(key, (basestring, int)) or\ not isinstance(val, (basestring, int)): raise faults.BadRequest("Malformed Request. Invalid metadata.") meta, created = vm.metadata.get_or_create(meta_key=key) meta.meta_value = val meta.save() vm.save() log.info("User %s updated metadata of VM %s", userid, vm.id) vm_meta = dict((m.meta_key, m.meta_value) for m in vm.metadata.all()) return util.render_metadata(request, vm_meta, status=201)
def delete_server_password(request, server_id): # Normal Response Code: 204 # Error Response Codes: computeFault (400, 500), # unauthorized (401), # itemNotFound (404), # badRequest (400), vm = util.get_vm(server_id, request.user_uniq, request.user_projects) VM_PASSWORD_CACHE.delete(str(vm.pk)) return HttpResponse(status=204)
def get_server(user_id, server_id, for_update=False, non_deleted=False, exception=faults.ItemNotFound): try: server_id = int(server_id) except (TypeError, ValueError): raise faults.BadRequest("Invalid server id: %s" % server_id) try: return get_vm(server_id, user_id, for_update=for_update, non_deleted=non_deleted, non_suspended=True) except faults.ItemNotFound: raise exception("Server %s not found" % server_id)
def list_metadata(request, server_id): # Normal Response Codes: 200, 203 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # overLimit (413) vm = util.get_vm(server_id, request.user_uniq, request.user_projects) metadata = dict((m.meta_key, m.meta_value) for m in vm.metadata.all()) return util.render_metadata(request, metadata, use_values=False, status=200)
def get_server_details(request, server_id): # Normal Response Codes: 200, 203 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # itemNotFound (404), # overLimit (413) vm = util.get_vm(server_id, request.user_uniq, request.user_projects, prefetch_related=["nics__ips", "metadata"]) server = vm_to_dict(vm, detail=True) return render_server(request, server)
def get_metadata_item(request, server_id, key): # Normal Response Codes: 200, 203 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # itemNotFound (404), # badRequest (400), # overLimit (413) vm = util.get_vm(server_id, request.user_uniq, request.user_projects) meta = util.get_vm_meta(vm, key) d = {meta.meta_key: meta.meta_value} return util.render_meta(request, d, status=200)
def get_metadata_item(request, server_id, key): # Normal Response Codes: 200, 203 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # itemNotFound (404), # badRequest (400), # overLimit (413) vm = util.get_vm(server_id, request.credentials) meta = util.get_vm_meta(vm, key) d = {meta.meta_key: meta.meta_value} return util.render_meta(request, d, status=200)
def create_metadata_item(request, server_id, key): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # itemNotFound (404), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_json_body(request) credentials = request.credentials userid = credentials.userid log.debug("User: %s, VM: %s, Action: create_metadata, Request: %s", userid, server_id, req) vm = util.get_vm(server_id, credentials, non_suspended=True, non_deleted=True) try: metadict = req['meta'] assert isinstance(metadict, dict) assert len(metadict) == 1 assert key in metadict except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") value = metadict[key] # Check key, value length if len(key) > VirtualMachineMetadata.KEY_LENGTH: raise faults.BadRequest("Malformed Request. Metadata key is too long") if len(value) > VirtualMachineMetadata.VALUE_LENGTH: raise faults.BadRequest("Malformed Request. Metadata value is too" " long") # Check number of metadata items if vm.metadata.exclude(meta_key=key).count() == \ settings.CYCLADES_VM_MAX_METADATA: raise faults.BadRequest("Virtual Machines cannot have more than %s" " metadata items" % settings.CYCLADES_VM_MAX_METADATA) meta, created = VirtualMachineMetadata.objects.get_or_create(meta_key=key, vm=vm) meta.meta_value = value meta.save() vm.save() d = {meta.meta_key: meta.meta_value} return util.render_meta(request, d, status=201)
def get_volume_info(request, server_id, volume_id): credentials = request.credentials vm = util.get_vm(server_id, credentials, for_update=False) volume = get_volume(credentials, volume_id, for_update=False, non_deleted=True, exception=faults.BadRequest) server_attachments._check_attachment(vm, volume) attachment = volume_to_attachment(volume) data = json.dumps({'volumeAttachment': attachment}) return HttpResponse(data, status=200)
def add_floating_ip(server_id, address, credentials): vm = util.get_vm(server_id, credentials, for_update=True, non_deleted=True, non_suspended=True) floating_ip = util.get_floating_ip_by_address( credentials, address, for_update=True) userid = vm.userid _create_port(userid, floating_ip.network, machine=vm, use_ipaddress=floating_ip) log.info("User %s attached floating IP %s to VM %s, address: %s," " network %s", credentials.userid, floating_ip.id, vm.id, floating_ip.address, floating_ip.network_id)
def create_metadata_item(request, server_id, key): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # itemNotFound (404), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_json_body(request) credentials = request.credentials userid = credentials.userid log.debug("User: %s, VM: %s, Action: create_metadata, Request: %s", userid, server_id, req) vm = util.get_vm(server_id, credentials, non_suspended=True, non_deleted=True) try: metadict = req['meta'] assert isinstance(metadict, dict) assert len(metadict) == 1 assert key in metadict except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") value = metadict[key] # Check key, value length if len(key) > VirtualMachineMetadata.KEY_LENGTH: raise faults.BadRequest("Malformed Request. Metadata key is too long") if len(value) > VirtualMachineMetadata.VALUE_LENGTH: raise faults.BadRequest("Malformed Request. Metadata value is too" " long") # Check number of metadata items if vm.metadata.exclude(meta_key=key).count() == \ settings.CYCLADES_VM_MAX_METADATA: raise faults.BadRequest("Virtual Machines cannot have more than %s" " metadata items" % settings.CYCLADES_VM_MAX_METADATA) meta, created = VirtualMachineMetadata.objects.get_or_create( meta_key=key, vm=vm) meta.meta_value = value meta.save() vm.save() d = {meta.meta_key: meta.meta_value} return util.render_meta(request, d, status=201)
def get_server_details(request, server_id): # Normal Response Codes: 200, 203 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # itemNotFound (404), # overLimit (413) log.debug('get_server_details %s', server_id) vm = util.get_vm(server_id, request.user_uniq) server = vm_to_dict(vm, detail=True) return render_server(request, server)
def list_metadata(request, server_id): # Normal Response Codes: 200, 203 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # overLimit (413) log.debug('list_server_metadata %s', server_id) vm = util.get_vm(server_id, request.user_uniq) metadata = dict((m.meta_key, m.meta_value) for m in vm.metadata.all()) return util.render_metadata(request, metadata, use_values=False, status=200)
def get_server_details(request, server_id): # Normal Response Codes: 200, 203 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # itemNotFound (404), # overLimit (413) vm = util.get_vm(server_id, request.credentials, prefetch_related=["nics__ips", "metadata"]) server = vm_to_dict(vm, detail=True) return render_server(request, server)
def rename(server_id, new_name, credentials=None): """Rename a VirtualMachine.""" server = util.get_vm(server_id, credentials, for_update=True, non_deleted=True, non_suspended=True) utils.check_name_length(new_name, VirtualMachine.VIRTUAL_MACHINE_NAME_LENGTH, "Server name is too long") old_name = server.name server.name = new_name server.save() log.info("Renamed server '%s' from '%s' to '%s'", server, old_name, new_name) return server
def detach_volume(request, server_id, volume_id): log.debug("User %s, VM: %s, Action: detach_volume, Volume: %s", request.user_uniq, server_id, volume_id) user_id = request.user_uniq vm = util.get_vm(server_id, user_id, request.user_projects, for_update=True, non_deleted=True) volume = get_volume(user_id, request.user_projects, volume_id, for_update=True, non_deleted=True, exception=faults.BadRequest) vm = server_attachments.detach_volume(vm, volume) log.info("User %s detached volume %s to VM %s", user_id, volume.id, vm.id) # TODO: Check volume state, send job to detach volume return HttpResponse(status=202)
def delete_server(request, server_id): # Normal Response Codes: 204 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # itemNotFound (404), # unauthorized (401), # buildInProgress (409), # overLimit (413) log.info('delete_server %s', server_id) vm = util.get_vm(server_id, request.user_uniq, for_update=True, non_suspended=True) vm = servers.destroy(vm) return HttpResponse(status=204)
def get_server_password(request, server_id): # Normal Response Code: 200 # Error Response Codes: computeFault (400, 500), # unauthorized (401), # itemNotFound (404), # badRequest (400), vm = util.get_vm(server_id, request.credentials) password = VM_PASSWORD_CACHE.get(str(vm.pk)) if not password: raise faults.ItemNotFound() data = json.dumps({'password': password}) return HttpResponse(data, status=200)