Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0d3153f
Fix code so it works under Python 3.
Kami May 18, 2018
7ab7e1b
Also create RuleEnforcementDB objects for trigger instances which failed
Kami May 18, 2018
734f45a
Correctly use rule_spec dictionary.
Kami May 18, 2018
71c1ae6
Add test cases for it.
Kami May 18, 2018
09195cd
Include original exception message in the failure_reason and update
Kami May 18, 2018
13e2075
Add changelog entry.
Kami May 18, 2018
e659872
Re-generate requirements.txt, use specific mock version.
Kami May 18, 2018
3188864
Add missing RandomWords to st2tests in requirements.
Kami May 18, 2018
9ce1668
Also run st2reactor tests under Python 3.
Kami May 18, 2018
cba6f04
Give it more time for garbage collection to avoid false negatives under
Kami May 18, 2018
0dc2094
Add missing pyrabbit to st2tests in-requirements.
Kami May 18, 2018
5dd422d
More Python 3 compatibility fixes for tests.
Kami May 18, 2018
392aca1
Also run st2reactor integration tests under Python 3.
Kami May 18, 2018
4d7b426
Use tox 3.0.0.
Kami May 18, 2018
476973a
Print tox version.
Kami May 18, 2018
9c11d01
Remove step we dont need.
Kami May 18, 2018
0bf867e
Increase sleep.
Kami May 18, 2018
488bc50
For now ignore GC tests.
Kami May 18, 2018
d2774ee
Add missing __all__, expose SUPPORTED_FILTERS dict.
Kami May 22, 2018
7032bfe
Also expose some other constants so they can be re-used inside a new
Kami May 22, 2018
6fd512f
Fix MongoDB profiling util and make sure document fields are correctly
Kami May 22, 2018
9bc8a3e
Add new /v1/ruleenforcements/views[/<id>] API endpoint which returns
Kami May 22, 2018
e093656
Update rule enforcements views API endpoint to also include
Kami May 22, 2018
24b5b66
Add changelog entry.
Kami May 22, 2018
da163e1
Use consistent module name - separate words with underscore.
Kami May 22, 2018
0d8786e
Add use_object_ids argument to the fixtures loader.
Kami May 23, 2018
45dde7f
Add test cases for rule enforcement views API endpoint.
Kami May 23, 2018
1ba8e6f
Merge branch 'master' of github.com:StackStorm/st2 into rule_enforcem…
Kami May 23, 2018
e040526
Also include action.parameters and runner.runner_parameters attributes
Kami May 23, 2018
61c1b4f
Update affected tests.
Kami May 23, 2018
2ab0358
We also need execution.status attribute.
Kami May 23, 2018
f2f9eea
Update affected tests.
Kami May 23, 2018
546555d
Try build workaround.
Kami May 23, 2018
68c3267
Fix openapi ordering - in Python 3 ordering matters and if the entries
Kami May 23, 2018
278ad62
Make tests more robust.
Kami May 23, 2018
faf150d
Add a comment.
Kami May 23, 2018
2ff0788
Try a change.
Kami May 23, 2018
914de0a
Revert "Try a change."
Kami May 23, 2018
71ee887
Add new "status" field to the RuleEnforcementDB object.
Kami May 24, 2018
cc08bbc
Update affected tests.
Kami May 24, 2018
f9b2753
Add changelog entry.
Kami May 24, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ cache:
pip: true
directories:
- virtualenv/
- .tox/
# NOTE: Caching .tox speeds up py3 build for 30-60 seconds, but causes issues when dependencies
# are updated so it's disabled
#- .tox/

before_install:
# Work around for Travis timeout issues, see https://github.com/travis-ci/travis-ci/issues/9112
Expand All @@ -53,7 +55,7 @@ before_install:
- sudo pip install --upgrade "virtualenv==15.1.0"

