Beispiel #1
0
def serial_action(request, serial):
    input_data = utils.get_json_body(request)
    check_is_dict(input_data)

    try:
        serial = int(serial)
    except ValueError:
        raise BadRequest("Serial should be an integer.")

    client_key = unicode(request.component_instance)

    accept = 'accept' in input_data
    reject = 'reject' in input_data

    if accept == reject:
        raise BadRequest('Specify either accept or reject action.')

    result = qh.resolve_pending_commission(clientkey=client_key,
                                           serial=serial,
                                           accept=accept)
    response = HttpResponse()
    if not result:
        response.status_code = 404

    return response
Beispiel #2
0
def update_metadata(request, image_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)
    log.info('update_image_metadata %s %s', image_id, req)
    with backend.PlanktonBackend(request.credentials.userid) as b:
        image = b.get_image(image_id)
        try:
            metadata = req['metadata']
            assert isinstance(metadata, dict)
        except (KeyError, AssertionError):
            raise faults.BadRequest('Malformed request.')

        properties = image['properties']
        properties.update(metadata)

        b.update_metadata(image_id, dict(properties=properties))

    return util.render_metadata(request, properties, status=201)
Beispiel #3
0
def update_volume(request, volume_id):
    req = utils.get_json_body(request)
    log.debug('update_volume volume_id: %s, request: %s', volume_id, req)

    volume = util.get_volume(request.user_uniq, volume_id, for_update=True,
                             non_deleted=True)

    vol_req = utils.get_attribute(req, "volume", attr_type=dict,
                                  required=True)
    name = utils.get_attribute(vol_req, "display_name", required=False)
    description = utils.get_attribute(vol_req, "display_description",
                                      required=False)
    delete_on_termination = utils.get_attribute(vol_req,
                                                "delete_on_termination",
                                                attr_type=bool,
                                                required=False)

    if name is None and description is None and\
       delete_on_termination is None:
        raise faults.BadRequest("Nothing to update.")
    else:
        volume = volumes.update(volume, name, description,
                                delete_on_termination)

    data = json.dumps({'volume': volume_to_dict(volume, detail=True)})
    return HttpResponse(data, content_type="application/json", status=200)
Beispiel #4
0
def reassign_volume(request, volume_id, args):
    req = utils.get_json_body(request)

    log.debug("User: %s, Volume: %s Action: reassign_volume, Request: %s",
              request.user_uniq, volume_id, args)

    shared_to_project = args.get("shared_to_project", False)
    if shared_to_project and not settings.CYCLADES_SHARED_RESOURCES_ENABLED:
        raise faults.Forbidden("Sharing resource to the members of the project"
                               " is not permitted")

    project = args.get("project")
    if project is None:
        raise faults.BadRequest("Missing 'project' attribute.")

    volume = util.get_volume(request.user_uniq,
                             request.user_projects,
                             volume_id,
                             for_update=True,
                             non_deleted=True)

    if request.user_uniq != volume.userid:
        raise faults.Forbidden("Action 'reassign' is allowed only to the owner"
                               " of the volume.")

    volumes.reassign_volume(volume, project, shared_to_project)

    log.info("User %s reassigned volume %s to project %s, shared: %s",
             request.user_uniq, volume.id, project, shared_to_project)

    return HttpResponse(status=200)
Beispiel #5
0
def membership_action(request, memb_id):
    user = request.user
    input_data = utils.get_json_body(request)
    func, action_data = get_action(MEMBERSHIP_ACTION, input_data)
    with ExceptionHandler():
        func(memb_id, user, reason=action_data)
    return HttpResponse()
Beispiel #6
0
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)

    credentials = request.credentials
    req = utils.get_json_body(request)
    log.debug("User: %s, VM: %s, Action: rename, Request: %s",
              credentials.userid, 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)

    servers.rename(server_id, new_name=name, credentials=credentials)

    log.info("User %s renamed server %s", credentials.userid, server_id)

    return HttpResponse(status=204)
Beispiel #7
0
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)
Beispiel #8
0
def update_snapshot(request, snapshot_id):
    util.assert_snapshots_enabled(request)
    req = utils.get_json_body(request)
    log.debug("User: %s, Snapshot: %s Action: update", request.user_uniq,
              snapshot_id)
    snapshot = util.get_snapshot(request.user_uniq, snapshot_id)

    snap_dict = utils.get_attribute(req,
                                    "snapshot",
                                    attr_type=dict,
                                    required=True)
    new_name = utils.get_attribute(snap_dict,
                                   "display_name",
                                   required=False,
                                   attr_type=basestring)
    new_description = utils.get_attribute(snap_dict,
                                          "display_description",
                                          required=False,
                                          attr_type=basestring)

    if new_name is None and new_description is None:
        raise faults.BadRequest("Nothing to update.")

    snapshot = snapshots.update(snapshot,
                                name=new_name,
                                description=new_description)

    log.info("User %s updated snapshot %s", request.user_uniq, snapshot["id"])

    data = json.dumps({'snapshot': snapshot_to_dict(snapshot, detail=True)})
    return HttpResponse(data, content_type="application/json", status=200)
Beispiel #9
0
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)
Beispiel #10
0
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)

    credentials = request.credentials
    req = utils.get_json_body(request)
    log.debug("User: %s, VM: %s, Action: rename, Request: %s",
              credentials.userid, 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)

    servers.rename(server_id, new_name=name, credentials=credentials)

    log.info("User %s renamed server %s", credentials.userid, server_id)

    return HttpResponse(status=204)
