def render(self, what, row, tags, custom_vars): if what == "service" and row["service_cached_at"]: output = _( "This service is based on cached agent data and cannot be rescheduled." ) output += " %s" % render_cache_info(what, row) return "cannot_reschedule", output, None # Reschedule button if row[what + "_check_type"] == 2: return # shadow hosts/services cannot be rescheduled if (row[what + "_active_checks_enabled"] == 1 or row[what + '_check_command'].startswith('check_mk-')) \ and config.user.may('action.reschedule'): servicedesc = '' wait_svc = '' icon = 'reload' txt = _('Reschedule check') if what == 'service': servicedesc = row['service_description'].replace("\\", "\\\\") wait_svc = servicedesc # Use Check_MK service for cmk based services if row[what + '_check_command'].startswith('check_mk-'): servicedesc = 'Check_MK' icon = 'reload_cmk' txt = _('Reschedule \'Check_MK\' service') url = 'onclick:cmk.views.reschedule_check(this, \'%s\', \'%s\', \'%s\', \'%s\');' % \ (row["site"], row["host_name"], html.urlencode(servicedesc), html.urlencode(wait_svc)) return icon, txt, url
def _add_wato_folder_to_url(self, url): if not self._wato_folder: return url if '/' in url: return url # do not append wato_folder to non-Check_MK-urls if '?' in url: return url + "&wato_folder=" + html.urlencode(self._wato_folder) return url + "?wato_folder=" + html.urlencode(self._wato_folder)
def page(self): config.user.need_permission("general.see_crash_reports") filename = "Checkmk_Crash_%s_%s_%s.tar.gz" % \ (html.urlencode(self._site_id), html.urlencode(self._crash_id), time.strftime("%Y-%m-%d_%H-%M-%S")) html.response.headers['Content-Disposition'] = 'Attachment; filename=%s' % filename html.response.headers['Content-Type'] = 'application/x-tar' html.write_binary(_pack_crash_report(self._get_serialized_crash_report()))
def page_download_crash_report(): site = html.request.var("site") host = html.request.var("host") service = html.request.var("service") filename = "Check_MK_Crash_%s_%s_%s.tar.gz" % \ (html.urlencode(host), html.urlencode(service), time.strftime("%Y-%m-%d_%H-%M-%S")) tardata = get_crash_report_archive_as_string(site, host, service) html.response.headers['Content-Disposition'] = 'Attachment; filename=%s' % filename html.response.headers['Content-Type'] = 'application/x-tar' html.write(tardata)
def host_service_graph_popup_pnp(site, host_name, service_description): pnp_host = cmk.utils.pnp_cleanup(host_name) pnp_svc = cmk.utils.pnp_cleanup(service_description) url_prefix = config.site(site)["url_prefix"] if html.mobile: url = url_prefix + ("pnp4nagios/index.php?kohana_uri=/mobile/popup/%s/%s" % \ (html.urlencode(pnp_host), html.urlencode(pnp_svc))) else: url = url_prefix + ("pnp4nagios/index.php/popup?host=%s&srv=%s" % \ (html.urlencode(pnp_host), html.urlencode(pnp_svc))) html.write(url)
def host_service_graph_dashlet_pnp(graph_identification): site = graph_identification[1]["site"] source = int(graph_identification[1]["graph_index"]) pnp_host = cmk.utils.pnp_cleanup(graph_identification[1]["host_name"]) pnp_svc = cmk.utils.pnp_cleanup( graph_identification[1]["service_description"]) url_prefix = config.site(site)["url_prefix"] pnp_theme = html.get_theme() if pnp_theme == "classic": pnp_theme = "multisite" html.write(url_prefix + "pnp4nagios/index.php/image?host=%s&srv=%s&source=%d&view=%s&theme=%s" % \ (html.urlencode(pnp_host), html.urlencode(pnp_svc), source, html.request.var("timerange"), pnp_theme))
def show(self): group_type = self._group_type_ident() html.open_ul() for name, alias in sites.all_groups(group_type.replace("group", "")): url = "view.py?view_name=%s&%s=%s" % (group_type, group_type, html.urlencode(name)) bulletlink(alias or name, url) html.close_ul()
def _handle_not_authenticated() -> Response: if fail_silently(): # While api call don't show the login dialog raise MKUnauthenticatedException(_('You are not authenticated.')) # Redirect to the login-dialog with the current url as original target # Never render the login form directly when accessing urls like "index.py" # or "dashboard.py". This results in strange problems. if html.myfile != 'login': post_login_url = makeuri(request, []) if html.myfile != "index": # Ensure that users start with a navigation after they have logged in post_login_url = makeuri_contextless( request, [("start_url", post_login_url)], filename="index.py") raise HTTPRedirect( '%scheck_mk/login.py?_origtarget=%s' % (config.url_prefix(), html.urlencode(post_login_url))) # This either displays the login page or validates the information submitted # to the login form. After successful login a http redirect to the originally # requested page is performed. login_page = login.LoginPage() login_page.set_no_html_output(plain_error()) login_page.handle_page() return html.response
def _check_auth_cookie(cookie_name: str) -> Optional[UserId]: username, issue_time, cookie_hash = _parse_auth_cookie(cookie_name) _check_parsed_auth_cookie(username, issue_time, cookie_hash) # Check whether or not there is an idle timeout configured, delete cookie and # require the user to renew the log when the timeout exceeded. if userdb.login_timed_out(username, issue_time): del_auth_cookie() return None # Check whether or not a single user session is allowed at a time and the user # is doing this request with the currently active session. if config.single_user_session is not None: session_id = _get_session_id_from_cookie(username) if not userdb.is_valid_user_session(username, session_id): del_auth_cookie() return None # Once reached this the cookie is a good one. Renew it! _renew_cookie(cookie_name, username) if html.myfile != 'user_change_pw': result = userdb.need_to_change_pw(username) if result: raise HTTPRedirect('user_change_pw.py?_origtarget=%s&reason=%s' % (html.urlencode(html.makeuri([])), result)) # Return the authenticated username return username
def _do_login(self) -> None: """handle the sent login form""" if not html.request.var('_login'): return try: if not config.user_login: raise MKUserError(None, _('Login is not allowed on this site.')) username_var = html.request.get_unicode_input('_username', '') assert username_var is not None username = UserId(username_var.rstrip()) if not username: raise MKUserError('_username', _('No username given.')) password = html.request.var('_password', '') if not password: raise MKUserError('_password', _('No password given.')) default_origtarget = config.url_prefix() + "check_mk/" origtarget = html.get_url_input("_origtarget", default_origtarget) # Disallow redirections to: # - logout.py: Happens after login # - side.py: Happens when invalid login is detected during sidebar refresh if "logout.py" in origtarget or 'side.py' in origtarget: origtarget = default_origtarget result = userdb.check_credentials(username, password) if result: # use the username provided by the successful login function, this function # might have transformed the username provided by the user. e.g. switched # from mixed case to lower case. username = result session_id = userdb.on_succeeded_login(username) # The login succeeded! Now: # a) Set the auth cookie # b) Unset the login vars in further processing # c) Redirect to really requested page _create_auth_session(username, session_id) # Never use inplace redirect handling anymore as used in the past. This results # in some unexpected situations. We simpy use 302 redirects now. So we have a # clear situation. # userdb.need_to_change_pw returns either False or the reason description why the # password needs to be changed change_pw_result = userdb.need_to_change_pw(username) if change_pw_result: raise HTTPRedirect( 'user_change_pw.py?_origtarget=%s&reason=%s' % (html.urlencode(origtarget), change_pw_result)) raise HTTPRedirect(origtarget) userdb.on_failed_login(username) raise MKUserError(None, _('Invalid credentials.')) except MKUserError as e: html.add_user_error(e.varname, e)
def show(self) -> None: html.open_ul() for group in bi.get_aggregation_group_trees(): bulletlink( group, "view.py?view_name=aggr_group&aggr_group=%s" % html.urlencode(group)) html.close_ul()
def _wato_link(self, folder, site, hostname, where): if not config.wato_enabled: return None if display_options.enabled(display_options.X): url = "wato.py?folder=%s&host=%s" % \ (html.urlencode(folder), html.urlencode(hostname)) if where == "inventory": url += "&mode=inventory" help_txt = _("Edit services") icon = "services" else: url += "&mode=edit_host" help_txt = _("Edit this host") icon = "wato" return icon, help_txt, url return None
def show_without_timeseries(self): @site_query def query(cls, properties, context): return [ "host_name", "service_check_command", "service_description", "service_perf_data", "service_state" ] col_names, data = query( # pylint: disable=unbalanced-tuple-unpacking self, json.dumps(self.vs_parameters().value_to_json(self._dashlet_spec)), self._dashlet_spec["context"]) if not data: raise MKUserError(None, _("There are no metrics meeting your context filters.")) row = dict(zip(col_names, data[0])) site = row["site"] host = row["host_name"] service = row["service_description"] metric = self._dashlet_spec.get("metric", "") t_metrics = translate_perf_data(row["service_perf_data"], row["service_check_command"]) chosen_metric = t_metrics.get(metric) if chosen_metric is None: raise MKUserError( None, _("The configured metric \"%s\" could not be found. For the " "selected service \"%s\" you can choose from the following metrics: %s") % (metric, service, ", ".join([m["title"] for m in t_metrics.values()]))) svc_url = "view.py?view_name=service&site=%s&host=%s&service=%s" % ( html.urlencode(site), html.urlencode(host), html.urlencode(service)) links = { "site": html.render_a(site, "view.py?view_name=sitehosts&site=%s" % (html.urlencode(site))), "host": html.render_a( host, "view.py?view_name=host&site=%s&host=%s" % (html.urlencode(site), html.urlencode(host))), "service": html.render_a(service, svc_url) } render_options = self._dashlet_spec["render_options"] svc_state = row["service_state"] html.open_div(class_="metric") metric_spec = { "site": site, "host": host, "service": service, "metric": chosen_metric.get("title", metric) } titles = self._get_titles(metric_spec, links, render_options) self._render_metric_content(chosen_metric, render_options, titles, svc_state, svc_url) html.close_div()
def show(self): host = self._dashlet_spec['context'].get("host", html.request.var("host")) if not host: raise MKUserError('host', _('Missing needed host parameter.')) service = self._dashlet_spec['context'].get("service") if not service: service = "_HOST_" metric = self._dashlet_spec["metric"] if "metric" in self._dashlet_spec else "" site = self._get_site_by_host_name(host) metric_spec = {"site": site, "host": host, "service": service, "metric": metric} svc_url = "view.py?view_name=service&site=%s&host=%s&service=%s" % ( html.urlencode(site), html.urlencode(host), html.urlencode(service)) links = { "site": html.render_a(site, "view.py?view_name=sitehosts&site=%s" % (html.urlencode(site))), "host": html.render_a( host, "view.py?view_name=host&site=%s&host=%s" % (html.urlencode(site), html.urlencode(host))), "service": html.render_a(service, svc_url) } render_options = self._dashlet_spec["metric_render_options"] metrics = self._query_for_metrics_of_host(site, host, service) t_metrics = self._get_translated_metrics_from_perf_data(metrics) chosen_metric_name, metric_choices = self._get_chosen_metric(t_metrics, metric) svc_state = metrics["svc_state"] html.open_div(class_="metric") if metrics: if chosen_metric_name: chosen_metric = t_metrics[chosen_metric_name] titles = self._get_titles(metric_spec, links, render_options) self._render_metric_content(chosen_metric, render_options, titles, svc_state, svc_url) else: html.open_div(class_="no_metric_match") if metric_choices: # TODO: Fix this handling of no available/matching metric # after the implementation of host/site contexts warning_txt = HTML( _("The given metric \"%s\" could not be found.\ For the selected service \"%s\" you can choose from the following metrics:" % (metric, service))) warning_txt += html.render_ul("".join( [str(html.render_li(b)) for _a, b in metric_choices])) html.show_warning(warning_txt) else: html.show_warning(_("No metric could be found.")) html.close_div() else: html.show_warning(_("There are no metrics meeting your context filters.")) html.close_div()
def _handle_not_authenticated(): if _fail_silently(): # While api call don't show the login dialog raise MKUnauthenticatedException(_('You are not authenticated.')) # Redirect to the login-dialog with the current url as original target # Never render the login form directly when accessing urls like "index.py" # or "dashboard.py". This results in strange problems. if html.myfile != 'login': raise HTTPRedirect( '%scheck_mk/login.py?_origtarget=%s' % (config.url_prefix(), html.urlencode(html.makeuri([])))) # This either displays the login page or validates the information submitted # to the login form. After successful login a http redirect to the originally # requested page is performed. login_page = login.LoginPage() login_page.set_no_html_output(_plain_error()) login_page.handle_page()
def render(self, what, row, tags, custom_vars): # service_check_command looks like: # u"check_mk_active-bi_aggr!... '-b' 'http://localhost/$HOSTNAME$' ... '-a' 'Host foobar' ..." if what == "service" and row.get("service_check_command", "").startswith("check_mk_active-bi_aggr!"): args = row['service_check_command'] start = args.find('-b\' \'') + 5 end = args.find('\' ', start) base_url = args[start:end].rstrip('/') base_url = base_url.replace('$HOSTADDRESS$', row['host_address']) base_url = base_url.replace('$HOSTNAME$', row['host_name']) start = args.find('-a\' \'') + 5 end = args.find('\' ', start) aggr_name = args[start:end] url = "%s/check_mk/view.py?view_name=aggr_single&aggr_name=%s" % \ (base_url, html.urlencode(aggr_name)) return 'aggr', _('Open this Aggregation'), url
def _check_auth_cookie(cookie_name: str) -> Optional[UserId]: username, session_id, cookie_hash = _parse_auth_cookie(cookie_name) _check_parsed_auth_cookie(username, session_id, cookie_hash) try: userdb.on_access(username, session_id) except MKAuthException: del_auth_cookie() raise # Once reached this the cookie is a good one. Renew it! _renew_cookie(cookie_name, username, session_id) if html.myfile != 'user_change_pw': result = userdb.need_to_change_pw(username) if result: raise HTTPRedirect('user_change_pw.py?_origtarget=%s&reason=%s' % (html.urlencode(html.makeuri([])), result)) # Return the authenticated username return username
def test_htmllib_integration(register_builtin_html): assert type(html.encoder) == htmllib.Encoder assert html.urlencode_vars([]) == "" assert html.urlencode("") == ""
def do_login(): # handle the sent login form if html.request.var('_login'): try: username = html.get_unicode_input('_username', '').rstrip() if username == '': raise MKUserError('_username', _('No username given.')) password = html.request.var('_password', '') if password == '': raise MKUserError('_password', _('No password given.')) default_origtarget = config.url_prefix() + "check_mk/" origtarget = html.get_url_input("_origtarget", default_origtarget) # Disallow redirections to: # - logout.py: Happens after login # - side.py: Happens when invalid login is detected during sidebar refresh if "logout.py" in origtarget or 'side.py' in origtarget: origtarget = default_origtarget # None -> User unknown, means continue with other connectors # '<user_id>' -> success # False -> failed result = userdb.hook_login(username, password) if result: # use the username provided by the successful login function, this function # might have transformed the username provided by the user. e.g. switched # from mixed case to lower case. username = result # When single user session mode is enabled, check that there is not another # active session userdb.ensure_user_can_init_session(username) # reset failed login counts userdb.on_succeeded_login(username) # The login succeeded! Now: # a) Set the auth cookie # b) Unset the login vars in further processing # c) Redirect to really requested page create_auth_session(username) # Never use inplace redirect handling anymore as used in the past. This results # in some unexpected situations. We simpy use 302 redirects now. So we have a # clear situation. # userdb.need_to_change_pw returns either False or the reason description why the # password needs to be changed result = userdb.need_to_change_pw(username) if result: raise HTTPRedirect('user_change_pw.py?_origtarget=%s&reason=%s' % (html.urlencode(origtarget), result)) else: raise HTTPRedirect(origtarget) else: userdb.on_failed_login(username) raise MKUserError(None, _('Invalid credentials.')) except MKUserError as e: html.add_user_error(e.varname, e) return "%s" % e
def test_htmllib_integration(register_builtin_html): assert isinstance(html.encoder, URLEncoder) assert html.urlencode_vars([]) == "" assert html.urlencode("") == ""
def show(self): mode = self._host_mode_ident() sites.live().set_prepend_site(True) query = "GET hosts\nColumns: name state worst_service_state\nLimit: 100\n" view = "host" if mode == "problems": view = "problemsofhost" # Exclude hosts and services in downtime svc_query = "GET services\nColumns: host_name\n"\ "Filter: state > 0\nFilter: scheduled_downtime_depth = 0\n"\ "Filter: host_scheduled_downtime_depth = 0\nAnd: 3" problem_hosts = {x[1] for x in sites.live().query(svc_query)} query += "Filter: state > 0\nFilter: scheduled_downtime_depth = 0\nAnd: 2\n" for host in problem_hosts: query += "Filter: name = %s\n" % host query += "Or: %d\n" % (len(problem_hosts) + 1) hosts = sites.live().query(query) sites.live().set_prepend_site(False) hosts.sort() longestname = 0 for site, host, state, worstsvc in hosts: longestname = max(longestname, len(host)) if longestname > 15: num_columns = 1 else: num_columns = 2 target = views.get_context_link(config.user.id, view) html.open_table(class_="allhosts") col = 1 for site, host, state, worstsvc in hosts: if col == 1: html.open_tr() html.open_td() if state > 0 or worstsvc == 2: statecolor = 2 elif worstsvc == 1: statecolor = 1 elif worstsvc == 3: statecolor = 3 else: statecolor = 0 html.open_div(class_=["statebullet", "state%d" % statecolor]) html.nbsp() html.close_div() link(host, target + "&host=%s&site=%s" % (html.urlencode(host), html.urlencode(site))) html.close_td() if col == num_columns: html.close_tr() col = 1 else: col += 1 if col < num_columns: html.close_tr() html.close_table()
def show(self): hosts = self._get_hosts() num_hosts = len(hosts) if num_hosts > 900: html.write_text( _("Sorry, I will not display more than 900 hosts.")) return # Choose smallest square number large enough # to show all hosts n = 1 while n * n < num_hosts: n += 1 rows = int(num_hosts / n) lastcols = num_hosts % n if lastcols > 0: rows += 1 # Calculate cell size (Automatic sizing with 100% does not work here) # - Get cell spacing: 1px between each cell # - Substract the cell spacing for each column from the total width # - Then divide the total width through the number of columns # - Then get the full-digit width of the cell and summarize the rest # to be substracted from the cell width # This is not a 100% solution but way better than having no links cell_spacing = 1 cell_size = int((snapin_width - cell_spacing * (n + 1)) / n) cell_size, cell_size_rest = divmod(cell_size, 1) style = 'width:%spx' % (snapin_width - n * cell_size_rest) html.open_table(class_=["content_center", "hostmatrix"], cellspacing="0", style=["border-collapse:collapse;", style]) col = 1 row = 1 for site, host, state, has_been_checked, worstsvc, downtimedepth in sorted( hosts): if col == 1: html.open_tr() if downtimedepth > 0: s = "d" elif not has_been_checked: s = "p" elif worstsvc == 2 or state == 1: s = "2" elif worstsvc == 3 or state == 2: s = "3" elif worstsvc == 1: s = "1" else: s = "0" url = "view.py?view_name=host&site=%s&host=%s" % ( html.urlencode(site), html.urlencode(host)) html.open_td(class_=["state", "state%s" % s]) html.a( '', href=url, title=host, target="main", style=["width:%spx;" % cell_size, "height:%spx;" % cell_size]) html.close_td() if col == n or (row == rows and n == lastcols): html.open_tr() col = 1 row += 1 else: col += 1 html.close_table()
def clone_url(self): backurl = html.urlencode(html.makeuri([])) return "edit_%s.py?load_user=%s&load_name=%s&mode=clone&back=%s" \ % (self.type_name(), self.owner(), self.name(), backurl)
def add_url(cls): return 'create_view_dashlet.py?name=%s&back=%s' % \ (html.urlencode(html.request.var('name')), html.urlencode(html.makeuri([('edit', '1')])))
def show(self, width, context): hosts = self._get_livestatus(context) num_hosts = len(hosts) if num_hosts > 900: html.write_text(_("Sorry, I will not display more than 900 hosts.")) return # Choose smallest square number large enough # to show all hosts n = 1 while n * n < num_hosts: n += 1 rows = int(num_hosts / n) lastcols = num_hosts % n if lastcols > 0: rows += 1 # Calculate cell size (Automatic sizing with 100% does not work here) # This is not a 100% solution but way better than having no links cell_spacing = 3 cell_size = (width - cell_spacing * n) / n cell_height = 2 * cell_size / 3 # Add one cell_spacing so that the cells fill the whole snapin width. # The spacing of the last cell overflows on the right. html.open_table(class_=["hostmatrix"], style=['width:%spx' % (width + cell_spacing)]) col, row = 1, 1 for site, host, state, has_been_checked, worstsvc, downtimedepth in sorted(hosts): if col == 1: html.open_tr() if downtimedepth > 0: s = "d" elif not has_been_checked: s = "p" elif worstsvc == 2 or state == 1: s = "2" elif worstsvc == 3 or state == 2: s = "3" elif worstsvc == 1: s = "1" else: s = "0" url = "view.py?view_name=host&site=%s&host=%s" % (html.urlencode(site), html.urlencode(host)) html.open_td(style=[ "width:%.2fpx" % (cell_size + cell_spacing), "height:%.2fpx" % (cell_height + cell_spacing) ]) html.a('', href=url, title=host, target="main", class_=["state", "state%s" % s], style=["width:%.2fpx;" % cell_size, "height:%.2fpx;" % cell_height]) html.close_td() if col == n or (row == rows and n == lastcols): html.open_tr() col = 1 row += 1 else: col += 1 html.close_table()