Skip to content

Commit

Permalink
Retrieve the list of availability zones from nova in Fn::GetAZs
Browse files Browse the repository at this point in the history
Fixes: bug #1096001
Change-Id: Ie5c46ae038dff4f53ba8d722e878583044bd194c
  • Loading branch information
therve committed May 1, 2013
1 parent a0df512 commit a955708
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 12 deletions.
18 changes: 14 additions & 4 deletions heat/engine/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class Stack(object):
created_time = timestamp.Timestamp(db_api.stack_get, 'created_at')
updated_time = timestamp.Timestamp(db_api.stack_get, 'updated_at')

_zones = None

def __init__(self, context, stack_name, tmpl, parameters=None,
stack_id=None, state=None, state_description='',
timeout_mins=60, resolve_data=True, disable_rollback=True):
Expand Down Expand Up @@ -558,28 +560,36 @@ def restart_resource(self, resource_name):
# TODO(asalkeld) if any of this fails we Should
# restart the whole stack

def get_availability_zones(self):
if self._zones is None:
self._zones = [
zone.zoneName for zone in
self.clients.nova().availability_zones.list(detailed=False)]
return self._zones

def resolve_static_data(self, snippet):
return resolve_static_data(self.t, self.parameters, snippet)
return resolve_static_data(self.t, self, self.parameters, snippet)

def resolve_runtime_data(self, snippet):
return resolve_runtime_data(self.t, self.resources, snippet)


def resolve_static_data(template, parameters, snippet):
def resolve_static_data(template, stack, parameters, snippet):
'''
Resolve static parameters, map lookups, etc. in a template.
Example:
>>> template = Template(template_format.parse(template_path))
>>> parameters = Parameters('stack', template, {'KeyName': 'my_key'})
>>> resolve_static_data(template, parameters, {'Ref': 'KeyName'})
>>> resolve_static_data(template, None, parameters, {'Ref': 'KeyName'})
'my_key'
'''
return transform(snippet,
[functools.partial(template.resolve_param_refs,
parameters=parameters),
template.resolve_availability_zones,
functools.partial(template.resolve_availability_zones,
stack=stack),
template.resolve_find_in_map,
template.reduce_joins])

Expand Down
7 changes: 5 additions & 2 deletions heat/engine/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def handle_find_in_map(args):
handle_find_in_map, s)

@staticmethod
def resolve_availability_zones(s):
def resolve_availability_zones(s, stack):
'''
looking for { "Fn::GetAZs" : "str" }
'''
Expand All @@ -98,7 +98,10 @@ def match_get_az(key, value):
isinstance(value, basestring))

def handle_get_az(ref):
return ['nova']
if stack is None:
return ['nova']
else:
return stack.get_availability_zones()

return _resolve(match_get_az, handle_get_az, s)

Expand Down
6 changes: 6 additions & 0 deletions heat/tests/test_autoscaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
from heat.engine.resources import autoscaling as asc
from heat.engine.resources import loadbalancer
from heat.engine.resources import instance
from heat.engine import clients
from heat.engine import parser
from heat.engine import scheduler
from heat.engine.resource import Metadata
from heat.openstack.common import timeutils
from heat.tests.v1_1 import fakes
from heat.tests.common import HeatTestCase
from heat.tests.utils import setup_dummy_db

Expand All @@ -37,6 +39,9 @@ class AutoScalingTest(HeatTestCase):
def setUp(self):
super(AutoScalingTest, self).setUp()
setup_dummy_db()
self.fc = fakes.FakeClient()
self.m.StubOutWithMock(clients.OpenStackClients, 'nova')
clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc)

def load_template(self):
self.path = os.path.dirname(os.path.realpath(__file__)).\
Expand All @@ -47,6 +52,7 @@ def load_template(self):
return t