Beispiel #11
0
def allocate_floating_ip(request):
    """Allocate a floating IP."""
    req = utils.get_json_body(request)
    floating_ip_dict = api.utils.get_attribute(req, "floatingip",
                                               required=True, attr_type=dict)
    userid = request.user_uniq
    project = floating_ip_dict.get("project", None)
    log.info('allocate_floating_ip user: %s request: %s', userid, req)

    # the network_pool is a mandatory field
    network_id = api.utils.get_attribute(floating_ip_dict,
                                         "floating_network_id",
                                         required=False,
                                         attr_type=(basestring, int))
    if network_id is None:
        floating_ip = ips.create_floating_ip(userid, project=project)
    else:
        try:
            network_id = int(network_id)
        except ValueError:
            raise faults.BadRequest("Invalid networkd ID.")

        network = util.get_network(network_id, userid, for_update=True,
                                   non_deleted=True)
        address = api.utils.get_attribute(floating_ip_dict,
                                          "floating_ip_address",
                                          required=False,
                                          attr_type=basestring)
        floating_ip = ips.create_floating_ip(userid, network, address,
                                             project=project)

    log.info("User '%s' allocated floating IP '%s'", userid, floating_ip)
    request.serialization = "json"
    data = json.dumps({"floatingip": ip_to_dict(floating_ip)})
    return HttpResponse(data, status=200)
Beispiel #12
0
def resolve_pending_commissions(request):
    input_data = utils.get_json_body(request)
    check_is_dict(input_data)

    client_key = unicode(request.component_instance)
    accept = input_data.get('accept', [])
    reject = input_data.get('reject', [])

    if not isinstance(accept, list) or not isinstance(reject, list):
        m = '"accept" and "reject" should reference lists of serials.'
        raise BadRequest(m)

    if not are_integer(accept) or not are_integer(reject):
        raise BadRequest("Serials should be integer.")

    result = qh.resolve_pending_commissions(clientkey=client_key,
                                            accept_set=accept,
                                            reject_set=reject)
    accepted, rejected, notFound, conflicting = result
    notFound = [(serial, notFoundCF(serial)) for serial in notFound]
    conflicting = [(serial, conflictingCF(serial)) for serial in conflicting]
    cloudfaults = notFound + conflicting
    data = {'accepted': accepted, 'rejected': rejected, 'failed': cloudfaults}

    return json_response(data)
Beispiel #13
0
def update_volume(request, volume_id):
    credentials = request.credentials
    req = utils.get_json_body(request)
    log.debug("User: %s, Volume: %s Action: update_volume, Request: %s",
              credentials.userid, volume_id, req)

    vol_req = utils.get_attribute(req, "volume", attr_type=dict,
                                  required=True)
    name = utils.get_attribute(vol_req, "display_name", required=False)
    description = utils.get_attribute(vol_req, "display_description",
                                      required=False)
    delete_on_termination = utils.get_attribute(vol_req,
                                                "delete_on_termination",
                                                attr_type=bool,
                                                required=False)

    if name is None and description is None and\
       delete_on_termination is None:
        raise faults.BadRequest("Nothing to update.")

    volume = volumes.update(volume_id, name, description,
                            delete_on_termination, credentials=credentials)

    log.info("User %s updated volume %s", credentials.userid, volume_id)

    data = json.dumps({'volume': volume_to_dict(volume, detail=True)})
    return HttpResponse(data, content_type="application/json", status=200)
Beispiel #14
0
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)
Beispiel #15
0
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)
Beispiel #16
0
def create_metadata_item(request, image_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)
    log.info('create_image_metadata_item %s %s %s', image_id, key, req)
    try:
        metadict = req['meta']
        assert isinstance(metadict, dict)
        assert len(metadict) == 1
        assert key in metadict
    except (KeyError, AssertionError):
        raise faults.BadRequest('Malformed request.')

    val = metadict[key]
    with backend.PlanktonBackend(request.user_uniq) as b:
        image = b.get_image(image_id)
        properties = image['properties']
        properties[key] = val

        b.update_metadata(image_id, dict(properties=properties))

    return util.render_meta(request, {key: val}, status=201)
Beispiel #17
0
def create_metadata_item(request, image_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)
    log.info('create_image_metadata_item %s %s %s', image_id, key, req)
    try:
        metadict = req['meta']
        assert isinstance(metadict, dict)
        assert len(metadict) == 1
        assert key in metadict
    except (KeyError, AssertionError):
        raise faults.BadRequest('Malformed request.')

    val = metadict[key]
    with backend.PlanktonBackend(request.credentials.userid) as b:
        image = b.get_image(image_id)
        properties = image['properties']
        properties[key] = val

        b.update_metadata(image_id, dict(properties=properties))

    return util.render_meta(request, {key: val}, status=201)
Beispiel #18
0
def create_snapshot(request):
    """Create a new Snapshot."""

    req = utils.get_json_body(request)
    log.debug("create_snapshot %s", req)
    user_id = request.user_uniq

    snap_dict = utils.get_attribute(req, "snapshot", required=True,
                                    attr_type=dict)
    volume_id = utils.get_attribute(snap_dict, "volume_id", required=True)
    volume = util.get_volume(user_id, volume_id, for_update=True,
                             non_deleted=True,
                             exception=faults.BadRequest)

    metadata = utils.get_attribute(snap_dict, "metadata", required=False,
                                   attr_type=dict, default={})
    name = utils.get_attribute(snap_dict, "display_name", required=False,
                               attr_type=basestring,
                               default="Snapshot of volume '%s'" % volume_id)
    description = utils.get_attribute(snap_dict, "display_description",
                                      required=False,
                                      attr_type=basestring, default="")

    # TODO: What to do with force ?
    force = utils.get_attribute(req, "force", required=False, attr_type=bool,
                                default=False)

    snapshot = snapshots.create(user_id=user_id, volume=volume, name=name,
                                description=description, metadata=metadata,
                                force=force)

    # Render response
    data = json.dumps(dict(snapshot=snapshot_to_dict(snapshot, detail=False)))
    return HttpResponse(data, status=202)
Beispiel #19
0
def membership_action(request, memb_id):
    user = request.user
    input_data = utils.get_json_body(request)
    func, action_data = get_action(MEMBERSHIP_ACTION, input_data)
    with ExceptionHandler():
        func(memb_id, user, reason=action_data)
    return HttpResponse()
