Esempio n. 1
0
    def _update(self, name, **kwargs):
        names = ('uri', 'weight', 'flavor', 'options')
        fields = common_utils.fields(kwargs,
                                     names,
                                     pred=lambda x: x is not None,
                                     key_transform=lambda x: x[0])
        assert fields, ('`weight`, `uri`, `flavor`, '
                        'or `options` not found in kwargs')

        if 'o' in fields:
            new_options = fields.get('o', None)
            fields['o'] = self._packer(new_options)

        pool_key = utils.pools_name_hash_key(name)
        # (gengchc2): Pipeline ensures atomic inserts.
        with self._client.pipeline() as pipe:
            # (gengchc2): If flavor is changed, we need to change.pool key
            #  in pools subset.
            if 'f' in fields:
                flavor_old = self._get(name).get('flavor')
                flavor_new = fields['f']
                if flavor_old != flavor_new:
                    if flavor_new is not None:
                        new_subset_key = utils.pools_subset_key(flavor_new)
                        pipe.zadd(new_subset_key, 1, pool_key)
                    # (gengchc2) remove pool from flavor_old.pools subset
                    if flavor_old is not None:
                        old_subset_key = utils.pools_subset_key(flavor_old)
                        pipe.zrem(old_subset_key, pool_key)
            pipe.hmset(pool_key, fields)
            pipe.execute()
Esempio n. 2
0
    def _update(self, name, **kwargs):
        names = ('uri', 'weight', 'flavor', 'options')
        fields = common_utils.fields(kwargs, names,
                                     pred=lambda x: x is not None,
                                     key_transform=lambda x: x[0])
        assert fields, ('`weight`, `uri`, `flavor`, '
                        'or `options` not found in kwargs')

        if 'o' in fields:
            new_options = fields.get('o', None)
            fields['o'] = self._packer(new_options)

        pool_key = utils.pools_name_hash_key(name)
        # (gengchc2): Pipeline ensures atomic inserts.
        with self._client.pipeline() as pipe:
            # (gengchc2): If flavor is changed, we need to change.pool key
            #  in pools subset.
            if 'f' in fields:
                flavor_old = self._get(name).get('flavor')
                flavor_new = fields['f']
                if flavor_old != flavor_new:
                    if flavor_new is not None:
                        new_subset_key = utils.pools_subset_key(flavor_new)
                        pipe.zadd(new_subset_key, {pool_key: 1})
                    # (gengchc2) remove pool from flavor_old.pools subset
                    if flavor_old is not None:
                        old_subset_key = utils.pools_subset_key(flavor_old)
                        pipe.zrem(old_subset_key, pool_key)
            pipe.hmset(pool_key, fields)
            pipe.execute()
Esempio n. 3
0
    def on_patch(self, request, response, project_id, flavor):
        """Allows one to update a flavors's pool and/or capabilities.

        This method expects the user to submit a JSON object
        containing at least one of: 'pool', 'capabilities'. If
        none are found, the request is flagged as bad. There is also
        strict format checking through the use of
        jsonschema. Appropriate errors are returned in each case for
        badly formatted input.

        :returns: HTTP | [200, 400]
        """

        LOG.debug(u'PATCH flavor - name: %s', flavor)
        data = wsgi_utils.load(request)

        EXPECT = ('pool', 'capabilities')
        if not any([(field in data) for field in EXPECT]):
            LOG.debug(u'PATCH flavor, bad params')
            raise wsgi_errors.HTTPBadRequestBody(
                'One of `pool` or `capabilities` needs '
                'to be specified')

        for field in EXPECT:
            wsgi_utils.validate(self._validators[field], data)

        fields = common_utils.fields(data,
                                     EXPECT,
                                     pred=lambda v: v is not None)

        try:
            self._ctrl.update(flavor, project=project_id, **fields)
        except errors.FlavorDoesNotExist as ex:
            LOG.exception(ex)
            raise falcon.HTTPNotFound()
