Beispiel #1
0
    def set_activity_shares(self):
        """
        Set a new/modify an activity share
        """
        input_dict = get_input_as_dict(request)
        if not input_dict.get('vo', None):
            raise HTTPBadRequest('Missing VO')
        if not input_dict.get('share', None):
            raise HTTPBadRequest('Missing share')
        if 'active' not in input_dict:
            input_dict['active'] = True

        input_dict['share'] = _normalize_activity_share_format(
            input_dict['share'])

        # Make sure the share weights are numbers
        for entry in input_dict['share']:
            for key, value in entry.iteritems():
                if not type(value) in (float, int):
                    raise HTTPBadRequest('Share weight must be a number')

        try:
            activity_share = ActivityShare(vo=input_dict['vo'],
                                           active=input_dict['active'],
                                           activity_share=input_dict['share'])

            Session.merge(activity_share)
            audit_configuration('activity-share', json.dumps(input_dict))
            Session.commit()
        except ValueError, e:
            raise HTTPBadRequest(str(e))
Beispiel #2
0
    def remove_authz(self, start_response):
        """
        Revoke access for a DN for a given operation, or all
        """
        input_dict = get_input_as_dict(request, from_query=True)
        dn = input_dict.get('dn')
        op = input_dict.get('operation')
        if not dn:
            raise HTTPBadRequest('Missing DN parameter')

        to_be_removed = Session.query(AuthorizationByDn).filter(
            AuthorizationByDn.dn == dn)
        if op:
            to_be_removed = to_be_removed.filter(
                AuthorizationByDn.operation == op)

        try:
            to_be_removed.delete()
            if op:
                audit_configuration('revoke', '%s revoked for "%s"' % (op, dn))
            else:
                audit_configuration('revoke', 'All revoked for "%s"' % dn)
            Session.commit()
        except:
            Session.rollback()
            raise

        start_response('204 No Content', [])
        return ['']
Beispiel #3
0
    def set_drain(self):
        """
        Set the drain status of a server
        """
        input_dict = get_input_as_dict(request)

        hostname = input_dict.get('hostname', None)
        drain = input_dict.get('drain', True)
        if not isinstance(drain, bool) or not isinstance(hostname, basestring):
            raise HTTPBadRequest('Invalid drain request')

        entries = Session.query(Host).filter(Host.hostname == hostname).all()
        if not entries:
            raise HTTPBadRequest('Host not found')

        try:
            audit_configuration(
                'drain',
                'Turning drain %s the drain mode for %s' % (drain, hostname))
            for entry in entries:
                entry.drain = drain
                Session.merge(entry)
            Session.commit()
        except:
            Session.rollback()
            raise
Beispiel #4
0
    def delete_share(self, start_response):
        """
        Delete a share
        """
        input_dict = get_input_as_dict(request, from_query=True)
        source = input_dict.get('source')
        destination = input_dict.get('destination')
        vo = input_dict.get('vo')

        if not source or not destination or not vo:
            raise HTTPBadRequest('Missing source, destination and/or vo')

        try:
            share = Session.query(ShareConfig).get((source, destination, vo))
            if share:
                Session.delete(share)
                audit_configuration(
                    'share-delete', 'Share %s, %s, %s has been deleted' %
                    (source, destination, vo))
                Session.commit()
        except:
            Session.rollback()
            raise

        start_response('204 No Content', [])
        return ['']
Beispiel #5
0
    def ban_dn(self):
        """
        Ban a user
        """
        if request.content_type == 'application/json':
            try:
                input_dict = json.loads(request.body)
            except Exception:
                raise HTTPBadRequest('Malformed input')
        else:
            input_dict = request.params

        user = request.environ['fts3.User.Credentials']
        dn = input_dict.get('user_dn', None)

        if not dn:
            raise HTTPBadRequest('Missing dn parameter')
        if dn == user.user_dn:
            raise HTTPConflict('The user tried to ban (her|his)self')

        _ban_dn(dn, input_dict.get('message', ''))
        affected = _cancel_jobs(dn=dn)

        audit_configuration('ban-dn', "User %s banned" % (dn))
        log.warn("User %s banned, %d jobs affected" % (dn, len(affected)))

        return affected