Beispiel #20
0
def update_snapshot(request, snapshot_id):
    credentials = request.credentials
    util.assert_snapshots_enabled(request)
    req = utils.get_json_body(request)
    log.debug("User: %s, Snapshot: %s Action: update",
              credentials.userid, snapshot_id)
    snapshot = util.get_snapshot(credentials.userid, snapshot_id)

    snap_dict = utils.get_attribute(req, "snapshot", attr_type=dict,
                                    required=True)
    new_name = utils.get_attribute(snap_dict, "display_name", required=False,
                                   attr_type=basestring)
    new_description = utils.get_attribute(snap_dict, "display_description",
                                          required=False, attr_type=basestring)

    if new_name is None and new_description is None:
        raise faults.BadRequest("Nothing to update.")

    snapshot = snapshots.update(snapshot, name=new_name,
                                description=new_description)

    log.info("User %s updated snapshot %s", credentials.userid, snapshot["id"])

    data = json.dumps({'snapshot': snapshot_to_dict(snapshot, detail=True)})
    return HttpResponse(data, content_type="application/json", status=200)
Beispiel #21
0
def update_volume(request, volume_id):
    req = utils.get_json_body(request)
    log.debug("User: %s, Volume: %s Action: update_volume, Request: %s",
              request.user_uniq, volume_id, req)

    volume = util.get_volume(request.user_uniq,
                             request.user_projects,
                             volume_id,
                             for_update=True,
                             non_deleted=True)

    vol_req = utils.get_attribute(req, "volume", attr_type=dict, required=True)
    name = utils.get_attribute(vol_req, "display_name", required=False)
    description = utils.get_attribute(vol_req,
                                      "display_description",
                                      required=False)
    delete_on_termination = utils.get_attribute(vol_req,
                                                "delete_on_termination",
                                                attr_type=bool,
                                                required=False)

    if name is None and description is None and\
       delete_on_termination is None:
        raise faults.BadRequest("Nothing to update.")
    else:
        volume = volumes.update(volume, name, description,
                                delete_on_termination)

    log.info("User %s updated volume %s", request.user_uniq, volume.id)

    data = json.dumps({'volume': volume_to_dict(volume, detail=True)})
    return HttpResponse(data, content_type="application/json", status=200)
Beispiel #22
0
def demux_server_action(request, server_id):
    credentials = request.credentials
    req = utils.get_json_body(request)

    if not isinstance(req, dict) and len(req) != 1:
        raise faults.BadRequest("Malformed request")

    try:
        action = req.keys()[0]
    except IndexError:
        raise faults.BadRequest("Malformed Request.")

    log.debug("User: %s, VM: %s, Action: %s Request: %s", credentials.userid,
              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=False,
                                      attr_type=dict)
    return server_actions[action](request, server_id, action_args)
Beispiel #23
0
def resolve_pending_commissions(request):
    input_data = utils.get_json_body(request)
    check_is_dict(input_data)

    client_key = unicode(request.component_instance)
    accept = input_data.get('accept', [])
    reject = input_data.get('reject', [])

    if not isinstance(accept, list) or not isinstance(reject, list):
        m = '"accept" and "reject" should reference lists of serials.'
        raise BadRequest(m)

    if not are_integer(accept) or not are_integer(reject):
        raise BadRequest("Serials should be integer.")

    result = qh.resolve_pending_commissions(clientkey=client_key,
                                            accept_set=accept,
                                            reject_set=reject)
    accepted, rejected, notFound, conflicting = result
    notFound = [(serial, notFoundCF(serial)) for serial in notFound]
    conflicting = [(serial, conflictingCF(serial)) for serial in conflicting]
    cloudfaults = notFound + conflicting
    data = {'accepted': accepted,
            'rejected': rejected,
            'failed': cloudfaults
            }

    return json_response(data)
Beispiel #24
0
def update_metadata(request, image_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)
    log.info('update_image_metadata %s %s', image_id, req)
    with backend.PlanktonBackend(request.user_uniq) as b:
        image = b.get_image(image_id)
        try:
            metadata = req['metadata']
            assert isinstance(metadata, dict)
        except (KeyError, AssertionError):
            raise faults.BadRequest('Malformed request.')

        properties = image['properties']
        properties.update(metadata)

        b.update_metadata(image_id, dict(properties=properties))

    return util.render_metadata(request, properties, status=201)
Beispiel #25
0
def serial_action(request, serial):
    input_data = utils.get_json_body(request)
    check_is_dict(input_data)

    try:
        serial = int(serial)
    except ValueError:
        raise BadRequest("Serial should be an integer.")

    client_key = unicode(request.component_instance)

    accept = 'accept' in input_data
    reject = 'reject' in input_data

    if accept == reject:
        raise BadRequest('Specify either accept or reject action.')

    result = qh.resolve_pending_commission(clientkey=client_key,
                                           serial=serial,
                                           accept=accept)
    response = HttpResponse()
    if not result:
        response.status_code = 404

    return response
Beispiel #26
0
def authenticate(request):
    try:
        content_length = get_content_length(request)
    except faults.LengthRequired:
        content_length = None

    public_mode = True if not content_length else False

    d = defaultdict(dict)
    if not public_mode:
        req = utils.get_json_body(request)

        uuid = None
        try:
            token_id = req['auth']['token']['id']
        except KeyError:
            try:
                token_id = req['auth']['passwordCredentials']['password']
                uuid = req['auth']['passwordCredentials']['username']
            except KeyError:
                raise faults.BadRequest(
                    'Malformed request: missing credentials')

        tenant = req['auth'].get('tenantName')

        if token_id is None:
            raise faults.BadRequest('Malformed request: missing token')

        try:
            user = AstakosUser.objects.get(auth_token=token_id)
        except AstakosUser.DoesNotExist:
            raise faults.Unauthorized('Invalid token')

        validate_user(user)

        if uuid is not None:
            if user.uuid != uuid:
                raise faults.Unauthorized('Invalid credentials')

        if tenant:
            if user.uuid != tenant:
                raise faults.BadRequest('Not conforming tenantName')

        d["access"]["token"] = {
            "id": user.auth_token,
            "expires": utils.isoformat(user.auth_token_expires),
            "tenant": {"id": user.uuid, "name": user.realname}}
        d["access"]["user"] = {
            "id": user.uuid, 'name': user.realname,
            "roles": [dict(id=str(g['id']), name=g['name']) for g in
                      user.groups.values('id', 'name')],
            "roles_links": []}

    d["access"]["serviceCatalog"] = get_endpoints()

    if request.serialization == 'xml':
        return xml_response({'d': d}, 'api/access.xml')
    else:
        return json_response(d)