Esempio n. 4
0
    def update(self, queue, subscription_id, project=None, **kwargs):
        names = ('subscriber', 'ttl', 'options')
        key_transform = lambda x: 'u' if x == 'subscriber' else x[0]
        fields = common_utils.fields(kwargs,
                                     names,
                                     pred=lambda x: x is not None,
                                     key_transform=key_transform)
        assert fields, ('`subscriber`, `ttl`, '
                        'or `options` not found in kwargs')

        new_ttl = fields.get('t', None)
        if new_ttl is not None:
            now = timeutils.utcnow_ts()
            now_dt = datetime.datetime.utcfromtimestamp(now)
            expires = now_dt + datetime.timedelta(seconds=new_ttl)
            fields['e'] = expires

        try:
            res = self._collection.update(
                {
                    '_id': utils.to_oid(subscription_id),
                    'p': project
                }, {'$set': fields},
                upsert=False)
        except pymongo.errors.DuplicateKeyError:
            raise errors.SubscriptionAlreadyExists()
        if not res['updatedExisting']:
            raise errors.SubscriptionDoesNotExist(subscription_id)
Esempio n. 5
0
    def on_patch(self, request, response, project_id, flavor):
        """Allows one to update a flavors's pool and/or capabilities.

        This method expects the user to submit a JSON object
        containing at least one of: 'pool', 'capabilities'. If
        none are found, the request is flagged as bad. There is also
        strict format checking through the use of
        jsonschema. Appropriate errors are returned in each case for
        badly formatted input.

        :returns: HTTP | [200, 400]
        """

        LOG.debug(u'PATCH flavor - name: %s', flavor)
        data = wsgi_utils.load(request)

        EXPECT = ('pool', 'capabilities')
        if not any([(field in data) for field in EXPECT]):
            LOG.debug(u'PATCH flavor, bad params')
            raise wsgi_errors.HTTPBadRequestBody(
                'One of `pool` or `capabilities` needs '
                'to be specified'
            )

        for field in EXPECT:
            wsgi_utils.validate(self._validators[field], data)

        fields = common_utils.fields(data, EXPECT,
                                     pred=lambda v: v is not None)

        try:
            self._ctrl.update(flavor, project=project_id, **fields)
        except errors.FlavorDoesNotExist as ex:
            LOG.exception(ex)
            raise falcon.HTTPNotFound()
Esempio n. 6
0
    def update(self, queue, subscription_id, project=None, **kwargs):
        names = ('subscriber', 'ttl', 'options')
        key_transform = lambda x: 'u' if x == 'subscriber' else x[0]
        fields = common_utils.fields(kwargs, names,
                                     pred=lambda x: x is not None,
                                     key_transform=key_transform)
        assert fields, ('`subscriber`, `ttl`, '
                        'or `options` not found in kwargs')

        new_ttl = fields.get('t', None)
        if new_ttl is not None:
            now = timeutils.utcnow_ts()
            now_dt = datetime.datetime.utcfromtimestamp(now)
            expires = now_dt + datetime.timedelta(seconds=new_ttl)
            fields['e'] = expires

        try:
            res = self._collection.update(
                {'_id': utils.to_oid(subscription_id),
                 'p': project},
                {'$set': fields},
                upsert=False)
        except pymongo.errors.DuplicateKeyError:
            raise errors.SubscriptionAlreadyExists()
        if not res['updatedExisting']:
            raise errors.SubscriptionDoesNotExist(subscription_id)
Esempio n. 7
0
    def _update(self, name, **kwargs):
        names = ("uri", "weight", "group", "options")
        fields = common_utils.fields(kwargs, names, pred=lambda x: x is not None, key_transform=lambda x: x[0])
        assert fields, "`weight`, `uri`, `group`, " "or `options` not found in kwargs"

        res = self._col.update({"n": name}, {"$set": fields}, upsert=False)
        if not res["updatedExisting"]:
            raise errors.PoolDoesNotExist(name)
Esempio n. 8
0
 def update(self, name, **kwargs):
     names = ('uri', 'weight', 'options')
     fields = common_utils.fields(kwargs, names,
                                  pred=lambda x: x is not None,
                                  key_transform=lambda x: x[0])
     assert fields, '`weight`, `uri`, or `options` not found in kwargs'
     res = self._col.update({'n': name},
                            {'$set': fields},
                            upsert=False)
     if not res['updatedExisting']:
         raise errors.PoolDoesNotExist(name)
