summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEldar Nugaev <enugaev@griddynamics.com>2010-12-29 19:51:25 +0300
committerEldar Nugaev <enugaev@griddynamics.com>2010-12-29 19:51:25 +0300
commitd30ec2b5814480010d1b42ce2e9bed9fbc441fd1 (patch)
tree20a3a0821411b97178f096211bea44fff35855bb
parent0dd84453db5d8a3293421049b92385b00a602fc3 (diff)
downloadnova-d30ec2b5814480010d1b42ce2e9bed9fbc441fd1.tar.gz
nova-d30ec2b5814480010d1b42ce2e9bed9fbc441fd1.tar.xz
nova-d30ec2b5814480010d1b42ce2e9bed9fbc441fd1.zip
Added implementation availability_zones to EC2 API
-rw-r--r--nova/api/ec2/cloud.py25
-rw-r--r--nova/db/api.py7
-rw-r--r--nova/db/sqlalchemy/api.py14
-rw-r--r--nova/flags.py1
-rw-r--r--nova/tests/test_cloud.py17
5 files changed, 55 insertions, 9 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 66060bbfc..0c20ef329 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -138,6 +138,9 @@ class CloudController(object):
{"method": "refresh_security_group",
"args": {"security_group_id": security_group.id}})
+ def _get_availability_zone_by_host(self, context, hostname):
+ return db.service_get_all_compute_by_host(context, hostname)[0]['availability_zone']
+
def get_metadata(self, address):
ctxt = context.get_admin_context()
instance_ref = db.fixed_ip_get_instance(ctxt, address)
@@ -150,6 +153,7 @@ class CloudController(object):
else:
keys = ''
hostname = instance_ref['hostname']
+ availability_zone = self._get_availability_zone_by_host(ctxt, hostname)
floating_ip = db.instance_get_floating_address(ctxt,
instance_ref['id'])
ec2_id = internal_id_to_ec2_id(instance_ref['internal_id'])
@@ -172,8 +176,7 @@ class CloudController(object):
'local-hostname': hostname,
'local-ipv4': address,
'kernel-id': instance_ref['kernel_id'],
- # TODO(vish): real zone
- 'placement': {'availability-zone': 'nova'},
+ 'placement': {'availability-zone': availability_zone},
'public-hostname': hostname,
'public-ipv4': floating_ip or '',
'public-keys': keys,
@@ -188,8 +191,20 @@ class CloudController(object):
return data
def describe_availability_zones(self, context, **kwargs):
- return {'availabilityZoneInfo': [{'zoneName': 'nova',
- 'zoneState': 'available'}]}
+ enabled_services = db.service_get_all_by_topic(context, 'compute')
+ disabled_services = db.service_get_all_by_topic(context, 'compute', True)
+ available_zones = [service.availability_zone for service in enabled_services]
+ not_available_zones = [service.availability_zone for service in disabled_services
+ and not service['availability_zone'] in available_zones]
+
+ result = []
+ for zone in available_zones:
+ result.append({'zoneName': zone,
+ 'zoneState': "available"})
+ for zone in not_available_zones:
+ result.append({'zoneName': zone,
+ 'zoneState': "not available"})
+ return {'availabilityZoneInfo': result}
def describe_regions(self, context, region_name=None, **kwargs):
if FLAGS.region_list:
@@ -660,6 +675,8 @@ class CloudController(object):
r['groupSet'] = self._convert_to_set([], 'groups')
r['instancesSet'] = []
reservations[instance['reservation_id']] = r
+ availability_zone = self._get_availability_zone_by_host(ctxt, instance['hostname'])
+ i['placement'] = {'availabilityZone': availability_zone}
reservations[instance['reservation_id']]['instancesSet'].append(i)
return list(reservations.values())
diff --git a/nova/db/api.py b/nova/db/api.py
index fde3f0852..c0cab1068 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -76,10 +76,13 @@ def service_get(context, service_id):
return IMPL.service_get(context, service_id)
-def service_get_all_by_topic(context, topic):
+def service_get_all_by_topic(context, topic, disabled=False):
"""Get all compute services for a given topic."""
- return IMPL.service_get_all_by_topic(context, topic)
+ return IMPL.service_get_all_by_topic(context, topic, disabled)
+def service_get_all_compute_by_host(context, host):
+ """Get all compute service for a given host"""
+ return IMPL.service_get_all_compute_by_host(context, host)
def service_get_all_compute_sorted(context):
"""Get all compute services sorted by instance count.
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 7e945e4cb..55c3c5594 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -136,11 +136,11 @@ def service_get(context, service_id, session=None):
@require_admin_context
-def service_get_all_by_topic(context, topic):
+def service_get_all_by_topic(context, topic, disabled=False):
session = get_session()
return session.query(models.Service).\
filter_by(deleted=False).\
- filter_by(disabled=False).\
+ filter_by(disabled=disabled).\
filter_by(topic=topic).\
all()
@@ -156,6 +156,16 @@ def _service_get_all_topic_subquery(context, session, topic, subq, label):
order_by(sort_value).\
all()
+@require_admin_context
+def service_get_all_compute_by_host(context, host):
+ session = get_session()
+ topic = 'compute'
+ return session.query(models.Service).\
+ filter_by(host=host).\
+ filter_by(deleted=False).\
+ filter_by(topic=topic).\
+ all()
+
@require_admin_context
def service_get_all_compute_sorted(context):
diff --git a/nova/flags.py b/nova/flags.py
index 76a98d35a..b157c9e5d 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -277,6 +277,5 @@ DEFINE_string('image_service', 'nova.image.s3.S3ImageService',
DEFINE_string('host', socket.gethostname(),
'name of this node')
-# UNUSED
DEFINE_string('node_availability_zone', 'nova',
'availability zone of this node')
diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py
index 70d2c44da..d7e99b3c8 100644
--- a/nova/tests/test_cloud.py
+++ b/nova/tests/test_cloud.py
@@ -133,6 +133,23 @@ class CloudTestCase(test.TestCase):
db.volume_destroy(self.context, vol1['id'])
db.volume_destroy(self.context, vol2['id'])
+ def test_describe_availability_zones(self):
+ """Makes sure describe_availability_zones works and filters results."""
+ service1 = db.service_create(self.context, {'host': 'host1_describe_zones',
+ 'binary': "nova-compute",
+ 'topic': 'compute',
+ 'report_count': 0,
+ 'availability_zone': "zone1"})
+ service2 = db.service_create(self.context, {'host': 'host2_describe_zones',
+ 'binary': "nova-compute",
+ 'topic': 'compute',
+ 'report_count': 0,
+ 'availability_zone': "zone2"})
+ result = self.cloud.describe_availability_zones(self.context)
+ self.assertEqual(len(result['availabilityZoneInfo']), 3)
+ db.service_destroy(self.context, service1['id'])
+ db.service_destroy(self.context, service2['id'])
+
def test_console_output(self):
image_id = FLAGS.default_image
instance_type = FLAGS.default_instance_type