install:
- if [ "${TASK}" = 'compilepy3 ci-py3-unit' ]; then pip install tox; else make requirements; fi
- if [ "${TASK}" = 'compilepy3 ci-py3-unit' ]; then pip install "tox==3.0.0"; else make requirements; fi
- if [ "${TASK}" = 'ci-unit' ] || [ "${TASK}" = 'ci-integration' ]; then pip install codecov; fi
- if [ "${TASK}" = 'ci-unit' ] || [ "${TASK}" = 'ci-integration' ] || [ "${TASK}" = 'compilepy3 ci-py3-unit' ]; then sudo .circle/add-itest-user.sh; fi

Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ Added
and functions. (new feature) #4004 #2974
* When running a dev (unstable) release include git revision hash in the output when using
``st2 --version`` CLI command. (new feature) #4117
* Update rules engine to also create rule enforcement object when trigger instances fails to match
a rule during the rule matching / filtering phase due to an exception in the rule criteria (e.g.
invalid Jinja expression, etc.).

This change increases visibility into rules which didn't match due to an exception. Previously
this was only visible / reflected in the rules engine log file. (improvement) #4134
* Add new ``GET /v1/ruleenforcements/views[/<enforcement id>]`` API endpoints which allow user to
retrieve RuleEnforcement objects with the corresponding TriggerInstance and Execution objects.
(new feature) #4134
* Add new ``status`` field to the ``RuleEnforcement`` model. This field can contain the following
values - ``succeeded`` (trigger instance matched a rule and action execution was triggered
successfully), ``failed`` (trigger instance matched a rule, but it didn't result in an action
execution due to Jinja rendering failure or other exception). (improvement) #4134

Changed
~~~~~~~
Expand Down
1 change: 1 addition & 0 deletions fixed-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ nose-timer>=0.7.2,<0.8
psutil==5.4.5
python-statsd==2.1.0
prometheus_client==0.1.1
mock==2.0.0
6 changes: 5 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Don't edit this file. It's generated automatically!
RandomWords
apscheduler==3.5.1
argcomplete
bcrypt
Expand All @@ -16,7 +17,7 @@ jsonpath-rw==1.4.0
jsonschema==2.6.0
kombu==4.1.0
lockfile==0.12.2
mock
mock==2.0.0
mongoengine==0.12.0
networkx==1.11
nose
Expand All @@ -26,15 +27,18 @@ oslo.utils<=3.33.0,>=3.15.0
paramiko==2.4.1
passlib==1.7.1
prettytable
prometheus_client==0.1.1
prompt-toolkit==1.0.15
psutil==5.4.5
pyinotify==0.9.6
pymongo==3.6.1
pyrabbit
python-dateutil
python-editor==1.0.3
python-gnupg==0.4.2
python-json-logger
python-keyczar==0.716
python-statsd==2.1.0
pytz
pyyaml<4.0,>=3.12
rednose
Expand Down
2 changes: 1 addition & 1 deletion st2api/st2api/controllers/exp/inquiries.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from six.moves import http_client
from st2common.models.db.auth import UserDB
from st2api.controllers.resource import ResourceController
from st2api.controllers.v1.executionviews import SUPPORTED_FILTERS
from st2api.controllers.v1.execution_views import SUPPORTED_FILTERS
from st2common import log as logging
from st2common.util import action_db as action_utils
from st2common.util import schema as util_schema
Expand Down
4 changes: 2 additions & 2 deletions st2api/st2api/controllers/v1/actionexecutions.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
from st2api.controllers.base import BaseRestControllerMixin
from st2api.controllers.resource import ResourceController
from st2api.controllers.resource import BaseResourceIsolationControllerMixin
from st2api.controllers.v1.executionviews import ExecutionViewsController
from st2api.controllers.v1.executionviews import SUPPORTED_FILTERS
from st2api.controllers.v1.execution_views import ExecutionViewsController
from st2api.controllers.v1.execution_views import SUPPORTED_FILTERS
from st2common import log as logging
from st2common.constants import action as action_constants
from st2common.exceptions import actionrunner as runner_exc
Expand Down
2 changes: 1 addition & 1 deletion st2api/st2api/controllers/v1/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
# StackStorm defined exceptions.

from st2api.controllers import resource
from st2api.controllers.v1.actionviews import ActionViewsController
from st2api.controllers.v1.action_views import ActionViewsController
from st2common import log as logging
from st2common.constants.triggers import ACTION_FILE_WRITTEN_TRIGGER
from st2common.exceptions.action import InvalidActionParameterException
Expand Down
2 changes: 1 addition & 1 deletion st2api/st2api/controllers/v1/packs.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def get_all(self):


