Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Added
* 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
execution due to Jinja rendering failure or other exception). (improvement) #4134 #4152
* Add trigger type reference based filtering to the ``/v1/triggerinstances`` API endpoint - e.g.
``/v1/triggerinstances?trigger_type=core.st2.webhook``. (new feature) #4151

Expand Down
11 changes: 11 additions & 0 deletions st2common/st2common/models/db/rule_enforcement.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from st2common.models.db import stormbase
from st2common.util import date as date_utils
from st2common.constants.rule_enforcement import RULE_ENFORCEMENT_STATUS_SUCCEEDED
from st2common.constants.rule_enforcement import RULE_ENFORCEMENT_STATUS_FAILED

__all__ = [
'RuleReferenceSpecDB',
Expand Down Expand Up @@ -77,6 +78,16 @@ class RuleEnforcementDB(stormbase.StormFoundationDB, stormbase.TagsMixin):
] + stormbase.TagsMixin.get_indices()
}

def __init__(self, *args, **values):
super(RuleEnforcementDB, self).__init__(*args, **values)

# Set status to succeeded for old / existing RuleEnforcementDB which predate status field
status = getattr(self, 'status', None)
failure_reason = getattr(self, 'failure_reason', None)

if status in [None, RULE_ENFORCEMENT_STATUS_SUCCEEDED] and failure_reason:
self.status = RULE_ENFORCEMENT_STATUS_FAILED

# NOTE: Note the following method is exposed so loggers in rbac resolvers can log objects
# with a consistent get_uid interface.
def get_uid(self):
Expand Down
58 changes: 58 additions & 0 deletions st2common/tests/unit/test_db_rule_enforcement.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@
from st2common.models.db.rule_enforcement import RuleEnforcementDB
from st2common.persistence.rule_enforcement import RuleEnforcement
from st2common.transport.publishers import PoolPublisher
from st2common.constants.rule_enforcement import RULE_ENFORCEMENT_STATUS_SUCCEEDED
from st2common.constants.rule_enforcement import RULE_ENFORCEMENT_STATUS_FAILED
from st2common.exceptions.db import StackStormDBObjectNotFoundError

from st2tests import DbTestCase

SKIP_DELETE = False

__all__ = [
'RuleEnforcementModelTest'
]


@mock.patch.object(PoolPublisher, 'publish', mock.MagicMock())
class RuleEnforcementModelTest(DbTestCase):
Expand All @@ -51,6 +58,57 @@ def test_ruleenforcment_crud(self):
retrieved = None
self.assertIsNone(retrieved, 'managed to retrieve after delete.')

def test_status_set_to_failed_for_objects_which_predate_status_field(self):
rule = {
'ref': 'foo_pack.foo_rule',
'uid': 'rule:foo_pack:foo_rule'
}

# 1. No status field explicitly set and no failure reason
enforcement_db = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()),
rule=rule,
execution_id=str(bson.ObjectId()))
enforcement_db = RuleEnforcement.add_or_update(enforcement_db)

self.assertEqual(enforcement_db.status, RULE_ENFORCEMENT_STATUS_SUCCEEDED)

# 2. No status field, with failure reason, status should be set to failed
enforcement_db = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()),
rule=rule,
execution_id=str(bson.ObjectId()),
failure_reason='so much fail')
enforcement_db = RuleEnforcement.add_or_update(enforcement_db)

self.assertEqual(enforcement_db.status, RULE_ENFORCEMENT_STATUS_FAILED)

# 3. Explcit status field - succeeded + failure reasun
enforcement_db = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()),
rule=rule,
execution_id=str(bson.ObjectId()),
status=RULE_ENFORCEMENT_STATUS_SUCCEEDED,
failure_reason='so much fail')
enforcement_db = RuleEnforcement.add_or_update(enforcement_db)

self.assertEqual(enforcement_db.status, RULE_ENFORCEMENT_STATUS_FAILED)

# 4. Explcit status field - succeeded + no failure reasun
enforcement_db = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()),
rule=rule,
execution_id=str(bson.ObjectId()),
status=RULE_ENFORCEMENT_STATUS_SUCCEEDED)
enforcement_db = RuleEnforcement.add_or_update(enforcement_db)

self.assertEqual(enforcement_db.status, RULE_ENFORCEMENT_STATUS_SUCCEEDED)

# 5. Explcit status field - failed + no failure reasun
enforcement_db = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()),
rule=rule,
execution_id=str(bson.ObjectId()),
status=RULE_ENFORCEMENT_STATUS_FAILED)
enforcement_db = RuleEnforcement.add_or_update(enforcement_db)

self.assertEqual(enforcement_db.status, RULE_ENFORCEMENT_STATUS_FAILED)

@staticmethod
def _create_save_rule_enforcement():
created = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()),
Expand Down