Esempio n. 1
0
def list_gateways_by_user(email, **q_opts):
    caller_user = _check_authenticated(q_opts)

    # user must exist
    user = read_user(email)
    if user == None:
        raise Exception("No such user '%s'" % email)

    # only admin can list other users' gateways
    if caller_user.owner_id != user.owner_id and not caller_user.is_admin:
        raise Exception("User '%s' is not sufficiently privileged" %
                        caller_user.email)

    return Gateway.ListAll({"Gateway.owner_id ==": user.owner_id}, **q_opts)
Esempio n. 2
0
def _remove_user_from_volume_helper(owner_id, volume_id):
    # helper function for remove_user_from_volume, to be run deferred.

    def _remove_gateway(gw):
        Gateway.Delete(gw.g_id)
        return None

    Gateway.ListAll(
        {
            "Gateway.owner_id ==": owner_id,
            "Gateway.volume_id ==": volume_id
        },
        map_func=_remove_gateway,
        projection=['g_id'])
Esempio n. 3
0
def list_gateways_by_volume(volume_name_or_id, **q_opts):
    caller_user = _check_authenticated(q_opts)

    # volume must exist
    volume = read_volume(volume_name_or_id)
    if volume == None or volume.deleted:
        raise Exception("No such Volume '%s'" % volume_name_or_id)

    # only admin can list gateways of volumes she doesn't own
    if volume.owner_id != caller_user.owner_id and not caller_user.is_admin:
        raise Exception("User '%s' is not sufficiently privileged" %
                        caller_user.email)

    return Gateway.ListAll({"Gateway.volume_id ==": volume.volume_id},
                           **q_opts)
Esempio n. 4
0
def list_gateways_by_user_and_volume(email, volume_name_or_id, **q_opts):
    caller_user = _check_authenticated(q_opts)

    user, volume = _read_user_and_volume(email, volume_name_or_id)

    # user and volume must exist
    if user is None:
        raise Exception("No such user '%s'" % email)

    if volume is None or volume.deleted:
        raise Exception("No such Volume '%s'" % email)

    # only admin can list other users' gateways
    if caller_user.owner_id != user.owner_id and not caller_user.is_admin:
        raise Exception("User '%s' is not sufficiently privileged" %
                        caller_user.email)

    return Gateway.ListAll(
        {
            "Gateway.owner_id ==": user.owner_id,
            "Gateway.volume_id ==": volume.volume_id
        }, **q_opts)
Esempio n. 5
0
def update_gateway(g_name_or_id, **fields):
    # NOTE: the UpdateAPIGuard ensures that the caller user exists,
    # and that the user is either admin or the owner of this gateway.
    # We only need to read the volume and gateway to call Volume.Reversion

    # gateway must exist...(defensive check)
    gateway = read_gateway(g_name_or_id)

    if gateway == None:
        raise Exception("No such Gateway '%s'" % g_name_or_id)

    volume = read_volume(gateway.volume_id)

    # volume must exist...(defensive check)
    if volume == None or volume.deleted:
        raise Exception("No volume with ID '%s'" % gateway.volume_id)

    rc = Gateway.Update(g_name_or_id, **fields)

    if rc:
        storagetypes.deferred.defer(Volume.Reversion, volume.volume_id)

    return rc
Esempio n. 6
0
def set_gateway_caps(g_name_or_id, caps):
    # NOTE: the UpdateAPIGuard ensures that the user exists, and that the user
    # is either an admin or the owner of this Gateway.
    # we only read the user and volume again since we have to call Volume.Reversion

    # gateway must exist...(defensive check)
    gateway = read_gateway(g_name_or_id)

    if gateway == None:
        raise Exception("No such Gateway '%s'" % g_name_or_id)

    volume = read_volume(gateway.volume_id)

    # volume must exist...(defensive check)
    if volume == None or volume.deleted:
        raise Exception("No volume with ID '%s'" % gateway.volume_id)

    rc = Gateway.SetCaps(g_name_or_id, caps)

    if rc:
        # reversion volume cert
        storagetypes.deferred.defer(Volume.Reversion, volume.volume_id)

    return rc