class PacksController(BasePacksController):
from st2api.controllers.v1.packviews import PackViewsController
from st2api.controllers.v1.pack_views import PackViewsController

model = PackAPI
access = Pack
Expand Down
136 changes: 136 additions & 0 deletions st2api/st2api/controllers/v1/rule_enforcement_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

from st2common.models.api.rule_enforcement import RuleEnforcementViewAPI
from st2common.models.api.trigger import TriggerInstanceAPI
from st2common.models.api.execution import ActionExecutionAPI
from st2common.persistence.rule_enforcement import RuleEnforcement
from st2common.persistence.execution import ActionExecution
from st2common.persistence.trigger import TriggerInstance
from st2api.controllers.v1.rule_enforcements import SUPPORTED_FILTERS
from st2api.controllers.v1.rule_enforcements import QUERY_OPTIONS
from st2api.controllers.v1.rule_enforcements import FILTER_TRANSFORM_FUNCTIONS
from st2common.rbac.types import PermissionType

from st2api.controllers.resource import ResourceController

__all__ = [
'RuleEnforcementViewController'
]


class RuleEnforcementViewController(ResourceController):
"""
API controller which adds some extra information to the rule enforcement object so it makes
more efficient for UI and clients to render rule enforcement object.

Right now we include those fields:

* trigger_instance object for each rule enforcement object
* subset of an execution object in case execution was triggered
"""

model = RuleEnforcementViewAPI
access = RuleEnforcement

query_options = QUERY_OPTIONS

supported_filters = SUPPORTED_FILTERS
filter_transform_functions = FILTER_TRANSFORM_FUNCTIONS

def get_all(self, sort=None, offset=0, limit=None, requester_user=None, **raw_filters):
rule_enforcement_apis = super(RuleEnforcementViewController, self)._get_all(sort=sort,
offset=offset,
limit=limit,
raw_filters=raw_filters,
requester_user=requester_user)

rule_enforcement_apis.json = self._append_view_properties(rule_enforcement_apis.json)
return rule_enforcement_apis

def get_one(self, id, requester_user):
rule_enforcement_api = super(RuleEnforcementViewController,
self)._get_one_by_id(id, requester_user=requester_user,
permission_type=PermissionType.RULE_ENFORCEMENT_VIEW)
rule_enforcement_api = self._append_view_properties([rule_enforcement_api.__json__()])[0]
return rule_enforcement_api

def _append_view_properties(self, rule_enforcement_apis):
"""
Method which appends corresponding execution (if available) and trigger instance object
properties.
"""
trigger_instance_ids = set([])
execution_ids = []

for rule_enforcement_api in rule_enforcement_apis:
trigger_instance_ids.add(str(rule_enforcement_api['trigger_instance_id']))

if rule_enforcement_api.get('execution_id', None):
execution_ids.append(rule_enforcement_api['execution_id'])

# 1. Retrieve corresponding execution objects
# NOTE: Executions contain a lot of field and could contain a lot of data so we only
# retrieve fields we need
only_fields = [
'id',

'action.ref',
'action.parameters',

'runner.name',
'runner.runner_parameters',

'parameters',
'status'
]
execution_dbs = ActionExecution.query(id__in=execution_ids,
only_fields=only_fields)

execution_dbs_by_id = {}
for execution_db in execution_dbs:
execution_dbs_by_id[str(execution_db.id)] = execution_db

# 2. Retrieve corresponding trigger instance objects
trigger_instance_dbs = TriggerInstance.query(id__in=list(trigger_instance_ids))

trigger_instance_dbs_by_id = {}

for trigger_instance_db in trigger_instance_dbs:
trigger_instance_dbs_by_id[str(trigger_instance_db.id)] = trigger_instance_db

# Ammend rule enforcement objects with additional data
for rule_enforcement_api in rule_enforcement_apis:
rule_enforcement_api['trigger_instance'] = {}
rule_enforcement_api['execution'] = {}

trigger_instance_id = rule_enforcement_api['trigger_instance_id']
execution_id = rule_enforcement_api.get('execution_id', None)