Beispiel #6
0
    def set_se_config(self):
        """
        Set the configuration parameters for a given SE
        """
        input_dict = get_input_as_dict(request)
        try:
            for storage, cfg in input_dict.iteritems():
                if not storage or storage.isspace():
                    raise ValueError
                se_info = None
                se_info_new = cfg.get('se_info', None)
                if se_info_new:
                    se_info = Session.query(Se).get(storage)
                    if not se_info:
                        se_info = Se(storage=storage)
                    for key, value in se_info_new.iteritems():
                        #value = validate_type(Se, key, value)
                        setattr(se_info, key, value)

                    audit_configuration(
                        'set-se-config',
                        'Set config %s: %s' % (storage, json.dumps(cfg)))
                    Session.merge(se_info)

                    # Operation limits
                    operations = cfg.get('operations', None)
                    if operations:
                        for vo, limits in operations.iteritems():
                            for op, limit in limits.iteritems():
                                limit = int(limit)
                                new_limit = Session.query(OperationConfig).get(
                                    (vo, storage, op))
                                if limit > 0:
                                    if not new_limit:
                                        new_limit = OperationConfig(
                                            vo_name=vo,
                                            host=storage,
                                            operation=op)
                                    new_limit.concurrent_ops = limit
                                    Session.merge(new_limit)
                                elif new_limit:
                                    Session.delete(new_limit)
                        audit_configuration(
                            'set-se-limits', 'Set limits for %s: %s' %
                            (storage, json.dumps(operations)))
            Session.commit()
        except (AttributeError, ValueError):
            Session.rollback()
            raise HTTPBadRequest('Malformed configuration')
        except:
            Session.rollback()
            raise
        return (se_info, operations)
Beispiel #7
0
 def delete_link_config(self,sym_name, start_response):
     """
     Deletes an existing link configuration
     """
     try:
         sym_name = urllib.unquote(sym_name)
         Session.query(LinkConfig).filter(LinkConfig.symbolicname == sym_name).delete()
         audit_configuration('link-delete', 'Link %s has been deleted' % sym_name)
         Session.commit()
     except:
         Session.rollback()
         raise
     start_response('204 No Content', [])
     return ['']
Beispiel #8
0
 def delete_activity_shares(self, vo_name, start_response):
     """
     Delete an existing activity share
     """
     activity_share = Session.query(ActivityShare).get(vo_name)
     if activity_share is None:
         raise HTTPNotFound('No activity shares for %s' % vo_name)
     try:
         Session.delete(activity_share)
         audit_configuration('activity-share',
                             'Activity share removed for "%s"' % (vo_name))
         Session.commit()
     except:
         Session.rollback()
         raise
     start_response('204 No Content', [])
     return ['']
Beispiel #9
0
    def set_share(self, start_response):
        """
        Add or modify a share
        """
        input_dict = get_input_as_dict(request)
        source = input_dict.get('source')
        destination = input_dict.get('destination')
        vo = input_dict.get('vo')
        try:
            share = int(input_dict.get('share'))
            if share < 0:
                raise HTTPBadRequest('Shares values cannot be negative')
        except:
            raise HTTPBadRequest('Bad share value')

        if not source or not destination or not vo or not share:
            raise HTTPBadRequest(
                'Missing source, destination, vo and/or share')

        source = urlparse(source)
        if not source.scheme or not source.hostname:
            raise HTTPBadRequest('Invalid source')
        source = "%s://%s" % (source.scheme, source.hostname)

        destination = urlparse(destination)
        if not destination.scheme or not destination.hostname:
            raise HTTPBadRequest('Invalid source')
        destination = "%s://%s" % (destination.scheme, destination.hostname)

        try:
            share_cfg = ShareConfig(source=source,
                                    destination=destination,
                                    vo=vo,
                                    share=share)
            Session.merge(share_cfg)
            audit_configuration(
                'share-set', 'Share %s, %s, %s has been set to %d' %
                (source, destination, vo, share))
            Session.commit()
        except:
            Session.rollback()
            raise

        return share
Beispiel #10
0
    def ban_se(self):
        """
        Ban a storage element. Returns affected jobs ids.
        """
        if request.content_type == 'application/json':
            try:
                input_dict = json.loads(request.body)
            except Exception:
                raise HTTPBadRequest('Malformed input')
        else:
            input_dict = request.params

        storage = input_dict.get('storage', None)
        if not storage:
            raise HTTPBadRequest('Missing storage parameter')

        user = request.environ['fts3.User.Credentials']
        vo_name = user.vos[0]
        allow_submit = bool(input_dict.get('allow_submit', False))
        status = input_dict.get('status', 'cancel').upper()

        if status not in ['CANCEL', 'WAIT']:
            raise HTTPBadRequest('status can only be cancel or wait')

        if allow_submit and status == 'CANCEL':
            raise HTTPBadRequest(
                'allow_submit and status = CANCEL can not be combined')

        _ban_se(storage, vo_name, allow_submit, status,
                input_dict.get('message', ''))
        audit_configuration(
            'ban-se',
            "Storage %s for %s banned (%s)" % (storage, vo_name, status))

        if status == 'CANCEL':
            affected = _cancel_transfers(storage=storage, vo_name=vo_name)
        else:
            affected = _set_to_wait(storage=storage, vo_name=vo_name)

        log.warn("Storage %s banned (%s), %d jobs affected" %
                 (storage, status, len(affected)))
        return affected
