summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvladimir.p <vladimir@zadarastorage.com>2011-08-11 12:04:03 -0700
committervladimir.p <vladimir@zadarastorage.com>2011-08-11 12:04:03 -0700
commit57b8f976f18b1f45de16ef8e87a6e215c009d228 (patch)
tree73fafd8fcc9b855c627e1a9062ce18cd975e0b62
parent820d28dcf09088b5878d4cd5dcb5f4765e0b4992 (diff)
moved vsa_id to metadata. Added search my meta
-rw-r--r--nova/db/sqlalchemy/api.py33
-rw-r--r--nova/tests/test_compute.py63
-rw-r--r--nova/vsa/api.py3
-rw-r--r--nova/vsa/manager.py1
4 files changed, 87 insertions, 13 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index bc1a3046c..b77f11abb 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1175,6 +1175,19 @@ def instance_get_all_by_filters(context, filters):
return True
return False
+ def _regexp_filter_by_metadata(instance, meta):
+ inst_metadata = [{node['key']: node['value']} \
+ for node in instance['metadata']]
+ if isinstance(meta, list):
+ for node in meta:
+ if node not in inst_metadata:
+ return False
+ elif isinstance(meta, dict):
+ for k, v in meta.iteritems():
+ if {k: v} not in inst_metadata:
+ return False
+ return True
+
def _regexp_filter_by_column(instance, filter_name, filter_re):
try:
v = getattr(instance, filter_name)
@@ -1232,7 +1245,9 @@ def instance_get_all_by_filters(context, filters):
query_prefix = _exact_match_filter(query_prefix, filter_name,
filters.pop(filter_name))
- instances = query_prefix.all()
+ instances = query_prefix.\
+ filter_by(deleted=can_read_deleted(context)).\
+ all()
if not instances:
return []
@@ -1248,6 +1263,9 @@ def instance_get_all_by_filters(context, filters):
filter_re = re.compile(str(filters[filter_name]))
if filter_func:
filter_l = lambda instance: filter_func(instance, filter_re)
+ elif filter_name == 'metadata':
+ filter_l = lambda instance: _regexp_filter_by_metadata(instance,
+ filters[filter_name])
else:
filter_l = lambda instance: _regexp_filter_by_column(instance,
filter_name, filter_re)
@@ -3718,16 +3736,9 @@ def vsa_get_vc_ips_list(context, vsa_id):
Retrieves IPs of instances associated with Virtual Storage Array.
"""
result = []
- session = get_session()
- """ VP-TODO: CHANGE THIS!!! Need to perform a search based on meta-data """
- vc_instances = session.query(models.Instance).\
- options(joinedload_all('fixed_ips.floating_ips')).\
- options(joinedload('security_groups')).\
- options(joinedload_all('fixed_ips.network')).\
- options(joinedload('instance_type')).\
- filter_by(vsa_id=vsa_id).\
- filter_by(deleted=False).\
- all()
+
+ vc_instances = instance_get_all_by_filters(context,
+ search_opts={'metadata': dict(vsa_id=str(vsa_id))})
for vc_instance in vc_instances:
if vc_instance['fixed_ips']:
for fixed in vc_instance['fixed_ips']:
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index 80f7ff489..661acc980 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -1320,6 +1320,69 @@ class ComputeTestCase(test.TestCase):
db.instance_destroy(c, instance_id2)
db.instance_destroy(c, instance_id3)
+ def test_get_all_by_metadata(self):
+ """Test searching instances by metadata"""
+
+ c = context.get_admin_context()
+ instance_id0 = self._create_instance()
+ instance_id1 = self._create_instance({
+ 'metadata': {'key1': 'value1'}})
+ instance_id2 = self._create_instance({
+ 'metadata': {'key2': 'value2'}})
+ instance_id3 = self._create_instance({
+ 'metadata': {'key3': 'value3'}})
+ instance_id4 = self._create_instance({
+ 'metadata': {'key3': 'value3',
+ 'key4': 'value4'}})
+
+ # get all instances
+ instances = self.compute_api.get_all(c,
+ search_opts={'metadata': {}})
+ self.assertEqual(len(instances), 5)
+
+ # wrong key/value combination
+ instances = self.compute_api.get_all(c,
+ search_opts={'metadata': {'key1': 'value3'}})
+ self.assertEqual(len(instances), 0)
+
+ # non-existing keys
+ instances = self.compute_api.get_all(c,
+ search_opts={'metadata': {'key5': 'value1'}})
+ self.assertEqual(len(instances), 0)
+
+ # find existing instance
+ instances = self.compute_api.get_all(c,
+ search_opts={'metadata': {'key2': 'value2'}})
+ self.assertEqual(len(instances), 1)
+ self.assertEqual(instances[0].id, instance_id2)
+
+ instances = self.compute_api.get_all(c,
+ search_opts={'metadata': {'key3': 'value3'}})
+ self.assertEqual(len(instances), 2)
+ instance_ids = [instance.id for instance in instances]
+ self.assertTrue(instance_id3 in instance_ids)
+ self.assertTrue(instance_id4 in instance_ids)
+
+ # multiple criterias as a dict
+ instances = self.compute_api.get_all(c,
+ search_opts={'metadata': {'key3': 'value3',
+ 'key4': 'value4'}})
+ self.assertEqual(len(instances), 1)
+ self.assertEqual(instances[0].id, instance_id4)
+
+ # multiple criterias as a list
+ instances = self.compute_api.get_all(c,
+ search_opts={'metadata': [{'key4': 'value4'},
+ {'key3': 'value3'}]})
+ self.assertEqual(len(instances), 1)
+ self.assertEqual(instances[0].id, instance_id4)
+
+ db.instance_destroy(c, instance_id0)
+ db.instance_destroy(c, instance_id1)
+ db.instance_destroy(c, instance_id2)
+ db.instance_destroy(c, instance_id3)
+ db.instance_destroy(c, instance_id4)
+
@staticmethod
def _parse_db_block_device_mapping(bdm_ref):
attr_list = ('delete_on_termination', 'device_name', 'no_device',
diff --git a/nova/vsa/api.py b/nova/vsa/api.py
index 00ab96162..3588e58cc 100644
--- a/nova/vsa/api.py
+++ b/nova/vsa/api.py
@@ -355,7 +355,8 @@ class API(base.Base):
self.delete_vsa_volumes(context, vsa_id, "BE", force_delete=True)
# Delete all VC instances
- instances = self.db.instance_get_all_by_vsa(context, vsa_id)
+ instances = self.compute_api.get_all(context,
+ search_opts={'metadata': dict(vsa_id=str(vsa_id))})
for instance in instances:
name = instance['name']
LOG.debug(_("VSA ID %(vsa_id)s: Delete instance %(name)s"),
diff --git a/nova/vsa/manager.py b/nova/vsa/manager.py
index 1d17340f2..d98d0fcb2 100644
--- a/nova/vsa/manager.py
+++ b/nova/vsa/manager.py
@@ -173,7 +173,6 @@ class VsaManager(manager.SchedulerDependentManager):
display_description='VC for VSA ' + vsa['display_name'],
availability_zone=vsa['availability_zone'],
user_data=storage_data,
- vsa_id=vsa_id,
metadata=dict(vsa_id=str(vsa_id)))
self.vsa_api.update_vsa_status(context, vsa_id, VsaState.CREATED)