diff --git a/muranoclient/common/utils.py b/muranoclient/common/utils.py index ffa0abbd..dd36178c 100644 --- a/muranoclient/common/utils.py +++ b/muranoclient/common/utils.py @@ -23,7 +23,6 @@ import StringIO import sys import tempfile import textwrap -import types import urlparse import uuid import warnings @@ -38,10 +37,18 @@ import requests import six import yaml import yaql -import yaql.exceptions from muranoclient.common import exceptions +try: + import yaql.language # noqa + + from muranoclient.common.yaqlexpression import YaqlExpression +except ImportError: + # no yaql.language means legacy yaql + from muranoclient.common.yaqlexpression_legacy import YaqlExpression + + LOG = logging.getLogger(__name__) @@ -549,38 +556,6 @@ class Bundle(FileWrapperMixin): yield pkg_obj -class YaqlExpression(object): - def __init__(self, expression): - self._expression = str(expression) - self._parsed_expression = yaql.parse(self._expression) - - def expression(self): - return self._expression - - def __repr__(self): - return 'YAQL(%s)' % self._expression - - def __str__(self): - return self._expression - - @staticmethod - def match(expr): - if not isinstance(expr, types.StringTypes): - return False - if re.match('^[\s\w\d.:]*$', expr): - return False - try: - yaql.parse(expr) - return True - except yaql.exceptions.YaqlGrammarException: - return False - except yaql.exceptions.YaqlLexicalException: - return False - - def evaluate(self, data=None, context=None): - return self._parsed_expression.evaluate(data=data, context=context) - - class YaqlYamlLoader(yaml.Loader): pass diff --git a/muranoclient/common/yaqlexpression.py b/muranoclient/common/yaqlexpression.py new file mode 100644 index 00000000..c19965c1 --- /dev/null +++ b/muranoclient/common/yaqlexpression.py @@ -0,0 +1,59 @@ +# All Rights Reserved. +# +# 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. +import re +import types + +import yaql +from yaql.language import exceptions as yaql_exc + + +def _set_up_yaql(): + legacy_engine_options = { + 'yaql.limitIterators': 100, + 'yaql.memoryQuota': 20000} + return yaql.YaqlFactory().create(options=legacy_engine_options) + +YAQL = _set_up_yaql() + + +class YaqlExpression(object): + def __init__(self, expression): + self._expression = str(expression) + self._parsed_expression = YAQL(self._expression) + + def expression(self): + return self._expression + + def __repr__(self): + return 'YAQL(%s)' % self._expression + + def __str__(self): + return self._expression + + @staticmethod + def match(expr): + if not isinstance(expr, types.StringTypes): + return False + if re.match('^[\s\w\d.:]*$', expr): + return False + try: + YAQL(expr) + return True + except yaql_exc.YaqlGrammarException: + return False + except yaql_exc.YaqlLexicalException: + return False + + def evaluate(self, data=yaql.utils.NO_VALUE, context=None): + return self._parsed_expression.evaluate(data=data, context=context) diff --git a/muranoclient/common/yaqlexpression_legacy.py b/muranoclient/common/yaqlexpression_legacy.py new file mode 100644 index 00000000..486cdd00 --- /dev/null +++ b/muranoclient/common/yaqlexpression_legacy.py @@ -0,0 +1,49 @@ +# All Rights Reserved. +# +# 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. +import re +import types + +import yaql + + +class YaqlExpression(object): + def __init__(self, expression): + self._expression = str(expression) + self._parsed_expression = yaql.parse(self._expression) + + def expression(self): + return self._expression + + def __repr__(self): + return 'YAQL(%s)' % self._expression + + def __str__(self): + return self._expression + + @staticmethod + def match(expr): + if not isinstance(expr, types.StringTypes): + return False + if re.match('^[\s\w\d.:]*$', expr): + return False + try: + yaql.parse(expr) + return True + except yaql.exceptions.YaqlGrammarException: + return False + except yaql.exceptions.YaqlLexicalException: + return False + + def evaluate(self, data=None, context=None): + return self._parsed_expression.evaluate(data=data, context=context) diff --git a/requirements.txt b/requirements.txt index 8a9ea919..537926ae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,9 +13,7 @@ Babel>=1.3 pyOpenSSL>=0.14 requests>=2.5.2 PyYAML>=3.1.0 +yaql>=0.2.7,!=0.3.0 # Apache 2.0 License oslo.serialization>=1.4.0 # Apache-2.0 oslo.utils>=2.0.0 # Apache-2.0 - -# not listed in global requirements -yaql!=0.3.0,>=0.2.7 # Apache 2.0 License