Exemple #1
0
 def test_reservation_rollback(self):
     reservations = _quota_reserve(self.ctxt, 'project1')
     expected = {
         'project_id': 'project1',
         'volumes': {
             'reserved': 1,
             'in_use': 0
         },
         'gigabytes': {
             'reserved': 2,
             'in_use': 0
         },
     }
     self.assertEqual(
         expected, db.quota_usage_get_all_by_project(self.ctxt, 'project1'))
     db.reservation_get(self.ctxt, reservations[0])
     db.reservation_rollback(self.ctxt, reservations, 'project1')
     self.assertRaises(exception.ReservationNotFound, db.reservation_get,
                       self.ctxt, reservations[0])
     expected = {
         'project_id': 'project1',
         'volumes': {
             'reserved': 0,
             'in_use': 0
         },
         'gigabytes': {
             'reserved': 0,
             'in_use': 0
         },
     }
     self.assertEqual(
         expected, db.quota_usage_get_all_by_project(self.ctxt, 'project1'))
    def test_transfer_accept_with_snapshots(self):
        svc = self.start_service('volume', host='test_host')
        self.addCleanup(svc.stop)
        tx_api = transfer_api.API()
        volume = utils.create_volume(self.ctxt,
                                     volume_type_id=fake.VOLUME_TYPE_ID,
                                     updated_at=self.updated_at)
        utils.create_volume_type(self.ctxt.elevated(),
                                 id=fake.VOLUME_TYPE_ID,
                                 name="test_type")
        utils.create_snapshot(self.ctxt, volume.id, status='available')
        with mock.patch('cinder.volume.volume_utils.notify_about_volume_usage'
                        ) as mock_notify:
            transfer = tx_api.create(self.ctxt, volume.id, 'Description')
            calls = [
                mock.call(self.ctxt, mock.ANY, "transfer.create.start"),
                mock.call(self.ctxt, mock.ANY, "transfer.create.end")
            ]
            mock_notify.assert_has_calls(calls)
            # The notify_about_volume_usage is called twice at create().
            self.assertEqual(2, mock_notify.call_count)

        # Get volume and snapshot quota before accept
        self.ctxt.user_id = fake.USER2_ID
        self.ctxt.project_id = fake.PROJECT2_ID
        usages = db.quota_usage_get_all_by_project(self.ctxt,
                                                   self.ctxt.project_id)
        self.assertEqual(0, usages.get('volumes', {}).get('in_use', 0))
        self.assertEqual(0, usages.get('snapshots', {}).get('in_use', 0))

        with mock.patch('cinder.volume.volume_utils.notify_about_volume_usage'
                        ) as mock_notify:
            tx_api.accept(self.ctxt, transfer['id'], transfer['auth_key'])
            calls = [
                mock.call(self.ctxt, mock.ANY, "transfer.accept.start"),
                mock.call(self.ctxt, mock.ANY, "transfer.accept.end")
            ]
            mock_notify.assert_has_calls(calls)
            # The notify_about_volume_usage is called twice at accept().
            self.assertEqual(2, mock_notify.call_count)

        volume = objects.Volume.get_by_id(self.ctxt, volume.id)
        self.assertEqual(fake.PROJECT2_ID, volume.project_id)
        self.assertEqual(fake.USER2_ID, volume.user_id)

        # Get volume and snapshot quota after accept
        self.ctxt.user_id = fake.USER2_ID
        self.ctxt.project_id = fake.PROJECT2_ID
        usages = db.quota_usage_get_all_by_project(self.ctxt,
                                                   self.ctxt.project_id)
        self.assertEqual(1, usages.get('volumes', {}).get('in_use', 0))
        self.assertEqual(1, usages.get('snapshots', {}).get('in_use', 0))
