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.timeout / self.SLEEP_DIV),
|
||||||
self.MIN_SLEEP)
|
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):
|
def _get_handle_resource_name(self):
|
||||||
handle_url = self.properties['Handle']
|
handle_url = self.properties['Handle']
|
||||||
handle_id = identifier.ResourceIdentifier.from_arn_url(handle_url)
|
handle_id = identifier.ResourceIdentifier.from_arn_url(handle_url)
|
||||||
@ -213,6 +233,7 @@ class WaitCondition(resource.Resource):
|
|||||||
return eventlet.Timeout(self.timeout)
|
return eventlet.Timeout(self.timeout)
|
||||||
|
|
||||||
def handle_create(self):
|
def handle_create(self):
|
||||||
|
self._validate_handle_url()
|
||||||
tmo = None
|
tmo = None
|
||||||
status = FAILURE
|
status = FAILURE
|
||||||
reason = "Unknown reason"
|
reason = "Unknown reason"
|
||||||
|
@ -17,6 +17,7 @@ import mox
|
|||||||
import uuid
|
import uuid
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
|
import json
|
||||||
|
|
||||||
import eventlet
|
import eventlet
|
||||||
import unittest
|
import unittest
|
||||||
@ -96,22 +97,26 @@ class WaitConditionTest(unittest.TestCase):
|
|||||||
# Note tests creating a stack should be decorated with @stack_delete_after
|
# Note tests creating a stack should be decorated with @stack_delete_after
|
||||||
# to ensure the stack is properly cleaned up
|
# to ensure the stack is properly cleaned up
|
||||||
def create_stack(self, stack_name='test_stack',
|
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)
|
temp = template_format.parse(template)
|
||||||
template = parser.Template(temp)
|
template = parser.Template(temp)
|
||||||
parameters = parser.Parameters(stack_name, template, params)
|
parameters = parser.Parameters(stack_name, template, params)
|
||||||
stack = parser.Stack(context.get_admin_context(), stack_name,
|
ctx = context.get_admin_context()
|
||||||
template, parameters)
|
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')
|
if stub:
|
||||||
wc.WaitConditionHandle.keystone().MultipleTimes().AndReturn(self.fc)
|
self.m.StubOutWithMock(wc.WaitConditionHandle, 'keystone')
|
||||||
|
wc.WaitConditionHandle.keystone().MultipleTimes().AndReturn(
|
||||||
|
self.fc)
|
||||||
|
|
||||||
id = identifier.ResourceIdentifier('test_tenant', stack.name,
|
id = identifier.ResourceIdentifier('test_tenant', stack.name,
|
||||||
stack.id, '', 'WaitHandle')
|
stack.id, '', 'WaitHandle')
|
||||||
self.m.StubOutWithMock(wc.WaitConditionHandle, 'identifier')
|
self.m.StubOutWithMock(wc.WaitConditionHandle, 'identifier')
|
||||||
wc.WaitConditionHandle.identifier().MultipleTimes().AndReturn(id)
|
wc.WaitConditionHandle.identifier().MultipleTimes().AndReturn(id)
|
||||||
|
|
||||||
return stack
|
return stack
|
||||||
|
|
||||||
@ -263,6 +268,113 @@ class WaitConditionTest(unittest.TestCase):
|
|||||||
self.assertEqual(wc_att, u'{"123": "foo", "456": "dog"}')
|
self.assertEqual(wc_att, u'{"123": "foo", "456": "dog"}')
|
||||||
self.m.VerifyAll()
|
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(tag=['unit', 'resource', 'WaitConditionHandle'])
|
||||||
@attr(speed='fast')
|
@attr(speed='fast')
|
||||||
|
Loading…
Reference in New Issue
Block a user