Beispiel #1
0
 def run(self, args):
     ident = args.ident.split('-')
     if len(ident) != 2:
         raise SystemExit("Invalid message identity: %s" % args.ident)
     res = {"sys": 'system_message', "usr": '******'}.get(ident[0])
     if res is None:
         raise SystemExit("Invalid message type: %s" % args.ident[0])
     # NOTE: system_message does not support detail get.
     msg = self.api.get_by(['id'], res, ident[1])
     shellish.vtmlprint('<b>Created: %s</b>' % msg['created'])
     shellish.vtmlprint('<b>Subject: %s</b>' % msg['title'])
     if 'message' in msg:
         output = shellish.htmlrender(msg['message'])
         for x in str(output).split('\n'):
             print(
                 textwrap.fill(x.strip(),
                               break_long_words=False,
                               replace_whitespace=False,
                               break_on_hyphens=False))
     if ident[0] == 'usr':
         if not msg['is_read']:
             self.api.put(res, ident[1], {"is_read": True})
     elif not msg['confirmed']:
         self.api.post('system_message_confirm',
                       {"message": msg['resource_uri']})
 def on_data(reader, writer):
     while True:
         data = yield from reader.readline()
         if not data:
             break
         log = json.loads(data.decode())
         addr = writer.get_extra_info('peername')[0]
         ts = datetime.datetime.utcnow()
         log['timestamp'] = ts.isoformat()
         log['host_addr'] = addr
         if verbose:
             shellish.vtmlprint('<b>LOG:<b>', log)
         asyncio.ensure_future(relaylog(log, ts))
Beispiel #3
0
 def on_data(reader, writer):
     while True:
         data = yield from reader.readline()
         if not data:
             break
         log = json.loads(data.decode())
         addr = writer.get_extra_info('peername')[0]
         ts = datetime.datetime.utcnow()
         log['timestamp'] = ts.isoformat()
         log['host_addr'] = addr
         if verbose:
             shellish.vtmlprint('<b>LOG:<b>', log)
         asyncio.ensure_future(relaylog(log, ts))
Beispiel #4
0
 def run(self, args):
     """ Validate the args work with our worker by instantiating it here.
     if it checks out and doesn't exit via a `--help` or other type of
     SystemExit then we start the coordinator and save the arguments used
     just for the worker to be proxied to the worker processes. """
     try:
         worker = setup.find_worker(args.worker_spec)
     except (ValueError, AttributeError, ImportError, TypeError) as e:
         shellish.vtmlprint("<b><red>Find Worker Error:</red> %s" % e)
         raise SystemExit(1)
     worker_cmd = setup.worker_coerce(worker)()
     worker_argv = ' '.join(map(shlex.quote, args.worker_args))
     worker_args = vars(worker_cmd.parse_args(worker_argv))
     worker_settings = {}
     if args.log_handler != 'off':
         worker_settings['logging'] = {
             "kind": args.log_handler,
             "level": args.log_level,
             "fmt": args.log_format,
             "verbose": args.verbose,
             "syslog_addr": args.syslog_addr,
         }
         setup.setup_logging(**worker_settings['logging'])
     worker_settings['event_loop'] = {
         "policy": args.event_loop,
         "debug": args.event_loop_debug
     }
     if not args.disable_diag:
         diag_settings = {
             "addr": args.diag_addr,
             "port": args.diag_port,
         }
     else:
         diag_settings = {}
     loop = setup.get_event_loop(**worker_settings['event_loop'])
     worker_restart = not args.disable_worker_restart
     coord = coordinator.Coordinator(args.worker_spec,
                                     worker_count=args.workers,
                                     worker_settings=worker_settings,
                                     worker_args=worker_args,
                                     worker_restart=worker_restart,
                                     diag_settings=diag_settings,
                                     loop=loop)
     loop.run_until_complete(coord.start())
     try:
         loop.run_until_complete(coord.wait_stopped())
     except KeyboardInterrupt:
         pass
     loop.close()
Beispiel #5
0
 def start(self):
     self.app = web.Application(loop=self.loop)
     tpl_loader = jinja2.FileSystemLoader(self.ui_dir)
     env = aiohttp_jinja2.setup(self.app, loader=tpl_loader)
     env.globals.update({
         "sorted": sorted
     })
     self.app.router.add_route('GET', '/', self.index_redir)
     self.app.router.add_route('GET', '/health', self.health)
     self.app.router.add_route('GET', '/ui/{path}', self.tpl_handler)
     self.app.router.add_static('/ui/static',
                                os.path.join(self.ui_dir, 'static'))
     self.handler = self.app.make_handler()
     listen = self.args.diag_addr, self.args.diag_port
     self.server = yield from self.loop.create_server(self.handler, *listen)
     shellish.vtmlprint('<b>Running diag web server</b>: '
                        '<blue><u>http://%s:%s</u></blue>' % listen,
                        plain=self.plain_output)
