Skip to content

Commit

Permalink
Merge pull request #58 from DataDog/clarify_mute_all
Browse files Browse the repository at this point in the history
Clarify monitor muting endpoints
  • Loading branch information
yannmh committed Jun 30, 2015
2 parents 282395e + a124a35 commit bcfccf2
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 24 deletions.
2 changes: 1 addition & 1 deletion datadog/api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def request(cls, method, path, body=None, attach_host_name=False, response_forma
cls._timeout_counter += 1
raise HttpTimeout('%s %s timed out after %d seconds.' % (method, url, _timeout))
except requests.exceptions.HTTPError as e:
if e.response.status_code == 404 or e.response.status_code == 400:
if e.response.status_code in (400, 403, 404):
pass
else:
raise
Expand Down
7 changes: 5 additions & 2 deletions datadog/api/monitors.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,17 @@ def unmute(cls, id, **params):
:param scope: scope to apply the unmute
:type scope: string
:param all_scopes: if True, clears mute settings for all scopes
:type all_scopes: boolean
:returns: JSON response from HTTP request
"""
return super(Monitor, cls)._trigger_class_action('POST', 'unmute', id, **params)

@classmethod
def mute_all(cls):
"""
Mute all monitors.
Globally mute monitors.
:returns: JSON response from HTTP request
"""
Expand All @@ -88,7 +91,7 @@ def mute_all(cls):
@classmethod
def unmute_all(cls):
"""
Unmute all monitors.
Cancel global monitor mute setting (does not remove mute settings for individual monitors).
:returns: JSON response from HTTP request
"""
Expand Down
26 changes: 16 additions & 10 deletions datadog/dogshell/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,28 @@ def setup_parser(cls, subparsers):
delete_parser.add_argument('monitor_id', help="monitor to delete")
delete_parser.set_defaults(func=cls._delete)

mute_all_parser = verb_parsers.add_parser('mute_all', help="Mute all monitors")
mute_all_parser = verb_parsers.add_parser('mute_all', help="Globally mute "
"monitors (downtime over *)")
mute_all_parser.set_defaults(func=cls._mute_all)

unmute_all_parser = verb_parsers.add_parser('unmute_all', help="Unmute all monitors")
unmute_all_parser = verb_parsers.add_parser('unmute_all', help="Globally unmute "
"monitors (cancel downtime over *)")
unmute_all_parser.set_defaults(func=cls._unmute_all)

mute_parser = verb_parsers.add_parser('mute', help="Mute a monitor")
mute_parser.add_argument('monitor_id', help="monitor to mute")
mute_parser.add_argument('--scope', help="scope to apply the mute to,"
" e.g. role:db", default=[])
" e.g. role:db (optional)", default=[])
mute_parser.add_argument('--end', help="POSIX timestamp for when"
" the mute should end", default=None)
" the mute should end (optional)", default=None)
mute_parser.set_defaults(func=cls._mute)

unmute_parser = verb_parsers.add_parser('unmute', help="Unmute a monitor")
unmute_parser.add_argument('monitor_id', help="monitor to unmute")
unmute_parser.add_argument('--scope', help="scope to apply the mute to, "
unmute_parser.add_argument('--scope', help="scope to unmute (must be muted), "
"e.g. role:db", default=[])
unmute_parser.add_argument('--all_scopes', help="clear muting across all scopes",
action='store_true')
unmute_parser.set_defaults(func=cls._unmute)

@classmethod
Expand Down Expand Up @@ -194,8 +198,10 @@ def _mute(cls, args):
@classmethod
def _unmute(cls, args):
api._timeout = args.timeout
# TODO CHECK
res = api.Monitor.unmute(args.monitor_id, scope=args.scope)
if res is not None:
report_warnings(res)
report_errors(res)
res = api.Monitor.unmute(args.monitor_id, scope=args.scope, all_scopes=args.all_scopes)
report_warnings(res)
report_errors(res)
if format == 'pretty':
print(cls._pretty_json(res))
else:
print(json.dumps(res))
25 changes: 18 additions & 7 deletions tests/integration/api/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,10 +357,8 @@ def test_type_check(self):
dog.Metric.send(metric="test.metric", points=1.0)
dog.Metric.send(metric="test.metric", points=(time.time(), 1.0))

@attr('monitor')
def test_monitors(self):
# Stop testing 'silenced' parameter
# Depending on the enabled flag (i.e. API release), 'silenced' can be a boolean or a dictionnary

query = "avg(last_1h):sum:system.net.bytes_rcvd{host:host0} > 100"

monitor_id = dog.Monitor.create(query=query, type="metric alert")['id']
Expand All @@ -371,13 +369,15 @@ def test_monitors(self):

options = {
"notify_no_data": True,
"no_data_timeframe": 20
"no_data_timeframe": 20,
"silenced": {"*": None}
}
dog.Monitor.update(monitor_id, query=query, silenced=True, options=options, timeout_h=1)
dog.Monitor.update(monitor_id, query=query, options=options, timeout_h=1)
monitor = dog.Monitor.get(monitor_id)
assert monitor['query'] == query, monitor['query']
assert monitor['options']['notify_no_data'] == True, monitor['options']['notify_no_data']
assert monitor['options']['no_data_timeframe'] == 20, monitor['options']['notify_no_data']
assert monitor['options']['no_data_timeframe'] == 20, monitor['options']['no_data_timeframe']
assert monitor['options']['silenced'] == {"*": None}, monitor['options']['silenced']

dog.Monitor.delete(monitor_id)
try:
Expand Down Expand Up @@ -676,6 +676,17 @@ def test_monitor_muting(self):
monitor = dog.Monitor.get(monitor_id)
eq(monitor['options']['silenced'], {})

options = {
"silenced": {"host:abcd1234": None, "host:abcd1235": None}
}
dog.Monitor.update(monitor_id, query=query, options=options)
monitor = dog.Monitor.get(monitor_id)
eq(monitor['options']['silenced'], options['silenced'])

dog.Monitor.unmute(monitor_id, all_scopes=True)
monitor = dog.Monitor.get(monitor_id)
eq(monitor['options']['silenced'], {})

dog.Monitor.delete(monitor_id)

@attr('monitor')
Expand Down Expand Up @@ -740,7 +751,7 @@ def test_host_muting(self):
eq(mute['action'], "Muted")
eq(mute['end'], end2)

unmute = dog.Host.unmute(hostname)
dog.Host.unmute(hostname)

if __name__ == '__main__':
unittest.main()
31 changes: 27 additions & 4 deletions tests/integration/dogshell/test_dogshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ def test_screenboards(self):

def test_monitors(self):
# Create a monitor
query = "avg(last_1h):sum:system.net.bytes_rcvd{host:host0} > 100"
query = "avg(last_1h):sum:system.net.bytes_rcvd{*} by {host} > 100"
type_alert = "metric alert"
out, err, return_code = self.dogshell(["monitor", "post", type_alert, query])

Expand Down Expand Up @@ -405,12 +405,35 @@ def test_monitors(self):
assert "id" in out, out
out = json.loads(out)
self.assertEquals(str(out["id"]), monitor_id)
self.assertEquals(out["options"]["silenced"], {"*": None})

# Unmute monitor
self.dogshell(["monitor", "unmute", monitor_id])
out, err, return_code = self.dogshell(["monitor", "unmute", monitor_id], check_return_code=False)
self.assertEquals(out, '')
self.assertEquals(return_code, 1)
out = json.loads(out)
self.assertEquals(str(out["id"]), monitor_id)
self.assertEquals(out["options"]["silenced"], {})

# Unmute all scopes of a monitor
options = {
"silenced": {"host:abcd1234": None, "host:abcd1235": None}
}

out, err, return_code = self.dogshell(
["monitor", "update", monitor_id, type_alert,
query, "--options", json.dumps(options)])

assert "id" in out, out
assert "options" in out, out
out = json.loads(out)
self.assertEquals(out["query"], query)
self.assertEquals(out["options"]["silenced"], {"host:abcd1234": None, "host:abcd1235": None})

out, err, return_code = self.dogshell(["monitor", "unmute", str(out["id"]),
"--all_scopes"])
assert "id" in out, out
out = json.loads(out)
self.assertEquals(str(out["id"]), monitor_id)
self.assertEquals(out["options"]["silenced"], {})

# Delete a monitor
self.dogshell(["monitor", "delete", monitor_id])
Expand Down

0 comments on commit bcfccf2

Please sign in to comment.