Ignore RESOLVE translation errors when translating before_props

When translating name to id, if we don't find the resource it's
better to ignore the error and return the non-translated value
for before properties.

Change-Id: Ic25c35098cff8b68e184a336b21f2e8df70bb1ee
Story: #2003015
Task: 23103
This commit is contained in:
rabi 2018-07-27 10:10:59 +05:30 committed by ramishra
parent 7228e34944
commit 8c39f3bb8b
4 changed files with 57 additions and 14 deletions

View File

@ -388,8 +388,10 @@ class Properties(collections.Mapping):
self.translation = (trans.Translation(properties=self)
if translation is None else translation)
def update_translation(self, rules, client_resolve=True):
self.translation.set_rules(rules, client_resolve=client_resolve)
def update_translation(self, rules, client_resolve=True,
ignore_resolve_error=False):
self.translation.set_rules(rules, client_resolve=client_resolve,
ignore_resolve_error=ignore_resolve_error)
@staticmethod
def schema_from_params(params_snippet):

View File

@ -1341,7 +1341,7 @@ class Resource(status.ResourceStatus):
return []
def translate_properties(self, properties,
client_resolve=True):
client_resolve=True, ignore_resolve_error=False):
"""Set resource specific rules for properties translation.
The properties parameter is a properties object and the
@ -1349,7 +1349,9 @@ class Resource(status.ResourceStatus):
do 'RESOLVE' translation with client lookup.
"""
rules = self.translation_rules(properties) or []
properties.update_translation(rules, client_resolve=client_resolve)
properties.update_translation(
rules, client_resolve=client_resolve,
ignore_resolve_error=ignore_resolve_error)
def cancel_grace_period(self):
canceller = getattr(self,
@ -1511,7 +1513,7 @@ class Resource(status.ResourceStatus):
after_props = after.properties(self.properties_schema,
self.context)
self.translate_properties(after_props)
self.translate_properties(before_props)
self.translate_properties(before_props, ignore_resolve_error=True)
if (cfg.CONF.observe_on_update or self.converge) and before_props:
if not self.resource_id:

View File

@ -13,10 +13,15 @@
import functools
from oslo_log import log as logging
import six
from heat.common import exception
from heat.common.i18n import _
from heat.engine import function
LOG = logging.getLogger(__name__)
@functools.total_ordering
class TranslationRule(object):
@ -159,15 +164,18 @@ class Translation(object):
self.resolved_translations = {}
self.is_active = True
self.store_translated_values = True
self._ignore_resolve_error = False
self._deleted_props = []
self._replaced_props = []
def set_rules(self, rules, client_resolve=True):
def set_rules(self, rules, client_resolve=True,
ignore_resolve_error=False):
if not rules:
return
self._rules = {}
self.store_translated_values = client_resolve
self._ignore_resolve_error = ignore_resolve_error
for rule in rules:
if not client_resolve and rule.rule == TranslationRule.RESOLVE:
continue
@ -220,7 +228,8 @@ class Translation(object):
resolved_value = resolve_and_find(result,
rule.client_plugin,
rule.finder,
rule.entity)
rule.entity,
self._ignore_resolve_error)
if self.store_translated_values:
self.resolved_translations[key] = resolved_value
result = resolved_value
@ -322,7 +331,8 @@ def get_value(path, props, validate=False):
return get_value(path[1:], prop)
def resolve_and_find(value, cplugin, finder, entity=None):
def resolve_and_find(value, cplugin, finder, entity=None,
ignore_resolve_error=False):
if isinstance(value, function.Function):
value = function.resolve(value)
if value:
@ -332,10 +342,18 @@ def resolve_and_find(value, cplugin, finder, entity=None):
resolved_value.append(resolve_and_find(item,
cplugin,
finder,
entity))
entity,
ignore_resolve_error))
return resolved_value
finder = getattr(cplugin, finder)
if entity:
return finder(entity, value)
else:
return finder(value)
try:
if entity:
return finder(entity, value)
else:
return finder(value)
except Exception as ex:
if ignore_resolve_error:
LOG.info("Ignoring error in RESOLVE translation: %s",
six.text_type(ex))
return value
raise

View File

@ -547,10 +547,13 @@ class TestTranslationRule(common.HeatTestCase):
self.assertIsNone(tran.translate('far'))
self.assertIsNone(tran.resolved_translations['far'])
def _test_resolve_rule(self, is_list=False):
def _test_resolve_rule(self, is_list=False,
check_error=False):
class FakeClientPlugin(object):
def find_name_id(self, entity=None,
src_value='far'):
if check_error:
raise exception.NotFound()
if entity == 'rose':
return 'pink'
return 'yellow'
@ -738,6 +741,24 @@ class TestTranslationRule(common.HeatTestCase):
self.assertEqual(['yellow', 'pink'], result)
self.assertEqual(['yellow', 'pink'], tran.resolved_translations['far'])
def test_resolve_rule_ignore_error(self):
client_plugin, schema = self._test_resolve_rule(check_error=True)
data = {'far': 'one'}
props = properties.Properties(schema, data)
rule = translation.TranslationRule(
props,
translation.TranslationRule.RESOLVE,
['far'],
client_plugin=client_plugin,
finder='find_name_id')
tran = translation.Translation(props)
tran.set_rules([rule], ignore_resolve_error=True)
self.assertTrue(tran.has_translation('far'))
result = tran.translate('far', data['far'])
self.assertEqual('one', result)
self.assertEqual('one', tran.resolved_translations['far'])
def test_resolve_rule_other(self):
client_plugin, schema = self._test_resolve_rule()
data = {'far': 'one'}