Beispiel #6
0
 def run(self, args):
     fw_field = 'actual_firmware__version'
     no_updates = True
     for x in self.api.get('routers',
                           group_by=fw_field + ',product__name',
                           count='id'):
         if x[fw_field] is None:
             continue  # unsupported/dev fw
         avail = self.available_firmware(product_name=x['product__name'],
                                         version=x[fw_field])
         name = '%s v%s (%s devices)' % (x['product__name'], x[fw_field],
                                         x['id_count'])
         if avail:
             no_updates = False
             shellish.vtmlprint("<b>Updates available for: %s</b>" % name)
             for xx in avail:
                 print("\tv%s (Release Date: %s)" %
                       (xx['version'], xx['release_date'].date()))
     if not no_updates:
         raise SystemExit(1)
Beispiel #7
0
 def run(self, args):
     with args.package as f:
         url = self.api.uri + self.api.urn
         session = self.api.adapter.session
         del session.headers['content-type']
         resp = session.post('%s/%s/' % (url, versions_res),
                             files={
                                 "archive": f
                             }).json()
     if not resp['success']:
         raise SystemExit(resp['message'])
     appid = resp['data']['id']
     print("Checking upload: ", end='', flush=True)
     for i in range(10):
         app = self.api.get_by('id', versions_res, appid)
         if app['state'] != 'uploading':
             break
         time.sleep(0.200)
     else:
         raise SystemExit("Timeout waiting for upload to complete")
     if app['state'] == 'error':
         shellish.vtmlprint("<red>ERROR</red>")
         self.api.delete(versions_res, app['id'])
         raise SystemExit(app['state_details'])
     elif app['state'] == 'ready':
         shellish.vtmlprint("<green>READY</green>")
     else:
         shellish.vtmlprint("<yellow>%s</yellow>" % app['state'].upper())
         if app['state_details']:
             print(app.get('state_details'))
Beispiel #8
0
 def run(self, args):
     while True:
         username = args.username or input('Username: '******'Email: ')
     password = args.password
     if not password:
         password = getpass.getpass('Password (or empty to send email): ')
         if password:
             password2 = getpass.getpass('Confirm Password: '******'Full Name: '))
     role = args.role or input('Role: ')
     role_id = self.api.get_by_id_or_name('roles', role)['id']
     user_data = {
         "username": username,
         "email": email,
         "first_name": name[0],
         "last_name": name[1],
         "password": password,
     }
     if args.account:
         a = self.api.get_by_id_or_name('accounts', args.account)
         user_data['account'] = a['resource_uri']
     user = self.api.post('users', user_data, expand='profile')
     self.api.put('profiles', user['profile']['id'], {
         "require_password_change": not password
     })
     self.api.post('authorizations', {
         "account": user['profile']['account'],
         "cascade": True,
         "role": '/api/v1/roles/%s/' % role_id,
         "user": user['resource_uri']
     })
Beispiel #9
0
 def post(self, data):
     payload = self.default_payload.copy()
     payload.update(data)
     with (yield from self.lock):
         while True:
             resp = yield from self.session.post(self.webhook,
                                                 data=json.dumps(payload))
             if resp.status != 200:
                 content = yield from resp.json()
                 if resp.status == 429:  # rate limited
                     retry = content['retry_after']
                     shellish.vtmlprint('<red>Slack Rate Limit Reached: '
                                        'Retry in %f seconds.</red>' % retry,
                                        plain=cronredux.PLAIN_OUTPUT)
                     yield from asyncio.sleep(retry)
                     continue
                 else:
                     shellish.vtmlprint('<b><red>Slack Post Failed:</red> '
                                        '(%d) - %s</b>' % (resp.status,
                                        content),
                                        plain=cronredux.PLAIN_OUTPUT)
             yield from resp.release()
             break
Beispiel #10
0
 def run(self, args):
     filters = {}
     if args.firmware:
         filters['version'] = args.firmware
     if args.product:
         filters['product__name'] = args.product
     firmwares = self.api.get('firmwares', expand='dtd', limit=1, **filters)
     if not firmwares:
         raise SystemExit("No firmware DTD matches this specification.")
     if firmwares.meta['total_count'] > 1:
         shellish.vtmlprint(
             '<red><b>WARNING:</b></red> More than one '
             'firmware DTD found for this specification.',
             file=sys.stderr)
     dtd = firmwares[0]['dtd']['value']
     with args.output_file as f:
         dtd = self.walk_dtd(dtd, args.path)
         if args.shallow:
             if 'nodes' in dtd:
                 dtd['nodes'] = list(dtd['nodes'])
         if args.format == 'json':
             print(json.dumps(dtd, indent=4, sort_keys=True), file=f)
         else:
             shellish.treeprint(dtd, file=f)