Beispiel #11
0
 def unban_se(self, start_response):
     """
     Unban a storage element
     """
     storage = request.params.get('storage', None)
     if not storage:
         raise HTTPBadRequest('Missing storage parameter')
     job_ids = []
     try:
         user = request.environ['fts3.User.Credentials']
         vo_name = user.vos[0]
         Session.query(BannedSE).filter(BannedSE.se == storage,
                                        BannedSE.vo == vo_name).delete()
         job_ids = _reenter_queue(storage, vo_name)
         Session.commit()
     except Exception:
         Session.rollback()
         raise HTTPBadRequest('Storage not found')
     log.warn("Storage %s unbanned" % storage)
     audit_configuration('unban-se', "Storage %s unbanned" % storage)
     start_response('204 No Content', [])
     return job_ids
Beispiel #12
0
    def add_authz(self):
        """
        Give special access to someone
        """
        input_dict = get_input_as_dict(request)
        dn = input_dict.get('dn')
        op = input_dict.get('operation')
        if not dn or not op:
            raise HTTPBadRequest('Missing dn and/or operation')

        try:
            authz = Session.query(AuthorizationByDn).get((dn, op))
            if not authz:
                authz = AuthorizationByDn(dn=dn, operation=op)
                audit_configuration('authorize',
                                    '%s granted to "%s"' % (op, dn))
                Session.merge(authz)
                Session.commit()
        except:
            Session.rollback()
            raise

        return authz
Beispiel #13
0
    def unban_dn(self, start_response):
        """
        Unban a user
        """
        dn = request.params.get('user_dn', None)
        if not dn:
            raise HTTPBadRequest('Missing user_dn parameter')

        banned = Session.query(BannedDN).get(dn)
        if banned:
            try:

                Session.delete(banned)
                Session.commit()
            except Exception:
                Session.rollback()
            log.warn("User %s unbanned" % dn)
        else:
            log.warn("Unban of user %s without effect" % dn)

        audit_configuration('unban-dn', "User %s unbanned" % (dn))
        start_response('204 No Content', [])
        return ['']
Beispiel #14
0
    def set_global_config(self):
        """
        Set the global configuration
        """
        cfg = get_input_as_dict(request)

        vo_name = cfg.get('vo_name', '*')
        db_cfg = Session.query(ServerConfig).get(vo_name)
        if not db_cfg:
            db_cfg = ServerConfig(vo_name=vo_name)

        for key, value in cfg.iteritems():
            value = validate_type(ServerConfig, key, value)
            setattr(db_cfg, key, value)

        Session.merge(db_cfg)
        audit_configuration('set-globals', to_json(db_cfg, indent=None))
        try:
            Session.commit()
        except:
            Session.rollback()
            raise

        return self.get_global_config()
Beispiel #15
0
class LinkConfigController(BaseController):
    """
    Link configuration
    """

    @doc.response(400, 'Invalid values passed in the request')
    @doc.response(403, 'The user is not allowed to query the configuration')
    @authorize(CONFIG)
    @jsonify
    def set_link_config(self):
        """
        Set the configuration for a given link
        """
        input_dict = get_input_as_dict(request)

        source = input_dict.get('source', '*')
        destination = input_dict.get('destination', '*')
        symbolicname = input_dict.get('symbolicname', None)
        
        if not symbolicname:
            raise HTTPBadRequest('Missing symbolicname')
          
        link_cfg = Session.query(LinkConfig).filter(LinkConfig.symbolicname == symbolicname).first()
        
        try:
            min_active = int(input_dict.get('min_active', 2))
            max_active = int(input_dict.get('max_active', 2))
        except Exception, e:
            raise HTTPBadRequest('Active must be an integer (%s)' % str(e))

        if not source or not destination:
            raise HTTPBadRequest('Missing source and/or destination')

        if min_active is None:
            raise HTTPBadRequest('Missing min_active')
        if max_active is None:
            raise HTTPBadRequest('Missing max_active')
        if min_active > max_active:
            raise HTTPBadRequest('max_active is lower than min_active')
    
        
        if not link_cfg:
            link_cfg = LinkConfig(
                source=source,
                destination=destination,
                symbolicname=symbolicname,
                min_active = min_active,
                max_active = max_active
            )
            

        for key, value in input_dict.iteritems():
          
            #value = validate_type(LinkConfig, key, value)
            setattr(link_cfg, key, value)

        audit_configuration('link', json.dumps(input_dict))

        Session.merge(link_cfg)
        try:
            Session.commit()
        except:
            Session.rollback()
            raise

        return link_cfg