Make Javascript implementation configurable

Currently the only Javascript implentation supported by the
std.javascript action is PyV8, a project that has been abandoned
for about two years and can only be compiled with an outdated
version of V8, one affected by several security vulnerabilities.

This change adds support for v8eval, a more recent interface to V8
that is still being maintained.

Change-Id: Id9cb89ffb05b37ef525a6085d49229de63420bbf
This commit is contained in:
Endre János Kovács 2016-09-19 14:56:16 +02:00
parent 04ac956138
commit 03e3ebe021
2 changed files with 31 additions and 6 deletions

View File

@ -80,6 +80,14 @@ api_opts = [
)
]
js_impl_opt = cfg.StrOpt(
'js_implementation',
default='pyv8',
choices=['pyv8', 'v8eval'],
help='The JavaScript implementation to be used by the std.javascript '
'action to evaluate scripts.'
)
rpc_impl_opt = cfg.StrOpt(
'rpc_implementation',
default='oslo',
@ -275,6 +283,7 @@ CONF.register_opts(event_engine_opts, group=EVENT_ENGINE_GROUP)
CONF.register_opts(pecan_opts, group=PECAN_GROUP)
CONF.register_opts(coordination_opts, group=COORDINATION_GROUP)
CONF.register_opts(profiler_opts, group=PROFILER_GROUP)
CONF.register_opt(js_impl_opt)
CONF.register_opt(rpc_impl_opt)
CONF.register_opt(rpc_response_timeout_opt)
CONF.register_opts(keycloak_oidc_opts, group=KEYCLOAK_OIDC_GROUP)
@ -288,8 +297,8 @@ CLI_OPTS = [
default_group_opts = itertools.chain(
CLI_OPTS,
[wf_trace_log_name_opt, auth_type_opt, rpc_impl_opt, os_endpoint_type,
rpc_response_timeout_opt, expiration_token_duration]
[wf_trace_log_name_opt, auth_type_opt, js_impl_opt, rpc_impl_opt,
os_endpoint_type, rpc_response_timeout_opt, expiration_token_duration]
)
CONF.register_cli_opts(CLI_OPTS)

View File

@ -15,12 +15,14 @@
import abc
import json
from oslo_config import cfg
from oslo_utils import importutils
from mistral import exceptions as exc
CONF = cfg.CONF
_PYV8 = importutils.try_import('PyV8')
_V8EVAL = importutils.try_import('v8eval')
class JSEvaluator(object):
@ -31,7 +33,7 @@ class JSEvaluator(object):
pass
class V8Evaluator(JSEvaluator):
class PyV8Evaluator(JSEvaluator):
@classmethod
def evaluate(cls, script, context):
if not _PYV8:
@ -46,8 +48,22 @@ class V8Evaluator(JSEvaluator):
result = ctx.eval(script)
return _PYV8.convert(result)
# TODO(nmakhotkin) Make it configurable.
EVALUATOR = V8Evaluator
class V8EvalEvaluator(JSEvaluator):
@classmethod
def evaluate(cls, script, context):
if not _V8EVAL:
raise exc.MistralException(
"v8eval module is not available. Please install v8eval."
)
v8 = _V8EVAL.V8()
return v8.eval(('$ = %s; %s' % (json.dumps(context), script)).encode(
encoding='UTF-8'))
EVALUATOR = (V8EvalEvaluator if CONF.js_implementation == 'v8eval'
else PyV8Evaluator)
def evaluate(script, context):