engine_api.EVENT_RES_NAME: 'LogicalResourceId',
engine_api.EVENT_RES_PHYSICAL_ID: 'PhysicalResourceId',
engine_api.EVENT_RES_PROPERTIES: 'ResourceProperties',
- engine_api.EVENT_RES_STATUS: 'ResourceStatus',
engine_api.EVENT_RES_STATUS_DATA: 'ResourceStatusReason',
engine_api.EVENT_RES_TYPE: 'ResourceType',
engine_api.EVENT_STACK_ID: 'StackId',
result = api_utils.reformat_dict_keys(keymap, e)
action = e[engine_api.EVENT_RES_ACTION]
status = e[engine_api.EVENT_RES_STATUS]
- if action and status:
- result['ResourceStatus'] = '_'.join((action, status))
- else:
- result['ResourceStatus'] = status
+ result['ResourceStatus'] = '_'.join((action, status))
result['ResourceProperties'] = json.dumps(result[
'ResourceProperties'])
return api_utils.format_response('DescribeStackEvents',
{'StackEvents': result})
+ @staticmethod
+ def _resource_status(res):
+ action = res[engine_api.RES_ACTION]
+ status = res[engine_api.RES_STATUS]
+ return '_'.join((action, status))
+
def describe_stack_resource(self, req):
"""
Implements the DescribeStackResource API action
engine_api.RES_NAME: 'LogicalResourceId',
engine_api.RES_METADATA: 'Metadata',
engine_api.RES_PHYSICAL_ID: 'PhysicalResourceId',
- engine_api.RES_STATUS: 'ResourceStatus',
engine_api.RES_STATUS_DATA: 'ResourceStatusReason',
engine_api.RES_TYPE: 'ResourceType',
engine_api.RES_STACK_ID: 'StackId',
result = api_utils.reformat_dict_keys(keymap, r)
+ result['ResourceStatus'] = self._resource_status(r)
+
return self._id_format(result)
con = req.context
engine_api.RES_DESCRIPTION: 'Description',
engine_api.RES_NAME: 'LogicalResourceId',
engine_api.RES_PHYSICAL_ID: 'PhysicalResourceId',
- engine_api.RES_STATUS: 'ResourceStatus',
engine_api.RES_STATUS_DATA: 'ResourceStatusReason',
engine_api.RES_TYPE: 'ResourceType',
engine_api.RES_STACK_ID: 'StackId',
result = api_utils.reformat_dict_keys(keymap, r)
+ result['ResourceStatus'] = self._resource_status(r)
+
return self._id_format(result)
con = req.context
engine_api.RES_UPDATED_TIME: 'LastUpdatedTimestamp',
engine_api.RES_NAME: 'LogicalResourceId',
engine_api.RES_PHYSICAL_ID: 'PhysicalResourceId',
- engine_api.RES_STATUS: 'ResourceStatus',
engine_api.RES_STATUS_DATA: 'ResourceStatusReason',
engine_api.RES_TYPE: 'ResourceType',
}
- return api_utils.reformat_dict_keys(keymap, r)
+ result = api_utils.reformat_dict_keys(keymap, r)
+
+ result['ResourceStatus'] = self._resource_status(r)
+
+ return result
con = req.context
engine_api.EVENT_ID,
engine_api.EVENT_TIMESTAMP,
engine_api.EVENT_RES_NAME,
- engine_api.EVENT_RES_ACTION,
engine_api.EVENT_RES_STATUS,
engine_api.EVENT_RES_STATUS_DATA,
engine_api.EVENT_RES_PHYSICAL_ID,
'resource'),
util.make_link(req, identity.stack(),
'stack')])
- elif (key == engine_api.EVENT_STACK_ID or
- key == engine_api.EVENT_STACK_NAME):
+ elif key in (engine_api.EVENT_STACK_ID, engine_api.EVENT_STACK_NAME,
+ engine_api.EVENT_RES_ACTION):
return
+ elif (key == engine_api.EVENT_RES_STATUS and
+ engine_api.EVENT_RES_ACTION in event):
+ # To avoid breaking API compatibility, we join RES_ACTION
+ # and RES_STATUS, so the API format doesn't expose the
+ # internal split of state into action/status
+ yield (key, '_'.join((event[engine_api.EVENT_RES_ACTION], value)))
+
else:
yield (key, value)
import heat.openstack.common.rpc.common as rpc_common
-def format_resource(req, stack, keys=[]):
+def format_resource(req, res, keys=[]):
include_key = lambda k: k in keys if keys else True
def transform(key, value):
yield ('links', [util.make_link(req, identity),
util.make_link(req, identity.stack(), 'stack')])
elif (key == engine_api.RES_STACK_NAME or
- key == engine_api.RES_STACK_ID):
+ key == engine_api.RES_STACK_ID or
+ key == engine_api.RES_ACTION):
return
elif (key == engine_api.RES_METADATA):
return
+ elif (key == engine_api.RES_STATUS and engine_api.RES_ACTION in res):
+ # To avoid breaking API compatibility, we join RES_ACTION
+ # and RES_STATUS, so the API format doesn't expose the
+ # internal split of state into action/status
+ yield (key, '_'.join((res[engine_api.RES_ACTION], value)))
else:
yield (key, value)
return dict(itertools.chain.from_iterable(
- transform(k, v) for k, v in stack.items()))
+ transform(k, v) for k, v in res.items()))
class ResourceController(object):
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from sqlalchemy import *
+from migrate import *
+
+
+def upgrade(migrate_engine):
+ meta = MetaData()
+ meta.bind = migrate_engine
+
+ resource = Table('resource', meta, autoload=True)
+ # Align the current state/state_description with the
+ # action/status now used in the event table
+ Column('action', String(length=255,
+ convert_unicode=False,
+ assert_unicode=None,
+ unicode_error=None,
+ _warn_on_bytestring=False)).create(resource)
+ resource.c.state.alter(name='status')
+ resource.c.state_description.alter(name='status_reason')
+
+
+def downgrade(migrate_engine):
+ meta = MetaData()
+ meta.bind = migrate_engine
+
+ resource = Table('resource', meta, autoload=True)
+ resource.c.status.drop()
+ resource.c.status.alter(name='state')
+ resource.c.status_reason.alter(name='state_description')
__tablename__ = 'resource'
id = Column(String, primary_key=True, default=uuidutils.generate_uuid)
- state = Column('state', String)
+ action = Column('action', String)
+ status = Column('status', String)
name = Column('name', String, nullable=False)
nova_instance = Column('nova_instance', String)
- state_description = Column('state_description', String)
+ status_reason = Column('status_reason', String)
# odd name as "metadata" is reserved
rsrc_metadata = Column('rsrc_metadata', Json)
RES_NAME: resource.name,
RES_PHYSICAL_ID: resource.resource_id or '',
RES_METADATA: resource.metadata,
- RES_STATUS: resource.state,
- RES_STATUS_DATA: resource.state_description,
+ RES_ACTION: resource.action or '',
+ RES_STATUS: resource.status or '',
+ RES_STATUS_DATA: resource.status_reason,
RES_TYPE: resource.t['Type'],
RES_ID: dict(resource.identifier()),
RES_STACK_ID: dict(resource.stack.identifier()),
'''
for r in self.resources.values():
if r.state in (
- r.CREATE_IN_PROGRESS,
- r.CREATE_COMPLETE,
- r.UPDATE_IN_PROGRESS,
- r.UPDATE_COMPLETE) and r.FnGetRefId() == refid:
+ (r.CREATE, r.IN_PROGRESS),
+ (r.CREATE, r.COMPLETE),
+ (r.UPDATE, r.IN_PROGRESS),
+ (r.UPDATE, r.COMPLETE)) and r.FnGetRefId() == refid:
return r
def validate(self):
logger.exception('create')
failed = True
else:
- res.state_set(res.CREATE_FAILED, 'Resource restart aborted')
+ res.state_set(res.CREATE, res.FAILED,
+ 'Resource restart aborted')
# TODO(asalkeld) if any of this fails we Should
# restart the whole stack
class Resource(object):
- # Status strings
- CREATE_IN_PROGRESS = 'IN_PROGRESS'
- CREATE_FAILED = 'CREATE_FAILED'
- CREATE_COMPLETE = 'CREATE_COMPLETE'
- DELETE_IN_PROGRESS = 'DELETE_IN_PROGRESS'
- DELETE_FAILED = 'DELETE_FAILED'
- DELETE_COMPLETE = 'DELETE_COMPLETE'
- UPDATE_IN_PROGRESS = 'UPDATE_IN_PROGRESS'
- UPDATE_FAILED = 'UPDATE_FAILED'
- UPDATE_COMPLETE = 'UPDATE_COMPLETE'
+ ACTIONS = (CREATE, DELETE, UPDATE, ROLLBACK
+ ) = ('CREATE', 'DELETE', 'UPDATE', 'ROLLBACK')
+
+ STATUSES = (IN_PROGRESS, FAILED, COMPLETE
+ ) = ('IN_PROGRESS', 'FAILED', 'COMPLETE')
# If True, this resource must be created before it can be referenced.
strict_dependency = True
name, stack.id)
if resource:
self.resource_id = resource.nova_instance
- self.state = resource.state
- self.state_description = resource.state_description
+ self.action = resource.action
+ self.status = resource.status
+ self.status_reason = resource.status_reason
self.id = resource.id
else:
self.resource_id = None
- self.state = None
- self.state_description = ''
+ self.action = None
+ self.status = None
+ self.status_reason = ''
self.id = None
def __eq__(self, other):
Create the resource. Subclasses should provide a handle_create() method
to customise creation.
'''
- assert self.state is None, 'Resource create requested in invalid state'
+ assert None in (self.action, self.status), 'invalid state for create'
logger.info('creating %s' % str(self))
self.name)
try:
self.properties.validate()
- self.state_set(self.CREATE_IN_PROGRESS)
+ self.state_set(self.CREATE, self.IN_PROGRESS)
create_data = None
if callable(getattr(self, 'handle_create', None)):
create_data = self.handle_create()
except Exception as ex:
logger.exception('create %s', str(self))
failure = exception.ResourceFailure(ex)
- self.state_set(self.CREATE_FAILED, str(failure))
+ self.state_set(self.CREATE, self.FAILED, str(failure))
raise failure
except:
with excutils.save_and_reraise_exception():
try:
- self.state_set(self.CREATE_FAILED, 'Creation aborted')
+ self.state_set(self.CREATE, self.FAILED,
+ 'Creation aborted')
except Exception:
logger.exception('Error marking resource as failed')
else:
- self.state_set(self.CREATE_COMPLETE)
+ self.state_set(self.CREATE, self.COMPLETE)
def check_create_complete(self, create_data):
'''
'''
assert json_snippet is not None, 'Must specify update json snippet'
- if self.state in (self.CREATE_IN_PROGRESS, self.UPDATE_IN_PROGRESS):
+ if (self.action, self.status) in ((self.CREATE, self.IN_PROGRESS),
+ (self.UPDATE, self.IN_PROGRESS)):
raise exception.ResourceFailure(Exception(
'Resource update already requested'))
logger.info('updating %s' % str(self))
try:
- self.state_set(self.UPDATE_IN_PROGRESS)
+ self.state_set(self.UPDATE, self.IN_PROGRESS)
properties = Properties(self.properties_schema,
json_snippet.get('Properties', {}),
self.stack.resolve_runtime_data,
except Exception as ex:
logger.exception('update %s : %s' % (str(self), str(ex)))
failure = exception.ResourceFailure(ex)
- self.state_set(self.UPDATE_FAILED, str(failure))
+ self.state_set(self.UPDATE, self.FAILED, str(failure))
raise failure
else:
self.t = self.stack.resolve_static_data(json_snippet)
- self.state_set(self.UPDATE_COMPLETE)
+ self.state_set(self.UPDATE, self.COMPLETE)
def physical_resource_name(self):
return '%s-%s' % (self.stack.name, self.name)
Delete the resource. Subclasses should provide a handle_delete() method
to customise deletion.
'''
- if self.state == self.DELETE_COMPLETE:
+ if (self.action, self.status) == (self.DELETE, self.COMPLETE):
return
- if self.state == self.DELETE_IN_PROGRESS:
+ if (self.action, self.status) == (self.DELETE, self.IN_PROGRESS):
raise exception.Error('Resource deletion already in progress')
# No need to delete if the resource has never been created
- if self.state is None:
+ if self.action is None:
return
initial_state = self.state
logger.info('deleting %s' % str(self))
try:
- self.state_set(self.DELETE_IN_PROGRESS)
+ self.state_set(self.DELETE, self.IN_PROGRESS)
deletion_policy = self.t.get('DeletionPolicy', 'Delete')
if deletion_policy == 'Delete':
except Exception as ex:
logger.exception('Delete %s', str(self))
failure = exception.ResourceFailure(ex)
- self.state_set(self.DELETE_FAILED, str(failure))
+ self.state_set(self.DELETE, self.FAILED, str(failure))
raise failure
except:
with excutils.save_and_reraise_exception():
try:
- self.state_set(self.DELETE_FAILED, 'Deletion aborted')
+ self.state_set(self.DELETE, self.FAILED,
+ 'Deletion aborted')
except Exception:
logger.exception('Error marking resource deletion failed')
else:
- self.state_set(self.DELETE_COMPLETE)
+ self.state_set(self.DELETE, self.COMPLETE)
def destroy(self):
'''
def _store(self):
'''Create the resource in the database.'''
try:
- rs = {'state': self.state,
+ rs = {'action': self.action,
+ 'status': self.status,
+ 'status_reason': self.status_reason,
'stack_id': self.stack.id,
'nova_instance': self.resource_id,
'name': self.name,
except Exception as ex:
logger.error('DB error %s' % str(ex))
- def _add_event(self, new_state, reason):
+ def _add_event(self, action, status, reason):
'''Add a state change event to the database.'''
ev = event.Event(self.context, self.stack, self,
- None, new_state, reason,
+ action, status, reason,
self.resource_id, self.properties)
try:
except Exception as ex:
logger.error('DB error %s' % str(ex))
- def _store_or_update(self, new_state, reason):
- self.state = new_state
- self.state_description = reason
+ def _store_or_update(self, action, status, reason):
+ self.action = action
+ self.status = status
+ self.status_reason = reason
if self.id is not None:
try:
rs = db_api.resource_get(self.context, self.id)
- rs.update_and_save({'state': self.state,
- 'state_description': reason,
+ rs.update_and_save({'action': self.action,
+ 'status': self.status,
+ 'status_reason': reason,
'nova_instance': self.resource_id})
self.stack.updated_time = datetime.utcnow()
# store resource in DB on transition to CREATE_IN_PROGRESS
# all other transistions (other than to DELETE_COMPLETE)
# should be handled by the update_and_save above..
- elif new_state == self.CREATE_IN_PROGRESS:
+ elif (action, status) == (self.CREATE, self.IN_PROGRESS):
self._store()
- def state_set(self, new_state, reason="state changed"):
- old_state = self.state
- self._store_or_update(new_state, reason)
+ def state_set(self, action, status, reason="state changed"):
+ if action not in self.ACTIONS:
+ raise ValueError("Invalid action %s" % action)
+
+ if status not in self.STATUSES:
+ raise ValueError("Invalid status %s" % status)
+
+ old_state = (self.action, self.status)
+ new_state = (action, status)
+ self._store_or_update(action, status, reason)
if new_state != old_state:
- self._add_event(new_state, reason)
+ self._add_event(action, status, reason)
+
+ @property
+ def state(self):
+ '''Returns state, tuple of action, status.'''
+ return (self.action, self.status)
def FnGetRefId(self):
'''
template, which causes problems for event handling since we can't
look up the resources via parser.Stack
'''
- def state_set(self, new_state, reason="state changed"):
- self._store_or_update(new_state, reason)
+ def state_set(self, action, status, reason="state changed"):
+ self._store_or_update(action, status, reason)
conf = self.properties['LaunchConfigurationName']
instance_definition = self.stack.t['Resources'][conf]
if volume_backups is not None:
def handle_snapshot_delete(self, state):
- backup = state not in (self.CREATE_FAILED,
- self.UPDATE_FAILED)
+ backup = state not in ((self.CREATE, self.FAILED),
+ (self.UPDATE, self.FAILED))
return self._delete(backup=backup)
def handle_delete(self):
try:
r = resources[resource]
if r.state in (
- r.CREATE_IN_PROGRESS,
- r.CREATE_COMPLETE,
- r.UPDATE_IN_PROGRESS,
- r.UPDATE_COMPLETE):
+ (r.CREATE, r.IN_PROGRESS),
+ (r.CREATE, r.COMPLETE),
+ (r.UPDATE, r.IN_PROGRESS),
+ (r.UPDATE, r.COMPLETE)):
return r.FnGetAtt(att)
except KeyError:
raise exception.InvalidTemplateAttribute(resource=resource,
self.assertEqual(response, expected)
self.m.VerifyAll()
- def test_events_list_onlystatus(self):
- # Format a dummy request
- stack_name = "wordpress"
- identity = dict(identifier.HeatIdentifier('t', stack_name, '6'))
- params = {'Action': 'DescribeStackEvents', 'StackName': stack_name}
- dummy_req = self._dummy_GET_request(params)
-
- # Stub out the RPC call to the engine with a pre-canned response
- engine_resp = [{u'stack_name': u'wordpress',
- u'event_time': u'2012-07-23T13:05:39Z',
- u'stack_identity': {u'tenant': u't',
- u'stack_name': u'wordpress',
- u'stack_id': u'6',
- u'path': u''},
- u'logical_resource_id': u'WikiDatabase',
- u'resource_status_reason': u'state changed',
- u'event_identity':
- {u'tenant': u't',
- u'stack_name': u'wordpress',
- u'stack_id': u'6',
- u'path': u'/resources/WikiDatabase/events/42'},
- u'resource_action': None,
- u'resource_status': u'TEST_IN_PROGRESS',
- u'physical_resource_id': None,
- u'resource_properties': {u'UserData': u'blah'},
- u'resource_type': u'AWS::EC2::Instance'}]
-
- self.m.StubOutWithMock(rpc, 'call')
- rpc.call(dummy_req.context, self.topic,
- {'namespace': None,
- 'method': 'identify_stack',
- 'args': {'stack_name': stack_name},
- 'version': self.api_version}, None).AndReturn(identity)
- rpc.call(dummy_req.context, self.topic,
- {'namespace': None,
- 'method': 'list_events',
- 'args': {'stack_identity': identity},
- 'version': self.api_version}, None).AndReturn(engine_resp)
-
- self.m.ReplayAll()
-
- response = self.controller.events_list(dummy_req)
-
- expected = {'DescribeStackEventsResponse':
- {'DescribeStackEventsResult':
- {'StackEvents':
- [{'EventId': u'42',
- 'StackId': u'arn:openstack:heat::t:stacks/wordpress/6',
- 'ResourceStatus': u'TEST_IN_PROGRESS',
- 'ResourceType': u'AWS::EC2::Instance',
- 'Timestamp': u'2012-07-23T13:05:39Z',
- 'StackName': u'wordpress',
- 'ResourceProperties':
- json.dumps({u'UserData': u'blah'}),
- 'PhysicalResourceId': None,
- 'ResourceStatusReason': u'state changed',
- 'LogicalResourceId': u'WikiDatabase'}]}}}
-
- self.assertEqual(response, expected)
- self.m.VerifyAll()
-
def test_events_list_err_rpcerr(self):
stack_name = "wordpress"
identity = dict(identifier.HeatIdentifier('t', stack_name, '6'))
u'stack_name': u'wordpress',
u'stack_id': u'6',
u'path': u''},
- u'resource_status': u'CREATE_COMPLETE',
+ u'resource_action': u'CREATE',
+ u'resource_status': u'COMPLETE',
u'physical_resource_id':
u'a3455d8c-9f88-404d-a85b-5315293e67de',
u'resource_type': u'AWS::EC2::Instance',
u'stack_name': u'wordpress',
u'stack_id': u'6',
u'path': u''},
- u'resource_status': u'CREATE_COMPLETE',
+ u'resource_action': u'CREATE',
+ u'resource_status': u'COMPLETE',
u'physical_resource_id':
u'a3455d8c-9f88-404d-a85b-5315293e67de',
u'resource_type': u'AWS::EC2::Instance',
u'stack_name': u'wordpress',
u'stack_id': u'6',
u'path': u''},
- u'resource_status': u'CREATE_COMPLETE',
+ u'resource_action': u'CREATE',
+ u'resource_status': u'COMPLETE',
u'physical_resource_id':
u'a3455d8c-9f88-404d-a85b-5315293e67de',
u'resource_type': u'AWS::EC2::Instance',
u'stack_name': u'wordpress',
u'stack_id': u'6',
u'path': u''},
- u'resource_status': u'CREATE_COMPLETE',
+ u'resource_action': u'CREATE',
+ u'resource_status': u'COMPLETE',
u'physical_resource_id':
u'a3455d8c-9f88-404d-a85b-5315293e67de',
u'resource_type': u'AWS::EC2::Instance'}]
u'resource_status_reason': None,
u'updated_time': u'2012-07-23T13:06:00Z',
u'stack_identity': stack_identity,
- u'resource_status': u'CREATE_COMPLETE',
+ u'resource_action': u'CREATE',
+ u'resource_status': u'COMPLETE',
u'physical_resource_id':
u'a3455d8c-9f88-404d-a85b-5315293e67de',
u'resource_type': u'AWS::EC2::Instance',
u'resource_status_reason': None,
u'updated_time': u'2012-07-23T13:06:00Z',
u'stack_identity': dict(stack_identity),
- u'resource_status': u'CREATE_COMPLETE',
+ u'resource_action': u'CREATE',
+ u'resource_status': u'COMPLETE',
u'physical_resource_id':
u'a3455d8c-9f88-404d-a85b-5315293e67de',
u'resource_type': u'AWS::EC2::Instance',
u'resource_status_reason': None,
u'updated_time': u'2012-07-23T13:06:00Z',
u'stack_identity': dict(stack_identity),
- u'resource_status': u'CREATE_COMPLETE',
+ u'resource_action': u'CREATE',
+ u'resource_status': u'COMPLETE',
u'physical_resource_id':
u'a3455d8c-9f88-404d-a85b-5315293e67de',
u'resource_type': u'AWS::EC2::Instance',
u'logical_resource_id': res_name,
u'resource_status_reason': u'state changed',
u'event_identity': dict(ev_identity),
+ u'resource_action': u'CREATE',
u'resource_status': u'IN_PROGRESS',
u'physical_resource_id': None,
u'resource_properties': {u'UserData': u'blah'},
u'logical_resource_id': 'SomeOtherResource',
u'resource_status_reason': u'state changed',
u'event_identity': dict(ev_identity),
+ u'resource_action': u'CREATE',
u'resource_status': u'IN_PROGRESS',
u'physical_resource_id': None,
u'resource_properties': {u'UserData': u'blah'},
u'logical_resource_id': res_name,
u'resource_status_reason': u'state changed',
u'event_time': u'2012-07-23T13:05:39Z',
- u'resource_status': u'IN_PROGRESS',
+ u'resource_status': u'CREATE_IN_PROGRESS',
u'physical_resource_id': None,
}
]
u'logical_resource_id': res_name,
u'resource_status_reason': u'state changed',
u'event_identity': dict(ev_identity),
+ u'resource_action': u'CREATE',
u'resource_status': u'IN_PROGRESS',
u'physical_resource_id': None,
u'resource_properties': {u'UserData': u'blah'},
u'logical_resource_id': res_name,
u'resource_status_reason': u'state changed',
u'event_time': u'2012-07-23T13:05:39Z',
- u'resource_status': u'IN_PROGRESS',
+ u'resource_status': u'CREATE_IN_PROGRESS',
u'physical_resource_id': None,
}
]
u'logical_resource_id': 'SomeOtherResource',
u'resource_status_reason': u'state changed',
u'event_identity': dict(ev_identity),
+ u'resource_action': u'CREATE',
u'resource_status': u'IN_PROGRESS',
u'physical_resource_id': None,
u'resource_properties': {u'UserData': u'blah'},
u'logical_resource_id': res_name,
u'resource_status_reason': u'state changed',
u'event_identity': dict(ev1_identity),
+ u'resource_action': u'CREATE',
u'resource_status': u'IN_PROGRESS',
u'physical_resource_id': None,
u'resource_properties': {u'UserData': u'blah'},
u'logical_resource_id': res_name,
u'resource_status_reason': u'state changed',
u'event_identity': dict(ev_identity),
- u'resource_status': u'CREATE_COMPLETE',
+ u'resource_action': u'CREATE',
+ u'resource_status': u'COMPLETE',
u'physical_resource_id':
u'a3455d8c-9f88-404d-a85b-5315293e67de',
u'resource_properties': {u'UserData': u'blah'},
u'logical_resource_id': res_name,
u'resource_status_reason': u'state changed',
u'event_identity': dict(ev_identity),
+ u'resource_action': u'CREATE',
u'resource_status': u'IN_PROGRESS',
u'physical_resource_id': None,
u'resource_properties': {u'UserData': u'blah'},
u'logical_resource_id': 'SomeOtherResourceName',
u'resource_status_reason': u'state changed',
u'event_identity': dict(ev_identity),
+ u'resource_action': u'CREATE',
u'resource_status': u'IN_PROGRESS',
u'physical_resource_id': None,
u'resource_properties': {u'UserData': u'blah'},
stack)
self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(asc.AutoScalingGroup.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def create_scaling_policy(self, t, stack, resource_name):
self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(asc.ScalingPolicy.CREATE_COMPLETE,
- rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def _stub_create(self, num):
stack)
self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(cloud_watch.CloudWatchAlarm.CREATE_COMPLETE,
- rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_mem_alarm_high_update_no_replace(self):
stack)
self.assertEqual(None, resource.validate())
scheduler.TaskRunner(resource.create)()
- self.assertEqual(dbi.DBInstance.CREATE_COMPLETE, resource.state)
+ self.assertEqual((resource.CREATE, resource.COMPLETE), resource.state)
return resource
def test_dbinstance(self):
stack)
self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(eip.ElasticIp.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def create_association(self, t, stack, resource_name):
stack)
self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(eip.ElasticIpAssociation.CREATE_COMPLETE,
- rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_eip(self):
mox.Replay(get)
stack.delete()
- self.assertEqual(stack.resources['WebServer'].state, 'DELETE_COMPLETE')
+ rsrc = stack.resources['WebServer']
+ self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.assertEqual(db_api.stack_get(ctx, stack_id), None)
self.assertEqual(db_s.status, 'DELETE_COMPLETE')
self.assertEqual(ev['resource_properties']['InstanceType'],
'm1.large')
- self.assertTrue('resource_action' in ev)
+ self.assertEqual(ev['resource_action'], 'CREATE')
self.assertTrue(ev['resource_status'] in ('IN_PROGRESS',
- 'CREATE_COMPLETE'))
+ 'COMPLETE'))
self.assertTrue('resource_status_reason' in ev)
self.assertEqual(ev['resource_status_reason'], 'state changed')
instance.delete()
self.assertTrue(instance.resource_id is None)
- self.assertEqual(instance.state, instance.DELETE_COMPLETE)
+ self.assertEqual(instance.state, (instance.DELETE, instance.COMPLETE))
self.m.VerifyAll()
def test_instance_update_metadata(self):
self.m.ReplayAll()
scheduler.TaskRunner(instance.create)()
- self.assertEqual(instance.state, instance.CREATE_COMPLETE)
+ self.assertEqual(instance.state, (instance.CREATE, instance.COMPLETE))
def test_instance_status_hard_reboot(self):
self._test_instance_status_not_build_active('HARD_REBOOT')
self.m.ReplayAll()
scheduler.TaskRunner(instance.create)()
- self.assertEqual(instance.state, instance.CREATE_COMPLETE)
+ self.assertEqual(instance.state, (instance.CREATE, instance.COMPLETE))
self.m.VerifyAll()
stack)
self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(asc.InstanceGroup.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_instance_group(self):
create = scheduler.TaskRunner(rsrc.create)
self.assertRaises(exception.ResourceFailure, create)
- self.assertEqual(asc.InstanceGroup.CREATE_FAILED, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
stack)
self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(lb.LoadBalancer.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_loadbalancer(self):
s2 = self.stack.resources['S2']
files = s1.metadata['AWS::CloudFormation::Init']['config']['files']
cont = files['/tmp/random_file']['content']
- self.assertEqual(s2.CREATE_COMPLETE, s2.state)
+ self.assertEqual((s2.CREATE, s2.COMPLETE), s2.state)
self.assertEqual(cont, 's2-ip=1.2.3.5')
s1.metadata_update()
self.assertNotEqual(None, resource)
self.assertEqual(rsrc, self.stack.resource_by_refid('aaaa'))
- rsrc.state = rsrc.DELETE_IN_PROGRESS
+ rsrc.state_set(rsrc.DELETE, rsrc.IN_PROGRESS)
try:
self.assertEqual(None, self.stack.resource_by_refid('aaaa'))
-
self.assertEqual(None, self.stack.resource_by_refid('bbbb'))
finally:
- rsrc.state = rsrc.CREATE_COMPLETE
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE)
@stack_delete_after
def test_update_add(self):
rsrc.resource_id_set('aaaa')
self.assertEqual('AResource', rsrc.FnGetAtt('foo'))
- for state in (
- rsrc.CREATE_IN_PROGRESS,
- rsrc.CREATE_COMPLETE,
- rsrc.UPDATE_IN_PROGRESS,
- rsrc.UPDATE_COMPLETE):
- rsrc.state = state
+ for action, status in (
+ (rsrc.CREATE, rsrc.IN_PROGRESS),
+ (rsrc.CREATE, rsrc.COMPLETE),
+ (rsrc.UPDATE, rsrc.IN_PROGRESS),
+ (rsrc.UPDATE, rsrc.COMPLETE)):
+ rsrc.state_set(action, status)
self.assertEqual('AResource', self.stack.output('TestOutput'))
- for state in (
- rsrc.CREATE_FAILED,
- rsrc.DELETE_IN_PROGRESS,
- rsrc.DELETE_FAILED,
- rsrc.DELETE_COMPLETE,
- rsrc.UPDATE_FAILED,
- None):
- rsrc.state = state
+ for action, status in (
+ (rsrc.CREATE, rsrc.FAILED),
+ (rsrc.DELETE, rsrc.IN_PROGRESS),
+ (rsrc.DELETE, rsrc.FAILED),
+ (rsrc.DELETE, rsrc.COMPLETE),
+ (rsrc.UPDATE, rsrc.FAILED)):
+ rsrc.state_set(action, status)
self.assertEqual(None, self.stack.output('TestOutput'))
-
- rsrc.state = rsrc.CREATE_COMPLETE
from heat.engine import scheduler
from heat.engine.resources.quantum import net
from heat.engine.resources.quantum import subnet
-from heat.engine.resources.quantum import floatingip
-from heat.engine.resources.quantum import port
from heat.engine.resources.quantum import router
from heat.engine.resources.quantum.quantum import QuantumResource as qr
from heat.openstack.common.importutils import try_import
def create_net(self, t, stack, resource_name):
rsrc = net.Net('test_net', t['Resources'][resource_name], stack)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(net.Net.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_net(self):
rsrc.handle_update, {}, {}, {})
rsrc.delete()
- rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again')
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
rsrc.delete()
self.m.VerifyAll()
rsrc = subnet.Subnet('test_subnet', t['Resources'][resource_name],
stack)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(subnet.Subnet.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_subnet(self):
rsrc.handle_update, {}, {}, {})
self.assertEqual(rsrc.delete(), None)
- rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again')
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
self.assertEqual(rsrc.delete(), None)
self.m.VerifyAll()
def create_router(self, t, stack, resource_name):
rsrc = router.Router('router', t['Resources'][resource_name], stack)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(router.Router.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def create_router_interface(self, t, stack, resource_name, properties={}):
t['Resources'][resource_name],
stack)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(
- router.RouterInterface.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def create_gateway_router(self, t, stack, resource_name, properties={}):
t['Resources'][resource_name],
stack)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(router.RouterGateway.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_router(self):
rsrc.handle_update, {}, {}, {})
self.assertEqual(rsrc.delete(), None)
- rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again')
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
self.assertEqual(rsrc.delete(), None)
self.m.VerifyAll()
})
self.assertEqual(rsrc.delete(), None)
- rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again')
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
self.assertEqual(rsrc.delete(), None)
self.m.VerifyAll()
})
self.assertEqual(rsrc.delete(), None)
- rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again')
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
self.assertEqual(rsrc.delete(), None)
self.m.VerifyAll()
fip = stack['floating_ip']
scheduler.TaskRunner(fip.create)()
- self.assertEqual(floatingip.FloatingIP.CREATE_COMPLETE, fip.state)
+ self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
fip.validate()
fip_id = fip.FnGetRefId()
self.assertRaises(resource.UpdateReplace,
fip.handle_update, {}, {}, {})
self.assertEqual(fip.delete(), None)
- fip.state_set(fip.CREATE_COMPLETE, 'to delete again')
+ fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
self.assertEqual(fip.delete(), None)
self.m.VerifyAll()
p = stack['port_floating']
scheduler.TaskRunner(p.create)()
- self.assertEqual(port.Port.CREATE_COMPLETE, p.state)
+ self.assertEqual((p.CREATE, p.COMPLETE), p.state)
p.validate()
port_id = p.FnGetRefId()
fip = stack['floating_ip']
scheduler.TaskRunner(fip.create)()
- self.assertEqual(floatingip.FloatingIP.CREATE_COMPLETE, fip.state)
+ self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
p = stack['port_floating']
scheduler.TaskRunner(p.create)()
- self.assertEqual(port.Port.CREATE_COMPLETE, p.state)
+ self.assertEqual((p.CREATE, p.COMPLETE), p.state)
fipa = stack['floating_ip_assoc']
scheduler.TaskRunner(fipa.create)()
- self.assertEqual(floatingip.FloatingIPAssociation.CREATE_COMPLETE,
- fipa.state)
+ self.assertEqual((fipa.CREATE, fipa.COMPLETE), fipa.state)
fipa.validate()
self.assertEqual(p.delete(), None)
self.assertEqual(fip.delete(), None)
- fipa.state_set(fipa.CREATE_COMPLETE, 'to delete again')
- fip.state_set(fip.CREATE_COMPLETE, 'to delete again')
- p.state_set(p.CREATE_COMPLETE, 'to delete again')
+ fipa.state_set(fipa.CREATE, fipa.COMPLETE, 'to delete again')
+ fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
+ p.state_set(p.CREATE, p.COMPLETE, 'to delete again')
self.assertEqual(fipa.delete(), None)
self.assertEqual(p.delete(), None)
from heat.engine import resource
from heat.engine import scheduler
from heat.openstack.common import uuidutils
+import heat.db.api as db_api
from heat.tests import generic_resource as generic_rsrc
from heat.tests.common import HeatTestCase
def test_state_defaults(self):
tmpl = {'Type': 'Foo'}
res = generic_rsrc.GenericResource('test_res_def', tmpl, self.stack)
- self.assertEqual(res.state, None)
- self.assertEqual(res.state_description, '')
+ self.assertEqual(res.state, (None, None))
+ self.assertEqual(res.status_reason, '')
- def test_state(self):
+ def test_state_set(self):
tmpl = {'Type': 'Foo'}
res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
- res.state_set('bar')
- self.assertEqual(res.state, 'bar')
+ res.state_set(res.CREATE, res.COMPLETE, 'wibble')
+ self.assertEqual(res.action, res.CREATE)
+ self.assertEqual(res.status, res.COMPLETE)
+ self.assertEqual(res.state, (res.CREATE, res.COMPLETE))
+ self.assertEqual(res.status_reason, 'wibble')
- def test_state_description(self):
+ def test_state_set_invalid(self):
tmpl = {'Type': 'Foo'}
res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
- res.state_set('blarg', 'wibble')
- self.assertEqual(res.state_description, 'wibble')
+ self.assertRaises(ValueError, res.state_set, 'foo', 'bla')
+ self.assertRaises(ValueError, res.state_set, 'foo', res.COMPLETE)
+ self.assertRaises(ValueError, res.state_set, res.CREATE, 'bla')
def test_type(self):
tmpl = {'Type': 'Foo'}
res = generic_rsrc.GenericResource('test_res_upd', tmpl, self.stack)
res._store()
stored_time = res.updated_time
- res.state_set(res.CREATE_IN_PROGRESS, 'testing')
+ res.state_set(res.CREATE, res.IN_PROGRESS, 'testing')
self.assertNotEqual(res.updated_time, None)
self.assertNotEqual(res.updated_time, stored_time)
+ def test_store_or_update(self):
+ tmpl = {'Type': 'Foo'}
+ res = generic_rsrc.GenericResource('test_res_upd', tmpl, self.stack)
+ res._store_or_update(res.CREATE, res.IN_PROGRESS, 'test_store')
+ self.assertNotEqual(None, res.id)
+ self.assertEqual(res.action, res.CREATE)
+ self.assertEqual(res.status, res.IN_PROGRESS)
+ self.assertEqual(res.status_reason, 'test_store')
+
+ db_res = r = db_api.resource_get(None, res.id)
+ self.assertEqual(db_res.action, res.CREATE)
+ self.assertEqual(db_res.status, res.IN_PROGRESS)
+ self.assertEqual(db_res.status_reason, 'test_store')
+
+ res._store_or_update(res.CREATE, res.COMPLETE, 'test_update')
+ self.assertEqual(res.action, res.CREATE)
+ self.assertEqual(res.status, res.COMPLETE)
+ self.assertEqual(res.status_reason, 'test_update')
+ self.assertEqual(db_res.action, res.CREATE)
+ self.assertEqual(db_res.status, res.COMPLETE)
+ self.assertEqual(db_res.status_reason, 'test_update')
+
def test_parsed_template(self):
tmpl = {
'Type': 'Foo',
tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}}
res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
scheduler.TaskRunner(res.create)()
- self.assertEqual(res.CREATE_COMPLETE, res.state)
+ self.assertEqual((res.CREATE, res.COMPLETE), res.state)
def test_create_fail_missing_req_prop(self):
# patch in a dummy property schema for GenericResource
estr = 'Property error : test_resource: Property Foo not assigned'
create = scheduler.TaskRunner(res.create)
self.assertRaises(exception.ResourceFailure, create)
- self.assertEqual(res.CREATE_FAILED, res.state)
+ self.assertEqual((res.CREATE, res.FAILED), res.state)
def test_create_fail_prop_typo(self):
# patch in a dummy property schema for GenericResource
estr = 'Property error : test_resource: Property Foo not assigned'
create = scheduler.TaskRunner(res.create)
self.assertRaises(exception.ResourceFailure, create)
- self.assertEqual(res.CREATE_FAILED, res.state)
+ self.assertEqual((res.CREATE, res.FAILED), res.state)
def test_update_ok(self):
# patch in a dummy property schema for GenericResource
res.update_allowed_keys = ('Properties',)
res.update_allowed_properties = ('Foo',)
scheduler.TaskRunner(res.create)()
- self.assertEqual(res.CREATE_COMPLETE, res.state)
+ self.assertEqual((res.CREATE, res.COMPLETE), res.state)
utmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'xyz'}}
tmpl_diff = {'Properties': {'Foo': 'xyz'}}
self.m.ReplayAll()
self.assertEqual(None, res.update(utmpl))
- self.assertEqual(res.UPDATE_COMPLETE, res.state)
+ self.assertEqual((res.UPDATE, res.COMPLETE), res.state)
self.m.VerifyAll()
def test_update_replace(self):
res.update_allowed_keys = ('Properties',)
res.update_allowed_properties = ('Foo',)
scheduler.TaskRunner(res.create)()
- self.assertEqual(res.CREATE_COMPLETE, res.state)
+ self.assertEqual((res.CREATE, res.COMPLETE), res.state)
utmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'xyz'}}
self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
res.update_allowed_keys = ('Properties',)
res.update_allowed_properties = ('Foo',)
scheduler.TaskRunner(res.create)()
- self.assertEqual(res.CREATE_COMPLETE, res.state)
+ self.assertEqual((res.CREATE, res.COMPLETE), res.state)
utmpl = {'Type': 'GenericResourceType', 'Properties': {}}
self.assertRaises(exception.ResourceFailure, res.update, utmpl)
- self.assertEqual(res.UPDATE_FAILED, res.state)
+ self.assertEqual((res.UPDATE, res.FAILED), res.state)
def test_update_fail_prop_typo(self):
# patch in a dummy property schema for GenericResource
res.update_allowed_keys = ('Properties',)
res.update_allowed_properties = ('Foo',)
scheduler.TaskRunner(res.create)()
- self.assertEqual(res.CREATE_COMPLETE, res.state)
+ self.assertEqual((res.CREATE, res.COMPLETE), res.state)
utmpl = {'Type': 'GenericResourceType', 'Properties': {'Food': 'xyz'}}
self.assertRaises(exception.ResourceFailure, res.update, utmpl)
- self.assertEqual(res.UPDATE_FAILED, res.state)
+ self.assertEqual((res.UPDATE, res.FAILED), res.state)
def test_update_not_implemented(self):
# patch in a dummy property schema for GenericResource
res.update_allowed_keys = ('Properties',)
res.update_allowed_properties = ('Foo',)
scheduler.TaskRunner(res.create)()
- self.assertEqual(res.CREATE_COMPLETE, res.state)
+ self.assertEqual((res.CREATE, res.COMPLETE), res.state)
utmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'xyz'}}
tmpl_diff = {'Properties': {'Foo': 'xyz'}}
).AndRaise(NotImplemented)
self.m.ReplayAll()
self.assertRaises(exception.ResourceFailure, res.update, utmpl)
- self.assertEqual(res.UPDATE_FAILED, res.state)
+ self.assertEqual((res.UPDATE, res.FAILED), res.state)
self.m.VerifyAll()
t['Resources'][resource_name],
stack)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(s3.S3Bucket.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_create_container_name(self):
rsrc = self.create_resource(t, stack, 'S3Bucket')
# if delete_container is called, mox verify will succeed
rsrc.delete()
- self.assertEqual(rsrc.DELETE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
try:
self.m.VerifyAll()
def assertResourceState(self, rsrc, ref_id, metadata={}):
self.assertEqual(None, rsrc.validate())
- self.assertEqual(rsrc.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual(ref_id, rsrc.FnGetRefId())
self.assertEqual(metadata, dict(rsrc.metadata))
self.assertEqual(None, sg.delete())
- sg.state_set(sg.CREATE_COMPLETE, 'to delete again')
+ sg.state_set(sg.CREATE, sg.COMPLETE, 'to delete again')
sg.resource_id = 2
stack.delete()
self.assertEqual(None, sg.delete())
- sg.state_set(sg.CREATE_COMPLETE, 'to delete again')
+ sg.state_set(sg.CREATE, sg.COMPLETE, 'to delete again')
sg.resource_id = 'aaaa'
stack.delete()
t['Resources'][resource_name],
stack)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(swift.SwiftContainer.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_create_container_name(self):
rsrc = self.create_resource(t, stack, 'SwiftContainer')
# if delete_container is called, mox verify will succeed
rsrc.delete()
- self.assertEqual(rsrc.DELETE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
try:
self.m.VerifyAll()
stack)
self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(user.User.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_user(self):
self.assertEqual(utils.PhysName('test_stack', 'CfnUser'),
rsrc.FnGetRefId())
- self.assertEqual('CREATE_COMPLETE', rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertRaises(resource.UpdateReplace,
rsrc.handle_update, {}, {}, {})
rsrc.resource_id = None
self.assertEqual(None, rsrc.delete())
- self.assertEqual('DELETE_COMPLETE', rsrc.state)
+ self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
rsrc.resource_id = self.fc.access
- rsrc.state_set('CREATE_COMPLETE')
- self.assertEqual('CREATE_COMPLETE', rsrc.state)
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual(None, rsrc.delete())
- self.assertEqual('DELETE_COMPLETE', rsrc.state)
+ self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
- rsrc.state_set('CREATE_COMPLETE')
- self.assertEqual('CREATE_COMPLETE', rsrc.state)
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual(None, rsrc.delete())
- self.assertEqual('DELETE_COMPLETE', rsrc.state)
+ self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
def test_user_validate_policies(self):
self.assertEqual(self.fc.user_id, rsrc.resource_id)
self.assertEqual(utils.PhysName('test_stack', 'CfnUser'),
rsrc.FnGetRefId())
- self.assertEqual('CREATE_COMPLETE', rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual([u'WebServerAccessPolicy'],
rsrc.properties['Policies'])
self.assertEqual(self.fc.user_id, rsrc.resource_id)
self.assertEqual(utils.PhysName('test_stack', 'CfnUser'),
rsrc.FnGetRefId())
- self.assertEqual('CREATE_COMPLETE', rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertTrue(rsrc.access_allowed('a_resource'))
self.assertFalse(rsrc.access_allowed('b_resource'))
self.assertEqual(self.fc.user_id, rsrc.resource_id)
self.assertEqual(utils.PhysName('test_stack', 'CfnUser'),
rsrc.FnGetRefId())
- self.assertEqual('CREATE_COMPLETE', rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertTrue(rsrc.access_allowed('a_resource'))
self.assertFalse(rsrc.access_allowed('b_resource'))
stack)
self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(user.AccessKey.CREATE_COMPLETE,
- rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def create_user(self, t, stack, resource_name):
rsrc = stack[resource_name]
self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(rsrc.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_access_key(self):
self.create_user(t, stack, 'CfnUser')
rsrc = self.create_access_key(t, stack, 'HostKeys')
- self.assertEqual(rsrc.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.m.StubOutWithMock(self.fc, 'delete_ec2_keypair')
NotFound = keystoneclient.exceptions.NotFound
self.fc.delete_ec2_keypair(self.fc.user_id,
rsrc.resource_id).AndRaise(NotFound('Gone'))
self.m.ReplayAll()
-
self.assertEqual(None, rsrc.delete())
self.m.VerifyAll()
stack)
create = scheduler.TaskRunner(rsrc.create)
self.assertRaises(exception.ResourceFailure, create)
- self.assertEqual(user.AccessKey.CREATE_FAILED,
- rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.assertEqual(None, rsrc.delete())
- self.assertEqual(user.AccessKey.DELETE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
t['Resources'][resource_name],
stack)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(user.User.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
def test_accesspolicy_create_ok_empty(self):
t = template_format.parse(user_policy_template)
t['Resources'][resource_name],
stack)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(user.User.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
def test_accesspolicy_create_err_notfound(self):
t = template_format.parse(user_policy_template)
rsrc = vol.Volume(resource_name, data, stack)
self.assertEqual(rsrc.validate(), None)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(rsrc.state, vol.Volume.CREATE_COMPLETE)
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
return rsrc
def create_attachment(self, t, stack, resource_name):
stack)
self.assertEqual(rsrc.validate(), None)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(rsrc.state, vol.VolumeAttachment.CREATE_COMPLETE)
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
return rsrc
def test_volume(self):
self.assertEqual(rsrc.destroy(), None)
# Test when volume already deleted
- rsrc.state = rsrc.CREATE_COMPLETE
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE)
self.assertEqual(rsrc.destroy(), None)
self.m.VerifyAll()
stack)
self.assertEqual(rsrc.validate(), None)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(rsrc.state, vol.Volume.CREATE_COMPLETE)
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
self.assertEqual(fv.status, 'available')
self.m.VerifyAll()
stack)
self.assertEqual(rsrc.validate(), None)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(rsrc.state, vol.Volume.CREATE_COMPLETE)
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
self.assertEqual(fv.status, 'available')
self.m.VerifyAll()
stack)
self.assertEqual(rsrc.validate(), None)
scheduler.TaskRunner(rsrc.create)()
- self.assertEqual(rsrc.state, vol.VolumeAttachment.CREATE_COMPLETE)
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
self.assertRaises(resource.UpdateReplace, rsrc.handle_update,
{}, {}, {})
def assertResourceState(self, rsrc, ref_id, metadata={}):
self.assertEqual(None, rsrc.validate())
- self.assertEqual(rsrc.CREATE_COMPLETE, rsrc.state)
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual(ref_id, rsrc.FnGetRefId())
self.assertEqual(metadata, dict(rsrc.metadata))
self.assertEqual('moon', rsrc.FnGetAtt('AvailabilityZone'))
self.assertEqual(None, rsrc.delete())
- rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again')
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
self.assertEqual(None, rsrc.delete())
self.assertEqual(None, stack['the_vpc'].delete())
self.m.VerifyAll()
stack = self.create_stack(self.test_template_error_no_ref)
try:
self.assertEqual(stack.CREATE_FAILED, stack.state)
- self.assertEqual(stack['the_nic'].CREATE_FAILED,
- stack['the_nic'].state)
- reason = stack['the_nic'].state_description
+ rsrc = stack['the_nic']
+ self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
+ reason = rsrc.status_reason
self.assertTrue(reason.startswith('InvalidTemplateAttribute:'))
finally:
stack.delete()
rsrc = self.stack.resources['WaitForTheHandle']
self.assertEqual(rsrc.state,
- 'CREATE_COMPLETE')
+ (rsrc.CREATE, rsrc.COMPLETE))
r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle',
self.stack.id)
self.stack.create()
rsrc = self.stack.resources['WaitForTheHandle']
- self.assertEqual(rsrc.state, rsrc.CREATE_FAILED)
- reason = rsrc.state_description
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.FAILED))
+ reason = rsrc.status_reason
self.assertTrue(reason.startswith('WaitConditionFailure:'))
r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle',
rsrc = self.stack.resources['WaitForTheHandle']
self.assertEqual(rsrc.state,
- 'CREATE_COMPLETE')
+ (rsrc.CREATE, rsrc.COMPLETE))
r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle',
self.stack.id)
self.stack.create()
rsrc = self.stack.resources['WaitForTheHandle']
- self.assertEqual(rsrc.state, rsrc.CREATE_FAILED)
- reason = rsrc.state_description
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.FAILED))
+ reason = rsrc.status_reason
self.assertTrue(reason.startswith('WaitConditionFailure:'))
r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle',
rsrc = self.stack.resources['WaitForTheHandle']
- self.assertEqual(rsrc.state, rsrc.CREATE_FAILED)
- reason = rsrc.state_description
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.FAILED))
+ reason = rsrc.status_reason
self.assertTrue(reason.startswith('WaitConditionTimeout:'))
self.assertRaises(resource.UpdateReplace,
self.stack.create()
rsrc = self.stack.resources['WaitForTheHandle']
- self.assertEqual(rsrc.state, 'CREATE_COMPLETE')
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
wc_att = rsrc.FnGetAtt('Data')
self.assertEqual(wc_att, unicode({}))
handle = self.stack.resources['WaitHandle']
- self.assertEqual(handle.state, 'CREATE_COMPLETE')
+ self.assertEqual(handle.state, (rsrc.CREATE, rsrc.COMPLETE))
test_metadata = {'Data': 'foo', 'Reason': 'bar',
'Status': 'SUCCESS', 'UniqueId': '123'}
rsrc = self.stack.resources['WaitHandle']
rsrc.created_time = created_time
- self.assertEqual(rsrc.state, 'CREATE_COMPLETE')
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
expected_url = "".join([
'http://127.0.0.1:8000/v1/waitcondition/',
@stack_delete_after
def test_metadata_update(self):
rsrc = self.stack.resources['WaitHandle']
- self.assertEqual(rsrc.state, 'CREATE_COMPLETE')
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
test_metadata = {'Data': 'foo', 'Reason': 'bar',
'Status': 'SUCCESS', 'UniqueId': '123'}
@stack_delete_after
def test_metadata_update_invalid(self):
rsrc = self.stack.resources['WaitHandle']
- self.assertEqual(rsrc.state, 'CREATE_COMPLETE')
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
# metadata_update should raise a ValueError if the metadata
# is missing any of the expected keys
@stack_delete_after
def test_get_status(self):
rsrc = self.stack.resources['WaitHandle']
- self.assertEqual(rsrc.state, 'CREATE_COMPLETE')
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
# UnsetStubs, don't want get_status stubbed anymore..
self.m.VerifyAll()
@stack_delete_after
def test_get_status_reason(self):
rsrc = self.stack.resources['WaitHandle']
- self.assertEqual(rsrc.state, 'CREATE_COMPLETE')
+ self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
test_metadata = {'Data': 'foo', 'Reason': 'bar',
'Status': 'SUCCESS', 'UniqueId': '123'}