Esempio n. 7
0
    def protobuf_gateway_cert_manifest(self,
                                       manifest,
                                       include_cert=None,
                                       sign=True):
        """
      Generate a specially-crafted manifest protobuf, which a gateway can use to learn 
      the IDs and types of all gateways in the Volume, as well as their certs' versions.
      """

        manifest.volume_id = self.volume_id
        manifest.coordinator_id = 0
        manifest.file_id = 0
        manifest.owner_id = 0
        manifest.file_version = self.cert_version
        manifest.mtime_sec = 0
        manifest.mtime_nsec = 0
        manifest.fent_mtime_sec = 0
        manifest.fent_mtime_nsec = 0

        sz = 0

        # query certificate versions, types, and caps of all gateways that need to be trusted
        listing = Gateway.ListAll(
            {
                "Gateway.volume_id ==": self.volume_id,
                "Gateway.need_cert ==": True
            },
            projection=["g_id", "gateway_type", "cert_version", "caps"])

        # if the caller wants to include a particular gateway's cert, do so
        has_included_cert = False

        for gateway_metadata in listing:
            cert_block = manifest.block_url_set.add()

            self.protobuf_gateway_cert_manifest_record(
                cert_block, gateway_metadata.g_id,
                gateway_metadata.gateway_type, gateway_metadata.caps,
                gateway_metadata.cert_version)

            logging.info(
                "cert block: (%s, %s, %s, %x)" %
                (gateway_metadata.gateway_type, gateway_metadata.g_id,
                 gateway_metadata.cert_version, gateway_metadata.caps))
            sz += 1

            if gateway_metadata.g_id == include_cert:
                has_included_cert = True

        if not has_included_cert and include_cert is not None:

            # get this gateway's cert as well
            gw = Gateway.Read(include_cert)

            if gw is not None:
                cert_block = manifest.block_url_set.add()

                self.protobuf_gateway_cert_manifest_record(
                    cert_block, gw.g_id, gw.gateway_type, gw.caps,
                    gw.cert_version)

                logging.info("cert block (included for %s): (%s, %s, %s, %x)" %
                             (include_cert, gw.gateway_type, gw.g_id,
                              gw.cert_version, gw.caps))
                sz += 1

        manifest.size = sz
        manifest.signature = ""

        if sign:
            data = manifest.SerializeToString()
            sig = self.sign_message(data)

            manifest.signature = sig

        return
Esempio n. 8
0
def delete_gateway(g_id):
    # TODO: when deleting an AG, delete all of its files and directories as well
    return Gateway.Delete(g_id)
Esempio n. 9
0
 def _remove_gateway(gw):
     Gateway.Delete(gw.g_id)
     return None
Esempio n. 10
0
def list_gateways_by_host(hostname, **q_opts):
    return Gateway.ListAll({"Gateway.host ==": hostname}, **q_opts)
Esempio n. 11
0
def list_gateways(attrs=None, **q_opts):
    return Gateway.ListAll(attrs, **q_opts)
Esempio n. 12
0
def read_gateway(g_name_or_id):
    return Gateway.Read(g_name_or_id)