Esempio n. 9
0
    def _update(self, name, **kwargs):
        names = ('uri', 'weight', 'group', 'options')
        fields = common_utils.fields(kwargs,
                                     names,
                                     pred=lambda x: x is not None,
                                     key_transform=lambda x: x[0])
        assert fields, ('`weight`, `uri`, `group`, '
                        'or `options` not found in kwargs')

        res = self._col.update_one({'n': name}, {'$set': fields}, upsert=False)
        if res.matched_count == 0:
            raise errors.PoolDoesNotExist(name)
Esempio n. 10
0
    def update(self, queue, subscription_id, project=None, **kwargs):
        names = ('subscriber', 'ttl', 'options')
        key_transform = lambda x: 'u' if x == 'subscriber' else x[0]
        fields = common_utils.fields(kwargs, names,
                                     pred=lambda x: x is not None,
                                     key_transform=key_transform)
        assert fields, ('`subscriber`, `ttl`, '
                        'or `options` not found in kwargs')

        # Pipeline ensures atomic inserts.
        with self._client.pipeline() as pipe:
            pipe.hmset(subscription_id, fields)
            pipe.execute()
Esempio n. 11
0
    def update(self, queue, subscription_id, project=None, **kwargs):
        names = ('subscriber', 'ttl', 'options')
        key_transform = lambda x: 'u' if x == 'subscriber' else x[0]
        fields = common_utils.fields(kwargs,
                                     names,
                                     pred=lambda x: x is not None,
                                     key_transform=key_transform)
        assert fields, ('`subscriber`, `ttl`, '
                        'or `options` not found in kwargs')

        # Pipeline ensures atomic inserts.
        with self._client.pipeline() as pipe:
            pipe.hmset(subscription_id, fields)
            pipe.execute()
Esempio n. 12
0
    def update(self, queue, subscription_id, project=None, **kwargs):
        names = ('subscriber', 'ttl', 'options')
        key_transform = lambda x: 'u' if x == 'subscriber' else x[0]
        fields = common_utils.fields(kwargs, names,
                                     pred=lambda x: x is not None,
                                     key_transform=key_transform)
        assert fields, ('`subscriber`, `ttl`, '
                        'or `options` not found in kwargs')

        res = self._collection.update({'_id': utils.to_oid(subscription_id),
                                       'p': project},
                                      {'$set': fields},
                                      upsert=False)

        if not res['updatedExisting']:
            raise errors.SubscriptionDoesNotExist(subscription_id)
Esempio n. 13
0
    def _update(self, name, **kwargs):
        names = ('uri', 'weight', 'flavor', 'options')
        fields = common_utils.fields(kwargs, names,
                                     pred=lambda x: x is not None,
                                     key_transform=lambda x: x[0])
        assert fields, ('`weight`, `uri`, '
                        'or `options` not found in kwargs')

        flavor = fields.get('f')
        if flavor is not None and len(flavor) == 0:
            fields['f'] = None

        res = self._col.update_one({'n': name},
                                   {'$set': fields},
                                   upsert=False)
        if res.matched_count == 0:
            raise errors.PoolDoesNotExist(name)
Esempio n. 14
0
    def update(self, queue, subscription_id, project=None, **kwargs):
        names = ('subscriber', 'ttl', 'options')
        key_transform = lambda x: 'u' if x == 'subscriber' else x[0]
        fields = common_utils.fields(kwargs,
                                     names,
                                     pred=lambda x: x is not None,
                                     key_transform=key_transform)
        assert fields, ('`subscriber`, `ttl`, '
                        'or `options` not found in kwargs')

        # Let's get our subscription by ID. If it does not exist,
        # SubscriptionDoesNotExist error will be raised internally.
        subscription_to_update = self.get(queue,
                                          subscription_id,
                                          project=project)

        new_subscriber = fields.get('u', None)

        # Let's do some checks to prevent subscription duplication.
        if new_subscriber:
            # Check if 'new_subscriber' is really new for our subscription.
            if subscription_to_update['subscriber'] != new_subscriber:
                # It's new. We should raise error if this subscriber already
                # exists for the queue and project.
                if self._is_duplicated_subscriber(new_subscriber, queue,
                                                  project):
                    raise errors.SubscriptionAlreadyExists()

        # NOTE(Eva-i): if there are new options, we need to pack them before
        # sending to the database.
        new_options = fields.get('o', None)
        if new_options is not None:
            fields['o'] = self._packer(new_options)

        new_ttl = fields.get('t', None)
        if new_ttl is not None:
            now = timeutils.utcnow_ts()
            expires = now + new_ttl
            fields['e'] = expires

        # Pipeline ensures atomic inserts.
        with self._client.pipeline() as pipe:
            pipe.hmset(subscription_id, fields)
            if new_ttl is not None:
                pipe.expire(subscription_id, new_ttl)
            pipe.execute()
