object-ify availability_zones
This change converts availability_zones to use the Aggregate and Service objects instead of direct database access. Related to blueprint compute-manager-objects-juno Change-Id: I2ec7373f063ed728dde2af3b7c8259f4391885bc
This commit is contained in:
parent
a167654eb3
commit
a15fa17efc
|
@ -15,9 +15,11 @@
|
|||
|
||||
"""Availability zone helper functions."""
|
||||
|
||||
import collections
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from nova import db
|
||||
from nova import objects
|
||||
from nova.openstack.common import memorycache
|
||||
|
||||
# NOTE(vish): azs don't change that often, so cache them for an hour to
|
||||
|
@ -61,11 +63,34 @@ def _make_cache_key(host):
|
|||
return "azcache-%s" % host.encode('utf-8')
|
||||
|
||||
|
||||
def _build_metadata_by_host(aggregates, hosts=None):
|
||||
if hosts and not isinstance(hosts, set):
|
||||
hosts = set(hosts)
|
||||
metadata = collections.defaultdict(set)
|
||||
for aggregate in aggregates:
|
||||
for host in aggregate.hosts:
|
||||
if hosts and host not in hosts:
|
||||
continue
|
||||
metadata[host].add(aggregate.metadata.values()[0])
|
||||
return metadata
|
||||
|
||||
|
||||
def _build_metadata_by_key(aggregates):
|
||||
metadata = collections.defaultdict(set)
|
||||
for aggregate in aggregates:
|
||||
for key, value in aggregate.metadata.iteritems():
|
||||
metadata[key].add(value)
|
||||
return metadata
|
||||
|
||||
|
||||
def set_availability_zones(context, services):
|
||||
# Makes sure services isn't a sqlalchemy object
|
||||
services = [dict(service.iteritems()) for service in services]
|
||||
metadata = db.aggregate_host_get_by_metadata_key(context,
|
||||
key='availability_zone')
|
||||
hosts = set([service['host'] for service in services])
|
||||
aggregates = objects.AggregateList.get_by_metadata_key(context,
|
||||
'availability_zone', hosts=hosts)
|
||||
metadata = _build_metadata_by_host(aggregates, hosts=hosts)
|
||||
# gather all of the availability zones associated with a service host
|
||||
for service in services:
|
||||
az = CONF.internal_service_availability_zone
|
||||
if service['topic'] == "compute":
|
||||
|
@ -85,8 +110,9 @@ def get_host_availability_zone(context, host, conductor_api=None):
|
|||
metadata = conductor_api.aggregate_metadata_get_by_host(
|
||||
context, host, key='availability_zone')
|
||||
else:
|
||||
metadata = db.aggregate_metadata_get_by_host(
|
||||
context, host, key='availability_zone')
|
||||
aggregates = objects.AggregateList.get_by_host(context, host,
|
||||
key='availability_zone')
|
||||
metadata = _build_metadata_by_key(aggregates)
|
||||
if 'availability_zone' in metadata:
|
||||
az = list(metadata['availability_zone'])[0]
|
||||
else:
|
||||
|
@ -114,7 +140,7 @@ def get_availability_zones(context, get_only_available=False,
|
|||
:param with_hosts: whether to return hosts part of the AZs
|
||||
:type with_hosts: bool
|
||||
"""
|
||||
enabled_services = db.service_get_all(context, False)
|
||||
enabled_services = objects.ServiceList.get_all(context, disabled=False)
|
||||
enabled_services = set_availability_zones(context, enabled_services)
|
||||
|
||||
available_zones = []
|
||||
|
@ -130,7 +156,7 @@ def get_availability_zones(context, get_only_available=False,
|
|||
available_zones = list(_available_zones.items())
|
||||
|
||||
if not get_only_available:
|
||||
disabled_services = db.service_get_all(context, True)
|
||||
disabled_services = objects.ServiceList.get_all(context, disabled=True)
|
||||
disabled_services = set_availability_zones(context, disabled_services)
|
||||
not_available_zones = []
|
||||
azs = available_zones if not with_hosts else dict(available_zones)
|
||||
|
|
|
@ -25,18 +25,20 @@ from nova import servicegroup
|
|||
from nova import test
|
||||
from nova.tests.api.openstack import fakes
|
||||
from nova.tests import matchers
|
||||
from nova.tests.objects import test_service
|
||||
|
||||
|
||||
def fake_service_get_all(context, disabled=None):
|
||||
def __fake_service(binary, availability_zone,
|
||||
created_at, updated_at, host, disabled):
|
||||
return {'binary': binary,
|
||||
'availability_zone': availability_zone,
|
||||
'available_zones': availability_zone,
|
||||
'created_at': created_at,
|
||||
'updated_at': updated_at,
|
||||
'host': host,
|
||||
'disabled': disabled}
|
||||
return dict(test_service.fake_service,
|
||||
binary=binary,
|
||||
availability_zone=availability_zone,
|
||||
available_zones=availability_zone,
|
||||
created_at=created_at,
|
||||
updated_at=updated_at,
|
||||
host=host,
|
||||
disabled=disabled)
|
||||
|
||||
if disabled:
|
||||
return [__fake_service("nova-compute", "zone-2",
|
||||
|
|
|
@ -16,6 +16,7 @@ import mock
|
|||
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova.objects import aggregate
|
||||
from nova.objects import service
|
||||
from nova.openstack.common import timeutils
|
||||
from nova.tests.objects import test_compute_node
|
||||
|
@ -163,12 +164,17 @@ class _TestServiceObject(object):
|
|||
|
||||
def test_get_all_with_az(self):
|
||||
self.mox.StubOutWithMock(db, 'service_get_all')
|
||||
self.mox.StubOutWithMock(db, 'aggregate_host_get_by_metadata_key')
|
||||
self.mox.StubOutWithMock(aggregate.AggregateList,
|
||||
'get_by_metadata_key')
|
||||
db.service_get_all(self.context, disabled=None).AndReturn(
|
||||
[dict(fake_service, topic='compute')])
|
||||
db.aggregate_host_get_by_metadata_key(
|
||||
self.context, key='availability_zone').AndReturn(
|
||||
{fake_service['host']: ['test-az']})
|
||||
agg = aggregate.Aggregate()
|
||||
agg.name = 'foo'
|
||||
agg.metadata = {'availability_zone': 'test-az'}
|
||||
agg.create(self.context)
|
||||
agg.hosts = [fake_service['host']]
|
||||
aggregate.AggregateList.get_by_metadata_key(self.context,
|
||||
'availability_zone', hosts=set(agg.hosts)).AndReturn([agg])
|
||||
self.mox.ReplayAll()
|
||||
services = service.ServiceList.get_all(self.context, set_zones=True)
|
||||
self.assertEqual(1, len(services))
|
||||
|
|
Loading…
Reference in New Issue