Exemple #3
0
 def test_reservation_rollback(self):
     reservations = _quota_reserve(self.ctxt, "project1")
     expected = {
         "project_id": "project1",
         "volumes": {"reserved": 1, "in_use": 0},
         "gigabytes": {"reserved": 2, "in_use": 0},
     }
     self.assertEqual(expected, db.quota_usage_get_all_by_project(self.ctxt, "project1"))
     db.reservation_rollback(self.ctxt, reservations, "project1")
     expected = {
         "project_id": "project1",
         "volumes": {"reserved": 0, "in_use": 0},
         "gigabytes": {"reserved": 0, "in_use": 0},
     }
     self.assertEqual(expected, db.quota_usage_get_all_by_project(self.ctxt, "project1"))
 def test_quota_usage_get_all_by_project(self):
     reservations = _quota_reserve(self.ctxt, 'p1')
     expected = {'project_id': 'p1',
                 'volumes': {'in_use': 0, 'reserved': 1},
                 'gigabytes': {'in_use': 0, 'reserved': 2}}
     self.assertEqual(expected, db.quota_usage_get_all_by_project(
                      self.ctxt, 'p1'))
Exemple #5
0
 def test_quota_destroy_all_by_project(self):
     reservations = _quota_reserve(self.ctxt, "project1")
     db.quota_destroy_all_by_project(self.ctxt, "project1")
     self.assertEqual(db.quota_get_all_by_project(self.ctxt, "project1"), {"project_id": "project1"})
     self.assertEqual(db.quota_usage_get_all_by_project(self.ctxt, "project1"), {"project_id": "project1"})
     for r in reservations:
         self.assertRaises(exception.ReservationNotFound, db.reservation_get, self.ctxt, r)
Exemple #6
0
    def get_project_quotas(self, context, resources, project_id,
                           quota_class=None, defaults=True,
                           usages=True):
        """
        Given a list of resources, retrieve the quotas for the given
        project.

        :param context: The request context, for access checks.
        :param resources: A dictionary of the registered resources.
        :param project_id: The ID of the project to return quotas for.
        :param quota_class: If project_id != context.project_id, the
                            quota class cannot be determined.  This
                            parameter allows it to be specified.  It
                            will be ignored if project_id ==
                            context.project_id.
        :param defaults: If True, the quota class value (or the
                         default value, if there is no value from the
                         quota class) will be reported if there is no
                         specific value for the resource.
        :param usages: If True, the current in_use and reserved counts
                       will also be returned.
        """

        quotas = {}
        project_quotas = db.quota_get_all_by_project(context, project_id)
        if usages:
            project_usages = db.quota_usage_get_all_by_project(context,
                                                               project_id)

        # Get the quotas for the appropriate class.  If the project ID
        # matches the one in the context, we use the quota_class from
        # the context, otherwise, we use the provided quota_class (if
        # any)
        if project_id == context.project_id:
            quota_class = context.quota_class
        if quota_class:
            class_quotas = db.quota_class_get_all_by_name(context, quota_class)
        else:
            class_quotas = {}

        for resource in resources.values():
            # Omit default/quota class values
            if not defaults and resource.name not in project_quotas:
                continue

            quotas[resource.name] = dict(
                limit=project_quotas.get(resource.name,
                                         class_quotas.get(resource.name,
                                                          resource.default)), )

            # Include usages if desired.  This is optional because one
            # internal consumer of this interface wants to access the
            # usages directly from inside a transaction.
            if usages:
                usage = project_usages.get(resource.name, {})
                quotas[resource.name].update(
                    in_use=usage.get('in_use', 0),
                    reserved=usage.get('reserved', 0), )

        return quotas
Exemple #7
0
 def test_reservation_commit(self):
     reservations = _quota_reserve(self.ctxt, "project1")
     expected = {
         "project_id": "project1",
         "volumes": {"reserved": 1, "in_use": 0},
         "gigabytes": {"reserved": 2, "in_use": 0},
     }
     self.assertEqual(expected, db.quota_usage_get_all_by_project(self.ctxt, "project1"))
     db.reservation_get(self.ctxt, reservations[0])
     db.reservation_commit(self.ctxt, reservations, "project1")
     self.assertRaises(exception.ReservationNotFound, db.reservation_get, self.ctxt, reservations[0])
     expected = {
         "project_id": "project1",
         "volumes": {"reserved": 0, "in_use": 1},
         "gigabytes": {"reserved": 0, "in_use": 2},
     }
     self.assertEqual(expected, db.quota_usage_get_all_by_project(self.ctxt, "project1"))
