예제 #1
0
    def test_get_account_info_cache(self):
        # The original test that we prefer to preserve
        cached = {'status': 404,
                  'bytes': 3333,
                  'total_object_count': 10}
        req = Request.blank("/v1/account/cont",
                            environ={'swift.cache': FakeCache(cached)})
        with patch('osd.proxyService.controllers.base.'
                   '_prepare_pre_auth_info_request', FakeRequest):
            resp = get_account_info(req.environ, 'xxx')
        self.assertEquals(resp['bytes'], 3333)
        self.assertEquals(resp['total_object_count'], 10)
        self.assertEquals(resp['status'], 404)

        # Here is a more realistic test
        cached = {'status': 404,
                  'bytes': '3333',
                  'container_count': '234',
                  'total_object_count': '10',
                  'meta': {}}
        req = Request.blank("/v1/account/cont",
                            environ={'swift.cache': FakeCache(cached)})
        with patch('osd.proxyService.controllers.base.'
                   '_prepare_pre_auth_info_request', FakeRequest):
            resp = get_account_info(req.environ, 'xxx')
        self.assertEquals(resp['status'], 404)
        self.assertEquals(resp['bytes'], '3333')
        self.assertEquals(resp['container_count'], 234)
        self.assertEquals(resp['meta'], {})
        self.assertEquals(resp['total_object_count'], '10')
예제 #2
0
    def _get_keys(self, env):
        """
        Fetch the tempurl keys for the account. Also validate that the request
        path indicates a valid container; if not, no keys will be returned.

        :param env: The WSGI environment for the request.
        :returns: list of tempurl keys
        """
        parts = env['PATH_INFO'].split('/', 4)
        if len(parts) < 4 or parts[0] or parts[1] != 'v1' or not parts[2] or \
                not parts[3]:
            return []

        #account_info = get_account_info(env, self.app, swift_source='FP')
        #return get_tempurl_keys_from_metadata(account_info['meta'])
        #TODO JAIVISH : Since account post is not supported container keys are searched
        #TODO : this needs to be changes once account post is supported
        account_info = get_account_info(env, self.app, swift_source='FP')
        account_keys = get_tempurl_keys_from_metadata(account_info['meta'])
        container_info = get_container_info(env, self.app, swift_source='FP')
        container_keys = get_tempurl_keys_from_metadata(
            container_info.get('meta', []))
        #TODO : to print in logs : print "========Keys========== %s, %s" %(account_keys, container_keys)

        return account_keys + container_keys
예제 #3
0
    def account_acls(self, req):
        """
        Return a dict of ACL data from the account server via get_account_info.

        Auth systems may define their own format, serialization, structure,
        and capabilities implemented in the ACL headers and persisted in the
        sysmeta data.  However, auth systems are strongly encouraged to be
        interoperable with Tempauth.

        Account ACLs are set and retrieved via the header
           X-Account-Access-Control

        For header format and syntax, see:
         * :func:`osd.common.middleware.acl.parse_acl()`
         * :func:`osd.common.middleware.acl.format_acl()`
        """
        info = get_account_info(req.environ, self.app, swift_source='TA')
        try:
            acls = acls_from_account_info(info)
        except ValueError as e1:
            self.logger.warn("Invalid ACL stored in metadata: %r" % e1)
            return None
        except NotImplementedError as e2:
            self.logger.warn("ACL version exceeds middleware version: %r" % e2)
            return None
        return acls
예제 #4
0
 def test_get_account_info_env(self):
     cache_key = get_account_memcache_key("account")
     env_key = 'swift.%s' % cache_key
     req = Request.blank("/v1/account",
                         environ={env_key: {'bytes': 3867},
                                  'swift.cache': FakeCache({})})
     resp = get_account_info(req.environ, 'xxx')
     self.assertEquals(resp['bytes'], 3867)
예제 #5
0
 def test_get_account_info_no_cache(self):
     req = Request.blank("/v1/AUTH_account",
                         environ={'swift.cache': FakeCache({})})
     with patch('osd.proxyService.controllers.base.'
                '_prepare_pre_auth_info_request', FakeRequest):
         resp = get_account_info(req.environ, 'xxx')
     self.assertEquals(resp['bytes'], 6666)
     self.assertEquals(resp['total_object_count'], 1000)