Beispiel #27
0
def create_server(request):
    # Normal Response Code: 202
    # Error Response Codes: computeFault (400, 500),
    #                       serviceUnavailable (503),
    #                       unauthorized (401),
    #                       badMediaType(415),
    #                       itemNotFound (404),
    #                       badRequest (400),
    #                       serverCapacityUnavailable (503),
    #                       overLimit (413)
    req = utils.get_json_body(request)
    user_id = request.user_uniq
    log.info('create_server user: %s request: %s', user_id, req)

    try:
        server = req['server']
        name = server['name']
        metadata = server.get('metadata', {})
        assert isinstance(metadata, dict)
        image_id = server['imageRef']
        flavor_id = server['flavorRef']
        personality = server.get('personality', [])
        assert isinstance(personality, list)
        networks = server.get("networks")
        if networks is not None:
            assert isinstance(networks, list)
        project = server.get("project")
    except (KeyError, AssertionError):
        raise faults.BadRequest("Malformed request")

    volumes = None
    dev_map = server.get("block_device_mapping_v2")
    if dev_map is not None:
        volumes = parse_block_device_mapping(dev_map)

    # Verify that personalities are well-formed
    util.verify_personality(personality)
    # Get flavor (ensure it is active)
    flavor = util.get_flavor(flavor_id, include_deleted=False)
    if not flavor.allow_create:
        msg = ("It is not allowed to create a server from flavor with id '%d',"
               " see 'allow_create' flavor attribute")
        raise faults.Forbidden(msg % flavor.id)
    # Generate password
    password = util.random_password()

    vm = servers.create(user_id, name, password, flavor, image_id,
                        metadata=metadata, personality=personality,
                        project=project, networks=networks, volumes=volumes)

    server = vm_to_dict(vm, detail=True)
    server['status'] = 'BUILD'
    server['adminPass'] = password

    response = render_server(request, server, status=202)

    return response
Beispiel #28
0
def issue_commission(request):
    input_data = utils.get_json_body(request)
    check_is_dict(input_data)

    client_key = unicode(request.component_instance)
    provisions = input_data.get('provisions')
    if provisions is None:
        raise BadRequest("Provisions are missing.")
    if not isinstance(provisions, list):
        raise BadRequest("Provisions should be a list.")

    provisions = _provisions_to_list(provisions)
    force = input_data.get('force', False)
    if not isinstance(force, bool):
        raise BadRequest('"force" option should be a boolean.')

    auto_accept = input_data.get('auto_accept', False)
    if not isinstance(auto_accept, bool):
        raise BadRequest('"auto_accept" option should be a boolean.')

    name = input_data.get('name', "")
    if not isinstance(name, basestring):
        raise BadRequest("Commission name should be a string.")

    try:
        result = _issue_commission(clientkey=client_key,
                                   provisions=provisions,
                                   name=name,
                                   force=force,
                                   accept=auto_accept)
        data = {"serial": result}
        status_code = 201
    except (qh_exception.NoCapacityError, qh_exception.NoQuantityError) as e:
        status_code = 413
        body = {
            "message": e.message,
            "code": status_code,
            "data": e.data,
        }
        data = {"overLimit": body}
    except qh_exception.NoHoldingError as e:
        status_code = 404
        body = {
            "message": e.message,
            "code": status_code,
            "data": e.data,
        }
        data = {"itemNotFound": body}
    except qh_exception.InvalidDataError as e:
        status_code = 400
        body = {
            "message": e.message,
            "code": status_code,
        }
        data = {"badRequest": body}

    return json_response(data, status_code=status_code)
Beispiel #29
0
def reassign_volume(request, volume_id, args):
    req = utils.get_json_body(request)
    log.debug('reassign_volume volume_id: %s, request: %s', volume_id, req)
    project = args.get("project")
    if project is None:
        raise faults.BadRequest("Missing 'project' attribute.")
    volume = util.get_volume(request.user_uniq, volume_id, for_update=True,
                             non_deleted=True)
    volumes.reassign_volume(volume, project)
    return HttpResponse(status=200)
Beispiel #30
0
def create_snapshot(request):
    """Create a new Snapshot."""
    util.assert_snapshots_enabled(request)
    req = utils.get_json_body(request)
    user_id = request.user_uniq

    log.debug("User: %s, Action: create_snapshot, Request: %s", user_id, req)

    snap_dict = utils.get_attribute(req,
                                    "snapshot",
                                    required=True,
                                    attr_type=dict)
    volume_id = utils.get_attribute(snap_dict, "volume_id", required=True)
    volume = util.get_volume(user_id,
                             request.user_projects,
                             volume_id,
                             for_update=True,
                             non_deleted=True,
                             exception=faults.BadRequest)

    metadata = utils.get_attribute(snap_dict,
                                   "metadata",
                                   required=False,
                                   attr_type=dict,
                                   default={})
    name = utils.get_attribute(snap_dict,
                               "display_name",
                               required=False,
                               attr_type=basestring,
                               default="Snapshot of volume '%s'" % volume_id)
    description = utils.get_attribute(snap_dict,
                                      "display_description",
                                      required=False,
                                      attr_type=basestring,
                                      default="")

    # TODO: What to do with force ?
    force = utils.get_attribute(req,
                                "force",
                                required=False,
                                attr_type=bool,
                                default=False)

    snapshot = snapshots.create(user_id=user_id,
                                volume=volume,
                                name=name,
                                description=description,
                                metadata=metadata,
                                force=force)

    log.info("User %s created snapshot %s", user_id, snapshot["id"])

    # Render response
    data = json.dumps(dict(snapshot=snapshot_to_dict(snapshot, detail=False)))
    return HttpResponse(data, status=202)
