Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MA-669] Add support for /v1/downtime/cancel/by_scope. #488

Merged
merged 5 commits into from
Dec 10, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 15 additions & 2 deletions datadog/api/downtimes.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
from datadog.api.resources import GetableAPIResource, CreateableAPIResource,\
UpdatableAPIResource, ListableAPIResource, DeletableAPIResource
UpdatableAPIResource, ListableAPIResource, DeletableAPIResource, \
ActionAPIResource


class Downtime(GetableAPIResource, CreateableAPIResource, UpdatableAPIResource,
ListableAPIResource, DeletableAPIResource):
ListableAPIResource, DeletableAPIResource, ActionAPIResource):
"""
A wrapper around Monitor Downtiming HTTP API.
"""
_resource_name = 'downtime'

@classmethod
def cancel_downtime_by_scope(cls, **body):
"""
Cancels all downtimes matching the scope.

:param scope: scope to cancel downtimes by
:type scope: string

:returns: Dictionary representing the API's JSON response
"""
return super(Downtime, cls)._trigger_class_action('POST', 'cancel/by_scope', **body)
14 changes: 14 additions & 0 deletions datadog/dogshell/downtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ def setup_parser(cls, subparsers):
delete_parser.add_argument('downtime_id', help="downtime to delete")
delete_parser.set_defaults(func=cls._cancel_downtime)

cancel_parser = verb_parsers.add_parser('cancel_by_scope', help="Cancel all downtimes with a given scope")
cancel_parser.add_argument('scope', help="The scope of the downtimes to cancel")
cancel_parser.set_defaults(func=cls._cancel_downtime_by_scope)

@classmethod
def _schedule_downtime(cls, args):
api._timeout = args.timeout
Expand Down Expand Up @@ -110,3 +114,13 @@ def _show_all_downtime(cls, args):
print(pretty_json(res))
else:
print(json.dumps(res))

@classmethod
def _cancel_downtime_by_scope(cls, args):
api._timeout = args.timeout
format = args.format
res = api.Downtime.cancel_downtime_by_scope(scope=args.scope)
if format == 'pretty':
print(pretty_json(res))
else:
print(json.dumps(res))
45 changes: 45 additions & 0 deletions tests/integration/api/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,51 @@ def test_downtime(self):
"Downtime", downtime["id"], retry_condition=lambda r: r["disabled"] is False
)

def test_downtime_cancel_by_scope(self):
scope_one = "test:integration_one"
scope_two = "test:integration_two"
start = int(time.time())

# Create downtime with scope_one
end = start + 1000
downtime_one = dog.Downtime.create(scope=scope_one, start=start, end=end)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about subsequent test runs here. Would creating a downtime that already exists and is disabled just flip the disabled flag back to False?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh no, it will create a separate downtime with a different downtime["id"].

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, to clarify: it creates a new one because the start and end will be different depending on the test execution - so you schedule it for a different time period.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh ok that sounds good to me.

assert downtime_one["scope"] == [scope_one]
assert downtime_one["disabled"] is False

# Create downtime with scope_one
end = int(time.time()) + 60000
downtime_two = dog.Downtime.create(scope=scope_one, start=start, end=end)
assert downtime_two["scope"] == [scope_one]
assert downtime_two["disabled"] is False

end = int(time.time()) + 120000
downtime_three = dog.Downtime.create(scope=scope_two, start=start, end=end)
assert downtime_three["scope"] == [scope_two]
assert downtime_three["disabled"] is False

downtimes_with_scope_one = [downtime_one, downtime_two]
downtimes_with_scope_two = [downtime_three]

# Cancel downtimes with scope `scope_one`
dog.Downtime.cancel_downtime_by_scope(scope=scope_one)

# Verify only the downtimes with scope `scope_one` were canceled
for downtime in downtimes_with_scope_one:
get_with_retry(
"Downtime", downtime["id"], retry_condition=lambda r: r["disabled"] is False
)
for downtime in downtimes_with_scope_two:
get_with_retry("Downtime", downtime["id"])
armcburney marked this conversation as resolved.
Show resolved Hide resolved

# Cancel downtimes with scope `scope_two`
dog.Downtime.cancel_downtime_by_scope(scope=scope_two)

# Verify downtimes with scope `scope_two` were canceled
for downtime in downtimes_with_scope_two:
get_with_retry(
"Downtime", downtime["id"], retry_condition=lambda r: r["disabled"] is False
)

def test_service_check(self):
assert dog.ServiceCheck.check(
check="check_pg",
Expand Down
18 changes: 18 additions & 0 deletions tests/integration/dogshell/test_dogshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,24 @@ def test_downtime_schedule(self):
assert out["scope"][0] == scope
assert out["disabled"] is True

def test_downtime_cancel_by_scope(self):
# Schedule a downtime
scope = "env:staging"
out, _, _ = self.dogshell(["downtime", "post", scope, str(int(time.time()))])
out = json.loads(out)
assert out["scope"][0] == scope
assert out["disabled"] is False
downtime_id = str(out["id"])

# Cancel the downtime by scope
self.dogshell(["downtime", "cancel_by_scope", scope])

# Get downtime and check if it is cancelled
out, _, _ = self.dogshell(["downtime", "show", downtime_id])
out = json.loads(out)
assert out["scope"][0] == scope
assert out["disabled"] is True

def test_service_check(self):
out, _, _ = self.dogshell(["service_check", "check", "check_pg", "host0", "1"])
out = json.loads(out)
Expand Down