Esempio n. 15
0
    def on_patch(self, request, response, project_id, flavor):
        """Allows one to update a flavors's pool_group.

        This method expects the user to submit a JSON object
        containing 'pool_group'. If none is found, the request is flagged
        as bad. There is also strict format checking through the use of
        jsonschema. Appropriate errors are returned in each case for
        badly formatted input.

        :returns: HTTP | [200, 400]
        """

        LOG.debug(u'PATCH flavor - name: %s', flavor)
        data = wsgi_utils.load(request)

        EXPECT = ('pool_group', 'pool')
        if not any([(field in data) for field in EXPECT]):
            LOG.debug(u'PATCH flavor, bad params')
            raise wsgi_errors.HTTPBadRequestBody(
                '`pool_group` or `pool` needs to be specified')

        for field in EXPECT:
            wsgi_utils.validate(self._validators[field], data)

        fields = common_utils.fields(data,
                                     EXPECT,
                                     pred=lambda v: v is not None)
        # NOTE(wanghao): remove this in Newton.
        if fields.get('pool') and fields.get('pool_group') is None:
            fields['pool_group'] = fields.get('pool')
            fields.pop('pool')

        resp_data = None
        try:
            self._ctrl.update(flavor, project=project_id, **fields)
            resp_data = self._ctrl.get(flavor, project=project_id)
            capabilities = self._pools_ctrl.capabilities(
                group=resp_data['pool_group'])
            resp_data['capabilities'] = [
                str(cap).split('.')[-1] for cap in capabilities
            ]
        except errors.FlavorDoesNotExist as ex:
            LOG.exception(ex)
            raise wsgi_errors.HTTPNotFound(six.text_type(ex))
        resp_data['href'] = request.path
        response.body = transport_utils.to_json(resp_data)
Esempio n. 16
0
    def on_patch(self, request, response, project_id, pool):
        """Allows one to update a pool's weight, uri, and/or options.

        This method expects the user to submit a JSON object
        containing at least one of: 'uri', 'weight', 'flavor',
        'options'.If none are found, the request is flagged as bad.
        There is also strict format checking through the use of
        jsonschema. Appropriate errors are returned in each case for
        badly formatted input.

        :returns: HTTP | 200,400
        """

        LOG.debug(u'PATCH pool - name: %s', pool)
        data = wsgi_utils.load(request)

        EXPECT = ('weight', 'uri', 'flavor', 'options')
        if not any([(field in data) for field in EXPECT]):
            LOG.debug(u'PATCH pool, bad params')
            raise wsgi_errors.HTTPBadRequestBody(
                'One of `uri`, `weight`, `flavor`,'
                ' or `options` needs '
                'to be specified'
            )

        for field in EXPECT:
            wsgi_utils.validate(self._validators[field], data)

        conf = self._ctrl.driver.conf
        if 'uri' in data and not storage_utils.can_connect(data['uri'],
                                                           conf=conf):
            raise wsgi_errors.HTTPBadRequestBody(
                'cannot connect to %s' % data['uri']
            )
        fields = common_utils.fields(data, EXPECT,
                                     pred=lambda v: v is not None)
        resp_data = None
        try:
            self._ctrl.update(pool, **fields)
            resp_data = self._ctrl.get(pool, False)
        except errors.PoolDoesNotExist as ex:
            LOG.exception('Pool "%s" does not exist', pool)
            raise wsgi_errors.HTTPNotFound(six.text_type(ex))

        resp_data['href'] = request.path
        response.body = transport_utils.to_json(resp_data)
