diff options
| author | Brian Waldon <brian.waldon@rackspace.com> | 2011-09-01 17:54:52 +0000 |
|---|---|---|
| committer | Tarmac <> | 2011-09-01 17:54:52 +0000 |
| commit | dbd5acd2ba6bc9853f165d457eaf6abe7559a92e (patch) | |
| tree | 3863e731df132d98a464ff48886e79fe41658280 /nova | |
| parent | 12ebed39bba39b4207344b90ec26323d4c251958 (diff) | |
| parent | 9b3a6c8cda99290f0b7aff740faec0e8544aafe0 (diff) | |
| download | nova-dbd5acd2ba6bc9853f165d457eaf6abe7559a92e.tar.gz nova-dbd5acd2ba6bc9853f165d457eaf6abe7559a92e.tar.xz nova-dbd5acd2ba6bc9853f165d457eaf6abe7559a92e.zip | |
- implements changes-since for servers resource
- default sort is now created_at desc for instances
Diffstat (limited to 'nova')
| -rw-r--r-- | nova/api/openstack/servers.py | 24 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 12 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_servers.py | 25 | ||||
| -rw-r--r-- | nova/tests/test_cloud.py | 7 | ||||
| -rw-r--r-- | nova/tests/test_db_api.py | 4 |
5 files changed, 54 insertions, 18 deletions
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 1b3eddd05..977958f5d 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -106,6 +106,14 @@ class Controller(object): raise exception.InvalidInput(reason=reason) search_opts['vm_state'] = state + if 'changes-since' in search_opts: + try: + parsed = utils.parse_isotime(search_opts['changes-since']) + except ValueError: + msg = _('Invalid changes-since value') + raise exc.HTTPBadRequest(explanation=msg) + search_opts['changes-since'] = parsed + # By default, compute's get_all() will return deleted instances. # If an admin hasn't specified a 'deleted' search option, we need # to filter out deleted instances by setting the filter ourselves. @@ -113,23 +121,17 @@ class Controller(object): # should return recently deleted images according to the API spec. if 'deleted' not in search_opts: - # Admin hasn't specified deleted filter if 'changes-since' not in search_opts: - # No 'changes-since', so we need to find non-deleted servers + # No 'changes-since', so we only want non-deleted servers search_opts['deleted'] = False - else: - # This is the default, but just in case.. - search_opts['deleted'] = True - - instance_list = self.compute_api.get_all( - context, search_opts=search_opts) - # FIXME(comstud): 'changes-since' is not fully implemented. Where - # should this be filtered? + instance_list = self.compute_api.get_all(context, + search_opts=search_opts) limited_list = self._limit_items(instance_list, req) servers = [self._build_view(req, inst, is_detail)['server'] - for inst in limited_list] + for inst in limited_list] + return dict(servers=servers) @scheduler_api.redirect_handler diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index c97ff5070..b99667afc 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -36,6 +36,7 @@ from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload_all from sqlalchemy.sql import func +from sqlalchemy.sql.expression import desc from sqlalchemy.sql.expression import literal_column FLAGS = flags.FLAGS @@ -1250,12 +1251,17 @@ def instance_get_all_by_filters(context, filters): options(joinedload_all('fixed_ips.network')).\ options(joinedload('metadata')).\ options(joinedload('instance_type')).\ - filter_by(deleted=can_read_deleted(context)) + order_by(desc(models.Instance.created_at)) # Make a copy of the filters dictionary to use going forward, as we'll # be modifying it and we shouldn't affect the caller's use of it. filters = filters.copy() + if 'changes-since' in filters: + changes_since = filters['changes-since'] + query_prefix = query_prefix.\ + filter(models.Instance.updated_at > changes_since) + if not context.is_admin: # If we're not admin context, add appropriate filter.. if context.project_id: @@ -1277,9 +1283,7 @@ def instance_get_all_by_filters(context, filters): query_prefix = _exact_match_filter(query_prefix, filter_name, filters.pop(filter_name)) - instances = query_prefix.\ - filter_by(deleted=can_read_deleted(context)).\ - all() + instances = query_prefix.all() if not instances: return [] diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 412aa439c..1591ea56c 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -1265,6 +1265,31 @@ class ServersTest(test.TestCase): self.assertEqual(len(servers), 1) self.assertEqual(servers[0]['id'], 100) + def test_get_servers_allows_changes_since_v1_1(self): + def fake_get_all(compute_self, context, search_opts=None): + self.assertNotEqual(search_opts, None) + self.assertTrue('changes-since' in search_opts) + changes_since = datetime.datetime(2011, 1, 24, 17, 8, 1) + self.assertEqual(search_opts['changes-since'], changes_since) + self.assertTrue('deleted' not in search_opts) + return [stub_instance(100)] + + self.stubs.Set(nova.compute.API, 'get_all', fake_get_all) + + params = 'changes-since=2011-01-24T17:08:01Z' + req = webob.Request.blank('/v1.1/fake/servers?%s' % params) + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) + servers = json.loads(res.body)['servers'] + self.assertEqual(len(servers), 1) + self.assertEqual(servers[0]['id'], 100) + + def test_get_servers_allows_changes_since_bad_value_v1_1(self): + params = 'changes-since=asdf' + req = webob.Request.blank('/v1.1/fake/servers?%s' % params) + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + def test_get_servers_unknown_or_admin_options1(self): """Test getting servers by admin-only or unknown options. This tests when admin_api is off. Make sure the admin and diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 806c29e42..3fe6a9b42 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -486,8 +486,11 @@ class CloudTestCase(test.TestCase): inst2 = db.instance_create(self.context, args2) db.instance_destroy(self.context, inst1.id) result = self.cloud.describe_instances(self.context) - result = result['reservationSet'][0]['instancesSet'] - self.assertEqual(result[0]['instanceId'], + result1 = result['reservationSet'][0]['instancesSet'] + self.assertEqual(result1[0]['instanceId'], + ec2utils.id_to_ec2_id(inst1.id)) + result2 = result['reservationSet'][1]['instancesSet'] + self.assertEqual(result2[0]['instanceId'], ec2utils.id_to_ec2_id(inst2.id)) def _block_device_mapping_create(self, instance_id, mappings): diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py index 038c07f40..60d7abd8c 100644 --- a/nova/tests/test_db_api.py +++ b/nova/tests/test_db_api.py @@ -91,5 +91,7 @@ class DbApiTestCase(test.TestCase): inst2 = db.instance_create(self.context, args2) db.instance_destroy(self.context, inst1.id) result = db.instance_get_all_by_filters(self.context.elevated(), {}) - self.assertEqual(1, len(result)) + self.assertEqual(2, len(result)) self.assertEqual(result[0].id, inst2.id) + self.assertEqual(result[1].id, inst1.id) + self.assertTrue(result[1].deleted) |