trigger_instance_db = trigger_instance_dbs_by_id.get(trigger_instance_id, None)
execution_db = execution_dbs_by_id.get(execution_id, None)

if trigger_instance_db:
trigger_instance_api = TriggerInstanceAPI.from_model(trigger_instance_db)
rule_enforcement_api['trigger_instance'] = trigger_instance_api

if execution_db:
execution_api = ActionExecutionAPI.from_model(execution_db)
rule_enforcement_api['execution'] = execution_api

return rule_enforcement_apis


rule_enforcement_view_controller = RuleEnforcementViewController()
32 changes: 22 additions & 10 deletions st2api/st2api/controllers/v1/rule_enforcements.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@
from st2common.util import isotime
from st2common.rbac.types import PermissionType

from st2api.controllers import resource
from st2api.controllers.resource import ResourceController

__all__ = [
'RuleEnforcementController',

'SUPPORTED_FILTERS',
'QUERY_OPTIONS',
'FILTER_TRANSFORM_FUNCTIONS'
]


http_client = six.moves.http_client
Expand All @@ -39,23 +47,27 @@
'enforced_at_lt': 'enforced_at.lt'
}

QUERY_OPTIONS = {
'sort': ['-enforced_at', 'rule.ref']
}

FILTER_TRANSFORM_FUNCTIONS = {
'enforced_at': lambda value: isotime.parse(value=value),
'enforced_at_gt': lambda value: isotime.parse(value=value),
'enforced_at_lt': lambda value: isotime.parse(value=value)
}


class RuleEnforcementController(resource.ResourceController):
class RuleEnforcementController(ResourceController):

model = RuleEnforcementAPI
access = RuleEnforcement

# ResourceController attributes
query_options = {
'sort': ['-enforced_at', 'rule.ref']
}
query_options = QUERY_OPTIONS

supported_filters = SUPPORTED_FILTERS
filter_transform_functions = {
'enforced_at': lambda value: isotime.parse(value=value),
'enforced_at_gt': lambda value: isotime.parse(value=value),
'enforced_at_lt': lambda value: isotime.parse(value=value)
}
filter_transform_functions = FILTER_TRANSFORM_FUNCTIONS

def get_all(self, sort=None, offset=0, limit=None, requester_user=None, **raw_filters):
return super(RuleEnforcementController, self)._get_all(sort=sort,
Expand Down
2 changes: 1 addition & 1 deletion st2api/st2api/controllers/v1/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from st2api.controllers.resource import BaseResourceIsolationControllerMixin
from st2api.controllers.resource import ContentPackResourceController
from st2api.controllers.controller_transforms import transform_to_bool
from st2api.controllers.v1.ruleviews import RuleViewController
from st2api.controllers.v1.rule_views import RuleViewController
from st2common.models.api.rule import RuleAPI
from st2common.models.db.auth import UserDB
from st2common.persistence.rule import Rule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from st2common.util import isotime
from st2common.util import date as date_utils
from st2api.controllers.v1.actionexecutions import ActionExecutionsController
from st2api.controllers.v1.executionviews import FILTERS_WITH_VALID_NULL_VALUES
from st2api.controllers.v1.execution_views import FILTERS_WITH_VALID_NULL_VALUES
from st2common.persistence.execution import ActionExecution
from st2common.models.api.execution import ActionExecutionAPI

Expand Down
2 changes: 1 addition & 1 deletion st2api/tests/unit/controllers/v1/test_packs_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def test_get_pack_file_pack_doesnt_exist(self):
resp = self.app.get('/v1/packs/views/files/doesntexist/pack.yaml', expect_errors=True)
self.assertEqual(resp.status_int, http_client.NOT_FOUND)

@mock.patch('st2api.controllers.v1.packviews.MAX_FILE_SIZE', 1)
@mock.patch('st2api.controllers.v1.pack_views.MAX_FILE_SIZE', 1)
def test_pack_file_file_larger_then_maximum_size(self):
resp = self.app.get('/v1/packs/views/file/dummy_pack_1/pack.yaml', expect_errors=True)
self.assertEqual(resp.status_int, http_client.BAD_REQUEST)
Expand Down
Loading