Esempio n. 17
0
    def on_patch(self, request, response, project_id, pool):
        """Allows one to update a pool's weight, uri, and/or options.

        This method expects the user to submit a JSON object
        containing at least one of: 'uri', 'weight', 'group', 'options'. If
        none are found, the request is flagged as bad. There is also
        strict format checking through the use of
        jsonschema. Appropriate errors are returned in each case for
        badly formatted input.

        :returns: HTTP | 200,400
        """

        LOG.debug(u'PATCH pool - name: %s', pool)
        data = wsgi_utils.load(request)

        EXPECT = ('weight', 'uri', 'group', 'options')
        if not any([(field in data) for field in EXPECT]):
            LOG.debug(u'PATCH pool, bad params')
            raise wsgi_errors.HTTPBadRequestBody(
                'One of `uri`, `weight`, `group`, or `options` needs '
                'to be specified'
            )

        for field in EXPECT:
            wsgi_utils.validate(self._validators[field], data)

        conf = self._ctrl.driver.conf
        if 'uri' in data and not storage_utils.can_connect(data['uri'],
                                                           conf=conf):
            raise wsgi_errors.HTTPBadRequestBody(
                'cannot connect to %s' % data['uri']
            )
        fields = common_utils.fields(data, EXPECT,
                                     pred=lambda v: v is not None)
        resp_data = None
        try:
            self._ctrl.update(pool, **fields)
            resp_data = self._ctrl.get(pool, False)
        except errors.PoolDoesNotExist as ex:
            LOG.exception(ex)
            raise wsgi_errors.HTTPNotFound(six.text_type(ex))

        resp_data['href'] = request.path
        response.body = transport_utils.to_json(resp_data)
Esempio n. 18
0
    def on_patch(self, request, response, project_id, flavor):
        """Allows one to update a flavors's pool_group.

        This method expects the user to submit a JSON object
        containing 'pool_group'. If none is found, the request is flagged
        as bad. There is also strict format checking through the use of
        jsonschema. Appropriate errors are returned in each case for
        badly formatted input.

        :returns: HTTP | [200, 400]
        """

        LOG.debug(u'PATCH flavor - name: %s', flavor)
        data = wsgi_utils.load(request)

        EXPECT = ('pool_group', 'pool')
        if not any([(field in data) for field in EXPECT]):
            LOG.debug(u'PATCH flavor, bad params')
            raise wsgi_errors.HTTPBadRequestBody(
                '`pool_group` or `pool` needs to be specified'
            )

        for field in EXPECT:
            wsgi_utils.validate(self._validators[field], data)

        fields = common_utils.fields(data, EXPECT,
                                     pred=lambda v: v is not None)
        # NOTE(wanghao): remove this in Newton.
        if fields.get('pool') and fields.get('pool_group') is None:
            fields['pool_group'] = fields.get('pool')
            fields.pop('pool')

        resp_data = None
        try:
            self._ctrl.update(flavor, project=project_id, **fields)
            resp_data = self._ctrl.get(flavor, project=project_id)
            capabilities = self._pools_ctrl.capabilities(
                group=resp_data['pool_group'])
            resp_data['capabilities'] = [str(cap).split('.')[-1]
                                         for cap in capabilities]
        except errors.FlavorDoesNotExist as ex:
            LOG.exception(ex)
            raise wsgi_errors.HTTPNotFound(six.text_type(ex))
        resp_data['href'] = request.path
        response.body = transport_utils.to_json(resp_data)
