Skip to content

Commit

Permalink
[dashboards] Add new endpoints & dog commands for new dashboard (Data…
Browse files Browse the repository at this point in the history
…Dog#351)

* [dashboards] Add new enpoints & dog commands for new dashboard

* [dashboards] Remove unused import

* [dashboards] Fix indentation and clean up comments

* [dashboards] Add dashboard and dashboard-list docs

* [dashboards] Fix typo

* [dashboards] Review feedback changes

* [dashboards] Remove file-based commands

* [dashboards] Remove unused function

* [dashboards] Remove unused import

* [dashboards] Add layout_type arg
  • Loading branch information
enbashi authored and David Bouchare committed Nov 28, 2019
1 parent ddfc66e commit d3a70d1
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 0 deletions.
1 change: 1 addition & 0 deletions datadog/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from datadog.api.distributions import Distribution
from datadog.api.downtimes import Downtime
from datadog.api.timeboards import Timeboard
from datadog.api.dashboards import Dashboard
from datadog.api.events import Event
from datadog.api.infrastructure import Infrastructure
from datadog.api.metadata import Metadata
Expand Down
10 changes: 10 additions & 0 deletions datadog/api/dashboards.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from datadog.api.resources import GetableAPIResource, CreateableAPIResource, \
UpdatableAPIResource, DeletableAPIResource


class Dashboard(GetableAPIResource, CreateableAPIResource,
UpdatableAPIResource, DeletableAPIResource):
"""
A wrapper around Dashboard HTTP API.
"""
_resource_name = 'dashboard'
2 changes: 2 additions & 0 deletions datadog/dogshell/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from datadog.dogshell.service_check import ServiceCheckClient
from datadog.dogshell.tag import TagClient
from datadog.dogshell.timeboard import TimeboardClient
from datadog.dogshell.dashboard import DashboardClient
from datadog.util.config import get_version


Expand Down Expand Up @@ -56,6 +57,7 @@ def main():
EventClient.setup_parser(subparsers)
MonitorClient.setup_parser(subparsers)
TimeboardClient.setup_parser(subparsers)
DashboardClient.setup_parser(subparsers)
ScreenboardClient.setup_parser(subparsers)
DashboardListClient.setup_parser(subparsers)
HostClient.setup_parser(subparsers)
Expand Down
176 changes: 176 additions & 0 deletions datadog/dogshell/dashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# stdlib
import json
import sys

# 3p
import argparse

# datadog
from datadog import api
from datadog.dogshell.common import report_errors, report_warnings
from datadog.util.format import pretty_json


class DashboardClient(object):

@classmethod
def setup_parser(cls, subparsers):
parser = subparsers.add_parser('dashboard', help="Create, edit, and delete dashboards")

verb_parsers = parser.add_subparsers(title='Verbs', dest='verb')
verb_parsers.required = True

post_parser = verb_parsers.add_parser('post', help="Create dashboards")
# Required arguments:
post_parser.add_argument('title', help="title for the new dashboard")
post_parser.add_argument('widgets', help="widget definitions as a JSON string. If unset,"
" reads from stdin.", nargs="?")
# for now, only "ordered" layout - current timeboard layout - is supported.
post_parser.add_argument('layout_type', choices=['ordered'],
help="Layout type of the dashboard.")
# Optional arguments:
post_parser.add_argument('--description', help="Short description of the dashboard")
post_parser.add_argument('--read_only', help="Whether this dashboard is read-only. "
"If True, only the author and admins can make changes to it.",
action='store_true')
post_parser.add_argument('--notify_list', type=_json_string,
help="A json list of user handles, e.g. "
"'[\"user1@domain.com\", \"user2@domain.com\"]'")
post_parser.add_argument('--template_variables', type=_json_string,
help="A json list of template variable dicts, e.g. "
"'[{\"name\": \"host\", \"prefix\": \"host\", "
"\"default\": \"my-host\"}]'")
post_parser.set_defaults(func=cls._post)

update_parser = verb_parsers.add_parser('update', help="Update existing dashboards")
# Required arguments:
update_parser.add_argument('dashboard_id', help="Dashboard to replace"
" with the new definition")
update_parser.add_argument('title', help="New title for the dashboard")
update_parser.add_argument('widgets', help="Widget definitions as a JSON string."
" If unset, reads from stdin", nargs="?")
# for now, only "ordered" layout - current timeboard layout - is supported.
update_parser.add_argument('layout_type', choices=['ordered'],
help="Layout type of the dashboard.")
# Optional arguments:
update_parser.add_argument('--description', help="Short description of the dashboard")
update_parser.add_argument('--read_only', help="Whether this dashboard is read-only. "
"If True, only the author and admins can make changes to it.",
action='store_true')
update_parser.add_argument('--notify_list', type=_json_string,
help="A json list of user handles, e.g. "
"'[\"user1@domain.com\", \"user2@domain.com\"]'")
update_parser.add_argument('--template_variables', type=_json_string,
help="A json list of template variable dicts, e.g. "
"'[{\"name\": \"host\", \"prefix\": \"host\", "
"\"default\": \"my-host\"}]'")
update_parser.set_defaults(func=cls._update)

show_parser = verb_parsers.add_parser('show', help="Show a dashboard definition")
show_parser.add_argument('dashboard_id', help="Dashboard to show")
show_parser.set_defaults(func=cls._show)

delete_parser = verb_parsers.add_parser('delete', help="Delete dashboards")
delete_parser.add_argument('dashboard_id', help="Dashboard to delete")
delete_parser.set_defaults(func=cls._delete)

@classmethod
def _post(cls, args):
api._timeout = args.timeout
format = args.format
widgets = args.widgets
if args.widgets is None:
widgets = sys.stdin.read()
try:
widgets = json.loads(widgets)
except:
raise Exception('bad json parameter')

# Required arguments
payload = {
"title": args.title,
"widgets": widgets,
"layout_type": args.layout_type
}
# Optional arguments
if(args.description):
payload["description"] = args.description
if(args.read_only):
payload["is_read_only"] = args.read_only
if(args.notify_list):
payload["notify_list"] = args.notify_list
if(args.template_variables):
payload["template_variables"] = args.template_variables

res = api.Dashboard.create(**payload)
report_warnings(res)
report_errors(res)
if format == 'pretty':
print(pretty_json(res))
else:
print(json.dumps(res))

@classmethod
def _update(cls, args):
api._timeout = args.timeout
format = args.format
widgets = args.widgets
if args.widgets is None:
widgets = sys.stdin.read()
try:
widgets = json.loads(widgets)
except:
raise Exception('bad json parameter')

# Required arguments
payload = {
"title": args.title,
"widgets": widgets,
"layout_type": args.layout_type
}
# Optional arguments
if(args.description):
payload["description"] = args.description
if(args.read_only):
payload["is_read_only"] = args.read_only
if(args.notify_list):
payload["notify_list"] = args.notify_list
if(args.template_variables):
payload["template_variables"] = args.template_variables

res = api.Dashboard.update(
args.dashboard_id, **payload)
report_warnings(res)
report_errors(res)
if format == 'pretty':
print(pretty_json(res))
else:
print(json.dumps(res))

@classmethod
def _show(cls, args):
api._timeout = args.timeout
format = args.format
res = api.Dashboard.get(args.dashboard_id)
report_warnings(res)
report_errors(res)

if format == 'pretty':
print(pretty_json(res))
else:
print(json.dumps(res))

@classmethod
def _delete(cls, args):
api._timeout = args.timeout
res = api.Dashboard.delete(args.dashboard_id)
if res is not None:
report_warnings(res)
report_errors(res)


def _json_string(str):
try:
return json.loads(str)
except Exception:
raise argparse.ArgumentTypeError('bad json parameter')
8 changes: 8 additions & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ Datadog.api client requires to run :mod:`datadog` `initialize` method first.
:inherited-members:
:exclude-members: invite

.. autoclass:: datadog.api.Dashboard
:members:
:inherited-members:

.. autoclass:: datadog.api.DashboardList
:members:
:inherited-members:


Datadog.threadstats module
==========================
Expand Down

0 comments on commit d3a70d1

Please sign in to comment.