add get_by_metadata_key to AggregateList object
This change adds the get_by_metadata_key function to the AggregateList object and the aggregate_get_by_metadata_key function to the DB API. Previously, the only DB API function available for finding aggregates matching a metadata key returned a dictionary of aggregated metadata. The aggregate_get_by_metadata_key function returns all rows matching the specified metadata key, and is called by the existing aggregate_host_get_by_metadata_key DB API function. The get_by_metadata_key function returns a list of Aggregate objects matching the specified metadata key. Related to blueprint compute-manager-objects-juno Change-Id: If50c9f613dd192ab44577f26a81dd5b40e3a7af7
This commit is contained in:
@@ -1769,6 +1769,10 @@ def aggregate_host_get_by_metadata_key(context, key):
|
|||||||
return IMPL.aggregate_host_get_by_metadata_key(context, key)
|
return IMPL.aggregate_host_get_by_metadata_key(context, key)
|
||||||
|
|
||||||
|
|
||||||
|
def aggregate_get_by_metadata_key(context, key):
|
||||||
|
return IMPL.aggregate_get_by_metadata_key(context, key)
|
||||||
|
|
||||||
|
|
||||||
def aggregate_update(context, aggregate_id, values):
|
def aggregate_update(context, aggregate_id, values):
|
||||||
"""Update the attributes of an aggregates.
|
"""Update the attributes of an aggregates.
|
||||||
|
|
||||||
|
|||||||
@@ -5094,13 +5094,7 @@ def aggregate_metadata_get_by_metadata_key(context, aggregate_id, key):
|
|||||||
|
|
||||||
|
|
||||||
def aggregate_host_get_by_metadata_key(context, key):
|
def aggregate_host_get_by_metadata_key(context, key):
|
||||||
query = model_query(context, models.Aggregate)
|
rows = aggregate_get_by_metadata_key(context, key)
|
||||||
query = query.join("_metadata")
|
|
||||||
query = query.filter(models.AggregateMetadata.key == key)
|
|
||||||
query = query.options(contains_eager("_metadata"))
|
|
||||||
query = query.options(joinedload("_hosts"))
|
|
||||||
rows = query.all()
|
|
||||||
|
|
||||||
metadata = collections.defaultdict(set)
|
metadata = collections.defaultdict(set)
|
||||||
for agg in rows:
|
for agg in rows:
|
||||||
for agghost in agg._hosts:
|
for agghost in agg._hosts:
|
||||||
@@ -5108,6 +5102,19 @@ def aggregate_host_get_by_metadata_key(context, key):
|
|||||||
return dict(metadata)
|
return dict(metadata)
|
||||||
|
|
||||||
|
|
||||||
|
def aggregate_get_by_metadata_key(context, key):
|
||||||
|
"""Return rows that match metadata key.
|
||||||
|
|
||||||
|
:param key Matches metadata key.
|
||||||
|
"""
|
||||||
|
query = model_query(context, models.Aggregate)
|
||||||
|
query = query.join("_metadata")
|
||||||
|
query = query.filter(models.AggregateMetadata.key == key)
|
||||||
|
query = query.options(contains_eager("_metadata"))
|
||||||
|
query = query.options(joinedload("_hosts"))
|
||||||
|
return query.all()
|
||||||
|
|
||||||
|
|
||||||
def aggregate_update(context, aggregate_id, values):
|
def aggregate_update(context, aggregate_id, values):
|
||||||
session = get_session()
|
session = get_session()
|
||||||
|
|
||||||
|
|||||||
@@ -151,7 +151,8 @@ class AggregateList(base.ObjectListBase, base.NovaObject):
|
|||||||
# Version 1.0: Initial version
|
# Version 1.0: Initial version
|
||||||
# Version 1.1: Added key argument to get_by_host()
|
# Version 1.1: Added key argument to get_by_host()
|
||||||
# Aggregate <= version 1.1
|
# Aggregate <= version 1.1
|
||||||
VERSION = '1.1'
|
# Version 1.2: Added get_by_metadata_key
|
||||||
|
VERSION = '1.2'
|
||||||
|
|
||||||
fields = {
|
fields = {
|
||||||
'objects': fields.ListOfObjectsField('Aggregate'),
|
'objects': fields.ListOfObjectsField('Aggregate'),
|
||||||
@@ -160,8 +161,21 @@ class AggregateList(base.ObjectListBase, base.NovaObject):
|
|||||||
'1.0': '1.1',
|
'1.0': '1.1',
|
||||||
'1.1': '1.1',
|
'1.1': '1.1',
|
||||||
# NOTE(danms): Aggregate was at 1.1 before we added this
|
# NOTE(danms): Aggregate was at 1.1 before we added this
|
||||||
|
'1.2': '1.1',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _filter_db_aggregates(cls, db_aggregates, hosts):
|
||||||
|
if not isinstance(hosts, set):
|
||||||
|
hosts = set(hosts)
|
||||||
|
filtered_aggregates = []
|
||||||
|
for db_aggregate in db_aggregates:
|
||||||
|
for host in db_aggregate['hosts']:
|
||||||
|
if host in hosts:
|
||||||
|
filtered_aggregates.append(db_aggregate)
|
||||||
|
break
|
||||||
|
return filtered_aggregates
|
||||||
|
|
||||||
@base.remotable_classmethod
|
@base.remotable_classmethod
|
||||||
def get_all(cls, context):
|
def get_all(cls, context):
|
||||||
db_aggregates = db.aggregate_get_all(context)
|
db_aggregates = db.aggregate_get_all(context)
|
||||||
@@ -173,3 +187,11 @@ class AggregateList(base.ObjectListBase, base.NovaObject):
|
|||||||
db_aggregates = db.aggregate_get_by_host(context, host, key=key)
|
db_aggregates = db.aggregate_get_by_host(context, host, key=key)
|
||||||
return base.obj_make_list(context, cls(context), objects.Aggregate,
|
return base.obj_make_list(context, cls(context), objects.Aggregate,
|
||||||
db_aggregates)
|
db_aggregates)
|
||||||
|
|
||||||
|
@base.remotable_classmethod
|
||||||
|
def get_by_metadata_key(cls, context, key, hosts=None):
|
||||||
|
db_aggregates = db.aggregate_get_by_metadata_key(context, key=key)
|
||||||
|
if hosts:
|
||||||
|
db_aggregates = cls._filter_db_aggregates(db_aggregates, hosts)
|
||||||
|
return base.obj_make_list(context, cls(context), objects.Aggregate,
|
||||||
|
db_aggregates)
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
from nova import db
|
from nova import db
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova.objects import aggregate
|
from nova.objects import aggregate
|
||||||
@@ -163,6 +165,29 @@ class _TestAggregateObject(object):
|
|||||||
self.assertEqual(1, len(aggs))
|
self.assertEqual(1, len(aggs))
|
||||||
self.compare_obj(aggs[0], fake_aggregate, subs=SUBS)
|
self.compare_obj(aggs[0], fake_aggregate, subs=SUBS)
|
||||||
|
|
||||||
|
@mock.patch('nova.db.aggregate_get_by_metadata_key')
|
||||||
|
def test_get_by_metadata_key(self, get_by_metadata_key):
|
||||||
|
get_by_metadata_key.return_value = [fake_aggregate]
|
||||||
|
aggs = aggregate.AggregateList.get_by_metadata_key(
|
||||||
|
self.context, 'this')
|
||||||
|
self.assertEqual(1, len(aggs))
|
||||||
|
self.compare_obj(aggs[0], fake_aggregate, subs=SUBS)
|
||||||
|
|
||||||
|
@mock.patch('nova.db.aggregate_get_by_metadata_key')
|
||||||
|
def test_get_by_metadata_key_and_hosts_no_match(self, get_by_metadata_key):
|
||||||
|
get_by_metadata_key.return_value = [fake_aggregate]
|
||||||
|
aggs = aggregate.AggregateList.get_by_metadata_key(
|
||||||
|
self.context, 'this', hosts=['baz'])
|
||||||
|
self.assertEqual(0, len(aggs))
|
||||||
|
|
||||||
|
@mock.patch('nova.db.aggregate_get_by_metadata_key')
|
||||||
|
def test_get_by_metadata_key_and_hosts_match(self, get_by_metadata_key):
|
||||||
|
get_by_metadata_key.return_value = [fake_aggregate]
|
||||||
|
aggs = aggregate.AggregateList.get_by_metadata_key(
|
||||||
|
self.context, 'this', hosts=['foo', 'bar'])
|
||||||
|
self.assertEqual(1, len(aggs))
|
||||||
|
self.compare_obj(aggs[0], fake_aggregate, subs=SUBS)
|
||||||
|
|
||||||
|
|
||||||
class TestAggregateObject(test_objects._LocalTest,
|
class TestAggregateObject(test_objects._LocalTest,
|
||||||
_TestAggregateObject):
|
_TestAggregateObject):
|
||||||
|
|||||||
@@ -895,7 +895,7 @@ object_data = {
|
|||||||
'Agent': '1.0-c4ff8a833aee8ae44ab8aed1a171273d',
|
'Agent': '1.0-c4ff8a833aee8ae44ab8aed1a171273d',
|
||||||
'AgentList': '1.0-f8b860e1f2ce80e676ba1a37ddf86e4f',
|
'AgentList': '1.0-f8b860e1f2ce80e676ba1a37ddf86e4f',
|
||||||
'Aggregate': '1.1-f5d477be06150529a9b2d27cc49030b5',
|
'Aggregate': '1.1-f5d477be06150529a9b2d27cc49030b5',
|
||||||
'AggregateList': '1.1-3e67b6a4840b19c797504cc6056b27ff',
|
'AggregateList': '1.2-504137b7ec3855b00d01f165dcebc23e',
|
||||||
'BlockDeviceMapping': '1.1-9968ffe513e7672484b0f528b034cd0f',
|
'BlockDeviceMapping': '1.1-9968ffe513e7672484b0f528b034cd0f',
|
||||||
'BlockDeviceMappingList': '1.2-d6d7df540ca149dda78b22b4b10bdef3',
|
'BlockDeviceMappingList': '1.2-d6d7df540ca149dda78b22b4b10bdef3',
|
||||||
'ComputeNode': '1.3-b3b8935a99ca48621dc9ba271d5ed668',
|
'ComputeNode': '1.3-b3b8935a99ca48621dc9ba271d5ed668',
|
||||||
|
|||||||
Reference in New Issue
Block a user