Beispiel #31
0
def create_new_keypair(request):
    """Generates or imports a keypair.

    Normal response code: 201

    Error response codes: badRequest(400), unauthorized(401), forbidden(403),
                          conflict(409)
    """

    userid = request.credentials.userid
    if PublicKeyPair.user_limit_exceeded(userid):
        return HttpResponseServerError("SSH keys limit exceeded")

    req = utils.get_json_body(request)
    try:
        keypair = req['keypair']
        assert (isinstance(req, dict))
        name = keypair['name']
    except (KeyError, AssertionError):
        raise faults.BadRequest('Malformed request.')

    if re.match(key_name_regex, name) is None:
        raise faults.BadRequest('Invalid name format')

    try:
        # If the key with the same name exists in the database
        # a conflict error will be raised

        util.get_keypair(name, userid)
        # If we get past this point then the key is already present
        # in the database
        raise faults.Conflict('A keypair with that name already exists')
    except faults.ItemNotFound:
        new_keypair = PublicKeyPair(name=name, user=userid)

    gen_keypair = None
    try:
        new_keypair.content = keypair['public_key']
    except KeyError:
        # If the public_key field is omitted, generate a new
        # keypair and return both the private and the public key
        if not SUPPORT_GENERATE_KEYS:
            raise faults.Forbidden(
                "Application does not support ssh keys generation")

        gen_keypair = generate_keypair()
        new_keypair.content = gen_keypair['public']

    new_keypair.save()

    data = keypair_to_dict(new_keypair)
    if gen_keypair is not None:
        data['keypair']['private_key'] = gen_keypair['private']

    return HttpResponse(json.dumps(data), status=201)
Beispiel #32
0
def create_new_keypair(request):
    """Generates or imports a keypair.

    Normal response code: 201

    Error response codes: badRequest(400), unauthorized(401), forbidden(403),
                          conflict(409)
    """

    userid = request.credentials.userid
    if PublicKeyPair.user_limit_exceeded(userid):
        return HttpResponseServerError("SSH keys limit exceeded")

    req = utils.get_json_body(request)
    try:
        keypair = req['keypair']
        assert(isinstance(req, dict))
        name = keypair['name']
    except (KeyError, AssertionError):
        raise faults.BadRequest('Malformed request.')

    if re.match(key_name_regex, name) is None:
        raise faults.BadRequest('Invalid name format')

    try:
        # If the key with the same name exists in the database
        # a conflict error will be raised

        util.get_keypair(name, userid)
        # If we get past this point then the key is already present
        # in the database
        raise faults.Conflict('A keypair with that name already exists')
    except faults.ItemNotFound:
        new_keypair = PublicKeyPair(name=name, user=userid)

    gen_keypair = None
    try:
        new_keypair.content = keypair['public_key']
    except KeyError:
        # If the public_key field is omitted, generate a new
        # keypair and return both the private and the public key
        if not SUPPORT_GENERATE_KEYS:
            raise faults.Forbidden(
                "Application does not support ssh keys generation")

        gen_keypair = generate_keypair()
        new_keypair.content = gen_keypair['public']

    new_keypair.save()

    data = keypair_to_dict(new_keypair)
    if gen_keypair is not None:
        data['keypair']['private_key'] = gen_keypair['private']

    return HttpResponse(json.dumps(data), status=201)
Beispiel #33
0
def issue_commission(request):
    input_data = utils.get_json_body(request)
    check_is_dict(input_data)

    client_key = unicode(request.component_instance)
    provisions = input_data.get('provisions')
    if provisions is None:
        raise BadRequest("Provisions are missing.")
    if not isinstance(provisions, list):
        raise BadRequest("Provisions should be a list.")

    provisions = _provisions_to_list(provisions)
    force = input_data.get('force', False)
    if not isinstance(force, bool):
        raise BadRequest('"force" option should be a boolean.')

    auto_accept = input_data.get('auto_accept', False)
    if not isinstance(auto_accept, bool):
        raise BadRequest('"auto_accept" option should be a boolean.')

    name = input_data.get('name', "")
    if not isinstance(name, basestring):
        raise BadRequest("Commission name should be a string.")

    try:
        result = _issue_commission(clientkey=client_key,
                                   provisions=provisions,
                                   name=name,
                                   force=force,
                                   accept=auto_accept)
        data = {"serial": result}
        status_code = 201
    except (qh_exception.NoCapacityError,
            qh_exception.NoQuantityError) as e:
        status_code = 413
        body = {"message": e.message,
                "code": status_code,
                "data": e.data,
                }
        data = {"overLimit": body}
    except qh_exception.NoHoldingError as e:
        status_code = 404
        body = {"message": e.message,
                "code": status_code,
                "data": e.data,
                }
        data = {"itemNotFound": body}
    except qh_exception.InvalidDataError as e:
        status_code = 400
        body = {"message": e.message,
                "code": status_code,
                }
        data = {"badRequest": body}

    return json_response(data, status_code=status_code)
Beispiel #34
0
def project_action(request, project_id):
    user = request.user
    input_data = utils.get_json_body(request)

    func, action_data = get_action(PROJECT_ACTION, input_data)
    with ExceptionHandler():
        kwargs = {"request_user": user, "reason": action_data.get("reason", "")}
        if func in APP_ACTION_FUNCS:
            kwargs["application_id"] = action_data["app_id"]
        func(project_id=project_id, **kwargs)
    return HttpResponse()
Beispiel #35
0
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)
Beispiel #36
0
def reassign_volume(request, volume_id, args):
    req = utils.get_json_body(request)
    log.debug('reassign_volume volume_id: %s, request: %s', volume_id, req)
    project = args.get("project")
    if project is None:
        raise faults.BadRequest("Missing 'project' attribute.")
    volume = util.get_volume(request.user_uniq,
                             volume_id,
                             for_update=True,
                             non_deleted=True)
    volumes.reassign_volume(volume, project)
    return HttpResponse(status=200)
Beispiel #37
0
def network_action_demux(request, network_id):
    req = utils.get_json_body(request)
    action = req.keys()[0]
    try:
        f = NETWORK_ACTIONS[action]
    except KeyError:
        raise api.faults.BadRequest("Action %s not supported." % action)
    action_args = req[action]
    if not isinstance(action_args, dict):
        raise api.faults.BadRequest("Invalid argument.")

    return f(request, network_id, action_args)