Esempio n. 19
0
    def update(self, queue, subscription_id, project=None, **kwargs):
        names = ('subscriber', 'ttl', 'options')
        key_transform = lambda x: 'u' if x == 'subscriber' else x[0]
        fields = common_utils.fields(kwargs, names,
                                     pred=lambda x: x is not None,
                                     key_transform=key_transform)
        assert fields, ('`subscriber`, `ttl`, '
                        'or `options` not found in kwargs')

        # Let's get our subscription by ID. If it does not exist,
        # SubscriptionDoesNotExist error will be raised internally.
        subscription_to_update = self.get(queue, subscription_id,
                                          project=project)

        new_subscriber = fields.get('u')

        # Let's do some checks to prevent subscription duplication.
        if new_subscriber:
            # Check if 'new_subscriber' is really new for our subscription.
            if subscription_to_update['subscriber'] != new_subscriber:
                # It's new. We should raise error if this subscriber already
                # exists for the queue and project.
                if self._is_duplicated_subscriber(new_subscriber, queue,
                                                  project):
                    raise errors.SubscriptionAlreadyExists()

        # NOTE(Eva-i): if there are new options, we need to pack them before
        # sending to the database.
        new_options = fields.get('o')
        if new_options is not None:
            fields['o'] = self._packer(new_options)

        new_ttl = fields.get('t')
        if new_ttl is not None:
            now = timeutils.utcnow_ts()
            expires = now + new_ttl
            fields['e'] = expires

        # Pipeline ensures atomic inserts.
        with self._client.pipeline() as pipe:
            pipe.hmset(subscription_id, fields)
            if new_ttl is not None:
                pipe.expire(subscription_id, new_ttl)
            pipe.execute()
Esempio n. 20
0
    def update(self, name, **kwargs):
        # NOTE(cpp-cabrera): by pruning None-valued kwargs, we avoid
        # overwriting the existing options field with None, since that
        # one can be null.
        names = ('uri', 'weight', 'options')
        fields = common_utils.fields(kwargs, names,
                                     pred=lambda x: x is not None)

        assert fields, '`weight`, `uri`, or `options` not found in kwargs'

        if 'options' in fields:
            fields['options'] = utils.json_encode(fields['options'])

        stmt = sa.sql.update(tables.Pools).where(
            tables.Pools.c.name == name).values(**fields)

        res = self._conn.execute(stmt)
        if res.rowcount == 0:
            raise errors.PoolDoesNotExist(name)
Esempio n. 21
0
    def _update(self, name, **kwargs):
        # NOTE(cpp-cabrera): by pruning None-valued kwargs, we avoid
        # overwriting the existing options field with None, since that
        # one can be null.
        names = ('uri', 'weight', 'flavor', 'options')
        fields = common_utils.fields(kwargs, names,
                                     pred=lambda x: x is not None)

        assert fields, ('`weight`, `uri`, `flavor`, '
                        'or `options` not found in kwargs')

        if 'options' in fields:
            fields['options'] = utils.json_encode(fields['options'])

        stmt = sa.sql.update(tables.Pools).where(
            tables.Pools.c.name == name).values(**fields)

        res = self.driver.run(stmt)
        if res.rowcount == 0:
            raise errors.PoolDoesNotExist(name)
Esempio n. 22
0
    def on_patch(self, request, response, project_id, pool):
        """Allows one to update a pool's weight, uri, and/or options.

        This method expects the user to submit a JSON object
        containing at least one of: 'uri', 'weight', 'group', 'options'. If
        none are found, the request is flagged as bad. There is also
        strict format checking through the use of
        jsonschema. Appropriate errors are returned in each case for
        badly formatted input.

        :returns: HTTP | 200,400
        """

        LOG.debug(u"PATCH pool - name: %s", pool)
        data = wsgi_utils.load(request)

        EXPECT = ("weight", "uri", "group", "options")
        if not any([(field in data) for field in EXPECT]):
            LOG.debug(u"PATCH pool, bad params")
            raise wsgi_errors.HTTPBadRequestBody(
                "One of `uri`, `weight`, `group`, or `options` needs " "to be specified"
            )

        for field in EXPECT:
            wsgi_utils.validate(self._validators[field], data)

        conf = self._ctrl.driver.conf
        if "uri" in data and not storage_utils.can_connect(data["uri"], conf=conf):
            raise wsgi_errors.HTTPBadRequestBody("cannot connect to %s" % data["uri"])
        fields = common_utils.fields(data, EXPECT, pred=lambda v: v is not None)

        try:
            self._ctrl.update(pool, **fields)
        except errors.PoolDoesNotExist as ex:
            LOG.exception(ex)
            raise falcon.HTTPNotFound()