NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

timeboard.py (12138B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\datadog\dogshell\timeboard.py
      2 from __future__ import print_function
      3 import os.path
      4 import platform
      5 import sys
      6 import webbrowser
      7 import argparse
      8 from datadog import api
      9 from datadog.dogshell.common import report_errors, report_warnings, print_err
     10 from datadog.util.compat import json
     11 from datadog.util.format import pretty_json
     12 from datetime import datetime
     13 
     14 class TimeboardClient(object):
     15 
     16     @classmethod
     17     def setup_parser(cls, subparsers):
     18         parser = subparsers.add_parser('timeboard', help='Create, edit, and delete timeboards')
     19         parser.add_argument('--string_ids', action='store_true', dest='string_ids', help='Represent timeboard IDs as strings instead of ints in JSON')
     20         verb_parsers = parser.add_subparsers(title='Verbs', dest='verb')
     21         verb_parsers.required = True
     22         post_parser = verb_parsers.add_parser('post', help='Create timeboards')
     23         post_parser.add_argument('title', help='title for the new timeboard')
     24         post_parser.add_argument('description', help='short description of the timeboard')
     25         post_parser.add_argument('graphs', help='graph definitions as a JSON string. if unset, reads from stdin.', nargs='?')
     26         post_parser.add_argument('--template_variables', type=_template_variables, default=[], help="a json list of template variable dicts, e.g. [{'name': 'host', 'prefix': 'host', 'default': 'host:my-host'}]'")
     27         post_parser.set_defaults(func=cls._post)
     28         update_parser = verb_parsers.add_parser('update', help='Update existing timeboards')
     29         update_parser.add_argument('timeboard_id', help='timeboard to replace with the new definition')
     30         update_parser.add_argument('title', help='new title for the timeboard')
     31         update_parser.add_argument('description', help='short description of the timeboard')
     32         update_parser.add_argument('graphs', help='graph definitions as a JSON string. if unset, reads from stdin', nargs='?')
     33         update_parser.add_argument('--template_variables', type=_template_variables, default=[], help="a json list of template variable dicts, e.g. [{'name': 'host', 'prefix': 'host', 'default': 'host:my-host'}]'")
     34         update_parser.set_defaults(func=cls._update)
     35         show_parser = verb_parsers.add_parser('show', help='Show a timeboard definition')
     36         show_parser.add_argument('timeboard_id', help='timeboard to show')
     37         show_parser.set_defaults(func=cls._show)
     38         show_all_parser = verb_parsers.add_parser('show_all', help='Show a list of all timeboards')
     39         show_all_parser.set_defaults(func=cls._show_all)
     40         pull_parser = verb_parsers.add_parser('pull', help='Pull a timeboard on the server into a local file')
     41         pull_parser.add_argument('timeboard_id', help='ID of timeboard to pull')
     42         pull_parser.add_argument('filename', help='file to pull timeboard into')
     43         pull_parser.set_defaults(func=cls._pull)
     44         pull_all_parser = verb_parsers.add_parser('pull_all', help='Pull all timeboards into files in a directory')
     45         pull_all_parser.add_argument('pull_dir', help='directory to pull timeboards into')
     46         pull_all_parser.set_defaults(func=cls._pull_all)
     47         push_parser = verb_parsers.add_parser('push', help='Push updates to timeboards from local files to the server')
     48         push_parser.add_argument('--append_auto_text', action='store_true', dest='append_auto_text', help='When pushing to the server, appends filename and timestamp to the end of the timeboard description')
     49         push_parser.add_argument('file', help='timeboard files to push to the server', nargs='+', type=argparse.FileType('r'))
     50         push_parser.set_defaults(func=cls._push)
     51         new_file_parser = verb_parsers.add_parser('new_file', help='Create a new timeboard and put its contents in a file')
     52         new_file_parser.add_argument('filename', help='name of file to create with empty timeboard')
     53         new_file_parser.add_argument('graphs', help='graph definitions as a JSON string. if unset, reads from stdin.', nargs='?')
     54         new_file_parser.set_defaults(func=cls._new_file)
     55         web_view_parser = verb_parsers.add_parser('web_view', help='View the timeboard in a web browser')
     56         web_view_parser.add_argument('file', help='timeboard file', type=argparse.FileType('r'))
     57         web_view_parser.set_defaults(func=cls._web_view)
     58         delete_parser = verb_parsers.add_parser('delete', help='Delete timeboards')
     59         delete_parser.add_argument('timeboard_id', help='timeboard to delete')
     60         delete_parser.set_defaults(func=cls._delete)
     61 
     62     @classmethod
     63     def _pull(cls, args):
     64         cls._write_dash_to_file(args.timeboard_id, args.filename, args.timeout, args.format, args.string_ids)
     65 
     66     @classmethod
     67     def _pull_all(cls, args):
     68         api._timeout = args.timeout
     69 
     70         def _title_to_filename(title):
     71             no_punct = ''.join([ c for c in title.lower() if c.isalnum() or c in (' ', '_', '-') ])
     72             return no_punct.replace(' ', '_').replace('-', '_').strip('_')
     73 
     74         format = args.format
     75         res = api.Timeboard.get_all()
     76         report_warnings(res)
     77         report_errors(res)
     78         if not os.path.exists(args.pull_dir):
     79             os.mkdir(args.pull_dir, 493)
     80         used_filenames = set()
     81         for dash_summary in res['dashes']:
     82             filename = _title_to_filename(dash_summary['title'])
     83             if filename in used_filenames:
     84                 filename = filename + '-' + dash_summary['id']
     85             used_filenames.add(filename)
     86             cls._write_dash_to_file(dash_summary['id'], os.path.join(args.pull_dir, filename + '.json'), args.timeout, format, args.string_ids)
     87 
     88         if format == 'pretty':
     89             print('\n### Total: {0} dashboards to {1} ###'.format(len(used_filenames), os.path.realpath(args.pull_dir)))
     90 
     91     @classmethod
     92     def _new_file(cls, args):
     93         api._timeout = args.timeout
     94         format = args.format
     95         graphs = args.graphs
     96         if args.graphs is None:
     97             graphs = sys.stdin.read()
     98         try:
     99             graphs = json.loads(graphs)
    100         except:
    101             raise Exception('bad json parameter')
    102 
    103         res = api.Timeboard.create(title=args.filename, description='Description for {0}'.format(args.filename), graphs=[graphs])
    104         report_warnings(res)
    105         report_errors(res)
    106         cls._write_dash_to_file(res['dash']['id'], args.filename, args.timeout, format, args.string_ids)
    107         if format == 'pretty':
    108             print(pretty_json(res))
    109         else:
    110             print(json.dumps(res))
    111 
    112     @classmethod
    113     def _write_dash_to_file(cls, dash_id, filename, timeout, format = 'raw', string_ids = False):
    114         with open(filename, 'w') as f:
    115             res = api.Timeboard.get(dash_id)
    116             report_warnings(res)
    117             report_errors(res)
    118             dash_obj = res['dash']
    119             if 'resource' in dash_obj:
    120                 del dash_obj['resource']
    121             if 'url' in dash_obj:
    122                 del dash_obj['url']
    123             if string_ids:
    124                 dash_obj['id'] = str(dash_obj['id'])
    125             json.dump(dash_obj, f, indent=2)
    126             if format == 'pretty':
    127                 print(u'Downloaded dashboard {0} to file {1}'.format(dash_id, filename))
    128             else:
    129                 print(u'{0} {1}'.format(dash_id, filename))
    130 
    131     @classmethod
    132     def _push(cls, args):
    133         api._timeout = args.timeout
    134         for f in args.file:
    135             try:
    136                 dash_obj = json.load(f)
    137             except Exception as err:
    138                 raise Exception('Could not parse {0}: {1}'.format(f.name, err))
    139 
    140             if args.append_auto_text:
    141                 datetime_str = datetime.now().strftime('%x %X')
    142                 auto_text = '<br/>\nUpdated at {0} from {1} ({2}) on {3}'.format(datetime_str, f.name, dash_obj['id'], platform.node())
    143                 dash_obj['description'] += auto_text
    144             tpl_vars = dash_obj.get('template_variables', [])
    145             if 'id' in dash_obj:
    146                 dash_obj['id'] = int(dash_obj['id'])
    147                 res = api.Timeboard.update(dash_obj['id'], title=dash_obj['title'], description=dash_obj['description'], graphs=dash_obj['graphs'], template_variables=tpl_vars)
    148             else:
    149                 res = api.Timeboard.create(title=dash_obj['title'], description=dash_obj['description'], graphs=dash_obj['graphs'], template_variables=tpl_vars)
    150             if 'errors' in res:
    151                 print_err('Upload of dashboard {0} from file {1} failed.'.format(dash_obj['id'], f.name))
    152             report_warnings(res)
    153             report_errors(res)
    154             if format == 'pretty':
    155                 print(pretty_json(res))
    156             else:
    157                 print(json.dumps(res))
    158             if args.format == 'pretty':
    159                 print('Uploaded file {0} (dashboard {1})'.format(f.name, dash_obj['id']))
    160 
    161     @classmethod
    162     def _post(cls, args):
    163         api._timeout = args.timeout
    164         format = args.format
    165         graphs = args.graphs
    166         if args.graphs is None:
    167             graphs = sys.stdin.read()
    168         try:
    169             graphs = json.loads(graphs)
    170         except:
    171             raise Exception('bad json parameter')
    172 
    173         res = api.Timeboard.create(title=args.title, description=args.description, graphs=[graphs], template_variables=args.template_variables)
    174         report_warnings(res)
    175         report_errors(res)
    176         if format == 'pretty':
    177             print(pretty_json(res))
    178         else:
    179             print(json.dumps(res))
    180 
    181     @classmethod
    182     def _update(cls, args):
    183         api._timeout = args.timeout
    184         format = args.format
    185         graphs = args.graphs
    186         if args.graphs is None:
    187             graphs = sys.stdin.read()
    188         try:
    189             graphs = json.loads(graphs)
    190         except:
    191             raise Exception('bad json parameter')
    192 
    193         res = api.Timeboard.update(args.timeboard_id, title=args.title, description=args.description, graphs=graphs, template_variables=args.template_variables)
    194         report_warnings(res)
    195         report_errors(res)
    196         if format == 'pretty':
    197             print(pretty_json(res))
    198         else:
    199             print(json.dumps(res))
    200 
    201     @classmethod
    202     def _show(cls, args):
    203         api._timeout = args.timeout
    204         format = args.format
    205         res = api.Timeboard.get(args.timeboard_id)
    206         report_warnings(res)
    207         report_errors(res)
    208         if args.string_ids:
    209             res['dash']['id'] = str(res['dash']['id'])
    210         if format == 'pretty':
    211             print(pretty_json(res))
    212         else:
    213             print(json.dumps(res))
    214 
    215     @classmethod
    216     def _show_all(cls, args):
    217         api._timeout = args.timeout
    218         format = args.format
    219         res = api.Timeboard.get_all()
    220         report_warnings(res)
    221         report_errors(res)
    222         if args.string_ids:
    223             for d in res['dashes']:
    224                 d['id'] = str(d['id'])
    225 
    226         if format == 'pretty':
    227             print(pretty_json(res))
    228         elif format == 'raw':
    229             print(json.dumps(res))
    230         else:
    231             for d in res['dashes']:
    232                 print('\t'.join([d['id'],
    233                  d['resource'],
    234                  d['title'],
    235                  cls._escape(d['description'])]))
    236 
    237     @classmethod
    238     def _delete(cls, args):
    239         api._timeout = args.timeout
    240         res = api.Timeboard.delete(args.timeboard_id)
    241         if res is not None:
    242             report_warnings(res)
    243             report_errors(res)
    244 
    245     @classmethod
    246     def _web_view(cls, args):
    247         dash_id = json.load(args.file)['id']
    248         url = api._api_host + '/dash/dash/{0}'.format(dash_id)
    249         webbrowser.open(url)
    250 
    251     @classmethod
    252     def _escape(cls, s):
    253         return s.replace('\r', '\\r').replace('\n', '\\n').replace('\t', '\\t')
    254 
    255 
    256 def _template_variables(tpl_var_input):
    257     if '[' not in tpl_var_input:
    258         return [ v.strip() for v in tpl_var_input.split(',') ]
    259     try:
    260         return json.loads(tpl_var_input)
    261     except Exception:
    262         raise argparse.ArgumentTypeError('bad template_variable json parameter')