heat engine : WaitCondition add Handle property validation
Add validation to the Handle property for WaitCondition, so we check that the identifier in the provided URL maps to a WaitConditionHandle resource in the same stack as the WaitCondition fixes bug 1100754 Change-Id: I44c8f52435016fad5a35183472d2b0df26c1915d
This commit is contained in:
parent
7574ce87bc
commit
c751abc05d
@ -204,6 +204,26 @@ class WaitCondition(resource.Resource):
|
||||
self.timeout / self.SLEEP_DIV),
|
||||
self.MIN_SLEEP)
|
||||
|
||||
def _validate_handle_url(self):
|
||||
handle_url = self.properties['Handle']
|
||||
handle_id = identifier.ResourceIdentifier.from_arn_url(handle_url)
|
||||
if handle_id.tenant != self.stack.context.tenant_id:
|
||||
raise ValueError("WaitCondition invalid Handle tenant %s" %
|
||||
handle_id.tenant)
|
||||
if handle_id.stack_name != self.stack.name:
|
||||
raise ValueError("WaitCondition invalid Handle stack %s" %
|
||||
handle_id.stack_name)
|
||||
if handle_id.stack_id != self.stack.id:
|
||||
raise ValueError("WaitCondition invalid Handle stack %s" %
|
||||
handle_id.stack_id)
|
||||
if handle_id.resource_name not in self.stack:
|
||||
raise ValueError("WaitCondition invalid Handle %s" %
|
||||
handle_id.resource_name)
|
||||
if not isinstance(self.stack[handle_id.resource_name],
|
||||
WaitConditionHandle):
|
||||
raise ValueError("WaitCondition invalid Handle %s" %
|
||||
handle_id.resource_name)
|
||||
|
||||
def _get_handle_resource_name(self):
|
||||
handle_url = self.properties['Handle']
|
||||
handle_id = identifier.ResourceIdentifier.from_arn_url(handle_url)
|
||||
@ -213,6 +233,7 @@ class WaitCondition(resource.Resource):
|
||||
return eventlet.Timeout(self.timeout)
|
||||
|
||||
def handle_create(self):
|
||||
self._validate_handle_url()
|
||||
tmo = None
|
||||
status = FAILURE
|
||||
reason = "Unknown reason"
|
||||
|
@ -17,6 +17,7 @@ import mox
|
||||
import uuid
|
||||
import time
|
||||
import datetime
|
||||
import json
|
||||
|
||||
import eventlet
|
||||
import unittest
|
||||
@ -96,22 +97,26 @@ class WaitConditionTest(unittest.TestCase):
|
||||
# Note tests creating a stack should be decorated with @stack_delete_after
|
||||
# to ensure the stack is properly cleaned up
|
||||
def create_stack(self, stack_name='test_stack',
|
||||
template=test_template_waitcondition, params={}):
|
||||
template=test_template_waitcondition, params={},
|
||||
stub=True):
|
||||
temp = template_format.parse(template)
|
||||
template = parser.Template(temp)
|
||||
parameters = parser.Parameters(stack_name, template, params)
|
||||
stack = parser.Stack(context.get_admin_context(), stack_name,
|
||||
template, parameters)
|
||||
ctx = context.get_admin_context()
|
||||
ctx.tenant_id = 'test_tenant'
|
||||
stack = parser.Stack(ctx, stack_name, template, parameters)
|
||||
|
||||
stack.store()
|
||||
self.stack_id = stack.store()
|
||||
|
||||
self.m.StubOutWithMock(wc.WaitConditionHandle, 'keystone')
|
||||
wc.WaitConditionHandle.keystone().MultipleTimes().AndReturn(self.fc)
|
||||
if stub:
|
||||
self.m.StubOutWithMock(wc.WaitConditionHandle, 'keystone')
|
||||
wc.WaitConditionHandle.keystone().MultipleTimes().AndReturn(
|
||||
self.fc)
|
||||
|
||||
id = identifier.ResourceIdentifier('test_tenant', stack.name,
|
||||
stack.id, '', 'WaitHandle')
|
||||
self.m.StubOutWithMock(wc.WaitConditionHandle, 'identifier')
|
||||
wc.WaitConditionHandle.identifier().MultipleTimes().AndReturn(id)
|
||||
id = identifier.ResourceIdentifier('test_tenant', stack.name,
|
||||
stack.id, '', 'WaitHandle')
|
||||
self.m.StubOutWithMock(wc.WaitConditionHandle, 'identifier')
|
||||
wc.WaitConditionHandle.identifier().MultipleTimes().AndReturn(id)
|
||||
|
||||
return stack
|
||||
|
||||
@ -263,6 +268,113 @@ class WaitConditionTest(unittest.TestCase):
|
||||
self.assertEqual(wc_att, u'{"123": "foo", "456": "dog"}')
|
||||
self.m.VerifyAll()
|
||||
|
||||
@stack_delete_after
|
||||
def test_validate_handle_url_bad_stackid(self):
|
||||
# Stub out the stack ID so we have a known value
|
||||
stack_id = 'STACKABCD1234'
|
||||
self.m.StubOutWithMock(uuid, 'uuid4')
|
||||
uuid.uuid4().AndReturn(stack_id)
|
||||
self.m.ReplayAll()
|
||||
|
||||
t = json.loads(test_template_waitcondition)
|
||||
badhandle = ("http://127.0.0.1:8000/v1/waitcondition/" +
|
||||
"arn%3Aopenstack%3Aheat%3A%3Atest_tenant" +
|
||||
"%3Astacks%2Ftest_stack%2F" +
|
||||
"bad1" +
|
||||
"%2Fresources%2FWaitHandle")
|
||||
t['Resources']['WaitForTheHandle']['Properties']['Handle'] = badhandle
|
||||
self.stack = self.create_stack(template=json.dumps(t), stub=False)
|
||||
self.m.ReplayAll()
|
||||
|
||||
resource = self.stack.resources['WaitForTheHandle']
|
||||
self.assertRaises(ValueError, resource.handle_create)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
@stack_delete_after
|
||||
def test_validate_handle_url_bad_stackname(self):
|
||||
# Stub out the stack ID so we have a known value
|
||||
stack_id = 'STACKABCD1234'
|
||||
self.m.StubOutWithMock(uuid, 'uuid4')
|
||||
uuid.uuid4().AndReturn(stack_id)
|
||||
self.m.ReplayAll()
|
||||
|
||||
t = json.loads(test_template_waitcondition)
|
||||
badhandle = ("http://127.0.0.1:8000/v1/waitcondition/" +
|
||||
"arn%3Aopenstack%3Aheat%3A%3Atest_tenant" +
|
||||
"%3Astacks%2FBAD_stack%2F" +
|
||||
stack_id + "%2Fresources%2FWaitHandle")
|
||||
t['Resources']['WaitForTheHandle']['Properties']['Handle'] = badhandle
|
||||
self.stack = self.create_stack(template=json.dumps(t), stub=False)
|
||||
|
||||
resource = self.stack.resources['WaitForTheHandle']
|
||||
self.assertRaises(ValueError, resource.handle_create)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
@stack_delete_after
|
||||
def test_validate_handle_url_bad_tenant(self):
|
||||
# Stub out the stack ID so we have a known value
|
||||
stack_id = 'STACKABCD1234'
|
||||
self.m.StubOutWithMock(uuid, 'uuid4')
|
||||
uuid.uuid4().AndReturn(stack_id)
|
||||
self.m.ReplayAll()
|
||||
|
||||
t = json.loads(test_template_waitcondition)
|
||||
badhandle = ("http://127.0.0.1:8000/v1/waitcondition/" +
|
||||
"arn%3Aopenstack%3Aheat%3A%3ABAD_tenant" +
|
||||
"%3Astacks%2Ftest_stack%2F" +
|
||||
stack_id + "%2Fresources%2FWaitHandle")
|
||||
t['Resources']['WaitForTheHandle']['Properties']['Handle'] = badhandle
|
||||
self.stack = self.create_stack(template=json.dumps(t), stub=False)
|
||||
|
||||
resource = self.stack.resources['WaitForTheHandle']
|
||||
self.assertRaises(ValueError, resource.handle_create)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
@stack_delete_after
|
||||
def test_validate_handle_url_bad_resource(self):
|
||||
# Stub out the stack ID so we have a known value
|
||||
stack_id = 'STACKABCD1234'
|
||||
self.m.StubOutWithMock(uuid, 'uuid4')
|
||||
uuid.uuid4().AndReturn(stack_id)
|
||||
self.m.ReplayAll()
|
||||
|
||||
t = json.loads(test_template_waitcondition)
|
||||
badhandle = ("http://127.0.0.1:8000/v1/waitcondition/" +
|
||||
"arn%3Aopenstack%3Aheat%3A%3Atest_tenant" +
|
||||
"%3Astacks%2Ftest_stack%2F" +
|
||||
stack_id + "%2Fresources%2FBADHandle")
|
||||
t['Resources']['WaitForTheHandle']['Properties']['Handle'] = badhandle
|
||||
self.stack = self.create_stack(template=json.dumps(t), stub=False)
|
||||
|
||||
resource = self.stack.resources['WaitForTheHandle']
|
||||
self.assertRaises(ValueError, resource.handle_create)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
@stack_delete_after
|
||||
def test_validate_handle_url_bad_resource_type(self):
|
||||
# Stub out the stack ID so we have a known value
|
||||
stack_id = 'STACKABCD1234'
|
||||
self.m.StubOutWithMock(uuid, 'uuid4')
|
||||
uuid.uuid4().AndReturn(stack_id)
|
||||
self.m.ReplayAll()
|
||||
|
||||
t = json.loads(test_template_waitcondition)
|
||||
badhandle = ("http://127.0.0.1:8000/v1/waitcondition/" +
|
||||
"arn%3Aopenstack%3Aheat%3A%3Atest_tenant" +
|
||||
"%3Astacks%2Ftest_stack%2F" +
|
||||
stack_id + "%2Fresources%2FWaitForTheHandle")
|
||||
t['Resources']['WaitForTheHandle']['Properties']['Handle'] = badhandle
|
||||
self.stack = self.create_stack(template=json.dumps(t), stub=False)
|
||||
|
||||
resource = self.stack.resources['WaitForTheHandle']
|
||||
self.assertRaises(ValueError, resource.handle_create)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
|
||||
@attr(tag=['unit', 'resource', 'WaitConditionHandle'])
|
||||
@attr(speed='fast')
|
||||
|
Loading…
Reference in New Issue
Block a user