Beispiel #38
0
def network_action_demux(request, network_id):
    req = utils.get_json_body(request)
    action = req.keys()[0]
    try:
        f = NETWORK_ACTIONS[action]
    except KeyError:
        raise api.faults.BadRequest("Action %s not supported." % action)
    action_args = req[action]
    if not isinstance(action_args, dict):
        raise api.faults.BadRequest("Invalid argument.")

    return f(request, network_id, action_args)
Beispiel #39
0
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)
Beispiel #40
0
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)
Beispiel #41
0
def update_volume_metadata(request, volume_id, reset=False):
    req = utils.get_json_body(request)
    log.debug("User: %s, Volume: %s Action: update_metadata, Request: %s",
              request.user_uniq, volume_id, req)

    meta_dict = utils.get_attribute(req,
                                    "metadata",
                                    required=True,
                                    attr_type=dict)
    for key, value in meta_dict.items():
        check_name_length(key, VolumeMetadata.KEY_LENGTH,
                          "Metadata key is too long.")
        check_name_length(value, VolumeMetadata.VALUE_LENGTH,
                          "Metadata value is too long.")
    volume = util.get_volume(request.user_uniq,
                             request.user_projects,
                             volume_id,
                             for_update=True,
                             non_deleted=True)
    if reset:
        if len(meta_dict) > settings.CYCLADES_VOLUME_MAX_METADATA:
            raise faults.BadRequest("Volumes cannot have more than %s metadata"
                                    " items" %
                                    settings.CYCLADES_VOLUME_MAX_METADATA)

        volume.metadata.all().delete()
        for key, value in meta_dict.items():
            volume.metadata.create(key=key, value=value)
    else:
        if len(meta_dict) + len(volume.metadata.all()) - \
           len(volume.metadata.all().filter(key__in=meta_dict.keys())) > \
           settings.CYCLADES_VOLUME_MAX_METADATA:
            raise faults.BadRequest("Volumes cannot have more than %s metadata"
                                    " items" %
                                    settings.CYCLADES_VOLUME_MAX_METADATA)

        for key, value in meta_dict.items():
            try:
                # Update existing metadata
                meta = volume.metadata.get(key=key)
                meta.value = value
                meta.save()
            except VolumeMetadata.DoesNotExist:
                # Or create a new one
                volume.metadata.create(key=key, value=value)

    log.info("User %s updated metadata for volume %s", request.user_uniq,
             volume.id)

    metadata = volume.metadata.values_list('key', 'value')
    data = json.dumps({"metadata": dict(metadata)})
    return HttpResponse(data, content_type="application/json", status=200)
Beispiel #42
0
def update_snapshot_metadata(request, snapshot_id, reset=False):
    req = utils.get_json_body(request)
    log.debug('update_snapshot_meta snapshot_id: %s, reset: %s request: %s',
              snapshot_id, reset, req)
    snapshot = util.get_snapshot(request.user_uniq, snapshot_id)
    meta_dict = utils.get_attribute(req, "metadata", required=True,
                                    attr_type=dict)
    with backend.PlanktonBackend(request.user_uniq) as b:
        b.update_properties(snapshot_id, meta_dict, replace=reset)
    snapshot = util.get_snapshot(request.user_uniq, snapshot_id)
    metadata = snapshot["properties"]
    data = json.dumps({"metadata": dict(metadata)})
    return HttpResponse(data, content_type="application/json", status=200)
Beispiel #43
0
def project_action(request, project_id):
    user = request.user
    input_data = utils.get_json_body(request)

    func, action_data = get_action(PROJECT_ACTION, input_data)
    with ExceptionHandler():
        kwargs = {"request_user": user,
                  "reason": action_data.get("reason", ""),
                  }
        if func in APP_ACTION_FUNCS:
            kwargs["application_id"] = action_data["app_id"]
        func(project_id=project_id, **kwargs)
    return HttpResponse()
Beispiel #44
0
def allocate_floating_ip(request):
    """Allocate a floating IP."""
    req = utils.get_json_body(request)

    log.debug("User: %s, Action: create_floating_ip, Request: %s",
              request.user_uniq, req)

    floating_ip_dict = api.utils.get_attribute(req,
                                               "floatingip",
                                               required=True,
                                               attr_type=dict)
    userid = request.user_uniq
    project = floating_ip_dict.get("project", None)
    shared_to_project = floating_ip_dict.get("shared_to_project", False)

    # the network_pool is a mandatory field
    network_id = api.utils.get_attribute(floating_ip_dict,
                                         "floating_network_id",
                                         required=False,
                                         attr_type=(basestring, int))

    if network_id is None:
        floating_ip = \
            ips.create_floating_ip(userid, project=project,
                                   shared_to_project=shared_to_project)
    else:
        try:
            network_id = int(network_id)
        except ValueError:
            raise faults.BadRequest("Invalid networkd ID.")

        network = util.get_network(network_id,
                                   userid,
                                   request.user_projects,
                                   for_update=True,
                                   non_deleted=True)
        address = api.utils.get_attribute(floating_ip_dict,
                                          "floating_ip_address",
                                          required=False,
                                          attr_type=basestring)
        floating_ip = \
            ips.create_floating_ip(userid, network, address,
                                   project=project,
                                   shared_to_project=shared_to_project)

    log.info("User %s created floating IP %s, network %s, address %s", userid,
             floating_ip.id, floating_ip.network_id, floating_ip.address)

    request.serialization = "json"
    data = json.dumps({"floatingip": ip_to_dict(floating_ip)})
    return HttpResponse(data, status=200)
