heat/heat/engine/resources/openstack/heat/wait_condition.py

151 lines
4.8 KiB
Python

#
# 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 oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import timeutils
import six
from heat.common.i18n import _
from heat.common.i18n import _LI
from heat.engine import attributes
from heat.engine import constraints
from heat.engine import properties
from heat.engine import resource
from heat.engine.resources import wait_condition as wc_base
from heat.engine import support
LOG = logging.getLogger(__name__)
class HeatWaitCondition(resource.Resource):
support_status = support.SupportStatus(version='2014.2')
PROPERTIES = (
HANDLE, TIMEOUT, COUNT,
) = (
'handle', 'timeout', 'count',
)
ATTRIBUTES = (
DATA,
) = (
'data',
)
properties_schema = {
HANDLE: properties.Schema(
properties.Schema.STRING,
_('A reference to the wait condition handle used to signal this '
'wait condition.'),
required=True
),
TIMEOUT: properties.Schema(
properties.Schema.NUMBER,
_('The number of seconds to wait for the correct number of '
'signals to arrive.'),
required=True,
constraints=[
constraints.Range(1, 43200),
]
),
COUNT: properties.Schema(
properties.Schema.INTEGER,
_('The number of success signals that must be received before '
'the stack creation process continues.'),
constraints=[
constraints.Range(min=1),
],
default=1,
update_allowed=True
),
}
attributes_schema = {
DATA: attributes.Schema(
_('JSON serialized dict containing data associated with wait '
'condition signals sent to the handle.'),
cache_mode=attributes.Schema.CACHE_NONE
),
}
def __init__(self, name, definition, stack):
super(HeatWaitCondition, self).__init__(name, definition, stack)
def _get_handle_resource(self):
return self.stack.resource_by_refid(self.properties[self.HANDLE])
def _wait(self, handle, started_at, timeout_in):
if timeutils.is_older_than(started_at, timeout_in):
exc = wc_base.WaitConditionTimeout(self, handle)
LOG.info(_LI('%(name)s Timed out (%(timeout)s)'),
{'name': str(self), 'timeout': str(exc)})
raise exc
handle_status = handle.get_status()
if any(s != handle.STATUS_SUCCESS for s in handle_status):
failure = wc_base.WaitConditionFailure(self, handle)
LOG.info(_LI('%(name)s Failed (%(failure)s)'),
{'name': str(self), 'failure': str(failure)})
raise failure
if len(handle_status) >= self.properties[self.COUNT]:
LOG.info(_LI("%s Succeeded"), str(self))
return True
return False
def handle_create(self):
handle = self._get_handle_resource()
started_at = timeutils.utcnow()
return handle, started_at, float(self.properties[self.TIMEOUT])
def check_create_complete(self, data):
return self._wait(*data)
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
if prop_diff:
self.properties = json_snippet.properties(self.properties_schema,
self.context)
handle = self._get_handle_resource()
started_at = timeutils.utcnow()
return handle, started_at, float(self.properties[self.TIMEOUT])
def check_update_complete(self, data):
return self._wait(*data)
def handle_delete(self):
handle = self._get_handle_resource()
if handle:
handle.metadata_set({})
def _resolve_attribute(self, key):
handle = self._get_handle_resource()
if key == self.DATA:
meta = handle.metadata_get(refresh=True)
res = {k: meta[k][handle.DATA] for k in meta}
LOG.debug('%(name)s.GetAtt(%(key)s) == %(res)s'
% {'name': self.name,
'key': key,
'res': res})
return six.text_type(jsonutils.dumps(res))
def resource_mapping():
return {
'OS::Heat::WaitCondition': HeatWaitCondition,
}