예제 #6
0
    def handle_bw_control(self, req, account, container, obj):
        if not self._need_to_apply_bw_control(req, account, container, obj):
            self.logger.debug('Need not to apply BWC for this request '\
                             'Method:%s, account:%s, container:%s, object:%s '\
                              %(req.method, account, container, obj))
            return False

        account_info = get_account_info(req.environ, self.app)
        if not account_info:
            return False
        try:
            max_read_bw = int(account_info['meta'].\
                              get('max-read-bandwidth', '-1').split(',')[-1])
            max_write_bw = int(account_info['meta'].\
                              get('max-write-bandwidth', '-1').split(',')[-1])
        except ValueError:
            return False

        if max_read_bw == -1:
            max_read_bw = self.def_max_bandwidth_read_limit
        if max_write_bw == -1:
            max_write_bw = self.def_max_bandwidth_write_limit

        if max_read_bw == 0 and req.method == 'GET':
            self.logger.debug('Need not to apply BWC for this request '\
                       'Method:%s, account:%s, container:%s, object:%s '\
                       'max_read_bw:%d, default_max_bandwidth_read_limit:%d '\
                       %(req.method, account, container, obj, max_read_bw, \
                       self.def_max_bandwidth_read_limit))
            return False

        if max_write_bw == 0 and req.method == 'PUT':
            self.logger.debug('Need not to apply BWC for this request '\
                       'Method:%s, account:%s, container:%s, object:%s '\
                       'max_write_bw:%d, default_max_bandwidth_write_limit:%d '\
                       %(req.method, account, container, obj, max_write_bw, \
                       self.def_max_bandwidth_read_limit))
            return False

        ##assuming the unit of bandwidth limit is KB/sec and unit_time_period is in seconds
        key = account
        read_limit = max_read_bw * self.unit_time_period * 1024
        write_limit = max_write_bw * self.unit_time_period * 1024
        self.logger.debug('Start applying BWC for this request '\
                       'account_info:%s, max_read_bw:%d, max_write_bw:%d '\
                       %(account_info, max_read_bw, max_write_bw))

        ##if account information is not in cache then insert it
        ## otherwise update it, for the case when bw has been changed in memcache
        if self.cache.get(key) is None:
            self.cache.add_new_key(key, read_limit, write_limit)
        else:
            self.cache.update_read_write_limit(key, read_limit, write_limit)
        self.cache.inc_req_count(key)
        input_proxy =  BWControlInputProxy(req.environ.get('wsgi.input'), \
                                           self.cache, key, self.logger)
        req.environ['wsgi.input'] = input_proxy
        return True
예제 #7
0
    def get_ratelimitable_key_tuples(self,
                                     req,
                                     account_name,
                                     container_name=None,
                                     obj_name=None):
        """
        Returns a list of key (used in memcache), ratelimit tuples. Keys
        should be checked in order.

        :param req: swob request
        :param account_name: account name from path
        :param container_name: container name from path
        :param obj_name: object name from path
        """
        keys = []
        # COPYs are not limited
        if self.account_ratelimit and \
                account_name and container_name and not obj_name and \
                req.method in ('PUT', 'DELETE'):
            keys.append(
                ("ratelimit/%s" % account_name, self.account_ratelimit))

        if account_name and container_name and obj_name and \
                req.method in ('PUT', 'DELETE', 'POST', 'COPY'):
            container_size = self.get_container_size(account_name,
                                                     container_name)
            container_rate = get_maxrate(self.container_ratelimits,
                                         container_size)
            if container_rate:
                keys.append(
                    ("ratelimit/%s/%s" % (account_name, container_name),
                     container_rate))

        if account_name and container_name and not obj_name and \
                req.method == 'GET':
            container_size = self.get_container_size(account_name,
                                                     container_name)
            container_rate = get_maxrate(self.container_listing_ratelimits,
                                         container_size)
            if container_rate:
                keys.append(("ratelimit_listing/%s/%s" %
                             (account_name, container_name), container_rate))

        if account_name and req.method in ('PUT', 'DELETE', 'POST', 'COPY'):
            account_info = get_account_info(req.environ, self.app)
            account_global_ratelimit = \
                account_info.get('sysmeta', {}).get('global-write-ratelimit')
            if account_global_ratelimit:
                try:
                    account_global_ratelimit = float(account_global_ratelimit)
                    if account_global_ratelimit > 0:
                        keys.append(
                            ("ratelimit/global-write/%s" % account_name,
                             account_global_ratelimit))
                except ValueError:
                    pass

        return keys
예제 #8
0
 def test_get_account_info_swift_source(self):
     req = Request.blank("/v1/a", environ={'swift.cache': FakeCache({})})
     with patch('osd.proxyService.controllers.base.'
                '_prepare_pre_auth_info_request', FakeRequest):
         resp = get_account_info(req.environ, 'a', swift_source='MC')
     self.assertEquals(resp['meta']['fakerequest-swift-source'], 'MC')