Exemple #8
0
 def test_quota_usage_get_all_by_project(self):
     _quota_reserve(self.ctxt, "p1")
     expected = {
         "project_id": "p1",
         "volumes": {"in_use": 0, "reserved": 1},
         "gigabytes": {"in_use": 0, "reserved": 2},
     }
     self.assertEqual(expected, db.quota_usage_get_all_by_project(self.ctxt, "p1"))
Exemple #9
0
 def test_quota_destroy_all_by_project(self):
     reservations = _quota_reserve(self.ctxt, 'project1')
     db.quota_destroy_all_by_project(self.ctxt, 'project1')
     self.assertEqual(db.quota_get_all_by_project(self.ctxt, 'project1'),
                      {'project_id': 'project1'})
     self.assertEqual(
         db.quota_usage_get_all_by_project(self.ctxt, 'project1'),
         {'project_id': 'project1'})
     for r in reservations:
         self.assertRaises(exception.ReservationNotFound,
                           db.reservation_get, self.ctxt, r)
Exemple #10
0
 def _commit_quota_reservation(self):
     # Create simple quota and quota usage.
     ctxt = context.get_admin_context()
     res = test_db_api._quota_reserve(ctxt, 'foo')
     db.reservation_commit(ctxt, res, 'foo')
     expected = {'project_id': 'foo',
                 'volumes': {'reserved': 0, 'in_use': 1},
                 'gigabytes': {'reserved': 0, 'in_use': 2},
                 }
     self.assertEqual(expected,
                      db.quota_usage_get_all_by_project(ctxt, 'foo'))
Exemple #11
0
 def _commit_quota_reservation(self):
     # Create simple quota and quota usage.
     ctxt = context.get_admin_context()
     res = test_db_api._quota_reserve(ctxt, fake.PROJECT_ID)
     db.reservation_commit(ctxt, res, fake.PROJECT_ID)
     expected = {
         "project_id": fake.PROJECT_ID,
         "volumes": {"reserved": 0, "in_use": 1},
         "gigabytes": {"reserved": 0, "in_use": 2},
     }
     self.assertEqual(expected, db.quota_usage_get_all_by_project(ctxt, fake.PROJECT_ID))
Exemple #12
0
 def _commit_quota_reservation(self):
     # Create simple quota and quota usage.
     ctxt = context.get_admin_context()
     res = test_db_api._quota_reserve(ctxt, 'foo')
     db.reservation_commit(ctxt, res, 'foo')
     expected = {'project_id': 'foo',
                 'volumes': {'reserved': 0, 'in_use': 1},
                 'gigabytes': {'reserved': 0, 'in_use': 2},
                 }
     self.assertEqual(expected,
                      db.quota_usage_get_all_by_project(ctxt, 'foo'))
Exemple #13
0
    def test_reservation_expire(self):
        self.values["expire"] = datetime.datetime.utcnow() + datetime.timedelta(days=1)
        _quota_reserve(self.ctxt, "project1")
        db.reservation_expire(self.ctxt)

        expected = {
            "project_id": "project1",
            "gigabytes": {"reserved": 0, "in_use": 0},
            "volumes": {"reserved": 0, "in_use": 0},
        }
        self.assertEqual(expected, db.quota_usage_get_all_by_project(self.ctxt, "project1"))
Exemple #14
0
 def test_quota_reserve(self):
     reservations = _quota_reserve(self.ctxt, "project1")
     self.assertEqual(len(reservations), 2)
     quota_usage = db.quota_usage_get_all_by_project(self.ctxt, "project1")
     self.assertEqual(
         {
             "project_id": "project1",
             "gigabytes": {"reserved": 2, "in_use": 0},
             "volumes": {"reserved": 1, "in_use": 0},
         },
         quota_usage,
     )