def parse_stack(self, t):
self.m.ReplayAll()
ctx = context.RequestContext.from_dict({
'tenant': 'test_tenant',
'username': 'test_username',
Expand Down
4 changes: 4 additions & 0 deletions heat/tests/test_instance_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from heat.engine.resources import autoscaling as asc
from heat.engine.resources import instance
from heat.engine.resources import loadbalancer
from heat.engine import clients
from heat.engine import parser
from heat.engine import scheduler
from heat.tests.common import HeatTestCase
Expand All @@ -37,6 +38,8 @@ def setUp(self):
self.fc = fakes.FakeClient()
self.m.StubOutWithMock(loadbalancer.LoadBalancer, 'reload')
setup_dummy_db()
self.m.StubOutWithMock(clients.OpenStackClients, 'nova')
clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc)

def load_template(self):
self.path = os.path.dirname(os.path.realpath(__file__)).\
Expand All @@ -47,6 +50,7 @@ def load_template(self):
return t

def parse_stack(self, t):
self.m.ReplayAll()
ctx = context.RequestContext.from_dict({
'tenant': 'test_tenant',
'username': 'test_username',
Expand Down
11 changes: 5 additions & 6 deletions heat/tests/test_loadbalancer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from heat.common import config
from heat.common import context
from heat.common import template_format
from heat.engine import clients
from heat.engine import parser
from heat.engine import scheduler
from heat.engine.resources import instance
Expand Down Expand Up @@ -50,8 +51,7 @@ def setUp(self):
super(LoadBalancerTest, self).setUp()
config.register_engine_opts()
self.fc = fakes.FakeClient()
self.m.StubOutWithMock(lb.LoadBalancer, 'nova')
self.m.StubOutWithMock(instance.Instance, 'nova')
self.m.StubOutWithMock(clients.OpenStackClients, 'nova')
self.m.StubOutWithMock(self.fc.servers, 'create')
self.m.StubOutWithMock(Metadata, '__set__')
self.fkc = test_fakes.FakeKeystoneClient(
Expand Down Expand Up @@ -96,8 +96,9 @@ def test_loadbalancer(self):
self.m.StubOutWithMock(wc.WaitConditionHandle, 'keystone')
wc.WaitConditionHandle.keystone().MultipleTimes().AndReturn(self.fkc)

lb.LoadBalancer.nova().AndReturn(self.fc)
instance.Instance.nova().MultipleTimes().AndReturn(self.fc)
clients.OpenStackClients.nova(
"compute").MultipleTimes().AndReturn(self.fc)
clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc)
self.fc.servers.create(
flavor=2, image=745, key_name='test',
meta=None, nics=None, name=u'test_stack.LoadBalancer.LB_instance',
Expand All @@ -107,8 +108,6 @@ def test_loadbalancer(self):
Metadata.__set__(mox.IgnoreArg(),
mox.IgnoreArg()).MultipleTimes().AndReturn(None)

lb.LoadBalancer.nova().MultipleTimes().AndReturn(self.fc)

self.m.StubOutWithMock(wc.WaitConditionHandle, 'get_status')
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS'])
self.m.ReplayAll()
Expand Down
19 changes: 19 additions & 0 deletions heat/tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@
from heat.common import context
from heat.common import exception
from heat.common import template_format
from heat.engine import clients
from heat.engine import resource
from heat.engine import parser
from heat.engine import parameters
from heat.engine import template

from heat.tests.common import HeatTestCase
from heat.tests.utils import setup_dummy_db
from heat.tests.v1_1 import fakes
from heat.tests.utils import stack_delete_after
from heat.tests import generic_resource as generic_rsrc

Expand Down Expand Up @@ -280,6 +282,23 @@ def test_base64_dict(self):
self.assertRaises(TypeError, parser.Template.resolve_base64,
dict_snippet)

def test_get_azs(self):
snippet = {"Fn::GetAZs": ""}
self.assertEqual(
parser.Template.resolve_availability_zones(snippet, None),
["nova"])

def test_get_azs_with_stack(self):
snippet = {"Fn::GetAZs": ""}
stack = parser.Stack(None, 'test_stack', parser.Template({}))
self.m.StubOutWithMock(clients.OpenStackClients, 'nova')
fc = fakes.FakeClient()
clients.OpenStackClients.nova().MultipleTimes().AndReturn(fc)
self.m.ReplayAll()
self.assertEqual(
parser.Template.resolve_availability_zones(snippet, stack),
["nova1"])


class StackTest(HeatTestCase):
def setUp(self):
Expand Down
3 changes: 3 additions & 0 deletions heat/tests/v1_1/fakes.py
Original file line number Diff line number Diff line change
Expand Up @@ -821,3 +821,6 @@ def put_os_hosts_sample_host(self, body, **kw):
result = {'host': 'dummy'}
result.update(body)
return (200, result)

def get_os_availability_zone(self, *kw):
return (200, {"availabilityZoneInfo": [{'zoneName': 'nova1'}]})

0 comments on commit a955708

Please sign in to comment.