2
# Licensed under the Apache License, Version 2.0 (the "License"); you may
3
# not use this file except in compliance with the License. You may obtain
4
# a copy of the License at
6
# http://www.apache.org/licenses/LICENSE-2.0
8
# Unless required by applicable law or agreed to in writing, software
9
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
# License for the specific language governing permissions and limitations
14
from oslo_log import log as logging
15
from oslo_serialization import jsonutils
16
from oslo_utils import timeutils
19
from heat.common.i18n import _
20
from heat.common.i18n import _LI
21
from heat.engine import attributes
22
from heat.engine import constraints
23
from heat.engine import properties
24
from heat.engine import resource
25
from heat.engine.resources import wait_condition as wc_base
26
from heat.engine import support
28
LOG = logging.getLogger(__name__)
31
class HeatWaitCondition(resource.Resource):
33
support_status = support.SupportStatus(version='2014.2')
36
HANDLE, TIMEOUT, COUNT,
38
'handle', 'timeout', 'count',
48
HANDLE: properties.Schema(
49
properties.Schema.STRING,
50
_('A reference to the wait condition handle used to signal this '
54
TIMEOUT: properties.Schema(
55
properties.Schema.NUMBER,
56
_('The number of seconds to wait for the correct number of '
57
'signals to arrive.'),
60
constraints.Range(1, 43200),
63
COUNT: properties.Schema(
64
properties.Schema.NUMBER,
65
_('The number of success signals that must be received before '
66
'the stack creation process continues.'),
68
constraints.Range(min=1),
76
DATA: attributes.Schema(
77
_('JSON serialized dict containing data associated with wait '
78
'condition signals sent to the handle.'),
79
cache_mode=attributes.Schema.CACHE_NONE
83
def __init__(self, name, definition, stack):
84
super(HeatWaitCondition, self).__init__(name, definition, stack)
86
def _get_handle_resource(self):
87
return self.stack.resource_by_refid(self.properties[self.HANDLE])
89
def _wait(self, handle, started_at, timeout_in):
90
if timeutils.is_older_than(started_at, timeout_in):
91
exc = wc_base.WaitConditionTimeout(self, handle)
92
LOG.info(_LI('%(name)s Timed out (%(timeout)s)'),
93
{'name': str(self), 'timeout': str(exc)})
96
handle_status = handle.get_status()
98
if any(s != handle.STATUS_SUCCESS for s in handle_status):
99
failure = wc_base.WaitConditionFailure(self, handle)
100
LOG.info(_LI('%(name)s Failed (%(failure)s)'),
101
{'name': str(self), 'failure': str(failure)})
104
if len(handle_status) >= self.properties[self.COUNT]:
105
LOG.info(_LI("%s Succeeded"), str(self))
109
def handle_create(self):
110
handle = self._get_handle_resource()
111
started_at = timeutils.utcnow()
112
return handle, started_at, float(self.properties[self.TIMEOUT])
114
def check_create_complete(self, data):
115
return self._wait(*data)
117
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
119
self.properties = json_snippet.properties(self.properties_schema,
122
handle = self._get_handle_resource()
123
started_at = timeutils.utcnow()
124
return handle, started_at, float(self.properties[self.TIMEOUT])
126
def check_update_complete(self, data):
127
return self._wait(*data)
129
def handle_delete(self):
130
handle = self._get_handle_resource()
132
handle.metadata_set({})
134
def _resolve_attribute(self, key):
135
handle = self._get_handle_resource()
137
meta = handle.metadata_get(refresh=True)
138
res = {k: meta[k][handle.DATA] for k in meta}
139
LOG.debug('%(name)s.GetAtt(%(key)s) == %(res)s'
140
% {'name': self.name,
144
return six.text_type(jsonutils.dumps(res))
147
def resource_mapping():
149
'OS::Heat::WaitCondition': HeatWaitCondition,