Esempio n. 13
0
def create_gateway(volume_id, email, gateway_type, gateway_name, host, port,
                   **kwargs):
    if "encryption_password" in kwargs.keys():
        del kwargs['encryption_password']

    # verify gateway type...
    if gateway_type not in [GATEWAY_TYPE_UG, GATEWAY_TYPE_RG, GATEWAY_TYPE_AG]:
        raise Exception("Unrecognized Gateway type %s" % gateway_type)

    gateway_type_str = GATEWAY_TYPE_TO_STR[gateway_type]

    caller_user = _check_authenticated(kwargs)

    # user and volume must both exist
    user, volume = _read_user_and_volume(email, volume_id)

    if user == None:
        raise Exception("No such user '%s'" % email)

    if (volume == None or volume.deleted):
        raise Exception("No such volume '%s'" % volume_id)

    # if the caller user doesn't own this Volume (or isn't an admin), (s)he must have a valid access request
    if not caller_user.is_admin and caller_user.owner_id != volume.owner_id:

        # caller user must be the same as the user
        if caller_user.owner_id != user.owner_id:
            raise Exception("Caller can only create gateways for itself.")

        # if the volume is not public, then there needs to be a volume access request that is granted to this user.
        if not volume.private:

            # check access status
            access_request = VolumeAccessRequest.GetAccess(
                user.owner_id, volume.volume_id)

            if access_request == None:
                # user has not been given permission to access this volume
                raise Exception(
                    "User '%s' is not allowed to access Volume '%s'" %
                    (caller_user.email, volume.name))

            if access_request.status != VolumeAccessRequest.STATUS_GRANTED:
                # user has not been given permission to create a gateway here
                raise Exception(
                    "User '%s' is not allowed to create a Gateway in Volume '%s'"
                    % (caller_user.email, volume.name))

            else:
                # verify caps
                requested_caps = kwargs.get("caps", None)
                if requested_caps is not None and requested_caps != access_request.gateway_caps:
                    raise Exception(
                        "User '%s' is not allowed to set Gateway capabilities '%s'"
                        % requested_caps)

                # verify the caller is allowed to create this kind of gateway
                if not access_request.is_gateway_type_allowed(gateway_type):
                    raise Exception(
                        "User '%s' is not allowed to create %s Gateways" %
                        (gateway_type_str))

        # user is allowed to create this gateway in this Volume...

    # verify quota
    gateway_quota = user.get_gateway_quota(gateway_type)

    if gateway_quota == 0:
        gateway_type_str = GATEWAY_TYPE_TO_STR[gateway_type]
        raise Exception("User '%s' cannot own %s Gateways" %
                        (email, gateway_type_str))

    if gateway_quota > 0:
        gateway_ids = list_gateways_by_user(user.email,
                                            caller_user=user,
                                            keys_only=True)
        if len(gateway_ids) > gateway_quota:
            gateway_type_str = GATEWAY_TYPE_TO_STR[gateway_type]
            raise Exception(
                "User '%s' has exceeded quota (%s) for %s Gateways" %
                (email, gateway_quota, gateway_type_str))

    gateway_key = Gateway.Create(user,
                                 volume,
                                 gateway_type=gateway_type,
                                 name=gateway_name,
                                 host=host,
                                 port=port,
                                 **kwargs)
    gw = gateway_key.get()

    # reversion volume cert?
    if gw is not None:
        storagetypes.deferred.defer(Volume.Reversion, volume_id)

    return gw
Esempio n. 14
0
def delete_gateway(g_id, **kw):
    # TODO: garbage-collect gateways...
    ret = Gateway.Delete(g_id)
    return {'result': ret}
Esempio n. 15
0
def list_gateways_by_host(hostname, **q_opts):
    return Gateway.ListAll(
        {
            "Gateway.host ==": hostname,
            "Gateway.deleted ==": False
        }, **q_opts)
Esempio n. 16
0
    if volume.private:

        # only volume owner or admin can create gateways in private volumes
        if not caller_user.is_admin and caller_user.owner_id != volume.owner_id:
            raise Exception(
                "User '%s' is not allowed to create gateways for '%s'" %
                (caller_user.email, volume.name))

    # if this is an archive volume, then there can be no other writers (DEPRECATED)
    if volume.archive and (
            gateway_cert.caps &
        (GATEWAY_CAP_WRITE_DATA | GATEWAY_CAP_WRITE_METADATA)):
        writer_gateways_qry = Gateway.ListAll(
            {
                "Gateway.need_cert ==": True,
                'Gateway.volume_id ==': volume_id
            },
            keys_only=True,
            query_only=True)
        if writer_gateways_qry.count() > 0:
            # there's already a writer
            raise Exception("Archive volume '%s' already has a writer" %
                            (volume.name))

    # sanity check: name can't be numeric
    tmp = None
    try:
        tmp = int(gateway_name)
    except:
        pass