st2
st2 copied to clipboard
Rendering rule action parameters with quoted strings causes an error
SUMMARY
When invoking a rule that processes a trigger with a value containing a quoted string causes an error.
ISSUE TYPE
- Bug Report
STACKSTORM VERSION
# st2 --version
st2 3.0.0, on Python 2.7.5
OS / ENVIRONMENT / INSTALL METHOD
CentOS 7.6
Puppet-st2
STEPS TO REPRODUCE
rule.yaml
---
name: "quoted_param_in_trigger_bug"
pack: "default"
description: "Demos how quoted values in a trigger instance cause render failures in a rule."
enabled: true
trigger:
type: "core.st2.key_value_pair.update"
criteria: {}
action:
ref: "examples.test"
parameters:
data:
test: "{{ trigger.object.value }}"
trigger.yaml (yes, this file needs to be called .yaml even though it has JSON data in it)
{
"id": "5ceed2bb9387ef0cefd1384b",
"occurrence_time": "2019-05-29T14:43:07.000000Z",
"payload": {
"object": {
"encrypted": false,
"id": "5ceed29d9387ef2a25148f26",
"name": "nick_test",
"scope": "st2kv.system",
"secret": false,
"uid": "key_value_pair:st2kv.system:nick_test",
"value": "Nick Test \"quoted string data\" blah"
}
},
"status": "processed",
"trigger": "core.st2.key_value_pair.update"
}
EXPECTED RESULTS
$ st2-rule-tester --rule=./rule.yaml --trigger-instance=./trigger.yaml --config-file=/etc/st2/st2.conf
2019-05-29 14:49:24,439 INFO [-] Connecting to database "st2" @ "127.0.0.1:27017" as user "stackstorm".
2019-05-29 14:49:24,443 INFO [-] Successfully connected to database "st2" @ "127.0.0.1:27017" as user "stackstorm".
2019-05-29 14:49:24,592 INFO [-] Validating rule default.quoted_param_in_trigger_bug for st2.key_value_pair.update.
2019-05-29 14:49:24,592 INFO [-] 1 rule(s) found to enforce for st2.key_value_pair.update.
2019-05-29 14:49:24,593 INFO [-] Failed to retrieve config for pack <Mock name='mock.pack' id='139681899526160'> and user stanley: 'Mock' object is not iterable
2019-05-29 14:49:24,598 INFO [-] Action parameters resolved to:
2019-05-29 14:49:24,598 INFO [-] data: {u'test': u'Nick Test "quoted string data" blah'}
2019-05-29 14:49:24,598 INFO [-] === RULE MATCHES ===
ACTUAL RESULTS
Note: i have removed a bunch of the exception catching code so we can see the real stack trace instead of the "masked" version that hides the root of the issue.
$ st2-rule-tester --rule=./rule.yaml --trigger-instance=./trigger.yaml --config-file=/etc/st2/st2.conf
2019-05-29 14:48:54,608 INFO [-] Connecting to database "st2" @ "127.0.0.1:27017" as user "stackstorm".
2019-05-29 14:48:54,612 INFO [-] Successfully connected to database "st2" @ "127.0.0.1:27017" as user "stackstorm".
2019-05-29 14:48:54,752 INFO [-] Validating rule default.quoted_param_in_trigger_bug for st2.key_value_pair.update.
2019-05-29 14:48:54,752 INFO [-] 1 rule(s) found to enforce for st2.key_value_pair.update.
2019-05-29 14:48:54,753 INFO [-] Failed to retrieve config for pack <Mock name='mock.pack' id='140023090276368'> and user stanley: 'Mock' object is not iterable
Traceback (most recent call last):
File "/usr/bin/st2-rule-tester", line 21, in <module>
rule_tester.main()
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2reactor/cmd/rule_tester.py", line 58, in main
matches = tester.evaluate()
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2reactor/rules/tester.py", line 106, in evaluate
additional_contexts=additional_contexts)
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2reactor/rules/enforcer.py", line 84, in get_resolved_parameters
additional_contexts=additional_contexts)
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/util/param.py", line 312, in render_live_params
context = _resolve_dependencies(G)
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/util/param.py", line 224, in _resolve_dependencies
context[name] = _render(node, context)
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/util/param.py", line 208, in _render
result = json.loads(result)
File "/usr/lib64/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/usr/lib64/python2.7/json/decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib64/python2.7/json/decoder.py", line 382, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting ',' delimiter: line 1 column 22 (char 21)
Debugging
If i run with --debug you can see the render parameter issue:
$ st2-rule-tester --rule=./rule.yaml --trigger-instance=./trigger.yaml --config-file=/etc/st2/st2.conf --debug
2019-05-29 14:54:15,053 INFO [-] Connecting to database "st2" @ "127.0.0.1:27017" as user "stackstorm".
2019-05-29 14:54:15,058 INFO [-] Successfully connected to database "st2" @ "127.0.0.1:27017" as user "stackstorm".
2019-05-29 14:54:15,058 DEBUG [-] Ensuring database indexes...
2019-05-29 14:54:15,152 DEBUG [-] Skipping index cleanup for blacklisted model "PermissionGrantDB"...
2019-05-29 14:54:15,197 DEBUG [-] Indexes are ensured for models: ActionAliasDB, ActionAliasDB, ActionDB, ActionExecutionDB, ActionExecutionDB, ActionExecutionOutputDB, ActionExecutionSchedulingQueueItemDB, ActionExecutionStateDB, ActionExecutionStateDB, ApiKeyDB, ConfigDB, ConfigSchemaDB, GroupToRoleMappingDB, KeyValuePairDB, LiveActionDB, LiveActionDB, PackDB, PermissionGrantDB, PolicyDB, PolicyTypeDB, RoleDB, RuleDB, RuleEnforcementDB, RunnerTypeDB, RunnerTypeDB, SensorTypeDB, TaskExecutionDB, TokenDB, TraceDB, TriggerDB, TriggerInstanceDB, TriggerTypeDB, UserDB, UserRoleAssignmentDB, WorkflowExecutionDB
2019-05-29 14:54:15,204 INFO [-] Validating rule default.quoted_param_in_trigger_bug for st2.key_value_pair.update.
2019-05-29 14:54:15,204 DEBUG [-] Trigger payload: {u'object': {u'uid': u'key_value_pair:st2kv.system:nick_test', u'encrypted': False, u'value': u'Nick Test "quoted string data" blah', u'secret': False, u'scope': u'st2kv.system', u'id': u'5ceed29d9387ef2a25148f26', u'name': u'nick_test'}}
2019-05-29 14:54:15,204 DEBUG [-] [1st_pass] 1 rule(s) found to enforce for st2.key_value_pair.update.
2019-05-29 14:54:15,204 DEBUG [-] [2nd_pass] 0 rule(s) found to enforce for st2.key_value_pair.update.
2019-05-29 14:54:15,204 INFO [-] 1 rule(s) found to enforce for st2.key_value_pair.update.
2019-05-29 14:54:15,205 DEBUG [-] Attempting to get config for pack "<Mock name='mock.pack' id='139946342672592'>" and user "stanley"
2019-05-29 14:54:15,205 DEBUG [-] Pack and user found. Loading config.
2019-05-29 14:54:15,205 INFO [-] Failed to retrieve config for pack <Mock name='mock.pack' id='139946342672592'> and user stanley: 'Mock' object is not iterable
2019-05-29 14:54:15,208 DEBUG [-] Template ast: Template(body=[Output(nodes=[TemplateData(data=u"{'test': '"), Getattr(node=Getattr(node=Name(name='trigger', ctx='load'), attr='object', ctx='load'), attr='value', ctx='load'), TemplateData(data=u"'}")])])
2019-05-29 14:54:15,209 DEBUG [-] Dependencies: set(['trigger'])
2019-05-29 14:54:15,209 DEBUG [-] Rendering complex type: {"test": "{{ trigger.object.value }}"}
2019-05-29 14:54:15,209 DEBUG [-] Rendering node: {'template': '{"test": "{{ trigger.object.value }}"}'} with context: {'trigger': {u'object': {u'uid': u'key_value_pair:st2kv.system:nick_test', u'encrypted': False, u'value': u'Nick Test "quoted string data" blah', u'secret': False, u'scope': u'st2kv.system', u'id': u'5ceed29d9387ef2a25148f26', u'name': u'nick_test'}}, 'action_context': {'trigger_instance': {'id': 'rule_tester_instance', 'name': None}, 'user': 'stanley', 'rule': {'id': 'rule_tester_rule', 'name': u'quoted_param_in_trigger_bug'}, 'pack': <Mock name='mock.pack' id='139946342672592'>}, 'st2kv': {'system': <st2common.services.keyvalues.KeyValueLookup object at 0x7f47cc0ae850>, 'user': <st2common.services.keyvalues.UserKeyValueLookup object at 0x7f47cc0aeb10>}}
2019-05-29 14:54:15,210 DEBUG [-] Render complete: {"test": "Nick Test "quoted string data" blah"}
Traceback (most recent call last):
File "/usr/bin/st2-rule-tester", line 21, in <module>
rule_tester.main()
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2reactor/cmd/rule_tester.py", line 58, in main
matches = tester.evaluate()
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2reactor/rules/tester.py", line 106, in evaluate
additional_contexts=additional_contexts)
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2reactor/rules/enforcer.py", line 84, in get_resolved_parameters
additional_contexts=additional_contexts)
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/util/param.py", line 312, in render_live_params
context = _resolve_dependencies(G)
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/util/param.py", line 224, in _resolve_dependencies
context[name] = _render(node, context)
File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/util/param.py", line 208, in _render
result = json.loads(result)
File "/usr/lib64/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/usr/lib64/python2.7/json/decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib64/python2.7/json/decoder.py", line 382, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting ',' delimiter: line 1 column 22 (char 21)
The final line:
2019-05-29 14:54:15,210 DEBUG [-] Render complete: {"test": "Nick Test "quoted string data" blah"}
You can see the quotes inside the string are not escaped resulting in invalid JSON
FYI i've been able to work around this problem using the | json_escape filter in my rule:
---
name: "quoted_param_in_trigger_bug"
pack: "default"
description: "Demos how quoted values in a trigger instance cause render failures in a rule."
enabled: true
trigger:
type: "core.st2.key_value_pair.update"
criteria: {}
action:
ref: "examples.test"
parameters:
data:
test: "{{ trigger.object.value | json_escape }}"
The | json_escape trick only works if you're extracting a single field. If you're extracting an object or array you still get an error, see the rule below:
---
name: "quoted_param_in_trigger_bug"
pack: "default"
description: "Demos how quoted values in a trigger instance cause render failures in a rule."
enabled: true
trigger:
type: "core.st2.key_value_pair.update"
criteria: {}
action:
ref: "examples.test"
parameters:
data:
test: "{{ trigger.object | json_escape }}"
Since i'm getting the entire trigger.object it fails to render. If i limit the data to extract just the single field trigger.object.value then | json_escape properly escapes the string and can work around the error.
Thanks for making this ticket @nmaludy
Failed to retrieve config for pack <Mock name='mock.pack' id='140714291121680'> and user digitalxcadmin: expected string or bytes-like object i am getting error like this give me a sollution for this.