Beispiel #45
0
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)
Beispiel #46
0
def update_snapshot_metadata(request, snapshot_id, reset=False):
    req = utils.get_json_body(request)
    log.debug('update_snapshot_meta snapshot_id: %s, reset: %s request: %s',
              snapshot_id, reset, req)
    snapshot = util.get_snapshot(request.user_uniq, snapshot_id)
    meta_dict = utils.get_attribute(req,
                                    "metadata",
                                    required=True,
                                    attr_type=dict)
    with backend.PlanktonBackend(request.user_uniq) as b:
        b.update_properties(snapshot_id, meta_dict, replace=reset)
    snapshot = util.get_snapshot(request.user_uniq, snapshot_id)
    metadata = snapshot["properties"]
    data = json.dumps({"metadata": dict(metadata)})
    return HttpResponse(data, content_type="application/json", status=200)
Beispiel #47
0
def update_snapshot_metadata(request, snapshot_id, reset=False):
    credentials = request.credentials
    util.assert_snapshots_enabled(request)
    req = utils.get_json_body(request)
    log.debug("User: %s, Snapshot: %s Action: update_metadata",
              credentials.userid, snapshot_id)
    snapshot = util.get_snapshot(credentials.userid, snapshot_id)
    meta_dict = utils.get_attribute(req, "metadata", required=True,
                                    attr_type=dict)
    with backend.PlanktonBackend(credentials.userid) as b:
        b.update_properties(snapshot_id, meta_dict, replace=reset)
    snapshot = util.get_snapshot(credentials.userid, snapshot_id)
    metadata = snapshot["properties"]
    data = json.dumps({"metadata": dict(metadata)})
    return HttpResponse(data, content_type="application/json", status=200)
Beispiel #48
0
def project_action(request, project_id):
    user = request.user
    input_data = utils.get_json_body(request)
    if not isinstance(input_data, dict):
        raise faults.BadRequest("Invalid input data")

    func, action_data = get_action(PROJECT_ACTION, input_data)
    with ExceptionHandler():
        kwargs = {"request_user": user,
                  "reason": action_data.get("reason", ""),
                  }
        if func in APP_ACTION_FUNCS:
            kwargs["application_id"] = action_data["app_id"]
        func(project_id=project_id, **kwargs)
    return HttpResponse()
Beispiel #49
0
def project_action(request, project_id):
    user = request.user
    input_data = utils.get_json_body(request)
    if not isinstance(input_data, dict):
        raise faults.BadRequest("Invalid input data")

    func, action_data = get_action(PROJECT_ACTION, input_data)
    with ExceptionHandler():
        kwargs = {"request_user": user,
                  "reason": action_data.get("reason", ""),
                  }
        if func in APP_ACTION_FUNCS:
            kwargs["application_id"] = action_data["app_id"]
        func(project_id=project_id, **kwargs)
    return HttpResponse()
Beispiel #50
0
def update_volume_metadata(request, volume_id, reset=False):
    credentials = request.credentials
    req = utils.get_json_body(request)
    log.debug("User: %s, Volume: %s Action: update_metadata, Request: %s",
              credentials.userid, volume_id, req)

    meta_dict = utils.get_attribute(req, "metadata", required=True,
                                    attr_type=dict)
    for key, value in meta_dict.items():
        check_name_length(key, VolumeMetadata.KEY_LENGTH,
                          "Metadata key is too long.")
        check_name_length(value, VolumeMetadata.VALUE_LENGTH,
                          "Metadata value is too long.")
    volume = util.get_volume(request.credentials,
                             volume_id, for_update=True, non_deleted=True)
    if reset:
        if len(meta_dict) > settings.CYCLADES_VOLUME_MAX_METADATA:
            raise faults.BadRequest("Volumes cannot have more than %s metadata"
                                    " items" %
                                    settings.CYCLADES_VOLUME_MAX_METADATA)

        volume.metadata.all().delete()
        for key, value in meta_dict.items():
            volume.metadata.create(key=key, value=value)
    else:
        if len(meta_dict) + len(volume.metadata.all()) - \
           len(volume.metadata.all().filter(key__in=meta_dict.keys())) > \
           settings.CYCLADES_VOLUME_MAX_METADATA:
            raise faults.BadRequest("Volumes cannot have more than %s metadata"
                                    " items" %
                                    settings.CYCLADES_VOLUME_MAX_METADATA)

        for key, value in meta_dict.items():
            try:
                # Update existing metadata
                meta = volume.metadata.get(key=key)
                meta.value = value
                meta.save()
            except VolumeMetadata.DoesNotExist:
                # Or create a new one
                volume.metadata.create(key=key, value=value)

    log.info("User %s updated metadata for volume %s", credentials.userid,
             volume.id)

    metadata = volume.metadata.values_list('key', 'value')
    data = json.dumps({"metadata": dict(metadata)})
    return HttpResponse(data, content_type="application/json", status=200)
Beispiel #51
0
def network_action_demux(request, network_id):
    req = utils.get_json_body(request)
    network = util.get_network(network_id,
                               request.user_uniq,
                               request.user_projects,
                               for_update=True,
                               non_deleted=True)
    action = req.keys()[0]
    try:
        f = NETWORK_ACTIONS[action]
    except KeyError:
        raise api.faults.BadRequest("Action %s not supported." % action)
    action_args = req[action]
    if not isinstance(action_args, dict):
        raise api.faults.BadRequest("Invalid argument.")

    return f(request, network, action_args)
Beispiel #52
0
def attach_volume(request, server_id):
    req = utils.get_json_body(request)
    log.debug("attach_volume server_id %s request", server_id, req)
    user_id = request.user_uniq
    vm = util.get_vm(server_id, user_id, for_update=True, non_deleted=True)

    attachment_dict = api.utils.get_attribute(req, "volumeAttachment",
                                              required=True)
    # Get volume
    volume_id = api.utils.get_attribute(attachment_dict, "volumeId")
    volume = get_volume(user_id, volume_id, for_update=True, non_deleted=True,
                        exception=faults.BadRequest)
    vm = server_attachments.attach_volume(vm, volume)
    attachment = volume_to_attachment(volume)
    data = json.dumps({'volumeAttachment': attachment})

    return HttpResponse(data, status=202)
