def cli(debug, work_dir, config): """ Powny command line tool. """ if debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) logging.config.dictConfig(Settings.get('logging', {})) # `pownyrules.yaml` from work dir has highest priority with open(os.path.join(work_dir, 'pownyrules.yaml')) as repo_conf: Settings.load(None, None, repo_conf) Settings.config['rules-path'] = work_dir
def kill_job(job_id): """ Terminate job by id. Now, by Powny API limitation, job just marked as `should be deleted`, physically it could be deleted for several time or never. """ pownyapi.terminate_job(Settings.get('powny_api_url'), job_id)
def _read_powny_api_url_from_settings(ctx, param, api_url): if api_url: return api_url api_url = Settings.get('powny_api_url') if api_url: return api_url else: click.BadParameter("Powny API url does not defined")
def cli(debug, config): """ Powny command line tool. """ if debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) logging.config.dictConfig(Settings.get('logging', {}))
def send_event(event_args, file): """ Send event to Powny via API. Could be called with arguments `host service status` or with JSON file event description. """ events = file or _get_event_from_args(event_args) for event in events: if 'description' not in event: event['description'] = '' logger.info("Send event: {}".format(event)) pownyapi.send_event(Settings.get('powny_api_url'), event)
def open_log_page(browser): """ Open kibana logs dashboard in browser. """ url = Settings.get("kibana_dashboard_url") try: if browser: webbrowser.get(using=browser).open_new_tab(url) else: webbrowser.open_new_tab(url) except Exception as error: logger.error("Can't open %s in %s browser. Error occurred: %s", url, browser or "default", error)
def job_logs(job_id, size): elastic_url = Settings.get('elastic_url') resp = requests.get(urljoin(elastic_url, '/_all/_search'), params={'q': 'job_id:%s' % job_id, 'size': size}) hits = resp.json()['hits']['hits'] hits.sort(key=lambda x: x["_source"]["@timestamp"]) lines = [] for hit in hits: fields = hit["_source"] message = fields["msg"] args = fields.get("args") time = dt.strptime(fields["@timestamp"], "%Y-%m-%dT%H:%M:%S.%f").strftime("%d %b %H:%M:%S") level = fields["level"] node = fields["node"] if logger.getEffectiveLevel() != logging.DEBUG and level == 'DEBUG': continue node_name, node_role = node.split('-')[0], node.split('-')[1] if args: try: # To catch cases when `message = '%s (parents: %s)'`, but `args = ['Spawned the new job']` formatted_msg = message % tuple(args) except TypeError as error: logger.warning("Can't format string. %s. So next record is a raw.", error) formatted_msg = message + str(args) else: formatted_msg = message lines.append([node_name, node_role, time, level, formatted_msg]) table = tabloid.FormattedTable() table.add_column('Role') table.add_column('Node', Colorfull.get_node) table.add_column('Time', Colorfull.timestamp) table.add_column('Level', Colorfull.get_level) table.add_column('Message') for line in lines: table.add_row(line) formatted_out = '\n'.join(table.get_table()) if formatted_out: click.echo(formatted_out) else: click.echo("No logs yet.")
def check(config, events_desc): cluster_config = Settings.merge(config, _get_cluster_config(config.get('powny_api_url'))) apps.init('powny', 'local', args=None, raw_config=cluster_config) context.get_context = FakeContext exposed, errors = tools.make_loader(config.get('rules-path')).get_exposed(config['rules-path']) for module in errors: logger.error("Can't load %s module by reason %s", module, errors[module]) for event in _build_events(events_desc): for (name, handler) in exposed.get("handlers", {}).items(): if rules.check_match(handler, event): try: handler(**event) except Exception as error: logger.exception("Can't execute %s rule by reason %s", name, error)
def upload(powny_server: str, path: str, force: bool): """ This function execute git commands: - git pull --rebase - git push # to origin - git push ssh://git@powny/remote.git # to each Powny git and POST new HEAD hash to Powny via API """ status = _execute_git_command('status --porcelain', path, "Can't get git status") current_branch = _get_current_branch(path) if len(status) > 0: logger.info("You have uncommited changes in working directory. Please commit them before upload.") raise GitCommandError logger.info("Pull changes from rules server...") _execute_git_command('pull --rebase origin {}'.format(current_branch), path, "Can't pull changes from server rules") logger.info("Sync you changes with rules server...") cmd = 'push --force origin {}' if force else 'push origin {}' _execute_git_command(cmd.format(current_branch), path, "Can't push your changes") powny_repos = Settings.get("powny_git_remotes") assert powny_repos, "Powny git remotes does not defined. Can't upload rules." for repo in powny_repos: logger.info("Upload rules to {}...".format(repo)) cmd = 'push --force {} {}:master' if force else 'push {} {}:master' _execute_git_command(cmd.format(repo, current_branch), path, "Can't push to Powny remote") logger.debug("Update head...") _update_head(powny_server, path) logger.info("You rules uploaded to Powny!")
def upload(powny_server: str, path: str, message: str, force: bool): """ This function execute git commands: - git commit -a -m "{message}" - git pull --rebase - git push # to origin - git push ssh://git@powny/remote.git # to each Powny git and POST new HEAD hash to Powny via API """ status = _execute_git_command('status --porcelain', path, "Can't get git status") if len(status) == 0: logger.info("There are no new or modified rules.") else: commit_needed = False for changed_file in filter(len, status.split('\n')): file_status, file_name = filter(len, changed_file.split(' ')) if file_status == "A": logger.info("New rule '%s' was added", file_name) commit_needed = True elif file_status == "M": logger.info("Rule '%s' was modified", file_name) commit_needed = True elif file_status == "D": logger.info("Rule '%s' will be removed", file_name) commit_needed = True elif file_status == "??": logger.info("New rule '%s' is present. Use `rules add` command to add the rule", file_name) else: raise RuntimeError("Unknown status %s for file %s", file_status, file_name) if commit_needed: logger.info("Commit current changes...") if not message: logger.info("`--message` option was not specified") message = input("Enter commit message: ") _execute_git_command('commit -a -m "{}"'.format(message), path, "Can't commit your changes") logger.info("Pull changes from rules server...") _execute_git_command('pull --rebase', path, "Can't pull changes from server rules") logger.info("Sync you changes with rules server...") cmd = 'push --force' if force else 'push' _execute_git_command(cmd, path, "Can't push your changes") powny_repos = Settings.get("powny_git_remotes") assert powny_repos, "Powny git remotes does not defined. Can't upload rules." for repo in powny_repos: logger.info("Upload rules to {}...".format(repo)) cmd = 'push --force {} master' if force else 'push {} master' _execute_git_command(cmd.format(repo), path, "Can't push to Powny remote") logger.debug("Update head...") _update_head(powny_server, path) logger.info("You rules uploaded to Powny!")
def job_list(): """ Show current jobs list by id. """ jobs = pownyapi.get_jobs(Settings.get('powny_api_url')) click.echo('\n'.join(list(jobs)))
def upload(force): """ Upload new or changed rules in Powny. """ logger.info("Upload updated rules to Powny...") gitapi.upload(Settings.get('powny_api_url'), Settings.get('rules-path'), force)
def cluster_info(): """ Show generic cluster info. """ powny_state = pownyapi.get_cluster_info(Settings.get('powny_api_url')) click.echo(yaml.dump(powny_state))