diff options
author | Jenkins <jenkins@review.openstack.org> | 2013-04-26 02:03:52 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2013-04-26 02:03:52 +0000 |
commit | 31cac9a9bae5ba4350677170bb397bcd81e43c23 (patch) | |
tree | aa7bbbe5256d33d46a36ff068fabfb5d12af55bf | |
parent | 13c085bc9605447c4ff39ed903e0ef5bffd965d0 (diff) | |
parent | 5cced7a31482d014fe31f815f38fd00e079cc491 (diff) | |
download | nova-31cac9a9bae5ba4350677170bb397bcd81e43c23.tar.gz nova-31cac9a9bae5ba4350677170bb397bcd81e43c23.tar.xz nova-31cac9a9bae5ba4350677170bb397bcd81e43c23.zip |
Merge "Allow listing fixed_ips for a given compute host."
-rw-r--r-- | nova/cmd/manage.py | 3 | ||||
-rw-r--r-- | nova/db/api.py | 5 | ||||
-rw-r--r-- | nova/db/sqlalchemy/api.py | 33 | ||||
-rw-r--r-- | nova/tests/db/fakes.py | 33 | ||||
-rw-r--r-- | nova/tests/test_db_api.py | 43 | ||||
-rw-r--r-- | nova/tests/test_nova_manage.py | 19 |
6 files changed, 123 insertions, 13 deletions
diff --git a/nova/cmd/manage.py b/nova/cmd/manage.py index f4a483c0d..ee3c123a9 100644 --- a/nova/cmd/manage.py +++ b/nova/cmd/manage.py @@ -285,7 +285,8 @@ class FixedIpCommands(object): if host is None: fixed_ips = db.fixed_ip_get_all(ctxt) else: - fixed_ips = db.fixed_ip_get_all_by_instance_host(ctxt, host) + fixed_ips = db.fixed_ip_get_by_host(ctxt, host) + except exception.NotFound as ex: print _("error: %s") % ex return(2) diff --git a/nova/db/api.py b/nova/db/api.py index 5073ad07e..f454a2d15 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -496,6 +496,11 @@ def fixed_ip_get_by_instance(context, instance_uuid): return IMPL.fixed_ip_get_by_instance(context, instance_uuid) +def fixed_ip_get_by_host(context, host): + """Get fixed ips by compute host.""" + return IMPL.fixed_ip_get_by_host(context, host) + + def fixed_ip_get_by_network_host(context, network_uuid, host): """Get fixed ip for a host in a network.""" return IMPL.fixed_ip_get_by_network_host(context, network_uuid, host) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index b6267f81a..11a7985f4 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1226,6 +1226,20 @@ def fixed_ip_get_by_instance(context, instance_uuid): return result +@require_admin_context +def fixed_ip_get_by_host(context, host): + session = get_session() + with session.begin(): + instance_uuids = _instance_get_all_uuids_by_host(context, host, + session=session) + if not instance_uuids: + return [] + + return model_query(context, models.FixedIp, session=session).\ + filter(models.FixedIp.instance_uuid.in_(instance_uuids)).\ + all() + + @require_context def fixed_ip_get_by_network_host(context, network_id, host): result = model_query(context, models.FixedIp, read_deleted="no").\ @@ -1859,6 +1873,22 @@ def instance_get_all_by_host(context, host, columns_to_join=None): @require_admin_context +def _instance_get_all_uuids_by_host(context, host, session=None): + """Return a list of the instance uuids on a given host. + + Returns a list of UUIDs, not Instance model objects. This internal version + allows you to specify a session object as a kwarg. + """ + uuids = [] + for tuple in model_query(context, models.Instance.uuid, read_deleted="no", + base_model=models.Instance, session=session).\ + filter_by(host=host).\ + all(): + uuids.append(tuple[0]) + return uuids + + +@require_admin_context def instance_get_all_by_host_and_node(context, host, node): return _instances_fill_metadata(context, _instance_get_all_query(context, joins=[]).filter_by(host=host). @@ -4924,6 +4954,9 @@ def _get_default_deleted_value(table): # from the column, but I don't see a way to do that in the low-level APIs # of SQLAlchemy 0.7. 0.8 has better introspection APIs, which we should # use when Nova is ready to require 0.8. + + # NOTE(mikal): this is a little confusing. This method returns the value + # that a _not_deleted_ row would have. deleted_column_type = table.c.deleted.type if isinstance(deleted_column_type, Integer): return 0 diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index 455751809..5556b6eb5 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -39,12 +39,27 @@ class FakeModel(object): def __repr__(self): return '<FakeModel: %s>' % self.values + def get(self, name): + return self.values[name] + def stub_out(stubs, funcs): """Set the stubs in mapping in the db api.""" for func in funcs: func_name = '_'.join(func.__name__.split('_')[1:]) stubs.Set(db, func_name, func) + stubs.Set(db.sqlalchemy.api, func_name, func) + + +fixed_ip_fields = {'id': 0, + 'network_id': 0, + 'address': '192.168.0.100', + 'instance': False, + 'instance_uuid': 'eb57d790-fc60-4119-a51a-f2b0913bdc93', + 'allocated': False, + 'virtual_interface_id': 0, + 'virtual_interface': None, + 'floating_ips': []} def stub_out_db_network_api(stubs): @@ -66,16 +81,6 @@ def stub_out_db_network_api(stubs): 'injected': False, 'vpn_public_address': '192.168.0.2'} - fixed_ip_fields = {'id': 0, - 'network_id': 0, - 'address': '192.168.0.100', - 'instance': False, - 'instance_id': 0, - 'allocated': False, - 'virtual_interface_id': 0, - 'virtual_interface': None, - 'floating_ips': []} - flavor_fields = {'id': 0, 'rxtx_cap': 3} @@ -196,8 +201,11 @@ def stub_out_db_network_api(stubs): def fake_fixed_ip_disassociate_all_by_timeout(context, host, time): return 0 - def fake_fixed_ip_get_by_instance(context, instance_id): - ips = filter(lambda i: i['instance_id'] == instance_id, + def fake_fixed_ip_get_all(context): + return [FakeModel(i) for i in fixed_ips] + + def fake_fixed_ip_get_by_instance(context, instance_uuid): + ips = filter(lambda i: i['instance_uuid'] == instance_uuid, fixed_ips) return [FakeModel(i) for i in ips] @@ -306,6 +314,7 @@ def stub_out_db_network_api(stubs): fake_fixed_ip_create, fake_fixed_ip_disassociate, fake_fixed_ip_disassociate_all_by_timeout, + fake_fixed_ip_get_all, fake_fixed_ip_get_by_instance, fake_fixed_ip_get_by_address, fake_fixed_ip_update, diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py index 3faa26e3b..639c2b487 100644 --- a/nova/tests/test_db_api.py +++ b/nova/tests/test_db_api.py @@ -20,6 +20,7 @@ """Unit tests for the DB API.""" import datetime +import types import uuid as stdlib_uuid from oslo.config import cfg @@ -30,6 +31,7 @@ from sqlalchemy.sql.expression import select from nova import context from nova import db +from nova.db.sqlalchemy import api as sqlalchemy_api from nova import exception from nova.openstack.common.db.sqlalchemy import session as db_session from nova.openstack.common import timeutils @@ -359,6 +361,27 @@ class DbApiTestCase(DbTestCase): fixed_ip_ref = db.fixed_ip_get_by_floating_address(ctxt, floating) self.assertEqual(fixed, fixed_ip_ref['address']) + def test_fixed_ip_get_by_host(self): + ctxt = context.get_admin_context() + + values = {'address': 'fixed1'} + fixed1 = db.fixed_ip_create(ctxt, values) + instance1 = self.create_instances_with_args() + db.fixed_ip_associate(ctxt, 'fixed1', instance1['uuid']) + + values = {'address': 'fixed2'} + fixed2 = db.fixed_ip_create(ctxt, values) + instance2 = self.create_instances_with_args() + db.fixed_ip_associate(ctxt, 'fixed2', instance2['uuid']) + + values = {'address': 'fixed3'} + fixed3 = db.fixed_ip_create(ctxt, values) + instance3 = self.create_instances_with_args(host='host2') + db.fixed_ip_associate(ctxt, 'fixed3', instance3['uuid']) + + result = db.fixed_ip_get_by_host(ctxt, 'host1') + self.assertEqual(2, len(result)) + def test_floating_ip_get_by_fixed_address(self): ctxt = context.get_admin_context() values = {'address': 'fixed'} @@ -1605,6 +1628,26 @@ class AggregateDBApiTestCase(test.TestCase): ctxt, result['id'], _get_fake_aggr_hosts()[0]) +class SqlAlchemyDbApiTestCase(DbTestCase): + def test_instance_get_all_by_host(self): + ctxt = context.get_admin_context() + + self.create_instances_with_args() + self.create_instances_with_args() + self.create_instances_with_args(host='host2') + result = sqlalchemy_api._instance_get_all_uuids_by_host(ctxt, 'host1') + self.assertEqual(2, len(result)) + + def test_instance_get_all_uuids_by_host(self): + ctxt = context.get_admin_context() + self.create_instances_with_args() + self.create_instances_with_args() + self.create_instances_with_args(host='host2') + result = sqlalchemy_api._instance_get_all_uuids_by_host(ctxt, 'host1') + self.assertEqual(2, len(result)) + self.assertEqual(types.UnicodeType, type(result[0])) + + class CapacityTestCase(test.TestCase): def setUp(self): super(CapacityTestCase, self).setUp() diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 3dc5cc5c2..654e68bfc 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -15,6 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. +import fixtures import StringIO import sys @@ -50,6 +51,24 @@ class FixedIpCommandsTestCase(test.TestCase): def test_unreserve_nonexistent_address(self): self.assertEqual(2, self.commands.unreserve('55.55.55.55')) + def test_list(self): + self.useFixture(fixtures.MonkeyPatch('sys.stdout', + StringIO.StringIO())) + self.commands.list() + self.assertTrue(sys.stdout.getvalue().find('192.168.0.100') != -1) + + def test_list_just_one_host(self): + def fake_fixed_ip_get_by_host(*args, **kwargs): + return [db_fakes.fixed_ip_fields] + + self.useFixture(fixtures.MonkeyPatch( + 'nova.db.fixed_ip_get_by_host', + fake_fixed_ip_get_by_host)) + self.useFixture(fixtures.MonkeyPatch('sys.stdout', + StringIO.StringIO())) + self.commands.list('banana') + self.assertTrue(sys.stdout.getvalue().find('192.168.0.100') != -1) + class FloatingIpCommandsTestCase(test.TestCase): def setUp(self): |