Beispiel #53
0
def allocate_floating_ip(request):
    """Allocate a floating IP."""
    req = utils.get_json_body(request)
    credentials = request.credentials

    log.debug("User: %s, Action: create_floating_ip, Request: %s",
              credentials.userid, req)

    floating_ip_dict = api.utils.get_attribute(req,
                                               "floatingip",
                                               required=True,
                                               attr_type=dict)
    userid = credentials.userid
    project = floating_ip_dict.get("project", None)
    shared_to_project = floating_ip_dict.get("shared_to_project", False)

    # the network_pool is a mandatory field
    network_id = api.utils.get_attribute(floating_ip_dict,
                                         "floating_network_id",
                                         required=False,
                                         attr_type=(basestring, int))

    if network_id is None:
        floating_ip = \
            ips.create_floating_ip(credentials, project=project,
                                   shared_to_project=shared_to_project)
    else:
        try:
            network_id = int(network_id)
        except ValueError:
            raise faults.BadRequest("Invalid networkd ID.")

        address = api.utils.get_attribute(floating_ip_dict,
                                          "floating_ip_address",
                                          required=False,
                                          attr_type=basestring)
        floating_ip = \
            ips.create_floating_ip(credentials, network_id, address,
                                   project=project,
                                   shared_to_project=shared_to_project)

    log.info("User %s created floating IP %s, network %s, address %s", userid,
             floating_ip.id, floating_ip.network_id, floating_ip.address)

    return HttpResponse(_floatingip_details_view(floating_ip), status=200)
Beispiel #54
0
def attach_volume(request, server_id):
    req = utils.get_json_body(request)
    credentials = request.credentials
    user_id = credentials.userid

    log.debug("User %s, VM: %s, Action: attach_volume, Request: %s",
              user_id, server_id, req)

    attachment_dict = api.utils.get_attribute(req, "volumeAttachment",
                                              required=True)
    # Get volume
    volume_id = api.utils.get_attribute(attachment_dict, "volumeId")

    volume = servers.attach_volume(server_id, volume_id, credentials)
    attachment = volume_to_attachment(volume)
    data = json.dumps({'volumeAttachment': attachment})

    return HttpResponse(data, status=202)
Beispiel #55
0
def volume_action_demux(request, volume_id):
    req = utils.get_json_body(request)

    if not isinstance(req, dict) and len(req) != 1:
        raise faults.BadRequest("Malformed request")

    action = req.keys()[0]
    if not isinstance(action, basestring):
        raise faults.BadRequest("Malformed Request. Invalid action.")

    try:
        action_func = VOLUME_ACTIONS[action]
    except KeyError:
        raise faults.BadRequest("Action %s not supported" % action)
    action_args = utils.get_attribute(req, action, required=True,
                                      attr_type=dict)

    return action_func(request, volume_id, action_args)
Beispiel #56
0
def allocate_floating_ip(request):
    """Allocate a floating IP."""
    req = utils.get_json_body(request)
    credentials = request.credentials

    log.debug("User: %s, Action: create_floating_ip, Request: %s",
              credentials.userid, req)

    floating_ip_dict = api.utils.get_attribute(req, "floatingip",
                                               required=True, attr_type=dict)
    userid = credentials.userid
    project = floating_ip_dict.get("project", None)
    shared_to_project = floating_ip_dict.get("shared_to_project", False)

    # the network_pool is a mandatory field
    network_id = api.utils.get_attribute(floating_ip_dict,
                                         "floating_network_id",
                                         required=False,
                                         attr_type=(basestring, int))

    if network_id is None:
        floating_ip = \
            ips.create_floating_ip(credentials, project=project,
                                   shared_to_project=shared_to_project)
    else:
        try:
            network_id = int(network_id)
        except ValueError:
            raise faults.BadRequest("Invalid networkd ID.")

        address = api.utils.get_attribute(floating_ip_dict,
                                          "floating_ip_address",
                                          required=False,
                                          attr_type=basestring)
        floating_ip = \
            ips.create_floating_ip(credentials, network_id, address,
                                   project=project,
                                   shared_to_project=shared_to_project)

    log.info("User %s created floating IP %s, network %s, address %s",
             userid, floating_ip.id, floating_ip.network_id,
             floating_ip.address)

    return HttpResponse(_floatingip_details_view(floating_ip), status=200)
Beispiel #57
0
def floating_ip_action_demux(request, floating_ip_id):
    userid = request.user_uniq
    req = utils.get_json_body(request)
    log.debug('floating_ip_action %s %s', floating_ip_id, req)
    if len(req) != 1:
        raise faults.BadRequest('Malformed request.')
    floating_ip = util.get_floating_ip_by_id(userid,
                                             floating_ip_id,
                                             for_update=True)
    action = req.keys()[0]
    try:
        f = FLOATING_IP_ACTIONS[action]
    except KeyError:
        raise faults.BadRequest("Action %s not supported." % action)
    action_args = req[action]
    if not isinstance(action_args, dict):
        raise faults.BadRequest("Invalid argument.")

    return f(request, floating_ip, action_args)
Beispiel #58
0
def attach_volume(request, server_id):
    req = utils.get_json_body(request)
    credentials = request.credentials
    user_id = credentials.userid

    log.debug("User %s, VM: %s, Action: attach_volume, Request: %s", user_id,
              server_id, req)

    attachment_dict = api.utils.get_attribute(req,
                                              "volumeAttachment",
                                              required=True)
    # Get volume
    volume_id = api.utils.get_attribute(attachment_dict, "volumeId")

    volume = servers.attach_volume(server_id, volume_id, credentials)
    attachment = volume_to_attachment(volume)
    data = json.dumps({'volumeAttachment': attachment})

    return HttpResponse(data, status=202)
Beispiel #59
0
def volume_action_demux(request, volume_id):
    req = utils.get_json_body(request)

    if not isinstance(req, dict) and len(req) != 1:
        raise faults.BadRequest("Malformed request")

    action = req.keys()[0]
    if not isinstance(action, basestring):
        raise faults.BadRequest("Malformed Request. Invalid action.")

    try:
        action_func = VOLUME_ACTIONS[action]
    except KeyError:
        raise faults.BadRequest("Action %s not supported" % action)
    action_args = utils.get_attribute(req,
                                      action,
                                      required=True,
                                      attr_type=dict)

    return action_func(request, volume_id, action_args)