Skip to content

Commit 7e8439e

Browse files
committed
chg: Add support for alert violations
1 parent 07b4430 commit 7e8439e

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

newrelic_api/alert_violations.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from .base import Resource
2+
3+
4+
class AlertViolations(Resource):
5+
"""
6+
An interface for interacting with the NewRelic Alerts Violations API.
7+
"""
8+
def list(self, filter_start_date=None, filter_end_date=None, filter_only_open=None, page=None):
9+
"""
10+
This API endpoint returns a paginated list of the violations
11+
associated with your New Relic account. Alert violations can be filtered
12+
by time window and open status.
13+
14+
:type filter_start_date: datetime.datetime
15+
:param filter_start_date: Filter to violations created after this time
16+
17+
:type filter_end_date: datetime.datetime
18+
:param filter_end_date: Filter to violations created before this time
19+
20+
:type filter_only_open: boolean
21+
:param filter_start_date: Filter by open violations
22+
23+
:type page: int
24+
:param page: Pagination index
25+
26+
:rtype: dict
27+
:return: The JSON response of the API, with an additional 'pages' key
28+
if there are paginated results
29+
30+
::
31+
32+
{
33+
"violation": {
34+
"id": "integer",
35+
"label": "string",
36+
"duration": "integer",
37+
"policy_name": "string",
38+
"condition_name": "string",
39+
"priority": "string",
40+
"opened_at": "integer",
41+
"closed_at": "integer",
42+
"entity": {
43+
"product": "string",
44+
"type": "string",
45+
"group_id": "integer",
46+
"id": "integer",
47+
"name": "string"
48+
},
49+
"links": {
50+
"policy_id": "integer",
51+
"condition_id": "integer",
52+
"incident_id": "integer"
53+
}
54+
}
55+
}
56+
57+
"""
58+
filters = [
59+
'start_date={0}'.format(filter_start_date.isoformat()) if filter_start_date else None,
60+
'end_date={0}'.format(filter_end_date.isoformat()) if filter_end_date else None,
61+
'only_open={0}'.format('true' if filter_only_open else 'false') if filter_only_open is not None else None,
62+
'page={0}'.format(page) if page else None
63+
]
64+
65+
return self._get(
66+
url='{0}alerts_violations.json'.format(self.URL),
67+
headers=self.headers,
68+
params=self.build_param_string(filters)
69+
)
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
from unittest import TestCase
2+
3+
from mock import patch, Mock
4+
import requests
5+
import datetime
6+
7+
from newrelic_api.alert_violations import AlertViolations
8+
9+
10+
class NRAlertViolationsTests(TestCase):
11+
def setUp(self):
12+
super(NRAlertViolationsTests, self).setUp()
13+
self.violation = AlertViolations(api_key='dummy_key')
14+
15+
self.violations_list_response = {
16+
"violations": [
17+
{
18+
"id": 12345,
19+
"label": "Violation of Default Server Policy",
20+
"duration": 100,
21+
"policy_name": "Default Server Policy",
22+
"condition_name": "CPU usage alert",
23+
"priority": "Warning",
24+
"opened_at": 123456789012,
25+
"entity": {
26+
"product": "Apm",
27+
"type": "Application",
28+
"group_id": 123456,
29+
"id": 1234567,
30+
"name": "Developer Application"
31+
},
32+
"links": {
33+
"policy_id": 12345,
34+
"condition_id": 100
35+
}
36+
}
37+
]
38+
}
39+
40+
@patch.object(requests, 'get')
41+
def test_list_success(self, mock_get):
42+
"""
43+
Test alert violations .list()
44+
"""
45+
mock_response = Mock(name='response')
46+
mock_response.json.return_value = self.violations_list_response
47+
mock_get.return_value = mock_response
48+
49+
# Call the method
50+
response = self.violation.list()
51+
52+
self.assertIsInstance(response, dict)
53+
mock_get.assert_called_once_with(
54+
url='https://api.newrelic.com/v2/alerts_violations.json',
55+
headers=self.violation.headers,
56+
params=''
57+
)
58+
59+
@patch.object(requests, 'get')
60+
def test_list_success_with_filters(self, mock_get):
61+
"""
62+
Test alert viollations .list() with filters
63+
"""
64+
mock_response = Mock(name='response')
65+
mock_response.json.return_value = self.violations_list_response
66+
mock_get.return_value = mock_response
67+
68+
# Call the method
69+
response = self.violation.list(
70+
filter_start_date=datetime.datetime(2000, 1, 1, 12, 0, 0, 0),
71+
filter_end_date=datetime.datetime(2010, 1, 1, 12, 0, 0, 0),
72+
filter_only_open=True,
73+
page=1
74+
)
75+
76+
self.assertIsInstance(response, dict)
77+
mock_get.assert_called_once_with(
78+
url='https://api.newrelic.com/v2/alerts_violations.json',
79+
headers=self.violation.headers,
80+
params='start_date=2000-01-01T12:00:00+00:00&end_date=2010-01-01T12:00:00+00:00&only_open=true&page=1'
81+
)
82+
83+
@patch.object(requests, 'get')
84+
def test_list_failure(self, mock_get):
85+
"""
86+
Test alert policies .list() failure case
87+
"""
88+
mock_response = Mock(name='response')
89+
mock_response.json.side_effect = ValueError('No JSON object could be decoded')
90+
mock_get.return_value = mock_response
91+
92+
with self.assertRaises(ValueError):
93+
# Call the method
94+
self.violation.list()

0 commit comments

Comments
 (0)