Exemple #15
0
 def test_reservation_commit(self):
     reservations = _quota_reserve(self.ctxt, 'project1')
     expected = {
         'project_id': 'project1',
         'res0': {
             'reserved': 0,
             'in_use': 0
         },
         'res1': {
             'reserved': 1,
             'in_use': 1
         },
         'res2': {
             'reserved': 2,
             'in_use': 2
         }
     }
     self.assertEqual(
         expected, db.quota_usage_get_all_by_project(self.ctxt, 'project1'))
     db.reservation_get(self.ctxt, reservations[0])
     db.reservation_commit(self.ctxt, reservations, 'project1')
     self.assertRaises(exception.ReservationNotFound, db.reservation_get,
                       self.ctxt, reservations[0])
     expected = {
         'project_id': 'project1',
         'res0': {
             'reserved': 0,
             'in_use': 0
         },
         'res1': {
             'reserved': 0,
             'in_use': 2
         },
         'res2': {
             'reserved': 0,
             'in_use': 4
         }
     }
     self.assertEqual(
         expected, db.quota_usage_get_all_by_project(self.ctxt, 'project1'))
Exemple #16
0
    def test_transfer_accept_with_snapshots(self, mock_notify):
        svc = self.start_service('volume', host='test_host')
        self.addCleanup(svc.stop)
        tx_api = transfer_api.API()
        volume = utils.create_volume(self.ctxt,
                                     volume_type_id=fake.VOLUME_TYPE_ID,
                                     updated_at=self.updated_at)
        utils.create_volume_type(self.ctxt.elevated(),
                                 id=fake.VOLUME_TYPE_ID, name="test_type")
        utils.create_snapshot(self.ctxt, volume.id, status='available')
        transfer = tx_api.create(self.ctxt, volume.id, 'Description')

        # Get volume and snapshot quota before accept
        self.ctxt.user_id = fake.USER2_ID
        self.ctxt.project_id = fake.PROJECT2_ID
        usages = db.quota_usage_get_all_by_project(self.ctxt,
                                                   self.ctxt.project_id)
        self.assertEqual(0, usages.get('volumes', {}).get('in_use', 0))
        self.assertEqual(0, usages.get('snapshots', {}).get('in_use', 0))

        tx_api.accept(self.ctxt, transfer['id'], transfer['auth_key'])
        volume = objects.Volume.get_by_id(self.ctxt, volume.id)
        self.assertEqual(fake.PROJECT2_ID, volume.project_id)
        self.assertEqual(fake.USER2_ID, volume.user_id)

        calls = [mock.call(self.ctxt, mock.ANY, "transfer.accept.start"),
                 mock.call(self.ctxt, mock.ANY, "transfer.accept.end")]
        mock_notify.assert_has_calls(calls)
        # The notify_about_volume_usage is called twice at create(),
        # and twice at accept().
        self.assertEqual(4, mock_notify.call_count)

        # Get volume and snapshot quota after accept
        self.ctxt.user_id = fake.USER2_ID
        self.ctxt.project_id = fake.PROJECT2_ID
        usages = db.quota_usage_get_all_by_project(self.ctxt,
                                                   self.ctxt.project_id)
        self.assertEqual(1, usages.get('volumes', {}).get('in_use', 0))
        self.assertEqual(1, usages.get('snapshots', {}).get('in_use', 0))
    def test_reservation_expire(self):
        self.values['expire'] = datetime.datetime.utcnow() + \
            datetime.timedelta(days=1)
        reservations = _quota_reserve(self.ctxt, 'project1')
        db.reservation_expire(self.ctxt)

        expected = {'project_id': 'project1',
                    'gigabytes': {'reserved': 0, 'in_use': 0},
                    'volumes': {'reserved': 0, 'in_use': 0}}
        self.assertEqual(expected,
                         db.quota_usage_get_all_by_project(
                             self.ctxt,
                             'project1'))
Exemple #18
0
 def test_reservation_commit(self):
     reservations = _quota_reserve(self.ctxt, 'project1')
     expected = {'project_id': 'project1',
                 'volumes': {'reserved': 1, 'in_use': 0},
                 'gigabytes': {'reserved': 2, 'in_use': 0},
                 }
     self.assertEqual(expected,
                      db.quota_usage_get_all_by_project(
                          self.ctxt, 'project1'))
     db.reservation_get(self.ctxt, reservations[0])
     db.reservation_commit(self.ctxt, reservations, 'project1')
     self.assertRaises(exception.ReservationNotFound,
                       db.reservation_get,
                       self.ctxt,
                       reservations[0])
     expected = {'project_id': 'project1',
                 'volumes': {'reserved': 0, 'in_use': 1},
                 'gigabytes': {'reserved': 0, 'in_use': 2},
                 }
     self.assertEqual(expected,
                      db.quota_usage_get_all_by_project(
                          self.ctxt,
                          'project1'))