Beispiel #11
0
 def postrun(self, args, result=None, exc=None):
     if exc is not None:
         return
     print()
     if self.accept:
         shellish.vtmlprint('I, %s %s (%s), do hereby accept the ECM '
                            'terms of service: <u><b>   X   </b></u>' %
                            (self.api.ident['user']['first_name'],
                             self.api.ident['user']['last_name'],
                             self.api.ident['user']['username']))
     else:
         accept = input('Type "accept" to comply with the TOS: ')
         if accept != 'accept':
             raise SystemExit("Aborted")
     tos_uri = self.tos['resource_uri']
     try:
         self.api.post('system_message_confirm', {"message": tos_uri})
     except SystemExit as e:
         try:
             if 'already exists' in e.__context__.response['message']:
                 raise SystemExit("TOS was already accepted.")
         except AttributeError:
             pass
         raise e
Beispiel #12
0
 def error(self, title, message='', raw='', footer=None):
     shellish.vtmlprint("<b><red>ERROR: %s</red></b>" % title,
                        plain=cronredux.PLAIN_OUTPUT)
     if message or raw:
         for line in (message + raw).splitlines():
             shellish.vtmlprint("    <red>%s</red>" % line,
                                plain=cronredux.PLAIN_OUTPUT)
     if footer:
         shellish.vtmlprint("    <dim>%s</dim>" % footer,
                            plain=cronredux.PLAIN_OUTPUT)
Beispiel #13
0
 def warning(self, title, message='', raw='', footer=None):
     shellish.vtmlprint("<b>WARN: %s</b>" % title,
                        plain=cronredux.PLAIN_OUTPUT)
     if message or raw:
         for line in (message + raw).splitlines():
             shellish.vtmlprint("    %s" % line,
                                plain=cronredux.PLAIN_OUTPUT)
     if footer:
         shellish.vtmlprint("<dim>%s</dim>" % footer,
                            plain=cronredux.PLAIN_OUTPUT)
Beispiel #14
0
 def info(self, title, message='', raw='', footer=None):
     shellish.vtmlprint("<b><blue>INFO: %s</blue></b>" % title,
                        plain=cronredux.PLAIN_OUTPUT)
     if message or raw:
         for line in (message + raw).splitlines():
             shellish.vtmlprint("    <blue>%s</blue>" % line,
                                plain=cronredux.PLAIN_OUTPUT)
     if footer:
         shellish.vtmlprint("    <dim>%s</dim>" % footer,
                            plain=cronredux.PLAIN_OUTPUT)
 async def relaylog(log, ts):
     data = json.dumps(log)
     url = '%s/%s-%s/%s' % (es_url, es_index, ts.strftime('%Y-%m-%d'),
                            es_type)
     try:
         with aiohttp.Timeout(60):
             async with es_session.post(url, data=data) as r:
                 if r.status != 201:
                     shellish.vtmlprint('<b><red>ES POST ERROR:</red> %s</b>' %
                                        (await r.text()))
                 elif verbose:
                     shellish.vtmlprint('<b>ES INDEX:</b>', await r.text())
     except asyncio.TimeoutError:
         shellish.vtmlprint('<b><red>ES POST TIMEOUT</red></b>')
Beispiel #16
0
 async def relaylog(log, ts):
     data = json.dumps(log)
     url = '%s/%s-%s/%s' % (es_url, es_index, ts.strftime('%Y-%m-%d'),
                            es_type)
     try:
         with aiohttp.Timeout(60):
             async with es_session.post(url, data=data) as r:
                 if r.status != 201:
                     shellish.vtmlprint(
                         '<b><red>ES POST ERROR:</red> %s</b>' %
                         (await r.text()))
                 elif verbose:
                     shellish.vtmlprint('<b>ES INDEX:</b>', await r.text())
     except asyncio.TimeoutError:
         shellish.vtmlprint('<b><red>ES POST TIMEOUT</red></b>')
