Repository: StackStorm/st2

Issue:
Special characters in object keys
Trying to run an action with `type:object` parameter with the key containing `.` like

```
{
  "a.b": "c"
}
```

returns 500 and creates a record in logs:

```
2015-11-11 23:55:43,183 ERROR [-] Unable to execute action. Unexpected error encountered.
Traceback (most recent call last):
  File "/mnt/st2/st2api/st2api/controllers/v1/actionexecutions.py", line 119, in _handle_schedule_execution
    return self._schedule_execution(liveaction=liveaction)
  File "/mnt/st2/st2api/st2api/controllers/v1/actionexecutions.py", line 149, in _schedule_execution
    _, actionexecutiondb = action_service.request(liveactiondb)
  File "/mnt/st2/st2common/st2common/services/action.py", line 98, in request
    liveaction = LiveAction.add_or_update(liveaction, publish=False)
  File "/mnt/st2/st2common/st2common/persistence/base.py", line 155, in add_or_update
    model_object = cls._get_impl().add_or_update(model_object)
  File "/mnt/st2/st2common/st2common/models/db/__init__.py", line 174, in add_or_update
    instance.save()
  File "/mnt/st2/virtualenv/local/lib/python2.7/site-packages/mongoengine/document.py", line 224, in save
    self.validate(clean=clean)
  File "/mnt/st2/virtualenv/local/lib/python2.7/site-packages/mongoengine/base/document.py", line 323, in validate
    raise ValidationError(message, errors=errors)
ValidationError: ValidationError (LiveActionDB:None) (Invalid dictionary key name - keys may not contain "." or "$" characters: ['parameters'])
2015-11-11 23:55:43,192 DEBUG [-] API call failed: None (exception_message='ValidationError (LiveActionDB:None) (Invalid dictionary key name - keys may not contain "." or "$" characters: [\'parameters\'])',exception_data={'comment': None, '_headers': None, 'conditional_response': False, 'detail': 'ValidationError (LiveActionDB:None) (Invalid dictionary key name - keys may not contain "." or "$" characters: [\'parameters\'])', '_app_iter': [''], '_status': '500 Internal Server Error', '_headerlist': [('Content-Type', 'text/html; charset=UTF-8'), ('Content-Length', '0')]},exception_class='HTTPInternalServerError')
2015-11-11 23:55:43,193 INFO [-] 2e24e698-6aa7-40d6-8122-b598b978bb44 - POST /v1/executions (remote_addr='172.168.60.1',method='POST',status_code='500 Internal Server Error',request_id='2e24e698-6aa7-40d6-8122-b598b978bb44',path='/v1/executions')
172.168.60.1 - - [11/Nov/2015 23:55:43] "POST /v1/executions HTTP/1.1" 500 646 0.021786
```

As much as I would like to just say "there's the list of characters you can't use in your object keys", we have a `core.remote` action which keys do indeed contain dots.



Discussion:

Resolving patch:
diff --git a/st2common/st2common/models/db/action.py b/st2common/st2common/models/db/action.py
--- a/st2common/st2common/models/db/action.py
+++ b/st2common/st2common/models/db/action.py
@@ -73,7 +73,7 @@ class ActionDB(stormbase.StormFoundationDB, stormbase.TagsMixin,
     runner_type = me.DictField(
         required=True, default={},
         help_text='The action runner to use for executing the action.')
-    parameters = me.DictField(
+    parameters = stormbase.EscapedDynamicField(
         help_text='The specification for parameters for the action.')
     notify = me.EmbeddedDocumentField(NotificationSchema)
 
diff --git a/st2common/st2common/models/db/execution.py b/st2common/st2common/models/db/execution.py
--- a/st2common/st2common/models/db/execution.py
+++ b/st2common/st2common/models/db/execution.py
@@ -54,7 +54,7 @@ class ActionExecutionDB(stormbase.StormFoundationDB):
         help_text='The timestamp when the liveaction was created.')
     end_timestamp = ComplexDateTimeField(
         help_text='The timestamp when the liveaction has finished.')
-    parameters = me.DictField(
+    parameters = stormbase.EscapedDynamicField(
         default={},
         help_text='The key-value pairs passed as to the action runner & action.')
     result = stormbase.EscapedDynamicField(
diff --git a/st2common/st2common/models/db/liveaction.py b/st2common/st2common/models/db/liveaction.py
--- a/st2common/st2common/models/db/liveaction.py
+++ b/st2common/st2common/models/db/liveaction.py
@@ -59,7 +59,7 @@ class LiveActionDB(stormbase.StormFoundationDB):
     action = me.StringField(
         required=True,
         help_text='Reference to the action that has to be executed.')
-    parameters = me.DictField(
+    parameters = stormbase.EscapedDynamicField(
         default={},
         help_text='The key-value pairs passed as to the action runner & execution.')
     result = stormbase.EscapedDynamicField(


Test patch:
diff --git a/st2actions/tests/unit/test_notifier.py b/st2actions/tests/unit/test_notifier.py
--- a/st2actions/tests/unit/test_notifier.py
+++ b/st2actions/tests/unit/test_notifier.py
@@ -80,7 +80,8 @@ def dispatch(self, *args, **kwargs):
                 self.tester.fail('Test failed')
 
     @mock.patch('st2common.util.action_db.get_action_by_ref', mock.MagicMock(
-        return_value=ActionDB(pack='core', name='local', runner_type={'name': 'run-local-cmd'})))
+        return_value=ActionDB(pack='core', name='local', runner_type={'name': 'run-local-cmd'},
+                              parameters={})))
     @mock.patch('st2common.util.action_db.get_runnertype_by_name', mock.MagicMock(
         return_value=RunnerTypeDB(runner_parameters={})))
     @mock.patch.object(Action, 'get_by_ref', mock.MagicMock(