Exemple #19
0
 def test_reservation_rollback(self):
     reservations = _quota_reserve(self.ctxt, 'project1')
     expected = {'project_id': 'project1',
                 'res0': {'reserved': 0, 'in_use': 0},
                 'res1': {'reserved': 1, 'in_use': 1},
                 'res2': {'reserved': 2, 'in_use': 2}}
     self.assertEqual(expected,
                      db.quota_usage_get_all_by_project(
                          self.ctxt,
                          'project1'))
     db.reservation_get(self.ctxt, reservations[0])
     db.reservation_rollback(self.ctxt, reservations, 'project1')
     self.assertRaises(exception.ReservationNotFound,
                       db.reservation_get,
                       self.ctxt,
                       reservations[0])
     expected = {'project_id': 'project1',
                 'res0': {'reserved': 0, 'in_use': 0},
                 'res1': {'reserved': 0, 'in_use': 1},
                 'res2': {'reserved': 0, 'in_use': 2}}
     self.assertEqual(expected,
                      db.quota_usage_get_all_by_project(
                          self.ctxt,
                          'project1'))
Exemple #20
0
    def get_project_quotas(self, context, resources, project_id,
                           quota_class=None, defaults=True,
                           usages=True, parent_project_id=None):
        """Given a list of resources, retrieve the quotas for the given
        project.

        :param context: The request context, for access checks.
        :param resources: A dictionary of the registered resources.
        :param project_id: The ID of the project to return quotas for.
        :param quota_class: If project_id != context.project_id, the
                            quota class cannot be determined.  This
                            parameter allows it to be specified.  It
                            will be ignored if project_id ==
                            context.project_id.
        :param defaults: If True, the quota class value (or the
                         default value, if there is no value from the
                         quota class) will be reported if there is no
                         specific value for the resource.
        :param usages: If True, the current in_use and reserved counts
                       will also be returned.
        :param parent_project_id: The id of the current project's parent,
                                  if any.
        """

        quotas = {}
        project_quotas = db.quota_get_all_by_project(context, project_id)
        if usages:
            project_usages = db.quota_usage_get_all_by_project(context,
                                                               project_id)

        # Get the quotas for the appropriate class.  If the project ID
        # matches the one in the context, we use the quota_class from
        # the context, otherwise, we use the provided quota_class (if
        # any)
        if project_id == context.project_id:
            quota_class = context.quota_class
        if quota_class:
            class_quotas = db.quota_class_get_all_by_name(context, quota_class)
        else:
            class_quotas = {}

        default_quotas = self.get_defaults(context, resources,
                                           parent_project_id=parent_project_id)

        for resource in resources.values():
            # Omit default/quota class values
            if not defaults and resource.name not in project_quotas:
                continue

            quotas[resource.name] = dict(
                limit=project_quotas.get(
                    resource.name,
                    class_quotas.get(resource.name,
                                     default_quotas[resource.name])),
            )

            # Include usages if desired.  This is optional because one
            # internal consumer of this interface wants to access the
            # usages directly from inside a transaction.
            if usages:
                usage = project_usages.get(resource.name, {})
                quotas[resource.name].update(
                    in_use=usage.get('in_use', 0),
                    reserved=usage.get('reserved', 0), )

        return quotas
Exemple #21
0
 def test_quota_destroy_all_by_project(self):
     _quota_reserve(self.ctxt, "project1")
     db.quota_destroy_all_by_project(self.ctxt, "project1")
     self.assertEqual(db.quota_get_all_by_project(self.ctxt, "project1"), {"project_id": "project1"})
     self.assertEqual(db.quota_usage_get_all_by_project(self.ctxt, "project1"), {"project_id": "project1"})