Beispiel #17
0
 def run(self, args):
     self.args = args
     tasks = []
     if args.plain:
         cronredux.PLAIN_OUTPUT = True
     if args.verbose:
         shellish.vtmlprint("<b>Processing crontab file:</b> <red>%s</red>"
                            % args.crontab, plain=cronredux.PLAIN_OUTPUT)
     with args.crontab as f:
         for spec, command in cronparser.parsef(f):
             if args.verbose:
                 shellish.vtmlprint("<b>Adding task:</b> <blue>%s</blue> %s"
                                    % (spec, command),
                                    plain=cronredux.PLAIN_OUTPUT)
             tasks.append(scheduler.Task(crontab.CronTab(spec), command))
     if args.slack_webhook:
         notifier = notification.SlackNotifier(
             args.slack_webhook,
             channel=args.slack_channel,
             username=args.slack_username,
             icon_emoji=args.slack_icon_emoji)
     else:
         notifier = notification.PrintNotifier()
     loop = asyncio.get_event_loop()
     sched = scheduler.Scheduler(tasks, args, notifier, loop)
     diag = web.DiagService(tasks,
                            args,
                            loop,
                            sched=sched,
                            plain=cronredux.PLAIN_OUTPUT)
     try:
         loop.run_until_complete(notifier.setup(loop))
         loop.run_until_complete(diag.start())
         loop.create_task(sched.run())
         loop.run_forever()
     except KeyboardInterrupt:
         pass
     finally:
         if args.verbose:
             shellish.vtmlprint("<b>Shutting Down</b>",
                                plain=cronredux.PLAIN_OUTPUT)
             loop.run_until_complete(diag.cleanup())
         loop.close()
Beispiel #18
0
 def run(self, args):
     group = self.api.get_by_id_or_name('groups', args.ident,
                                        expand='configuration')
     cur_patch = group['configuration']
     if args.replace:
         with args.replace as f:
             patch = json.load(f)
         patch_validate(patch)
     elif args.merge:
         with args.merge as f:
             overlay = json.load(f)
         patch_validate(overlay)
         patch = self.merge(cur_patch, overlay)
     elif args.set:
         path, value = args.set.split('=', 1)
         path = path.strip().split('.')
         value = json.loads(value)
         updates = copy.deepcopy(cur_patch[0])
         offt = updates
         for x in path[:-1]:
             if x in offt:
                 offt = offt[x]
             else:
                 offt[x] = {}
         offt[path[-1]] = value
         patch = [updates, cur_patch[1]]
     patch_validate(patch)
     if args.json_diff:
         oldjson = json.dumps(cur_patch, indent=4, sort_keys=True)
         newjson = json.dumps(patch, indent=4, sort_keys=True)
         printed = False
         for line in difflib.unified_diff(oldjson.splitlines(True),
                                          newjson.splitlines(True),
                                          fromfile='current config',
                                          tofile='proposed config', n=10):
             if line.startswith('---') or line.startswith('+++'):
                 line = '<b>%s</b>' % line
             elif line.startswith('@@'):
                 line = '<cyan>%s</cyan>' % line
             elif line[0] == '-':
                 line = '<red>%s</red>' % line
             elif line[0] == '+':
                 line = '<green>%s</green>' % line
             shellish.vtmlprint(line, end='')
             printed = True
         if printed:
             print()
     else:
         old_adds = dict(base.totuples(cur_patch[0]))
         new_adds = dict(base.totuples(patch[0]))
         old_add_keys = set(old_adds)
         new_add_keys = set(new_adds)
         for x in old_add_keys - new_add_keys:
             shellish.vtmlprint('<red>Unsetting:</red> %s=%s' % (
                                x, old_adds[x]))
         for x in new_add_keys - old_add_keys:
             shellish.vtmlprint('<green>Adding:</green> %s=%s' % (
                                x, new_adds[x]))
         for x in new_add_keys & old_add_keys:
             if old_adds[x] != new_adds[x]:
                 shellish.vtmlprint('<yellow>Changing:</yellow> %s (%s'
                                    '<b> -> </b>%s)' %
                                    (x, old_adds[x], new_adds[x]))
         old_removes = set(map(tuple, cur_patch[1]))
         new_removes = set(map(tuple, patch[1]))
         for x in old_removes - new_removes:
             shellish.vtmlprint('<red>Unsetting removal:</red> %s' % (
                                '.'.join(map(str, x))))
         for x in new_removes - old_removes:
             shellish.vtmlprint('<green>Adding removal:</green> %s' % (
                                '.'.join(map(str, x))))
     self.confirm('Confirm update of config of: %s' % group['name'])
     self.api.put('groups', group['id'], {"configuration": patch})
Beispiel #19
0
 def verror(self, *args, **kwargs):
     msg = ' '.join(map(str, args))
     shellish.vtmlprint(msg, file=sys.stderr, **kwargs)